diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-05-04 13:54:37 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-05-04 13:54:37 +0200 |
commit | 3ac52564f990c074462cd92e4787eb65c6005bb0 (patch) | |
tree | 45b9fbc7aeef4b349ad8bb7e5ce6a542b1f04112 /crates | |
parent | 8d0d0b253286decb4bb3eeccdc33fef92c203fa6 (diff) | |
download | rebel-3ac52564f990c074462cd92e4787eb65c6005bb0.tar rebel-3ac52564f990c074462cd92e4787eb65c6005bb0.zip |
rebel-lang: make method naming more consistent
Diffstat (limited to 'crates')
-rw-r--r-- | crates/rebel-lang/benches/recipe.rs | 4 | ||||
-rw-r--r-- | crates/rebel-lang/examples/repl.rs | 4 | ||||
-rw-r--r-- | crates/rebel-lang/src/typing.rs | 178 | ||||
-rw-r--r-- | crates/rebel-lang/src/value.rs | 98 |
4 files changed, 142 insertions, 142 deletions
diff --git a/crates/rebel-lang/benches/recipe.rs b/crates/rebel-lang/benches/recipe.rs index fdeda50..b2c8f64 100644 --- a/crates/rebel-lang/benches/recipe.rs +++ b/crates/rebel-lang/benches/recipe.rs @@ -65,7 +65,7 @@ fn typecheck(bencher: divan::Bencher) { continue; }; - ctx.record_type(stmt).unwrap(); + ctx.type_block_stmt(stmt).unwrap(); } }); } @@ -88,7 +88,7 @@ fn execute(bencher: divan::Bencher) { continue; }; - ctx.execute(stmt).unwrap(); + ctx.eval_block_stmt(stmt).unwrap(); } }); } diff --git a/crates/rebel-lang/examples/repl.rs b/crates/rebel-lang/examples/repl.rs index 92bda70..7ed3966 100644 --- a/crates/rebel-lang/examples/repl.rs +++ b/crates/rebel-lang/examples/repl.rs @@ -109,7 +109,7 @@ fn main() { let mut type_scope_tmp = type_scope.clone(); let mut type_ctx = typing::Context(&mut type_scope_tmp); - let typ = match type_ctx.record_type(&stmt) { + let typ = match type_ctx.type_block_stmt(&stmt) { Ok(typ) => typ, Err(err) => { println!("Type checking failed: {err}"); @@ -119,7 +119,7 @@ fn main() { let mut value_scope_tmp = value_scope.clone(); let mut value_ctx = value::Context(&mut value_scope_tmp); - let value = match value_ctx.execute(&stmt) { + let value = match value_ctx.eval_block_stmt(&stmt) { Ok(value) => value, Err(err) => { println!("Evaluation failed: {err}"); diff --git a/crates/rebel-lang/src/typing.rs b/crates/rebel-lang/src/typing.rs index 10563d0..5fd9341 100644 --- a/crates/rebel-lang/src/typing.rs +++ b/crates/rebel-lang/src/typing.rs @@ -104,21 +104,21 @@ impl Type { } impl<'scope> Context<'scope> { - pub fn ast_type(&self, typ: &typ::Type<'_>) -> Result<Type> { + pub fn type_type(&self, typ: &typ::Type<'_>) -> Result<Type> { use typ::Type::*; Ok(match typ { - Paren(subexpr) => self.ast_type(subexpr)?, - Path(path) => self.path_type(path)?, - Literal(lit) => self.literal_type(lit)?, + Paren(subexpr) => self.type_type(subexpr)?, + Path(path) => self.type_type_path(path)?, + Literal(lit) => self.type_type_literal(lit)?, }) } - fn path_type(&self, path: &ast::Path<'_>) -> Result<Type> { + fn type_type_path(&self, path: &ast::Path<'_>) -> Result<Type> { self.0.lookup_type(path).cloned() } - fn literal_type(&self, lit: &typ::Literal<'_>) -> Result<Type> { + fn type_type_literal(&self, lit: &typ::Literal<'_>) -> Result<Type> { use typ::Literal; use Type::*; @@ -127,42 +127,89 @@ impl<'scope> Context<'scope> { Literal::Tuple(elems) => Tuple( elems .iter() - .map(|elem| self.ast_type(elem)) + .map(|elem| self.type_type(elem)) .collect::<Result<_>>()?, ), - Literal::Array(typ) => Array(Box::new(self.ast_type(typ)?)), + Literal::Array(typ) => Array(Box::new(self.type_type(typ)?)), Literal::Struct(entries) => Struct( entries .iter() .map(|typ::StructField { name, typ }| { - Ok(((*name).to_owned(), self.ast_type(typ)?)) + Ok(((*name).to_owned(), self.type_type(typ)?)) }) .collect::<Result<_>>()?, ), }) } - pub fn ast_expr_type(&self, expr: &expr::Expr<'_>) -> Result<Type> { + pub fn type_block_stmt(&mut self, stmt: &ast::BlockStmt) -> Result<Type> { + Ok(match stmt { + ast::BlockStmt::Let { dest, expr } => { + let ast::TypedPat { pat, typ } = dest.as_ref(); + + let dest_ident = scope::pat_ident(pat); + + let explicit_type = if let Some(typ) = typ { + self.type_type(typ)? + } else { + Type::Free + }; + + let expr_type = expr + .as_ref() + .map(|expr| { + let expr_type = self.type_expr(expr)?; + explicit_type + .clone() + .unify(expr_type.clone(), Coerce::Assign)?; + Ok(expr_type) + }) + .transpose()?; + + if dest_ident.name == "_" { + return Ok(Type::Unit); + } + + self.0 + .defs + .insert_value(dest_ident.name, VarType::new(explicit_type, false)); + + let Some(expr_type) = expr_type else { + return Ok(Type::Unit); + }; + + self.assign_destr_pat_type(&pat::DestrPat::from(pat), expr_type)? + } + ast::BlockStmt::Assign { dest, expr } => { + let expr_type = self.type_expr(expr)?; + self.assign_destr_pat_type(dest, expr_type)? + } + ast::BlockStmt::Expr { expr } => self.type_expr(expr)?, + ast::BlockStmt::Empty => Type::Unit, + }) + } + + pub fn type_expr(&self, expr: &expr::Expr<'_>) -> Result<Type> { use expr::Expr::*; match expr { - Binary { left, op, right } => self.binary_op_expr_type(left, *op, right), - Unary { op, expr } => self.unary_op_expr_type(*op, expr), - Apply { expr, params } => self.apply_expr_type(expr, params), + Binary { left, op, right } => self.type_binary_op(left, *op, right), + Unary { op, expr } => self.type_unary_op(*op, expr), + Apply { expr, params } => self.type_apply(expr, params), Method { expr, method, params, - } => self.method_expr_type(expr, method, params), - Index { base, index } => self.index_expr_type(base, index), - Field { base, field } => self.field_expr_type(base, field), - Paren(subexpr) => self.ast_expr_type(subexpr), - Path(path) => self.path_expr_type(path), - Literal(lit) => self.literal_expr_type(lit), + } => self.type_method(expr, method, params), + Index { base, index } => self.type_index(base, index), + Field { base, field } => self.type_field(base, field), + Paren(subexpr) => self.type_expr(subexpr), + Path(path) => self.type_path(path), + Literal(lit) => self.type_literal(lit), } } - fn binary_op_expr_type( + fn type_binary_op( &self, left: &expr::Expr<'_>, op: expr::OpBinary, @@ -171,8 +218,8 @@ impl<'scope> Context<'scope> { use expr::OpBinary::*; use Type::*; - let tl = self.ast_expr_type(left)?; - let tr = self.ast_expr_type(right)?; + let tl = self.type_expr(left)?; + let tr = self.type_expr(right)?; Ok(match (tl, op, tr) { (Str, Add, Str) => Str, @@ -208,11 +255,11 @@ impl<'scope> Context<'scope> { }) } - fn unary_op_expr_type(&self, op: expr::OpUnary, expr: &expr::Expr<'_>) -> Result<Type> { + fn type_unary_op(&self, op: expr::OpUnary, expr: &expr::Expr<'_>) -> Result<Type> { use expr::OpUnary::*; use Type::*; - let typ = self.ast_expr_type(expr)?; + let typ = self.type_expr(expr)?; Ok(match (op, typ) { (Not, Bool) => Bool, @@ -221,11 +268,11 @@ impl<'scope> Context<'scope> { }) } - fn index_expr_type(&self, base: &expr::Expr<'_>, index: &expr::Expr<'_>) -> Result<Type> { + fn type_index(&self, base: &expr::Expr<'_>, index: &expr::Expr<'_>) -> Result<Type> { use Type::*; - let base_type = self.ast_expr_type(base)?; - let index_type = self.ast_expr_type(index)?; + let base_type = self.type_expr(base)?; + let index_type = self.type_expr(index)?; let Array(elem_type) = base_type else { return Err(Error::typ("invalid array index base")); @@ -236,10 +283,10 @@ impl<'scope> Context<'scope> { Ok(*elem_type) } - fn apply_expr_type(&self, expr: &expr::Expr<'_>, params: &[expr::Expr]) -> Result<Type> { + fn type_apply(&self, expr: &expr::Expr<'_>, params: &[expr::Expr]) -> Result<Type> { use Type::*; - let expr_type = self.ast_expr_type(expr)?; + let expr_type = self.type_expr(expr)?; let Fn(func) = expr_type else { return Err(Error::typ("invalid type for function call")); @@ -252,7 +299,7 @@ impl<'scope> Context<'scope> { } for (func_param_type, call_param) in func.params.iter().zip(params) { - let call_param_type = self.ast_expr_type(call_param)?; + let call_param_type = self.type_expr(call_param)?; func_param_type .clone() .unify(call_param_type, Coerce::Assign)?; @@ -261,13 +308,13 @@ impl<'scope> Context<'scope> { Ok(func.ret) } - fn method_expr_type( + fn type_method( &self, expr: &expr::Expr<'_>, method: &ast::Ident<'_>, params: &[expr::Expr], ) -> Result<Type> { - let expr_type = self.ast_expr_type(expr)?; + let expr_type = self.type_expr(expr)?; let type_family = TypeFamily::from(&expr_type); let method = self @@ -289,7 +336,7 @@ impl<'scope> Context<'scope> { } for (func_param_type, call_param) in func_params.iter().zip(params) { - let call_param_type = self.ast_expr_type(call_param)?; + let call_param_type = self.type_expr(call_param)?; func_param_type .clone() .unify(call_param_type, Coerce::Assign)?; @@ -298,10 +345,10 @@ impl<'scope> Context<'scope> { Ok(method.typ.ret.clone()) } - fn field_expr_type(&self, base: &expr::Expr<'_>, field: &ast::Ident<'_>) -> Result<Type> { + fn type_field(&self, base: &expr::Expr<'_>, field: &ast::Ident<'_>) -> Result<Type> { use Type::*; - let base_type = self.ast_expr_type(base)?; + let base_type = self.type_expr(base)?; let name = field.name; Ok(match base_type { @@ -317,7 +364,7 @@ impl<'scope> Context<'scope> { }) } - fn path_expr_type(&self, path: &ast::Path<'_>) -> Result<Type> { + fn type_path(&self, path: &ast::Path<'_>) -> Result<Type> { Ok(self.0.lookup_value(path)?.inferred_type()?.clone()) } @@ -325,7 +372,7 @@ impl<'scope> Context<'scope> { let typ = match piece { expr::StrPiece::Chars(_) => return Ok(()), expr::StrPiece::Escape(_) => return Ok(()), - expr::StrPiece::Interp(expr) => self.ast_expr_type(expr)?, + expr::StrPiece::Interp(expr) => self.type_expr(expr)?, }; match (typ, kind) { (Type::Bool, _) => Ok(()), @@ -337,7 +384,7 @@ impl<'scope> Context<'scope> { } } - fn literal_expr_type(&self, lit: &expr::Literal<'_>) -> Result<Type> { + fn type_literal(&self, lit: &expr::Literal<'_>) -> Result<Type> { use expr::Literal; use Type::*; @@ -354,19 +401,19 @@ impl<'scope> Context<'scope> { Literal::Tuple(elems) => Tuple( elems .iter() - .map(|elem| self.ast_expr_type(elem)) + .map(|elem| self.type_expr(elem)) .collect::<Result<_>>()?, ), Literal::Array(elems) => Array(Box::new( elems.iter().try_fold(Type::Free, |acc, elem| { - acc.unify(self.ast_expr_type(elem)?, Coerce::Common) + acc.unify(self.type_expr(elem)?, Coerce::Common) })?, )), Literal::Struct(entries) => Struct( entries .iter() .map(|expr::StructField { name, value }| { - Ok(((*name).to_owned(), self.ast_expr_type(value)?)) + Ok(((*name).to_owned(), self.type_expr(value)?)) }) .collect::<Result<_>>()?, ), @@ -379,7 +426,7 @@ impl<'scope> Context<'scope> { ) -> Result<(&mut Type, &mut bool)> { Ok(match pat { pat::DestrPat::Index { base, index } => { - match self.ast_expr_type(index)? { + match self.type_expr(index)? { Type::Int => {} _ => { return Err(Error::typ("invalid array index type")); @@ -444,53 +491,6 @@ impl<'scope> Context<'scope> { Ok(inferred_type) } - - pub fn record_type(&mut self, stmt: &ast::BlockStmt) -> Result<Type> { - Ok(match stmt { - ast::BlockStmt::Let { dest, expr } => { - let ast::TypedPat { pat, typ } = dest.as_ref(); - - let dest_ident = scope::pat_ident(pat); - - let explicit_type = if let Some(typ) = typ { - self.ast_type(typ)? - } else { - Type::Free - }; - - let expr_type = expr - .as_ref() - .map(|expr| { - let expr_type = self.ast_expr_type(expr)?; - explicit_type - .clone() - .unify(expr_type.clone(), Coerce::Assign)?; - Ok(expr_type) - }) - .transpose()?; - - if dest_ident.name == "_" { - return Ok(Type::Unit); - } - - self.0 - .defs - .insert_value(dest_ident.name, VarType::new(explicit_type, false)); - - let Some(expr_type) = expr_type else { - return Ok(Type::Unit); - }; - - self.assign_destr_pat_type(&pat::DestrPat::from(pat), expr_type)? - } - ast::BlockStmt::Assign { dest, expr } => { - let expr_type = self.ast_expr_type(expr)?; - self.assign_destr_pat_type(dest, expr_type)? - } - ast::BlockStmt::Expr { expr } => self.ast_expr_type(expr)?, - ast::BlockStmt::Empty => Type::Unit, - }) - } } impl Display for Type { diff --git a/crates/rebel-lang/src/value.rs b/crates/rebel-lang/src/value.rs index 4a7ce75..9c30ea1 100644 --- a/crates/rebel-lang/src/value.rs +++ b/crates/rebel-lang/src/value.rs @@ -59,7 +59,39 @@ impl Value { } impl<'scope> Context<'scope> { - pub fn eval(&self, expr: &expr::Expr<'_>) -> Result<Value> { + pub fn eval_block_stmt(&mut self, stmt: &ast::BlockStmt) -> Result<Value> { + Ok(match stmt { + ast::BlockStmt::Let { dest, expr } => { + let ast::TypedPat { pat, typ: _ } = dest.as_ref(); + + let dest_ident = scope::pat_ident(pat); + + let value = expr.as_ref().map(|expr| self.eval_expr(expr)).transpose()?; + + if dest_ident.name == "_" { + return Ok(Value::Unit); + } + + self.0 + .defs + .insert_value(dest_ident.name, Value::Uninitialized); + + let Some(value) = value else { + return Ok(Value::Unit); + }; + + self.assign_destr_pat_value(&pat::DestrPat::from(pat), value)? + } + ast::BlockStmt::Assign { dest, expr } => { + let value = self.eval_expr(expr)?; + self.assign_destr_pat_value(dest, value)? + } + ast::BlockStmt::Expr { expr } => self.eval_expr(expr)?, + ast::BlockStmt::Empty => Value::Unit, + }) + } + + pub fn eval_expr(&self, expr: &expr::Expr<'_>) -> Result<Value> { use expr::Expr::*; match expr { @@ -73,7 +105,7 @@ impl<'scope> Context<'scope> { } => self.eval_method(expr, method, params), Index { base, index } => self.eval_index(base, index), Field { base, field } => self.eval_field(base, field), - Paren(subexpr) => self.eval(subexpr), + Paren(subexpr) => self.eval_expr(subexpr), Path(path) => self.eval_path(path), Literal(lit) => self.eval_literal(lit), } @@ -88,8 +120,8 @@ impl<'scope> Context<'scope> { use expr::OpBinary::*; use Value::*; - let tl = self.eval(left)?; - let tr = self.eval(right)?; + let tl = self.eval_expr(left)?; + let tr = self.eval_expr(right)?; Ok(match (tl, op, tr) { (Str(s1), Add, Str(s2)) => Str(s1 + &s2), @@ -135,7 +167,7 @@ impl<'scope> Context<'scope> { use expr::OpUnary::*; use Value::*; - let typ = self.eval(expr)?; + let typ = self.eval_expr(expr)?; Ok(match (op, typ) { (Not, Bool(val)) => Bool(!val), @@ -149,8 +181,8 @@ impl<'scope> Context<'scope> { fn eval_index(&self, base: &expr::Expr<'_>, index: &expr::Expr<'_>) -> Result<Value> { use Value::*; - let base_value = self.eval(base)?; - let index_value = self.eval(index)?; + let base_value = self.eval_expr(base)?; + let index_value = self.eval_expr(index)?; let Array(elems) = base_value else { return Err(Error::typ("invalid array index base")); @@ -170,7 +202,7 @@ impl<'scope> Context<'scope> { fn eval_apply(&self, expr: &expr::Expr<'_>, params: &[expr::Expr]) -> Result<Value> { use Value::*; - let value = self.eval(expr)?; + let value = self.eval_expr(expr)?; let Fn(func) = value else { return Err(Error::typ("invalid type for function call")); @@ -184,7 +216,7 @@ impl<'scope> Context<'scope> { let param_values: Vec<_> = params .iter() - .map(|param| self.eval(param)) + .map(|param| self.eval_expr(param)) .collect::<Result<_>>()?; for (func_param_type, call_param_value) in func.typ.params.iter().zip(¶m_values) { @@ -208,7 +240,7 @@ impl<'scope> Context<'scope> { method: &ast::Ident<'_>, params: &[expr::Expr], ) -> Result<Value> { - let expr_value = self.eval(expr)?; + let expr_value = self.eval_expr(expr)?; let expr_type = expr_value.typ()?; let type_family = TypeFamily::from(&expr_type); @@ -231,7 +263,7 @@ impl<'scope> Context<'scope> { } let param_values: Vec<_> = iter::once(Ok(expr_value)) - .chain(params.iter().map(|param| self.eval(param))) + .chain(params.iter().map(|param| self.eval_expr(param))) .collect::<Result<_>>()?; for (func_param_type, call_param_value) in func_param_types.iter().zip(¶m_values[1..]) { @@ -255,7 +287,7 @@ impl<'scope> Context<'scope> { fn eval_field(&self, base: &expr::Expr<'_>, field: &ast::Ident<'_>) -> Result<Value> { use Value::*; - let base_value = self.eval(base)?; + let base_value = self.eval_expr(base)?; let name = field.name; Ok(match base_value { @@ -292,20 +324,20 @@ impl<'scope> Context<'scope> { Literal::Tuple(elems) => Tuple( elems .iter() - .map(|elem| self.eval(elem)) + .map(|elem| self.eval_expr(elem)) .collect::<Result<_>>()?, ), Literal::Array(elems) => Array( elems .iter() - .map(|elem| self.eval(elem)) + .map(|elem| self.eval_expr(elem)) .collect::<Result<_>>()?, ), Literal::Struct(entries) => Struct( entries .iter() .map(|expr::StructField { name, value }| { - Ok(((*name).to_owned(), self.eval(value)?)) + Ok(((*name).to_owned(), self.eval_expr(value)?)) }) .collect::<Result<_>>()?, ), @@ -315,7 +347,7 @@ impl<'scope> Context<'scope> { fn lookup_destr_pat_var_value_mut(&mut self, pat: &pat::DestrPat) -> Result<&mut Value> { Ok(match pat { pat::DestrPat::Index { base, index } => { - let index = usize::try_from(match self.eval(index)? { + let index = usize::try_from(match self.eval_expr(index)? { Value::Int(index) => index, _ => { return Err(Error::typ("invalid array index type")); @@ -360,38 +392,6 @@ impl<'scope> Context<'scope> { Ok(value) } - - pub fn execute(&mut self, stmt: &ast::BlockStmt) -> Result<Value> { - Ok(match stmt { - ast::BlockStmt::Let { dest, expr } => { - let ast::TypedPat { pat, typ: _ } = dest.as_ref(); - - let dest_ident = scope::pat_ident(pat); - - let value = expr.as_ref().map(|expr| self.eval(expr)).transpose()?; - - if dest_ident.name == "_" { - return Ok(Value::Unit); - } - - self.0 - .defs - .insert_value(dest_ident.name, Value::Uninitialized); - - let Some(value) = value else { - return Ok(Value::Unit); - }; - - self.assign_destr_pat_value(&pat::DestrPat::from(pat), value)? - } - ast::BlockStmt::Assign { dest, expr } => { - let value = self.eval(expr)?; - self.assign_destr_pat_value(dest, value)? - } - ast::BlockStmt::Expr { expr } => self.eval(expr)?, - ast::BlockStmt::Empty => Value::Unit, - }) - } } impl Display for Value { @@ -517,7 +517,7 @@ impl<'a> Display for StrDisplay<'a> { expr::StrPiece::Chars(chars) => f.write_str(chars)?, expr::StrPiece::Escape(c) => f.write_char(*c)?, expr::StrPiece::Interp(expr) => { - let val = self.ctx.eval(expr).or(Err(std::fmt::Error))?; + let val = self.ctx.eval_expr(expr).or(Err(std::fmt::Error))?; match self.kind { expr::StrKind::Regular => Stringify(&val).fmt(f), expr::StrKind::Raw => unreachable!(), |