From 7dc7c7e40eb6f8ab6a528969593c6f542d8062c2 Mon Sep 17 00:00:00 2001 From: Francois Brodeur Date: Wed, 10 Jan 2024 14:01:48 -0500 Subject: [PATCH 1/2] move box to expr --- src/eval.rs | 10 ++-- src/expr.rs | 63 +++++++++++----------- src/infer.rs | 111 ++++++++++++++++++--------------------- src/parser.rs | 48 ++++++++--------- src/tests/parse_at.rs | 8 +-- src/tests/parse_only.rs | 34 ++++++------ src/tests/typed_exprs.rs | 3 +- 7 files changed, 129 insertions(+), 148 deletions(-) diff --git a/src/eval.rs b/src/eval.rs index af196da..299ae6a 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -170,14 +170,14 @@ impl Env { } fn eval_pattern(&mut self, pattern: &PatternAt, value: Value) -> Result<()> { - match &pattern.expr { + match pattern.expr.as_ref() { Pattern::Var(var) => { self.vars.insert(var.clone(), value); } Pattern::RecordExtend(labels, rest) => { - match &rest.expr { + match rest.expr.as_ref() { Expr::RecordEmpty => (), - _ => return Err(Error::PatternRecordRestNotEmpty(*rest.clone())), + _ => return Err(Error::PatternRecordRestNotEmpty(rest.clone())), } let labels_value = match value { Value::Record(labels) => labels, @@ -198,7 +198,7 @@ impl Env { } fn eval_inner(&mut self, expr: &ExprAt) -> Result { - match &expr.expr { + match expr.expr.as_ref() { Expr::Bool(b) => Ok(Wrap::Value(Value::Bool(*b))), Expr::Int(i) => Ok(Wrap::Value(Value::Int(*i))), Expr::IntBinOp(op, lhs, rhs) => { @@ -265,7 +265,7 @@ impl Env { Expr::Fun(params, body) => { let env = self.clone(); let params = params.clone(); - let body = *body.clone(); + let body = body.clone(); let fun = Function { env, params, body }; Ok(Wrap::Value(Value::Function(fun))) } diff --git a/src/expr.rs b/src/expr.rs index a260b25..b9f19d4 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -117,7 +117,7 @@ impl From for TypeContext { #[derive(Clone, Debug, PartialEq)] pub struct ExprIn { pub context: Context, - pub expr: Expr, + pub expr: Box>, } impl fmt::Display for ExprIn { @@ -128,7 +128,10 @@ impl fmt::Display for ExprIn { impl From> for ExprOnly { fn from(expr: Expr) -> Self { - ExprIn { context: (), expr } + ExprIn { + context: (), + expr: expr.into(), + } } } @@ -139,7 +142,7 @@ impl From>> for ExprAt { start: value.start, end: value.end, }, - expr: value.value, + expr: value.value.into(), } } } @@ -148,7 +151,7 @@ impl ExprIn { pub fn strip_context(self) -> ExprIn { ExprIn { context: (), - expr: self.expr.strip_context(), + expr: self.expr.strip_context().into(), } } } @@ -157,7 +160,7 @@ impl ExprIn { pub fn strip_position(self) -> ExprIn { ExprIn { context: self.context.ty, - expr: self.expr.strip_position(), + expr: self.expr.strip_position().into(), } } @@ -187,34 +190,30 @@ pub type PatternTypedAt = ExprTypedAt; pub enum Expr { Bool(bool), Int(i64), - IntBinOp(IntBinOp, Box>, Box>), - Negate(Box>), - EqualEqual(Box>, Box>), + IntBinOp(IntBinOp, ExprIn, ExprIn), + Negate(ExprIn), + EqualEqual(ExprIn, ExprIn), Var(String), - Call(Box>, Vec>), - Fun(Vec>, Box>), - Let( - Box>, - Box>, - Box>, - ), - RecordSelect(Box>, String), - RecordExtend(BTreeMap>, Box>), - RecordRestrict(Box>, String), + Call(ExprIn, Vec>), + Fun(Vec>, ExprIn), + Let(PatternIn, ExprIn, ExprIn), + RecordSelect(ExprIn, String), + RecordExtend(BTreeMap>, ExprIn), + RecordRestrict(ExprIn, String), RecordEmpty, - Variant(String, Box>), + Variant(String, ExprIn), Case( - Box>, + ExprIn, Vec<(String, String, ExprIn)>, - Option<(String, Box>)>, + Option<(String, ExprIn)>, ), If( - Box>, - Box>, + ExprIn, + ExprIn, Vec<(ExprIn, ExprIn)>, - Box>, + ExprIn, ), - Unwrap(Box>), + Unwrap(ExprIn), } impl fmt::Display for Expr { @@ -243,7 +242,7 @@ impl fmt::Display for Expr { .iter() .map(|(label, val)| format!("{}: {}", label, val)) .join(", "); - match rest.expr { + match rest.expr.as_ref() { Expr::RecordEmpty => write!(f, "{{{}}}", labels), _ => write!(f, "{{{} | {}}}", labels, rest), } @@ -260,9 +259,8 @@ impl fmt::Display for Expr { impl Expr { fn strip_context(self) -> Expr { - #[allow(clippy::boxed_local)] - fn fix(e: Box) -> Box { - e.strip_context().into() + fn fix(e: ExprAt) -> ExprOnly { + e.strip_context() } match self { Expr::Bool(b) => Expr::Bool(b), @@ -316,14 +314,13 @@ impl Expr { let ty = TypeContext { ty }; ExprIn { context: PositionTypeContext { position, ty }, - expr: self, + expr: self.into(), } } pub fn strip_position(self) -> Expr { - #[allow(clippy::boxed_local)] - fn fix(e: Box) -> Box { - e.strip_position().into() + fn fix(e: ExprTypedAt) -> ExprTyped { + e.strip_position() } match self { Expr::Bool(b) => Expr::Bool(b), diff --git a/src/infer.rs b/src/infer.rs index ab435c5..ae5fcc6 100644 --- a/src/infer.rs +++ b/src/infer.rs @@ -598,15 +598,15 @@ impl Env { } fn assign_pattern(&mut self, pattern: PatternAt, ty: Type) -> Result { - match (pattern.expr, ty) { + match (*pattern.expr, ty) { (Pattern::Var(name), ty) => { self.insert_var(name.clone(), ty.clone()); Ok(Pattern::Var(name).with(pattern.context, ty)) } (Pattern::RecordExtend(labels, rest), Type::Record(row)) => { - match rest.expr { + match *rest.expr { Pattern::RecordEmpty => (), - _ => return Err(Error::PatternRecordRestNotEmpty(*rest.clone())), + _ => return Err(Error::PatternRecordRestNotEmpty(rest.clone())), } let (labels_ty, rest_ty) = self.match_row_ty(&row)?; let mut label_patterns = BTreeMap::new(); @@ -621,7 +621,7 @@ impl Env { } } let rest = Pattern::RecordEmpty.with(rest.context, rest_ty); - Ok(Pattern::RecordExtend(label_patterns, rest.into()) + Ok(Pattern::RecordExtend(label_patterns, rest) .with(pattern.context, Type::Record(row))) } (Pattern::RecordExtend(_, _), ty) => { @@ -630,22 +630,22 @@ impl Env { } (expr, _) => Err(Error::InvalidPattern(ExprIn { context: pattern.context, - expr, + expr: expr.into(), })), } } fn infer_pattern(&mut self, level: Level, pattern: PatternAt) -> Result { - match pattern.expr { + match *pattern.expr { Pattern::Var(name) => { let ty = self.new_unbound(level); self.insert_var(name.clone(), ty.clone()); Ok(Pattern::Var(name).with(pattern.context, ty)) } Pattern::RecordExtend(labels, rest) => { - match &rest.expr { + match *rest.expr { Pattern::RecordEmpty => (), - _ => return Err(Error::PatternRecordRestNotEmpty(*rest.clone())), + _ => return Err(Error::PatternRecordRestNotEmpty(rest.clone())), } let constraints = labels.keys().cloned().collect(); let mut label_exprs = BTreeMap::new(); @@ -658,7 +658,7 @@ impl Env { let rest_ty = self.new_unbound_row(level, constraints); let ty = Type::Record(Type::RowExtend(label_tys, rest_ty.clone().into()).into()); let rest = Pattern::RecordEmpty.with(rest.context, rest_ty); - Ok(Pattern::RecordExtend(label_exprs, rest.into()).with(pattern.context, ty)) + Ok(Pattern::RecordExtend(label_exprs, rest).with(pattern.context, ty)) } _ => Err(Error::InvalidPattern(pattern.clone())), } @@ -692,29 +692,29 @@ impl Env { } fn infer_inner(&mut self, level: Level, expr: ExprAt) -> Result { - match expr.expr { + match *expr.expr { Expr::Bool(b) => Ok(Expr::Bool(b).with(expr.context, Type::bool())), Expr::Int(i) => Ok(Expr::Int(i).with(expr.context, Type::int())), Expr::IntBinOp(op, lhs, rhs) => { let ty = Type::int(); - let lhs = self.infer_inner(level, *lhs)?; + let lhs = self.infer_inner(level, lhs)?; self.unify(&ty, lhs.ty())?; - let rhs = self.infer_inner(level, *rhs)?; + let rhs = self.infer_inner(level, rhs)?; self.unify(&ty, rhs.ty())?; let ty = op.output_ty(); - Ok(Expr::IntBinOp(op, lhs.into(), rhs.into()).with(expr.context, ty)) + Ok(Expr::IntBinOp(op, lhs, rhs).with(expr.context, ty)) } Expr::Negate(value) => { let ty = Type::bool(); - let value = self.infer_inner(level, *value)?; + let value = self.infer_inner(level, value)?; self.unify(&ty, value.ty())?; - Ok(Expr::Negate(value.into()).with(expr.context, ty)) + Ok(Expr::Negate(value).with(expr.context, ty)) } Expr::EqualEqual(lhs, rhs) => { - let lhs = self.infer_inner(level, *lhs)?; - let rhs = self.infer_inner(level, *rhs)?; + let lhs = self.infer_inner(level, lhs)?; + let rhs = self.infer_inner(level, rhs)?; self.unify(lhs.ty(), rhs.ty())?; - Ok(Expr::EqualEqual(lhs.into(), rhs.into()).with(expr.context, Type::bool())) + Ok(Expr::EqualEqual(lhs, rhs).with(expr.context, Type::bool())) } Expr::Var(name) => { let ty = self.get_var(&name)?.clone(); @@ -731,22 +731,22 @@ impl Env { param_tys.push(param_expr.ty().clone()); param_exprs.push(param_expr); } - let body = self.infer_inner(level, *body)?; + let body = self.infer_inner(level, body)?; self.vars = old_vars; self.wrap = old_wrap; let ty = Type::Arrow(param_tys, body.ty().clone().into()); - Ok(Expr::Fun(param_exprs, body.into()).with(expr.context, ty)) + Ok(Expr::Fun(param_exprs, body).with(expr.context, ty)) } Expr::Let(pattern, value, body) => { - let value = self.infer_inner(level + 1, *value)?; + let value = self.infer_inner(level + 1, value)?; self.generalize(level, value.ty())?; - let pattern = self.assign_pattern(*pattern, value.ty().clone())?; - let body = self.infer_inner(level, *body)?; + let pattern = self.assign_pattern(pattern, value.ty().clone())?; + let body = self.infer_inner(level, body)?; let ty = body.ty().clone(); - Ok(Expr::Let(pattern.into(), value.into(), body.into()).with(expr.context, ty)) + Ok(Expr::Let(pattern, value, body).with(expr.context, ty)) } Expr::Call(fun, args) => { - let fun = self.infer_inner(level, *fun)?; + let fun = self.infer_inner(level, fun)?; let (params, ret) = self.match_fun_ty(args.len(), fun.ty().clone())?; let mut typed_args = Vec::with_capacity(args.len()); for (i, arg) in args.into_iter().enumerate() { @@ -755,7 +755,7 @@ impl Env { self.unify(arg.ty(), param)?; typed_args.push(arg); } - Ok(Expr::Call(fun.into(), typed_args).with(expr.context, *ret)) + Ok(Expr::Call(fun, typed_args).with(expr.context, *ret)) } Expr::RecordEmpty => { let ty = Type::Record(Type::RowEmpty.into()); @@ -772,9 +772,9 @@ impl Env { .into(), ); let ret = field; - let record = self.infer_inner(level, *record)?; + let record = self.infer_inner(level, record)?; self.unify(¶m, record.ty())?; - Ok(Expr::RecordSelect(record.into(), label).with(expr.context, ret)) + Ok(Expr::RecordSelect(record, label).with(expr.context, ret)) } Expr::RecordRestrict(record, label) => { let rest = self.new_unbound_row(level, Constraints::singleton(label.clone())); @@ -787,9 +787,9 @@ impl Env { .into(), ); let ret = Type::Record(rest.into()); - let record = self.infer_inner(level, *record)?; + let record = self.infer_inner(level, record)?; self.unify(¶m, record.ty())?; - Ok(Expr::RecordRestrict(record.into(), label).with(expr.context, ret)) + Ok(Expr::RecordRestrict(record, label).with(expr.context, ret)) } Expr::RecordExtend(labels, record) => { let mut tys = BTreeMap::new(); @@ -801,10 +801,10 @@ impl Env { typed_labels.insert(label, expr); } let rest = self.new_unbound_row(level, constraints); - let record = self.infer_inner(level, *record)?; + let record = self.infer_inner(level, record)?; self.unify(&Type::Record(rest.clone().into()), record.ty())?; let ty = Type::Record(Type::RowExtend(tys, rest.into()).into()); - Ok(Expr::RecordExtend(typed_labels, record.into()).with(expr.context, ty)) + Ok(Expr::RecordExtend(typed_labels, record).with(expr.context, ty)) } Expr::Variant(label, value) => { let rest = self.new_unbound_row(level, Constraints::singleton(label.clone())); @@ -814,16 +814,16 @@ impl Env { Type::RowExtend(BTreeMap::singleton(label.clone(), variant), rest.into()) .into(), ); - let value = self.infer_inner(level, *value)?; + let value = self.infer_inner(level, value)?; self.unify(¶m, value.ty())?; - Ok(Expr::Variant(label, value.into()).with(expr.context, ret)) + Ok(Expr::Variant(label, value).with(expr.context, ret)) } Expr::Case(value, cases, None) => { let ret = self.new_unbound(level); - let value = self.infer_inner(level, *value)?; + let value = self.infer_inner(level, value)?; let (cases_row, cases) = self.infer_cases(level, &ret, Type::RowEmpty, cases)?; self.unify(value.ty(), &Type::Variant(cases_row.into()))?; - Ok(Expr::Case(value.into(), cases, None).with(expr.context, ret)) + Ok(Expr::Case(value, cases, None).with(expr.context, ret)) } Expr::Case(value, cases, Some((def_var, def_expr))) => { let constraints = cases.iter().map(|(label, _, _)| label).cloned().collect(); @@ -831,19 +831,16 @@ impl Env { let old_vars = self.vars.clone(); self.vars .insert(def_var.clone(), Type::Variant(def_variant.clone().into())); - let def_expr = self.infer_inner(level, *def_expr)?; + let def_expr = self.infer_inner(level, def_expr)?; let ret = def_expr.ty().clone(); self.vars = old_vars; - let value = self.infer_inner(level, *value)?; + let value = self.infer_inner(level, value)?; let (cases_row, cases) = self.infer_cases(level, &ret, def_variant, cases)?; self.unify(value.ty(), &Type::Variant(cases_row.into()))?; - Ok( - Expr::Case(value.into(), cases, Some((def_var, def_expr.into()))) - .with(expr.context, ret), - ) + Ok(Expr::Case(value, cases, Some((def_var, def_expr))).with(expr.context, ret)) } Expr::Unwrap(value) => { - let value = self.infer_inner(level, *value)?; + let value = self.infer_inner(level, value)?; match value.ty() { Type::Variant(rows) => { let (mut labels, _) = self.match_row_ty(rows)?; @@ -854,7 +851,7 @@ impl Env { } Some(ty) => { self.wrap_with(labels)?; - Ok(Expr::Unwrap(value.into()).with(expr.context, ty)) + Ok(Expr::Unwrap(value).with(expr.context, ty)) } } } @@ -866,9 +863,9 @@ impl Env { } Expr::If(if_expr, if_body, elifs, else_body) => { let bool = Type::bool(); - let if_expr = self.infer_inner(level, *if_expr)?; + let if_expr = self.infer_inner(level, if_expr)?; self.unify(&bool, if_expr.ty())?; - let if_body = self.infer_inner(level, *if_body)?; + let if_body = self.infer_inner(level, if_body)?; let mut typed_elifs = Vec::with_capacity(elifs.len()); for (elif_expr, elif_body) in elifs { let elif_expr = self.infer_inner(level, elif_expr)?; @@ -877,7 +874,7 @@ impl Env { self.unify(if_body.ty(), elif_body.ty())?; typed_elifs.push((elif_expr, elif_body)); } - let else_body = self.infer_inner(level, *else_body)?; + let else_body = self.infer_inner(level, else_body)?; self.unify(if_body.ty(), else_body.ty())?; // TODO: if calling a function with an open variant should keep it open match if_body.ty().clone() { @@ -885,21 +882,13 @@ impl Env { let (labels, _rest) = self.match_row_ty(&row)?; let ty = Type::Variant(Type::RowExtend(labels, Type::RowEmpty.into()).into()); - Ok(Expr::If( - if_expr.into(), - if_body.into(), - typed_elifs, - else_body.into(), - ) - .with(expr.context, ty)) + Ok(Expr::If(if_expr, if_body, typed_elifs, else_body) + .with(expr.context, ty)) + } + ty => { + Ok(Expr::If(if_expr, if_body, typed_elifs, else_body) + .with(expr.context, ty)) } - ty => Ok(Expr::If( - if_expr.into(), - if_body.into(), - typed_elifs, - else_body.into(), - ) - .with(expr.context, ty)), } } } diff --git a/src/parser.rs b/src/parser.rs index 2ae6a54..0cca654 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -217,7 +217,7 @@ impl<'a> Parser<'a> { let (labels, r) = self.pattern_expr_inner()?; Ok(l.span_with( r.clone(), - Expr::RecordExtend(labels, Box::new(r.map(|()| Expr::RecordEmpty).into())), + Expr::RecordExtend(labels, r.map(|()| Expr::RecordEmpty).into()), ) .into()) } else { @@ -243,7 +243,7 @@ impl<'a> Parser<'a> { fn let_expr(&mut self, at: At<()>) -> Result { let pattern = self.pattern_expr()?; - match pattern.expr { + match *pattern.expr { Pattern::Var(_) if self.matches(Token::LParen)?.is_some() => { let params = self.pattern_list()?; self.expect(Token::Equal, "let expr fun")?; @@ -256,12 +256,12 @@ impl<'a> Parser<'a> { }; let fun = ExprAt { context: at.clone().into(), - expr: Expr::Fun(params, fun_body.into()), + expr: Expr::Fun(params, fun_body).into(), }; - let expr = Expr::Let(pattern.into(), fun.into(), body.into()); + let expr = Expr::Let(pattern, fun, body); Ok(ExprAt { context: at.into(), - expr, + expr: expr.into(), }) } _ => { @@ -271,14 +271,14 @@ impl<'a> Parser<'a> { let body = pattern.clone(); Ok(ExprAt { context: at.into(), - expr: Expr::Let(pattern.into(), value.into(), body.into()), + expr: Expr::Let(pattern, value, body).into(), }) } else { self.expect(Token::In, "let expr")?; let body = self.expr_inner(0)?; Ok(ExprAt { context: at.into(), - expr: Expr::Let(pattern.into(), value.into(), body.into()), + expr: Expr::Let(pattern, value, body).into(), }) } } @@ -292,7 +292,7 @@ impl<'a> Parser<'a> { let body = self.expr_inner(0)?; Ok(ExprAt { context: at.into(), - expr: Expr::Fun(params, body.into()), + expr: Expr::Fun(params, body).into(), }) } @@ -316,7 +316,7 @@ impl<'a> Parser<'a> { } else if let Some(r) = self.matches(Token::RBrace)? { let rest = ExprAt { context: r.clone().into(), - expr: Expr::RecordEmpty, + expr: Expr::RecordEmpty.into(), }; return Ok((labels, rest, r)); } else if self.matches(Token::Pipe)?.is_some() { @@ -339,7 +339,7 @@ impl<'a> Parser<'a> { let (labels, rest, r) = self.record_expr_inner()?; Ok(ExprAt { context: l.span_with(r, ()).into(), - expr: Expr::RecordExtend(labels, rest.into()), + expr: Expr::RecordExtend(labels, rest).into(), }) } @@ -350,7 +350,7 @@ impl<'a> Parser<'a> { let context = at.span_with(label, ()).into(); Ok(ExprAt { context, - expr: Expr::Variant(label_only, expr.into()), + expr: Expr::Variant(label_only, expr).into(), }) } @@ -369,7 +369,7 @@ impl<'a> Parser<'a> { } else if let Some(var) = self.matches_ident()? { self.expect(Token::Arrow, "match expr default case")?; let expr = self.expr_inner(0)?; - default_case = Some((var.value, Box::new(expr))); + default_case = Some((var.value, expr)); self.expect(Token::RBrace, "match expr default case")?; break; } else { @@ -385,7 +385,7 @@ impl<'a> Parser<'a> { } Ok(ExprAt { context: at.into(), - expr: Expr::Case(expr.into(), cases, default_case), + expr: Expr::Case(expr, cases, default_case).into(), }) } @@ -409,7 +409,7 @@ impl<'a> Parser<'a> { let else_body = self.expr_inner(0)?; Ok(ExprAt { context: at.into(), - expr: Expr::If(if_expr.into(), if_body.into(), elifs, else_body.into()), + expr: Expr::If(if_expr, if_body, elifs, else_body).into(), }) } @@ -440,7 +440,7 @@ impl<'a> Parser<'a> { let r_bp = self.prefix_bp()?; if let Some(at) = self.matches(Token::Negate)? { let rhs = self.expr_inner(r_bp)?; - Ok(at.map(|()| Expr::Negate(rhs.into())).into()) + Ok(at.map(|()| Expr::Negate(rhs)).into()) } else { Err(Error::InvalidPrefix(self.token.take())) } @@ -461,26 +461,22 @@ impl<'a> Parser<'a> { } Ok(ExprAt { context: lhs.context.clone(), - expr: Expr::Call(lhs.into(), args), + expr: Expr::Call(lhs, args).into(), }) } fn record_select_expr(&mut self, lhs: ExprAt) -> Result { let field = self.expect_ident("record select expr")?; - Ok(field - .map(|field| Expr::RecordSelect(lhs.into(), field)) - .into()) + Ok(field.map(|field| Expr::RecordSelect(lhs, field)).into()) } fn record_restrict_expr(&mut self, lhs: ExprAt) -> Result { let field = self.expect_ident("record restrict expr")?; - Ok(field - .map(|field| Expr::RecordRestrict(lhs.into(), field)) - .into()) + Ok(field.map(|field| Expr::RecordRestrict(lhs, field)).into()) } fn unwrap_expr(&mut self, lhs: ExprAt, at: At<()>) -> Result { - Ok(at.map(|()| Expr::Unwrap(lhs.into())).into()) + Ok(at.map(|()| Expr::Unwrap(lhs)).into()) } fn expr_postfix(&mut self, lhs: ExprAt) -> Result { @@ -502,9 +498,7 @@ impl<'a> Parser<'a> { fn binop_expr(&mut self, at: At<()>, op: IntBinOp, lhs: ExprAt, r_bp: u8) -> Result { let rhs = self.expr_inner(r_bp)?; - Ok(at - .map(|()| Expr::IntBinOp(op, lhs.into(), rhs.into())) - .into()) + Ok(at.map(|()| Expr::IntBinOp(op, lhs, rhs)).into()) } fn expr_infix(&mut self, lhs: ExprAt, r_bp: u8) -> Result { @@ -518,7 +512,7 @@ impl<'a> Parser<'a> { self.binop_expr(at, IntBinOp::Divide, lhs, r_bp) } else if let Some(at) = self.matches(Token::EqualEqual)? { let rhs = self.expr_inner(r_bp)?; - Ok(at.map(|()| Expr::EqualEqual(lhs.into(), rhs.into())).into()) + Ok(at.map(|()| Expr::EqualEqual(lhs, rhs)).into()) } else if let Some(at) = self.matches(Token::LessThan)? { self.binop_expr(at, IntBinOp::LessThan, lhs, r_bp) } else if let Some(at) = self.matches(Token::LessThanOrEqual)? { diff --git a/src/tests/parse_at.rs b/src/tests/parse_at.rs index 8f536f4..e714205 100644 --- a/src/tests/parse_at.rs +++ b/src/tests/parse_at.rs @@ -6,28 +6,28 @@ use crate::{ pub fn int_at(i: i64, context: PositionContext) -> ExprAt { ExprAt { context, - expr: Expr::Int(i), + expr: Expr::Int(i).into(), } } pub fn var_at(var: &str, context: PositionContext) -> ExprAt { ExprAt { context, - expr: Expr::Var(var.to_owned()), + expr: Expr::Var(var.to_owned()).into(), } } pub fn let_at(var: PatternAt, value: ExprAt, body: ExprAt, context: PositionContext) -> ExprAt { ExprAt { context, - expr: Expr::Let(var.into(), value.into(), body.into()), + expr: Expr::Let(var, value, body).into(), } } pub fn plus_at(lhs: ExprAt, rhs: ExprAt, context: PositionContext) -> ExprAt { ExprAt { context, - expr: Expr::IntBinOp(IntBinOp::Plus, lhs.into(), rhs.into()), + expr: Expr::IntBinOp(IntBinOp::Plus, lhs, rhs).into(), } } diff --git a/src/tests/parse_only.rs b/src/tests/parse_only.rs index 77e4baa..1c434db 100644 --- a/src/tests/parse_only.rs +++ b/src/tests/parse_only.rs @@ -17,7 +17,7 @@ pub fn precord(labels: Vec<(&str, PatternOnly)>) -> PatternOnly { .into_iter() .map(|(label, pattern)| (label.to_owned(), pattern)) .collect(); - Expr::RecordExtend(labels, Box::new(Expr::RecordEmpty.into())).into() + Expr::RecordExtend(labels, Expr::RecordEmpty.into()).into() } pub fn bool(b: bool) -> ExprOnly { @@ -33,15 +33,15 @@ pub fn var(var: &str) -> ExprOnly { } pub fn call(fn_expr: ExprOnly, args: Vec) -> ExprOnly { - Expr::Call(fn_expr.into(), args).into() + Expr::Call(fn_expr, args).into() } pub fn fun(args: Vec, body: ExprOnly) -> ExprOnly { - Expr::Fun(args, body.into()).into() + Expr::Fun(args, body).into() } pub fn let_(var: PatternOnly, value: ExprOnly, body: ExprOnly) -> ExprOnly { - Expr::Let(var.into(), value.into(), body.into()).into() + Expr::Let(var, value, body).into() } pub fn empty() -> ExprOnly { @@ -49,11 +49,11 @@ pub fn empty() -> ExprOnly { } pub fn select(r: ExprOnly, label: &str) -> ExprOnly { - Expr::RecordSelect(r.into(), label.to_owned()).into() + Expr::RecordSelect(r, label.to_owned()).into() } pub fn restrict(r: ExprOnly, label: &str) -> ExprOnly { - Expr::RecordRestrict(r.into(), label.to_owned()).into() + Expr::RecordRestrict(r, label.to_owned()).into() } pub fn record(labels: Vec<(&str, ExprOnly)>, r: ExprOnly) -> ExprOnly { @@ -61,35 +61,35 @@ pub fn record(labels: Vec<(&str, ExprOnly)>, r: ExprOnly) -> ExprOnly { .into_iter() .map(|(label, expr)| (label.to_owned(), expr)) .collect(); - Expr::RecordExtend(labels, r.into()).into() + Expr::RecordExtend(labels, r).into() } pub fn plus(lhs: ExprOnly, rhs: ExprOnly) -> ExprOnly { - Expr::IntBinOp(IntBinOp::Plus, lhs.into(), rhs.into()).into() + Expr::IntBinOp(IntBinOp::Plus, lhs, rhs).into() } pub fn minus(lhs: ExprOnly, rhs: ExprOnly) -> ExprOnly { - Expr::IntBinOp(IntBinOp::Minus, lhs.into(), rhs.into()).into() + Expr::IntBinOp(IntBinOp::Minus, lhs, rhs).into() } pub fn multiply(lhs: ExprOnly, rhs: ExprOnly) -> ExprOnly { - Expr::IntBinOp(IntBinOp::Multiply, lhs.into(), rhs.into()).into() + Expr::IntBinOp(IntBinOp::Multiply, lhs, rhs).into() } pub fn divide(lhs: ExprOnly, rhs: ExprOnly) -> ExprOnly { - Expr::IntBinOp(IntBinOp::Divide, lhs.into(), rhs.into()).into() + Expr::IntBinOp(IntBinOp::Divide, lhs, rhs).into() } pub fn negate(expr: ExprOnly) -> ExprOnly { - Expr::Negate(expr.into()).into() + Expr::Negate(expr).into() } pub fn equalequal(lhs: ExprOnly, rhs: ExprOnly) -> ExprOnly { - Expr::EqualEqual(lhs.into(), rhs.into()).into() + Expr::EqualEqual(lhs, rhs).into() } pub fn gt(lhs: ExprOnly, rhs: ExprOnly) -> ExprOnly { - Expr::IntBinOp(IntBinOp::GreaterThan, lhs.into(), rhs.into()).into() + Expr::IntBinOp(IntBinOp::GreaterThan, lhs, rhs).into() } pub fn match_( @@ -101,8 +101,8 @@ pub fn match_( .into_iter() .map(|(variant, var, body)| (variant.to_owned(), var.to_owned(), body)) .collect(); - let def = def.map(|(var, body)| (var.to_owned(), body.into())); - Expr::Case(val.into(), cases, def).into() + let def = def.map(|(var, body)| (var.to_owned(), body)); + Expr::Case(val, cases, def).into() } pub fn if_( @@ -111,7 +111,7 @@ pub fn if_( elifs: Vec<(ExprOnly, ExprOnly)>, else_body: ExprOnly, ) -> ExprOnly { - Expr::If(if_expr.into(), if_body.into(), elifs, else_body.into()).into() + Expr::If(if_expr, if_body, elifs, else_body).into() } #[track_caller] diff --git a/src/tests/typed_exprs.rs b/src/tests/typed_exprs.rs index 6d389fe..c8e5ded 100644 --- a/src/tests/typed_exprs.rs +++ b/src/tests/typed_exprs.rs @@ -15,6 +15,7 @@ fn pass(expr_str: &str, expected: ExprTyped) { fn expr(expr: Expr, ty: Type) -> ExprTyped { let context = TypeContext { ty }; + let expr = Box::new(expr); ExprIn { context, expr } } @@ -28,7 +29,7 @@ fn var(name: &str, ty: Type) -> ExprTyped { fn let_(pattern: ExprTyped, value: ExprTyped, body: ExprTyped) -> ExprTyped { let ty = body.context.ty.clone(); - expr(Expr::Let(pattern.into(), value.into(), body.into()), ty) + expr(Expr::Let(pattern, value, body), ty) } #[test] From c064015a80d6a3c538d510553d69aace518a6b9f Mon Sep 17 00:00:00 2001 From: Francois Brodeur Date: Wed, 10 Jan 2024 20:24:29 -0500 Subject: [PATCH 2/2] refactor --- src/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 36f3905..61cf448 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ use std::{ use parser::Parser; pub mod core; +// pub mod emit; pub mod eval; pub mod expr; pub mod infer; @@ -73,7 +74,7 @@ impl Env { let expr = Parser::repl(source)?; let typed_expr = self.infer.infer(expr.clone())?; let value = self.eval.eval(&expr)?; - let ty = self.infer.ty_to_string(&typed_expr.context.ty.ty).unwrap(); + let ty = self.infer.ty_to_string(typed_expr.ty()).unwrap(); let val = value.to_string(); Ok(Output { ty, val }) }