From 2a574b1b42f5342677113a2c0cffb5d64c9e48ab Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Thu, 9 Sep 2021 23:56:28 -0700 Subject: [PATCH] Properly track locations on every AST node. Semantic errors are much more useful now. Also print parse errors in same (pseudo-standard compiler error) output format. --- cranelift/isle/src/ast.rs | 107 ++++++++++++++++++++------ cranelift/isle/src/error.rs | 2 +- cranelift/isle/src/main.rs | 9 ++- cranelift/isle/src/parser.rs | 145 +++++++++++------------------------ cranelift/isle/src/sema.rs | 84 +++++++++++--------- 5 files changed, 183 insertions(+), 164 deletions(-) diff --git a/cranelift/isle/src/ast.rs b/cranelift/isle/src/ast.rs index 8f1cd820c4..bbfdc59698 100644 --- a/cranelift/isle/src/ast.rs +++ b/cranelift/isle/src/ast.rs @@ -19,7 +19,7 @@ pub enum Def { /// An identifier -- a variable, term symbol, or type. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Ident(pub String); +pub struct Ident(pub String, pub Pos); /// A declaration of a type. #[derive(Clone, PartialEq, Eq, Debug)] @@ -35,8 +35,8 @@ pub struct Type { /// TODO: add structs as well? #[derive(Clone, PartialEq, Eq, Debug)] pub enum TypeValue { - Primitive(Ident), - Enum(Vec), + Primitive(Ident, Pos), + Enum(Vec, Pos), } /// One variant of an enum type. @@ -44,6 +44,7 @@ pub enum TypeValue { pub struct Variant { pub name: Ident, pub fields: Vec, + pub pos: Pos, } /// One field of an enum variant. @@ -51,6 +52,7 @@ pub struct Variant { pub struct Field { pub name: Ident, pub ty: Ident, + pub pos: Pos, } /// A declaration of a term with its argument and return types. @@ -85,22 +87,27 @@ pub struct Extractor { pub enum Pattern { /// An operator that binds a variable to a subterm and match the /// subpattern. - BindPattern { var: Ident, subpat: Box }, + BindPattern { + var: Ident, + subpat: Box, + pos: Pos, + }, /// A variable that has already been bound (`=x` syntax). - Var { var: Ident }, + Var { var: Ident, pos: Pos }, /// An operator that matches a constant integer value. - ConstInt { val: i64 }, + ConstInt { val: i64, pos: Pos }, /// An application of a type variant or term. Term { sym: Ident, args: Vec, + pos: Pos, }, /// An operator that matches anything. - Wildcard, + Wildcard { pos: Pos }, /// N sub-patterns that must all match. - And { subpats: Vec }, + And { subpats: Vec, pos: Pos }, /// Internal use only: macro argument in a template. - MacroArg { index: usize }, + MacroArg { index: usize, pos: Pos }, } impl Pattern { @@ -118,9 +125,11 @@ impl Pattern { &Pattern::BindPattern { ref var, ref subpat, - } if matches!(&**subpat, &Pattern::Wildcard) => { + pos, + .. + } if matches!(&**subpat, &Pattern::Wildcard { .. }) => { if let Some(i) = macro_args.iter().position(|arg| arg == var) { - Pattern::MacroArg { index: i } + Pattern::MacroArg { index: i, pos } } else { self.clone() } @@ -128,18 +137,24 @@ impl Pattern { &Pattern::BindPattern { ref var, ref subpat, + pos, } => Pattern::BindPattern { var: var.clone(), subpat: Box::new(subpat.make_macro_template(macro_args)), + pos, }, - &Pattern::And { ref subpats } => { + &Pattern::And { ref subpats, pos } => { let subpats = subpats .iter() .map(|subpat| subpat.make_macro_template(macro_args)) .collect::>(); - Pattern::And { subpats } + Pattern::And { subpats, pos } } - &Pattern::Term { ref sym, ref args } => { + &Pattern::Term { + ref sym, + ref args, + pos, + } => { let args = args .iter() .map(|arg| arg.make_macro_template(macro_args)) @@ -147,10 +162,13 @@ impl Pattern { Pattern::Term { sym: sym.clone(), args, + pos, } } - &Pattern::Var { .. } | &Pattern::Wildcard | &Pattern::ConstInt { .. } => self.clone(), + &Pattern::Var { .. } | &Pattern::Wildcard { .. } | &Pattern::ConstInt { .. } => { + self.clone() + } &Pattern::MacroArg { .. } => unreachable!(), } } @@ -160,18 +178,24 @@ impl Pattern { &Pattern::BindPattern { ref var, ref subpat, + pos, } => Pattern::BindPattern { var: var.clone(), subpat: Box::new(subpat.subst_macro_args(macro_args)), + pos, }, - &Pattern::And { ref subpats } => { + &Pattern::And { ref subpats, pos } => { let subpats = subpats .iter() .map(|subpat| subpat.subst_macro_args(macro_args)) .collect::>(); - Pattern::And { subpats } + Pattern::And { subpats, pos } } - &Pattern::Term { ref sym, ref args } => { + &Pattern::Term { + ref sym, + ref args, + pos, + } => { let args = args .iter() .map(|arg| arg.subst_macro_args(macro_args)) @@ -179,11 +203,26 @@ impl Pattern { Pattern::Term { sym: sym.clone(), args, + pos, } } - &Pattern::Var { .. } | &Pattern::Wildcard | &Pattern::ConstInt { .. } => self.clone(), - &Pattern::MacroArg { index } => macro_args[index].clone(), + &Pattern::Var { .. } | &Pattern::Wildcard { .. } | &Pattern::ConstInt { .. } => { + self.clone() + } + &Pattern::MacroArg { index, .. } => macro_args[index].clone(), + } + } + + pub fn pos(&self) -> Pos { + match self { + &Pattern::ConstInt { pos, .. } + | &Pattern::And { pos, .. } + | &Pattern::Term { pos, .. } + | &Pattern::BindPattern { pos, .. } + | &Pattern::Var { pos, .. } + | &Pattern::Wildcard { pos, .. } + | &Pattern::MacroArg { pos, .. } => pos, } } } @@ -231,13 +270,32 @@ impl TermArgPattern { #[derive(Clone, PartialEq, Eq, Debug)] pub enum Expr { /// A term: `(sym args...)`. - Term { sym: Ident, args: Vec }, + Term { + sym: Ident, + args: Vec, + pos: Pos, + }, /// A variable use. - Var { name: Ident }, + Var { name: Ident, pos: Pos }, /// A constant integer. - ConstInt { val: i64 }, + ConstInt { val: i64, pos: Pos }, /// The `(let ((var ty val)*) body)` form. - Let { defs: Vec, body: Box }, + Let { + defs: Vec, + body: Box, + pos: Pos, + }, +} + +impl Expr { + pub fn pos(&self) -> Pos { + match self { + &Expr::Term { pos, .. } + | &Expr::Var { pos, .. } + | &Expr::ConstInt { pos, .. } + | &Expr::Let { pos, .. } => pos, + } + } } /// One variable locally bound in a `(let ...)` expression. @@ -246,6 +304,7 @@ pub struct LetDef { pub var: Ident, pub ty: Ident, pub val: Box, + pub pos: Pos, } /// An external binding: an extractor or constructor function attached diff --git a/cranelift/isle/src/error.rs b/cranelift/isle/src/error.rs index a3afd1fce7..70a2140401 100644 --- a/cranelift/isle/src/error.rs +++ b/cranelift/isle/src/error.rs @@ -23,7 +23,7 @@ impl fmt::Display for Error { ref filename, pos, } => { - write!(f, "{}:{}: {}", filename, pos.line, msg) + write!(f, "{}:{}:{}: error: {}", filename, pos.line, pos.col, msg) } &Error::SystemError { ref msg } => { write!(f, "{}", msg) diff --git a/cranelift/isle/src/main.rs b/cranelift/isle/src/main.rs index 5f2e168a19..13c37a8125 100644 --- a/cranelift/isle/src/main.rs +++ b/cranelift/isle/src/main.rs @@ -46,7 +46,14 @@ fn main() -> Result<(), error::Error> { let lexer = lexer::Lexer::from_files(input_files)?; let mut parser = parser::Parser::new(lexer); - let defs = parser.parse_defs()?; + let defs = match parser.parse_defs() { + Ok(defs) => defs, + Err(error) => { + eprintln!("{}", error); + eprintln!("Failed to parse input."); + std::process::exit(1); + } + }; let code = match compile::compile(&defs) { Ok(code) => code, Err(errors) => { diff --git a/cranelift/isle/src/parser.rs b/cranelift/isle/src/parser.rs index 8c6b080b10..77ca738f7d 100644 --- a/cranelift/isle/src/parser.rs +++ b/cranelift/isle/src/parser.rs @@ -147,7 +147,7 @@ impl<'a> Parser<'a> { ), )); } - Ok(Ident(s.to_string())) + Ok(Ident(s.to_string(), pos)) } fn parse_ident(&mut self) -> ParseResult { @@ -180,7 +180,8 @@ impl<'a> Parser<'a> { self.symbol()?; let primitive_ident = self.parse_ident()?; self.rparen()?; - Ok(TypeValue::Primitive(primitive_ident)) + let pos = pos.unwrap(); + Ok(TypeValue::Primitive(primitive_ident, pos)) } else if self.is_sym_str("enum") { self.symbol()?; let mut variants = vec![]; @@ -189,7 +190,8 @@ impl<'a> Parser<'a> { variants.push(variant); } self.rparen()?; - Ok(TypeValue::Enum(variants)) + let pos = pos.unwrap(); + Ok(TypeValue::Enum(variants, pos)) } else { Err(self.error(pos.unwrap(), "Unknown type definition".to_string())) } @@ -197,12 +199,15 @@ impl<'a> Parser<'a> { fn parse_type_variant(&mut self) -> ParseResult { if self.is_sym() { + let pos = self.pos().unwrap(); let name = self.parse_ident()?; Ok(Variant { name, fields: vec![], + pos, }) } else { + let pos = self.pos(); self.lparen()?; let name = self.parse_ident()?; let mut fields = vec![]; @@ -210,16 +215,19 @@ impl<'a> Parser<'a> { fields.push(self.parse_type_field()?); } self.rparen()?; - Ok(Variant { name, fields }) + let pos = pos.unwrap(); + Ok(Variant { name, fields, pos }) } } fn parse_type_field(&mut self) -> ParseResult { + let pos = self.pos(); self.lparen()?; let name = self.parse_ident()?; let ty = self.parse_ident()?; self.rparen()?; - Ok(Field { name, ty }) + let pos = pos.unwrap(); + Ok(Field { name, ty, pos }) } fn parse_decl(&mut self) -> ParseResult { @@ -342,30 +350,38 @@ impl<'a> Parser<'a> { fn parse_pattern(&mut self) -> ParseResult { let pos = self.pos(); if self.is_int() { - Ok(Pattern::ConstInt { val: self.int()? }) + let pos = pos.unwrap(); + Ok(Pattern::ConstInt { + val: self.int()?, + pos, + }) } else if self.is_sym_str("_") { + let pos = pos.unwrap(); self.symbol()?; - Ok(Pattern::Wildcard) + Ok(Pattern::Wildcard { pos }) } else if self.is_sym() { + let pos = pos.unwrap(); let s = self.symbol()?; if s.starts_with("=") { let s = &s[1..]; - let var = self.str_to_ident(pos.unwrap(), s)?; - Ok(Pattern::Var { var }) + let var = self.str_to_ident(pos, s)?; + Ok(Pattern::Var { var, pos }) } else { - let var = self.str_to_ident(pos.unwrap(), &s)?; + let var = self.str_to_ident(pos, &s)?; if self.is_at() { self.at()?; let subpat = Box::new(self.parse_pattern()?); - Ok(Pattern::BindPattern { var, subpat }) + Ok(Pattern::BindPattern { var, subpat, pos }) } else { Ok(Pattern::BindPattern { var, - subpat: Box::new(Pattern::Wildcard), + subpat: Box::new(Pattern::Wildcard { pos }), + pos, }) } } } else if self.is_lparen() { + let pos = pos.unwrap(); self.lparen()?; if self.is_sym_str("and") { self.symbol()?; @@ -374,7 +390,7 @@ impl<'a> Parser<'a> { subpats.push(self.parse_pattern()?); } self.rparen()?; - Ok(Pattern::And { subpats }) + Ok(Pattern::And { subpats, pos }) } else { let sym = self.parse_ident()?; let mut args = vec![]; @@ -382,7 +398,7 @@ impl<'a> Parser<'a> { args.push(self.parse_pattern_term_arg()?); } self.rparen()?; - Ok(Pattern::Term { sym, args }) + Ok(Pattern::Term { sym, args, pos }) } } else { Err(self.error(pos.unwrap(), "Unexpected pattern".into())) @@ -401,6 +417,7 @@ impl<'a> Parser<'a> { fn parse_expr(&mut self) -> ParseResult { let pos = self.pos(); if self.is_lparen() { + let pos = pos.unwrap(); self.lparen()?; if self.is_sym_str("let") { self.symbol()?; @@ -413,7 +430,7 @@ impl<'a> Parser<'a> { self.rparen()?; let body = Box::new(self.parse_expr()?); self.rparen()?; - Ok(Expr::Let { defs, body }) + Ok(Expr::Let { defs, body, pos }) } else { let sym = self.parse_ident()?; let mut args = vec![]; @@ -421,111 +438,37 @@ impl<'a> Parser<'a> { args.push(self.parse_expr()?); } self.rparen()?; - Ok(Expr::Term { sym, args }) + Ok(Expr::Term { sym, args, pos }) } } else if self.is_sym_str("#t") { + let pos = pos.unwrap(); self.symbol()?; - Ok(Expr::ConstInt { val: 1 }) + Ok(Expr::ConstInt { val: 1, pos }) } else if self.is_sym_str("#f") { + let pos = pos.unwrap(); self.symbol()?; - Ok(Expr::ConstInt { val: 0 }) + Ok(Expr::ConstInt { val: 0, pos }) } else if self.is_sym() { + let pos = pos.unwrap(); let name = self.parse_ident()?; - Ok(Expr::Var { name }) + Ok(Expr::Var { name, pos }) } else if self.is_int() { + let pos = pos.unwrap(); let val = self.int()?; - Ok(Expr::ConstInt { val }) + Ok(Expr::ConstInt { val, pos }) } else { Err(self.error(pos.unwrap(), "Invalid expression".into())) } } fn parse_letdef(&mut self) -> ParseResult { + let pos = self.pos(); self.lparen()?; + let pos = pos.unwrap(); let var = self.parse_ident()?; let ty = self.parse_ident()?; let val = Box::new(self.parse_expr()?); self.rparen()?; - Ok(LetDef { var, ty, val }) - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn parse_type() { - let text = r" - ;; comment - (type Inst extern (enum - (Alu (a Reg) (b Reg) (dest Reg)) - (Load (a Reg) (dest Reg)))) - (type u32 (primitive u32)) - "; - let defs = Parser::new(Lexer::from_str(text, "(none)")) - .parse_defs() - .expect("should parse"); - assert_eq!( - defs, - Defs { - filenames: vec!["(none)".to_string()], - defs: vec![ - Def::Type(Type { - name: Ident("Inst".to_string()), - is_extern: true, - ty: TypeValue::Enum(vec![ - Variant { - name: Ident("Alu".to_string()), - fields: vec![ - Field { - name: Ident("a".to_string()), - ty: Ident("Reg".to_string()), - }, - Field { - name: Ident("b".to_string()), - ty: Ident("Reg".to_string()), - }, - Field { - name: Ident("dest".to_string()), - ty: Ident("Reg".to_string()), - }, - ], - }, - Variant { - name: Ident("Load".to_string()), - fields: vec![ - Field { - name: Ident("a".to_string()), - ty: Ident("Reg".to_string()), - }, - Field { - name: Ident("dest".to_string()), - ty: Ident("Reg".to_string()), - }, - ], - } - ]), - pos: Pos { - file: 0, - offset: 42, - line: 3, - col: 18, - }, - }), - Def::Type(Type { - name: Ident("u32".to_string()), - is_extern: false, - ty: TypeValue::Primitive(Ident("u32".to_string())), - pos: Pos { - file: 0, - offset: 167, - line: 6, - col: 18, - }, - }), - ] - } - ); + Ok(LetDef { var, ty, val, pos }) } } diff --git a/cranelift/isle/src/sema.rs b/cranelift/isle/src/sema.rs index 19f136acf0..b7ee0dace1 100644 --- a/cranelift/isle/src/sema.rs +++ b/cranelift/isle/src/sema.rs @@ -356,17 +356,20 @@ impl TypeEnv { fn type_from_ast(&mut self, tid: TypeId, ty: &ast::Type) -> Option { let name = self.intern(&ty.name).unwrap(); match &ty.ty { - &ast::TypeValue::Primitive(ref id) => Some(Type::Primitive(tid, self.intern_mut(id))), - &ast::TypeValue::Enum(ref ty_variants) => { + &ast::TypeValue::Primitive(ref id, ..) => { + Some(Type::Primitive(tid, self.intern_mut(id))) + } + &ast::TypeValue::Enum(ref ty_variants, ..) => { let mut variants = vec![]; for variant in ty_variants { - let combined_ident = ast::Ident(format!("{}.{}", ty.name.0, variant.name.0)); + let combined_ident = + ast::Ident(format!("{}.{}", ty.name.0, variant.name.0), variant.name.1); let fullname = self.intern_mut(&combined_ident); let name = self.intern_mut(&variant.name); let id = VariantId(variants.len()); if variants.iter().any(|v: &Variant| v.name == name) { self.report_error( - ty.pos, + variant.pos, format!("Duplicate variant name in type: '{}'", variant.name.0), ); return None; @@ -376,7 +379,7 @@ impl TypeEnv { let field_name = self.intern_mut(&field.name); if fields.iter().any(|f: &Field| f.name == field_name) { self.report_error( - ty.pos, + field.pos, format!( "Duplicate field name '{}' in variant '{}' of type", field.name.0, variant.name.0 @@ -389,7 +392,7 @@ impl TypeEnv { Some(tid) => *tid, None => { self.report_error( - ty.pos, + field.ty.1, format!( "Unknown type '{}' for field '{}' in variant '{}'", field.ty.0, field.name.0, variant.name.0 @@ -503,10 +506,7 @@ impl TermEnv { .map(|id| { let sym = tyenv.intern_mut(id); tyenv.type_map.get(&sym).cloned().ok_or_else(|| { - tyenv.report_error( - decl.pos, - format!("Unknown arg type: '{}'", id.0), - ); + tyenv.report_error(id.1, format!("Unknown arg type: '{}'", id.0)); () }) }) @@ -523,7 +523,7 @@ impl TermEnv { Some(t) => t, None => { tyenv.report_error( - decl.pos, + decl.ret_ty.1, format!("Unknown return type: '{}'", decl.ret_ty.0), ); continue; @@ -676,7 +676,6 @@ impl TermEnv { let (lhs, ty) = match self.translate_pattern( tyenv, - rule.pos, &rule.pattern, None, &mut bindings, @@ -688,7 +687,7 @@ impl TermEnv { } }; let rhs = - match self.translate_expr(tyenv, rule.pos, &rule.expr, ty, &mut bindings) { + match self.translate_expr(tyenv, &rule.expr, ty, &mut bindings) { Some(x) => x, None => { continue; @@ -794,7 +793,6 @@ impl TermEnv { fn translate_pattern( &self, tyenv: &mut TypeEnv, - pos: Pos, pat: &ast::Pattern, expected_ty: Option, bindings: &mut Bindings, @@ -803,7 +801,7 @@ impl TermEnv { log::trace!("translate_pattern: bindings = {:?}", bindings); match pat { // TODO: flag on primitive type decl indicating it's an integer type? - &ast::Pattern::ConstInt { val } => { + &ast::Pattern::ConstInt { val, pos } => { let ty = match expected_ty { Some(t) => t, None => { @@ -816,7 +814,7 @@ impl TermEnv { }; Some((Pattern::ConstInt(ty, val), ty)) } - &ast::Pattern::Wildcard => { + &ast::Pattern::Wildcard { pos } => { let ty = match expected_ty { Some(t) => t, None => { @@ -826,12 +824,12 @@ impl TermEnv { }; Some((Pattern::Wildcard(ty), ty)) } - &ast::Pattern::And { ref subpats } => { + &ast::Pattern::And { ref subpats, pos } => { let mut expected_ty = expected_ty; let mut children = vec![]; for subpat in subpats { let (subpat, ty) = - match self.translate_pattern(tyenv, pos, &*subpat, expected_ty, bindings) { + match self.translate_pattern(tyenv, &*subpat, expected_ty, bindings) { Some(x) => x, None => { // Try to keep going for more errors. @@ -851,10 +849,11 @@ impl TermEnv { &ast::Pattern::BindPattern { ref var, ref subpat, + pos, } => { // Do the subpattern first so we can resolve the type for sure. let (subpat, ty) = - self.translate_pattern(tyenv, pos, &*subpat, expected_ty, bindings)?; + self.translate_pattern(tyenv, &*subpat, expected_ty, bindings)?; let name = tyenv.intern_mut(var); if bindings.vars.iter().any(|bv| bv.name == name) { @@ -871,7 +870,7 @@ impl TermEnv { Some((Pattern::BindPattern(ty, id, Box::new(subpat)), ty)) } - &ast::Pattern::Var { ref var } => { + &ast::Pattern::Var { ref var, pos } => { // Look up the variable; it must already have been bound. let name = tyenv.intern_mut(var); let bv = match bindings.vars.iter().rev().find(|bv| bv.name == name) { @@ -903,7 +902,11 @@ impl TermEnv { }; Some((Pattern::Var(ty, bv.id), ty)) } - &ast::Pattern::Term { ref sym, ref args } => { + &ast::Pattern::Term { + ref sym, + ref args, + pos, + } => { let name = tyenv.intern_mut(&sym); // Look up the term. let tid = match self.term_map.get(&name) { @@ -950,7 +953,7 @@ impl TermEnv { match &termdata.kind { &TermKind::EnumVariant { .. } => { for arg in args { - if let &ast::TermArgPattern::Expr(..) = arg { + if let &ast::TermArgPattern::Expr(_) = arg { tyenv.report_error(pos, format!("Term in pattern '{}' cannot have an injected expr, because it is an enum variant", sym.0)); } } @@ -961,16 +964,16 @@ impl TermEnv { for (arg, pol) in args.iter().zip(arg_polarity.iter()) { match (arg, pol) { (&ast::TermArgPattern::Expr(..), &ArgPolarity::Input) => {} - (&ast::TermArgPattern::Expr(..), &ArgPolarity::Output) => { + (&ast::TermArgPattern::Expr(ref e), &ArgPolarity::Output) => { tyenv.report_error( - pos, + e.pos(), "Expression used for output-polarity extractor arg" .to_string(), ); } (_, &ArgPolarity::Output) => {} - (_, &ArgPolarity::Input) => { - tyenv.report_error(pos, "Non-expression used in pattern but expression required for input-polarity extractor arg".to_string()); + (&ast::TermArgPattern::Pattern(ref p), &ArgPolarity::Input) => { + tyenv.report_error(p.pos(), "Non-expression used in pattern but expression required for input-polarity extractor arg".to_string()); } } } @@ -993,7 +996,7 @@ impl TermEnv { } log::trace!("internal extractor macro args = {:?}", args); let pat = template.subst_macro_args(¯o_args[..]); - return self.translate_pattern(tyenv, pos, &pat, expected_ty, bindings); + return self.translate_pattern(tyenv, &pat, expected_ty, bindings); } &TermKind::ExternalConstructor { .. } | &TermKind::InternalConstructor => { // OK. @@ -1043,7 +1046,7 @@ impl TermEnv { match pat { &ast::TermArgPattern::Pattern(ref pat) => { let (subpat, ty) = - self.translate_pattern(tyenv, pos, pat, expected_ty, bindings)?; + self.translate_pattern(tyenv, pat, expected_ty, bindings)?; Some((TermArgPattern::Pattern(subpat), ty)) } &ast::TermArgPattern::Expr(ref expr) => { @@ -1055,7 +1058,7 @@ impl TermEnv { return None; } let ty = expected_ty.unwrap(); - let expr = self.translate_expr(tyenv, pos, expr, expected_ty.unwrap(), bindings)?; + let expr = self.translate_expr(tyenv, expr, expected_ty.unwrap(), bindings)?; Some((TermArgPattern::Expr(expr), ty)) } } @@ -1064,14 +1067,17 @@ impl TermEnv { fn translate_expr( &self, tyenv: &mut TypeEnv, - pos: Pos, expr: &ast::Expr, ty: TypeId, bindings: &mut Bindings, ) -> Option { log::trace!("translate_expr: {:?}", expr); match expr { - &ast::Expr::Term { ref sym, ref args } => { + &ast::Expr::Term { + ref sym, + ref args, + pos, + } => { // Look up the term. let name = tyenv.intern_mut(&sym); // Look up the term. @@ -1108,7 +1114,7 @@ impl TermEnv { let mut subexprs = vec![]; for (i, arg) in args.iter().enumerate() { let arg_ty = self.terms[tid.index()].arg_tys[i]; - let subexpr = match self.translate_expr(tyenv, pos, arg, arg_ty, bindings) { + let subexpr = match self.translate_expr(tyenv, arg, arg_ty, bindings) { Some(s) => s, None => { continue; @@ -1119,7 +1125,7 @@ impl TermEnv { Some(Expr::Term(ty, *tid, subexprs)) } - &ast::Expr::Var { ref name } => { + &ast::Expr::Var { ref name, pos } => { let sym = tyenv.intern_mut(name); // Look through bindings, innermost (most recent) first. let bv = match bindings.vars.iter().rev().find(|b| b.name == sym) { @@ -1145,8 +1151,12 @@ impl TermEnv { Some(Expr::Var(bv.ty, bv.id)) } - &ast::Expr::ConstInt { val } => Some(Expr::ConstInt(ty, val)), - &ast::Expr::Let { ref defs, ref body } => { + &ast::Expr::ConstInt { val, .. } => Some(Expr::ConstInt(ty, val)), + &ast::Expr::Let { + ref defs, + ref body, + pos, + } => { let orig_binding_len = bindings.vars.len(); // For each new binding... @@ -1182,7 +1192,7 @@ impl TermEnv { // Evaluate the variable's value. let val = Box::new( - match self.translate_expr(tyenv, pos, &def.val, ty, bindings) { + match self.translate_expr(tyenv, &def.val, ty, bindings) { Some(e) => e, None => { // Keep going for more errors. @@ -1200,7 +1210,7 @@ impl TermEnv { } // Evaluate the body, expecting the type of the overall let-expr. - let body = Box::new(self.translate_expr(tyenv, pos, body, ty, bindings)?); + let body = Box::new(self.translate_expr(tyenv, body, ty, bindings)?); let body_ty = body.ty(); // Pop the bindings.