summaryrefslogtreecommitdiffstats
path: root/crates
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2024-04-28 17:08:38 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2024-04-28 17:11:13 +0200
commit1ff5827e6a1b4f8b58b1790aa1843c7cd7a54ea8 (patch)
treef740b136f63a0b083afb4fa364014c3df5d96f50 /crates
parent48af91375ad9466874d516543641c4ff68d9936e (diff)
downloadrebel-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.
Diffstat (limited to 'crates')
-rw-r--r--crates/rebel-lang/src/scope.rs39
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)