summaryrefslogtreecommitdiffstats
path: root/crates
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2024-05-04 13:54:37 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2024-05-04 13:54:37 +0200
commit3ac52564f990c074462cd92e4787eb65c6005bb0 (patch)
tree45b9fbc7aeef4b349ad8bb7e5ce6a542b1f04112 /crates
parent8d0d0b253286decb4bb3eeccdc33fef92c203fa6 (diff)
downloadrebel-3ac52564f990c074462cd92e4787eb65c6005bb0.tar
rebel-3ac52564f990c074462cd92e4787eb65c6005bb0.zip
rebel-lang: make method naming more consistent
Diffstat (limited to 'crates')
-rw-r--r--crates/rebel-lang/benches/recipe.rs4
-rw-r--r--crates/rebel-lang/examples/repl.rs4
-rw-r--r--crates/rebel-lang/src/typing.rs178
-rw-r--r--crates/rebel-lang/src/value.rs98
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(&param_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(&param_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!(),