summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2024-04-28 23:10:23 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2024-04-28 23:10:23 +0200
commit8e19452f3271e9c746ad00b1b93b8b3b1f687e4c (patch)
tree1c5b6999193c861dfbdf664503dbf8f54219247f
parentb6e97c70ae13fff134c0b26a21fef25e7f441ca8 (diff)
downloadrebel-8e19452f3271e9c746ad00b1b93b8b3b1f687e4c.tar
rebel-8e19452f3271e9c746ad00b1b93b8b3b1f687e4c.zip
rebel-lang: distinguish explicit and inferred type of variables
-rw-r--r--crates/rebel-lang/benches/recipe.rs24
-rw-r--r--crates/rebel-lang/src/scope.rs25
-rw-r--r--crates/rebel-lang/src/typing.rs5
-rw-r--r--crates/rebel-lang/src/value.rs5
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> {