summaryrefslogtreecommitdiffstats
path: root/crates/rebel-lang/src/typing.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/rebel-lang/src/typing.rs')
-rw-r--r--crates/rebel-lang/src/typing.rs22
1 files changed, 19 insertions, 3 deletions
diff --git a/crates/rebel-lang/src/typing.rs b/crates/rebel-lang/src/typing.rs
index 6bb0fb5..70fc759 100644
--- a/crates/rebel-lang/src/typing.rs
+++ b/crates/rebel-lang/src/typing.rs
@@ -2,7 +2,7 @@ use std::{collections::HashMap, fmt::Display};
use enum_kinds::EnumKind;
-use rebel_parse::ast::{self, expr, typ};
+use rebel_parse::ast::{self, expr, pat, typ};
use crate::{func::FuncType, scope::Context};
@@ -125,9 +125,25 @@ impl Type {
pub fn ast_stmt_type(ctx: &Context, stmt: &ast::BlockStmt<'_>) -> Result<Type> {
match stmt {
- ast::BlockStmt::Assign { dest: _, expr } => {
+ ast::BlockStmt::Let { dest: _, expr } => {
// TODO: Assignability, dest type
- let dest_type = Type::Free;
+ let mut dest_type = Type::Free;
+ if let Some(expr) = expr {
+ let expr_type = Self::ast_expr_type(ctx, expr)?;
+ dest_type = dest_type.unify(expr_type, Coerce::Assign)?;
+ }
+ Ok(dest_type)
+ }
+ ast::BlockStmt::Assign { dest, expr } => {
+ // TODO: Assignability
+ let pat::Pat::Path(dest_path) = dest.as_ref();
+
+ let dest_type = ctx
+ .vars
+ .lookup(&dest_path.components)
+ .map(|var| var.inferred_type.clone())
+ .ok_or(TypeError)?;
+
let expr_type = Self::ast_expr_type(ctx, expr)?;
dest_type.unify(expr_type, Coerce::Assign)
}