added strings
This commit is contained in:
@@ -20,6 +20,7 @@ This language is under active development, progress will be marked here as the l
|
|||||||
- [x] Functions
|
- [x] Functions
|
||||||
- [x] Int Literals
|
- [x] Int Literals
|
||||||
- [x] Float Literals
|
- [x] Float Literals
|
||||||
|
- [x] String Literals
|
||||||
- [x] Block expression
|
- [x] Block expression
|
||||||
- [x] Return keyword
|
- [x] Return keyword
|
||||||
- [x] Normal assignment
|
- [x] Normal assignment
|
||||||
|
|||||||
5
examples/strings.bl
Normal file
5
examples/strings.bl
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
|
fn main(): String {
|
||||||
|
return "foo";
|
||||||
|
}
|
||||||
@@ -172,6 +172,12 @@ pub struct LiteralBool {
|
|||||||
pub type_: TypeUsage,
|
pub type_: TypeUsage,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct LiteralString {
|
||||||
|
pub value: Spanned<String>,
|
||||||
|
pub type_: TypeUsage,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct LiteralStruct {
|
pub struct LiteralStruct {
|
||||||
pub type_parameters: GenericUsage,
|
pub type_parameters: GenericUsage,
|
||||||
@@ -227,6 +233,7 @@ pub enum Subexpression {
|
|||||||
LiteralInt(LiteralInt),
|
LiteralInt(LiteralInt),
|
||||||
LiteralFloat(LiteralFloat),
|
LiteralFloat(LiteralFloat),
|
||||||
LiteralBool(LiteralBool),
|
LiteralBool(LiteralBool),
|
||||||
|
LiteralString(LiteralString),
|
||||||
LiteralStruct(LiteralStruct),
|
LiteralStruct(LiteralStruct),
|
||||||
FunctionCall(FunctionCall),
|
FunctionCall(FunctionCall),
|
||||||
VariableUsage(VariableUsage),
|
VariableUsage(VariableUsage),
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::ast;
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ match {
|
|||||||
"struct",
|
"struct",
|
||||||
"impl",
|
"impl",
|
||||||
",",
|
",",
|
||||||
|
r"'(\\'|[^'])*'",
|
||||||
|
r#""(\\"|[^"])*""#,
|
||||||
|
|
||||||
r"\s*" => { },
|
r"\s*" => { },
|
||||||
r"//[^\n\r]*[\n\r]*" => { }, // `// comment`
|
r"//[^\n\r]*[\n\r]*" => { }, // `// comment`
|
||||||
@@ -65,6 +67,16 @@ pub SpannedLiteralBool: ast::LiteralBool = {
|
|||||||
<literal_bool:Spanned<LiteralBool>> => ast::LiteralBool{value: literal_bool, type_: ast::TypeUsage::new_builtin("bool".to_string())}
|
<literal_bool:Spanned<LiteralBool>> => ast::LiteralBool{value: literal_bool, type_: ast::TypeUsage::new_builtin("bool".to_string())}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub LiteralString: String = {
|
||||||
|
<s:r"'(\\'|[^'])*'"> => String::from(&s[1..s.len()-1]),
|
||||||
|
<s:r#""(\\"|[^"])*""#> => String::from(&s[1..s.len()-1]),
|
||||||
|
};
|
||||||
|
|
||||||
|
pub SpannedLiteralString: ast::LiteralString = {
|
||||||
|
<literal_string:Spanned<LiteralString>> => ast::LiteralString{value: literal_string, type_: ast::TypeUsage::new_builtin("String".to_string())}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
pub Identifier: String = {
|
pub Identifier: String = {
|
||||||
<i:r"[A-Za-z_][A-Za-z0-9_]*"> => i.to_string()
|
<i:r"[A-Za-z_][A-Za-z0-9_]*"> => i.to_string()
|
||||||
};
|
};
|
||||||
@@ -163,6 +175,7 @@ pub Term: ast::Expression = {
|
|||||||
SpannedLiteralInt => ast::Expression{subexpression: Box::new(ast::Subexpression::LiteralInt(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
|
SpannedLiteralInt => ast::Expression{subexpression: Box::new(ast::Subexpression::LiteralInt(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
|
||||||
SpannedLiteralFloat => ast::Expression{subexpression: Box::new(ast::Subexpression::LiteralFloat(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
|
SpannedLiteralFloat => ast::Expression{subexpression: Box::new(ast::Subexpression::LiteralFloat(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
|
||||||
SpannedLiteralBool => ast::Expression{subexpression: Box::new(ast::Subexpression::LiteralBool(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
|
SpannedLiteralBool => ast::Expression{subexpression: Box::new(ast::Subexpression::LiteralBool(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
|
||||||
|
SpannedLiteralString => ast::Expression{subexpression: Box::new(ast::Subexpression::LiteralString(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
|
||||||
LiteralStruct => ast::Expression{subexpression: Box::new(ast::Subexpression::LiteralStruct(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
|
LiteralStruct => ast::Expression{subexpression: Box::new(ast::Subexpression::LiteralStruct(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
|
||||||
FunctionCall => ast::Expression{subexpression: Box::new(ast::Subexpression::FunctionCall(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
|
FunctionCall => ast::Expression{subexpression: Box::new(ast::Subexpression::FunctionCall(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
|
||||||
StructGetter => ast::Expression{subexpression: Box::new(ast::Subexpression::StructGetter(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
|
StructGetter => ast::Expression{subexpression: Box::new(ast::Subexpression::StructGetter(<>)), type_: ast::TypeUsage::new_unknown(&id_generator)},
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ pub struct Function {
|
|||||||
pub enum Value {
|
pub enum Value {
|
||||||
Numeric(NumericValue),
|
Numeric(NumericValue),
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
|
String(String),
|
||||||
Function(Function),
|
Function(Function),
|
||||||
Struct(Arc<Mutex<StructValue>>),
|
Struct(Arc<Mutex<StructValue>>),
|
||||||
Unit,
|
Unit,
|
||||||
@@ -207,6 +208,12 @@ fn create_builtins() -> HashMap<String, NamedEntity> {
|
|||||||
name: "!".to_string(),
|
name: "!".to_string(),
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
|
result.insert(
|
||||||
|
"String".to_string(),
|
||||||
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
|
||||||
|
name: "String".to_string(),
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -331,6 +338,10 @@ impl TreeWalkInterpreter {
|
|||||||
let value: bool = if &literal_bool.value.value == "true" { true } else { false };
|
let value: bool = if &literal_bool.value.value == "true" { true } else { false };
|
||||||
return ExpressionResult::Value(Value::Bool(value));
|
return ExpressionResult::Value(Value::Bool(value));
|
||||||
}
|
}
|
||||||
|
ast::Subexpression::LiteralString(literal_string) => {
|
||||||
|
let value: String = literal_string.value.value.to_string();
|
||||||
|
return ExpressionResult::Value(Value::String(value));
|
||||||
|
}
|
||||||
ast::Subexpression::LiteralStruct(literal_struct) => {
|
ast::Subexpression::LiteralStruct(literal_struct) => {
|
||||||
let declaration = match &ctx.environment[&literal_struct.name.name.value] {
|
let declaration = match &ctx.environment[&literal_struct.name.name.value] {
|
||||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Struct(declaration)) => declaration.clone(),
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Struct(declaration)) => declaration.clone(),
|
||||||
|
|||||||
@@ -308,6 +308,10 @@ impl TypeAliasResolver {
|
|||||||
value: literal_bool.value.clone(),
|
value: literal_bool.value.clone(),
|
||||||
type_: process_type(ctx, &literal_bool.type_)?,
|
type_: process_type(ctx, &literal_bool.type_)?,
|
||||||
}),
|
}),
|
||||||
|
ast::Subexpression::LiteralString(literal_string) => ast::Subexpression::LiteralString(ast::LiteralString {
|
||||||
|
value: literal_string.value.clone(),
|
||||||
|
type_: process_type(ctx, &literal_string.type_)?,
|
||||||
|
}),
|
||||||
ast::Subexpression::LiteralStruct(literal_struct) => {
|
ast::Subexpression::LiteralStruct(literal_struct) => {
|
||||||
let result = resolve_type(
|
let result = resolve_type(
|
||||||
ctx,
|
ctx,
|
||||||
|
|||||||
@@ -386,6 +386,15 @@ fn create_builtins() -> HashMap<String, NamedEntity> {
|
|||||||
impls: vec![],
|
impls: vec![],
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
result.insert(
|
||||||
|
"String".to_string(),
|
||||||
|
NamedEntity::NamedType(EnvType {
|
||||||
|
generic: ast::Generic{parameters: vec!()},
|
||||||
|
is_a: TypeType::Scalar,
|
||||||
|
fields: HashMap::new(),
|
||||||
|
impls: vec![],
|
||||||
|
}),
|
||||||
|
);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1215,6 +1224,12 @@ impl TypeChecker {
|
|||||||
substitution = compose_substitutions(ctx, &substitution, &unify(ctx, &expression.type_, &result.type_)?)?;
|
substitution = compose_substitutions(ctx, &substitution, &unify(ctx, &expression.type_, &result.type_)?)?;
|
||||||
ast::Subexpression::LiteralBool(result)
|
ast::Subexpression::LiteralBool(result)
|
||||||
}
|
}
|
||||||
|
ast::Subexpression::LiteralString(literal_string) => {
|
||||||
|
let (result, subst) = self.with_literal_string(ctx, &substitution, literal_string)?;
|
||||||
|
substitution = compose_substitutions(ctx, &substitution, &subst)?;
|
||||||
|
substitution = compose_substitutions(ctx, &substitution, &unify(ctx, &expression.type_, &result.type_)?)?;
|
||||||
|
ast::Subexpression::LiteralString(result)
|
||||||
|
}
|
||||||
ast::Subexpression::LiteralStruct(literal_struct) => {
|
ast::Subexpression::LiteralStruct(literal_struct) => {
|
||||||
let (result, subst) = self.with_literal_struct(ctx, &substitution, literal_struct)?;
|
let (result, subst) = self.with_literal_struct(ctx, &substitution, literal_struct)?;
|
||||||
substitution = compose_substitutions(ctx, &substitution, &subst)?;
|
substitution = compose_substitutions(ctx, &substitution, &subst)?;
|
||||||
@@ -1312,6 +1327,21 @@ impl TypeChecker {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn with_literal_string(
|
||||||
|
self: &Self,
|
||||||
|
ctx: &Context,
|
||||||
|
substitution: &SubstitutionMap,
|
||||||
|
literal_string: &ast::LiteralString,
|
||||||
|
) -> Result<(ast::LiteralString, SubstitutionMap)> {
|
||||||
|
Ok((
|
||||||
|
ast::LiteralString {
|
||||||
|
value: literal_string.value.clone(),
|
||||||
|
type_: apply_substitution(ctx, &substitution, &literal_string.type_)?,
|
||||||
|
},
|
||||||
|
substitution.clone(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
fn with_literal_struct(
|
fn with_literal_struct(
|
||||||
self: &Self,
|
self: &Self,
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
|
|||||||
Reference in New Issue
Block a user