added strings

This commit is contained in:
2022-10-12 11:06:58 -06:00
parent c4be846c1d
commit ce23415663
8 changed files with 73 additions and 0 deletions

View File

@@ -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
View File

@@ -0,0 +1,5 @@
fn main(): String {
return "foo";
}

View File

@@ -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),

View File

@@ -1 +1,3 @@
use std::collections::HashMap; use std::collections::HashMap;
use crate::ast;

View File

@@ -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)},

View File

@@ -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(),

View File

@@ -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,

View File

@@ -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,