diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-04-28 23:10:23 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-04-28 23:10:23 +0200 |
commit | 8e19452f3271e9c746ad00b1b93b8b3b1f687e4c (patch) | |
tree | 1c5b6999193c861dfbdf664503dbf8f54219247f | |
parent | b6e97c70ae13fff134c0b26a21fef25e7f441ca8 (diff) | |
download | rebel-8e19452f3271e9c746ad00b1b93b8b3b1f687e4c.tar rebel-8e19452f3271e9c746ad00b1b93b8b3b1f687e4c.zip |
rebel-lang: distinguish explicit and inferred type of variables
-rw-r--r-- | crates/rebel-lang/benches/recipe.rs | 24 | ||||
-rw-r--r-- | crates/rebel-lang/src/scope.rs | 25 | ||||
-rw-r--r-- | crates/rebel-lang/src/typing.rs | 5 | ||||
-rw-r--r-- | crates/rebel-lang/src/value.rs | 5 |
4 files changed, 41 insertions, 18 deletions
diff --git a/crates/rebel-lang/benches/recipe.rs b/crates/rebel-lang/benches/recipe.rs index ceb8520..b1e08c2 100644 --- a/crates/rebel-lang/benches/recipe.rs +++ b/crates/rebel-lang/benches/recipe.rs @@ -1,5 +1,5 @@ use rebel_lang::{ - scope::{Context, ModuleEntry}, + scope::{Context, ModuleEntry, Var}, typing::Type, }; use rebel_parse::ast; @@ -18,12 +18,22 @@ fn recipe() -> ast::Recipe<'static> { fn context() -> Context { let mut ctx = Context::default(); - ctx.values - .0 - .insert("workdir".to_owned(), ModuleEntry::Def((Type::Str, None))); - ctx.values - .0 - .insert("name".to_owned(), ModuleEntry::Def((Type::Str, None))); + ctx.vars.0.insert( + "workdir".to_owned(), + ModuleEntry::Def(Var { + explicit_type: Type::Str, + inferred_type: Type::Str, + value: None, + }), + ); + ctx.vars.0.insert( + "name".to_owned(), + ModuleEntry::Def(Var { + explicit_type: Type::Str, + inferred_type: Type::Str, + value: None, + }), + ); ctx } diff --git a/crates/rebel-lang/src/scope.rs b/crates/rebel-lang/src/scope.rs index d57a1f4..533af54 100644 --- a/crates/rebel-lang/src/scope.rs +++ b/crates/rebel-lang/src/scope.rs @@ -8,9 +8,16 @@ use crate::{ value::{self, EvalError, Value}, }; +#[derive(Debug, Clone)] +pub struct Var { + pub explicit_type: Type, + pub inferred_type: Type, + pub value: Option<Value>, +} + #[derive(Debug, Clone, Default)] pub struct Context { - pub values: Module<(Type, Option<Value>)>, + pub vars: Module<Var>, pub methods: HashMap<TypeFamily, HashMap<&'static str, Func>>, } @@ -36,9 +43,13 @@ impl Context { }; // TODO: Lexical scoping - self.values.0.insert( + self.vars.0.insert( dest_ident.name.to_owned(), - ModuleEntry::Def((typ.clone(), None)), + ModuleEntry::Def(Var { + explicit_type: Type::Free, + inferred_type: typ.clone(), + value: None, + }), ); Ok(typ) @@ -70,9 +81,13 @@ impl Context { }; // TODO: Lexical scoping - self.values.0.insert( + self.vars.0.insert( dest_ident.name.to_owned(), - ModuleEntry::Def((typ, Some(value.clone()))), + ModuleEntry::Def(Var { + explicit_type: Type::Free, + inferred_type: typ, + value: Some(value.clone()), + }), ); Ok(value) diff --git a/crates/rebel-lang/src/typing.rs b/crates/rebel-lang/src/typing.rs index ebb3116..6d8ee8b 100644 --- a/crates/rebel-lang/src/typing.rs +++ b/crates/rebel-lang/src/typing.rs @@ -264,11 +264,10 @@ impl Type { return Ok(Free); } - ctx.values + ctx.vars .lookup(&path.components) - .map(|(typ, _)| typ) + .map(|var| var.inferred_type.clone()) .ok_or(TypeError) - .cloned() } fn check_string_piece(ctx: &Context, piece: &ast::StrPiece, kind: ast::StrKind) -> Result<()> { diff --git a/crates/rebel-lang/src/value.rs b/crates/rebel-lang/src/value.rs index 112f689..48d6272 100644 --- a/crates/rebel-lang/src/value.rs +++ b/crates/rebel-lang/src/value.rs @@ -252,11 +252,10 @@ impl Value { return Err(EvalError); } - ctx.values + ctx.vars .lookup(&path.components) - .and_then(|(_, val)| val.as_ref()) + .and_then(|var| var.value.clone()) .ok_or(EvalError) - .cloned() } fn eval_literal(ctx: &Context, lit: &ast::Literal<'_>) -> Result<Value> { |