diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-04-28 17:08:38 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-04-28 17:11:13 +0200 |
commit | 1ff5827e6a1b4f8b58b1790aa1843c7cd7a54ea8 (patch) | |
tree | f740b136f63a0b083afb4fa364014c3df5d96f50 | |
parent | 48af91375ad9466874d516543641c4ff68d9936e (diff) | |
download | rebel-1ff5827e6a1b4f8b58b1790aa1843c7cd7a54ea8.tar rebel-1ff5827e6a1b4f8b58b1790aa1843c7cd7a54ea8.zip |
rebel-lang: scope: add Context::record_type()
Add a function for incrementally typechecking a list of statements,
without actually evaluating it.
-rw-r--r-- | crates/rebel-lang/src/scope.rs | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/crates/rebel-lang/src/scope.rs b/crates/rebel-lang/src/scope.rs index 3fd7c99..a030f47 100644 --- a/crates/rebel-lang/src/scope.rs +++ b/crates/rebel-lang/src/scope.rs @@ -4,7 +4,7 @@ use rebel_parse::ast; use crate::{ func::Func, - typing::{Type, TypeFamily}, + typing::{self, Type, TypeError, TypeFamily}, value::{self, EvalError, Value}, }; @@ -15,13 +15,46 @@ pub struct Context { } impl Context { + pub fn record_type(&mut self, stmt: &ast::BodyStmt) -> typing::Result<Type> { + match stmt { + ast::BodyStmt::Assign { dest, expr } => { + let typ = Type::ast_expr_type(self, expr)?; + + // TODO: Handle explicit type + let ast::TypedExpr { + expr: dest_expr, + typ: _, + } = dest; + + // TODO: Handle other assignable expressions + let dest_path = match dest_expr { + ast::Expr::Path(path) => path, + _ => return Err(TypeError), + }; + let [dest_ident] = dest_path.components[..] else { + return Err(TypeError); + }; + + // TODO: Lexical scoping + self.values.0.insert( + dest_ident.name.to_owned(), + ModuleEntry::Def((typ.clone(), None)), + ); + + Ok(typ) + } + ast::BodyStmt::Expr { expr } => Type::ast_expr_type(self, expr), + ast::BodyStmt::Empty => Ok(Type::Unit), + } + } + pub fn execute(&mut self, stmt: &ast::BodyStmt) -> value::Result<Value> { match stmt { ast::BodyStmt::Assign { dest, expr } => { let value = Value::eval(self, expr)?; let typ = value.typ().or(Err(EvalError))?; - // TODO: Handle specified type + // TODO: Handle explicit type let ast::TypedExpr { expr: dest_expr, typ: _, @@ -39,7 +72,7 @@ impl Context { // TODO: Lexical scoping self.values.0.insert( dest_ident.name.to_owned(), - ModuleEntry::Def((typ, (Some(value.clone())))), + ModuleEntry::Def((typ, Some(value.clone()))), ); Ok(value) |