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] Int Literals
|
||||
- [x] Float Literals
|
||||
- [x] String Literals
|
||||
- [x] Block expression
|
||||
- [x] Return keyword
|
||||
- [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,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct LiteralString {
|
||||
pub value: Spanned<String>,
|
||||
pub type_: TypeUsage,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct LiteralStruct {
|
||||
pub type_parameters: GenericUsage,
|
||||
@@ -227,6 +233,7 @@ pub enum Subexpression {
|
||||
LiteralInt(LiteralInt),
|
||||
LiteralFloat(LiteralFloat),
|
||||
LiteralBool(LiteralBool),
|
||||
LiteralString(LiteralString),
|
||||
LiteralStruct(LiteralStruct),
|
||||
FunctionCall(FunctionCall),
|
||||
VariableUsage(VariableUsage),
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::ast;
|
||||
|
||||
@@ -34,6 +34,8 @@ match {
|
||||
"struct",
|
||||
"impl",
|
||||
",",
|
||||
r"'(\\'|[^'])*'",
|
||||
r#""(\\"|[^"])*""#,
|
||||
|
||||
r"\s*" => { },
|
||||
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())}
|
||||
};
|
||||
|
||||
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 = {
|
||||
<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)},
|
||||
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)},
|
||||
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)},
|
||||
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)},
|
||||
|
||||
@@ -44,6 +44,7 @@ pub struct Function {
|
||||
pub enum Value {
|
||||
Numeric(NumericValue),
|
||||
Bool(bool),
|
||||
String(String),
|
||||
Function(Function),
|
||||
Struct(Arc<Mutex<StructValue>>),
|
||||
Unit,
|
||||
@@ -207,6 +208,12 @@ fn create_builtins() -> HashMap<String, NamedEntity> {
|
||||
name: "!".to_string(),
|
||||
})),
|
||||
);
|
||||
result.insert(
|
||||
"String".to_string(),
|
||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
|
||||
name: "String".to_string(),
|
||||
})),
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -331,6 +338,10 @@ impl TreeWalkInterpreter {
|
||||
let value: bool = if &literal_bool.value.value == "true" { true } else { false };
|
||||
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) => {
|
||||
let declaration = match &ctx.environment[&literal_struct.name.name.value] {
|
||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Struct(declaration)) => declaration.clone(),
|
||||
|
||||
@@ -308,6 +308,10 @@ impl TypeAliasResolver {
|
||||
value: literal_bool.value.clone(),
|
||||
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) => {
|
||||
let result = resolve_type(
|
||||
ctx,
|
||||
|
||||
@@ -386,6 +386,15 @@ fn create_builtins() -> HashMap<String, NamedEntity> {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1215,6 +1224,12 @@ impl TypeChecker {
|
||||
substitution = compose_substitutions(ctx, &substitution, &unify(ctx, &expression.type_, &result.type_)?)?;
|
||||
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) => {
|
||||
let (result, subst) = self.with_literal_struct(ctx, &substitution, literal_struct)?;
|
||||
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(
|
||||
self: &Self,
|
||||
ctx: &Context,
|
||||
|
||||
Reference in New Issue
Block a user