From f041cc17d26ab2186f16c71f50afada41314139b Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 21 Feb 2019 19:07:07 -0800 Subject: [PATCH] Wrap all Expression nodes in Meta --- TODO.md | 2 + schala-lang/language/src/ast.rs | 18 +++--- schala-lang/language/src/parsing.rs | 79 ++++++++++++++---------- schala-lang/language/src/reduced_ast.rs | 4 +- schala-lang/language/src/typechecking.rs | 2 +- 5 files changed, 61 insertions(+), 44 deletions(-) diff --git a/TODO.md b/TODO.md index 610484c..e4e0905 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,7 @@ #Typechecking Notes +IS BOX SYNTAX READY???? + (cf. cardelli paper) Given a length function def: diff --git a/schala-lang/language/src/ast.rs b/schala-lang/language/src/ast.rs index aa23496..9f47ee0 100644 --- a/schala-lang/language/src/ast.rs +++ b/schala-lang/language/src/ast.rs @@ -59,7 +59,7 @@ pub enum Declaration { name: Rc, constant: bool, type_anno: Option, - expr: Expression, + expr: Meta, }, Impl { type_name: TypeIdentifier, @@ -121,22 +121,22 @@ pub enum ExpressionKind { Value(Rc), NamedStruct { name: Rc, - fields: Vec<(Rc, Expression)>, + fields: Vec<(Rc, Meta)>, }, Call { - f: Box, + f: Box>, arguments: Vec>, }, Index { - indexee: Box, - indexers: Vec, + indexee: Box>, + indexers: Vec>, }, IfExpression { discriminator: Box, body: Box, }, WhileExpression { - condition: Option>, + condition: Option>>, body: Block, }, ForExpression { @@ -148,7 +148,7 @@ pub enum ExpressionKind { type_anno: Option, body: Block, }, - ListLiteral(Vec), + ListLiteral(Vec>), } #[derive(Debug, PartialEq, Clone)] @@ -205,11 +205,11 @@ pub enum PatternLiteral { #[derive(Debug, PartialEq, Clone)] pub struct Enumerator { pub id: Rc, - pub generator: Expression, + pub generator: Meta, } #[derive(Debug, PartialEq, Clone)] pub enum ForBody { - MonadicReturn(Expression), + MonadicReturn(Meta), StatementBlock(Block), } diff --git a/schala-lang/language/src/parsing.rs b/schala-lang/language/src/parsing.rs index a17a3d2..4b422f6 100644 --- a/schala-lang/language/src/parsing.rs +++ b/schala-lang/language/src/parsing.rs @@ -451,7 +451,7 @@ impl Parser { }; expect!(self, Operator(ref o) if **o == "="); - let expr = self.expression()?; + let expr = self.expression()?.into(); Ok(Declaration::Binding { name, constant, type_anno, expr }) } @@ -590,7 +590,7 @@ impl Parser { while let LParen = self.token_handler.peek_kind() { let arguments = delimited!(self, LParen, expression, Comma, RParen); let arguments = arguments.into_iter().map(|s| Meta::new(s)).collect(); - expr = Expression(ExpressionKind::Call { f: bx!(expr), arguments }, None); //TODO none is incorrect + expr = Expression(ExpressionKind::Call { f: bx!(expr.into()), arguments }, None); //TODO none is incorrect } Ok(expr) @@ -600,9 +600,10 @@ impl Parser { fn index_expr(&mut self) -> ParseResult { let primary = self.primary()?; Ok(if let LSquareBracket = self.token_handler.peek_kind() { - let indexers = delimited!(self, LSquareBracket, expression, Comma, RSquareBracket); + let indexers = delimited!(self, LSquareBracket, expression, Comma, RSquareBracket) + .into_iter().map(|ex| ex.into()).collect(); Expression(ExpressionKind::Index { - indexee: bx!(Expression(primary.0, None)), + indexee: bx!(Expression(primary.0, None).into()), indexers, }, None) } else { @@ -627,7 +628,8 @@ impl Parser { #[recursive_descent_method] fn list_expr(&mut self) -> ParseResult { - let exprs = delimited!(self, LSquareBracket, expression, Comma, RSquareBracket); + let exprs = delimited!(self, LSquareBracket, expression, Comma, RSquareBracket) + .into_iter().map(|ex| ex.into()).collect(); Ok(Expression(ExpressionKind::ListLiteral(exprs), None)) } @@ -692,8 +694,11 @@ impl Parser { } #[recursive_descent_method] - fn record_block(&mut self) -> ParseResult, Expression)>> { - Ok(delimited!(self, LCurlyBrace, record_entry, Comma, RCurlyBrace)) + fn record_block(&mut self) -> ParseResult, Meta)>> { + Ok( + delimited!(self, LCurlyBrace, record_entry, Comma, RCurlyBrace) + .into_iter().map(|(s, ex)| (s, ex.into())).collect() + ) } #[recursive_descent_method] @@ -926,7 +931,7 @@ impl Parser { self.restrictions.no_struct_literal = true; let x = self.while_cond(); self.restrictions.no_struct_literal = false; - x?.map(|expr| bx!(expr)) + x?.map(|expr| bx!(expr.into())) }; let body = self.block()?; Ok(Expression(WhileExpression {condition, body}, None)) @@ -962,7 +967,7 @@ impl Parser { fn enumerator(&mut self) -> ParseResult { let id = self.identifier()?; expect!(self, Operator(ref c) if **c == "<-"); - let generator = self.expression()?; + let generator = self.expression()?.into(); Ok(Enumerator { id, generator }) } @@ -977,7 +982,7 @@ impl Parser { }, Keyword(Kw::Return) => { self.token_handler.next(); - MonadicReturn(self.expression()?) + MonadicReturn(self.expression()?.into()) }, _ => return ParseError::new_with_token("for expressions must end in a block or 'return'", tok), }) @@ -1157,6 +1162,8 @@ mod parse_tests { macro_rules! ex { ($expr_type:expr) => { Expression($expr_type, None) }; + (m $expr_type:expr) => { Meta::new(Expression($expr_type, None)) }; + (m $expr_type:expr, $type_anno:expr) => { Meta::new(Expression($expr_type, Some($type_anno))) }; (s $expr_text:expr) => { { let tokens: Vec = tokenize($expr_text); @@ -1259,12 +1266,20 @@ mod parse_tests { ]) } */ - parse_test!("a[b,c]", AST(vec![exst!(Index { indexee: bx!(ex!(val!("a"))), indexers: vec![ex!(val!("b")), ex!(val!("c"))]} )])); + parse_test!("a[b,c]", AST(vec![exst!(Index { indexee: bx!(ex!(m val!("a"))), indexers: vec![ex!(m val!("b")), ex!(m val!("c"))]} )])); parse_test!("None", AST(vec![exst!(val!("None"))])); parse_test!("Pandas { a: x + y }", AST(vec![ - exst!(NamedStruct { name: rc!(Pandas), fields: vec![(rc!(a), ex!(binexp!("+", val!("x"), val!("y"))))]}) + exst!(NamedStruct { name: rc!(Pandas), fields: vec![(rc!(a), ex!(m binexp!("+", val!("x"), val!("y"))))]}) ])); + parse_test! { "Pandas { a: n, b: q, }", + AST(vec![ + exst!(NamedStruct { name: rc!(Pandas), fields: + vec![(rc!(a), ex!(m val!("n"))), (rc!(b), ex!(m val!("q")))] + } + ) + ]) + }; } #[test] @@ -1287,9 +1302,9 @@ mod parse_tests { #[test] fn parsing_functions() { parse_test!("fn oi()", AST(vec![Meta::new(Declaration(FuncSig(Signature { name: rc!(oi), operator: false, params: vec![], type_anno: None })))])); - parse_test!("oi()", AST(vec![exst!(Call { f: bx!(ex!(val!("oi"))), arguments: vec![] })])); + parse_test!("oi()", AST(vec![exst!(Call { f: bx!(ex!(m val!("oi"))), arguments: vec![] })])); parse_test!("oi(a, 2 + 2)", AST(vec![exst!(Call - { f: bx!(ex!(val!("oi"))), + { f: bx!(ex!(m val!("oi"))), arguments: vec![ex!(val!("a")).into(), ex!(binexp!("+", NatLiteral(2), NatLiteral(2))).into()] })])); parse_error!("a(b,,c)"); @@ -1302,10 +1317,10 @@ mod parse_tests { parse_test!("fn a(x) { x() }", AST(vec![Meta::new(Declaration( FuncDecl(Signature { name: rc!(a), operator: false, params: vec![(rc!(x),None)], type_anno: None }, - vec![exst!(Call { f: bx!(ex!(val!("x"))), arguments: vec![] })])))])); + vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })])))])); parse_test!("fn a(x) {\n x() }", AST(vec![Meta::new(Declaration( FuncDecl(Signature { name: rc!(a), operator: false, params: vec![(rc!(x),None)], type_anno: None }, - vec![exst!(Call { f: bx!(ex!(val!("x"))), arguments: vec![] })])))])); + vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })])))])); let multiline = r#" fn a(x) { @@ -1314,7 +1329,7 @@ fn a(x) { "#; parse_test!(multiline, AST(vec![Meta::new(Declaration( FuncDecl(Signature { name: rc!(a), operator: false, params: vec![(rc!(x),None)], type_anno: None }, - vec![exst!(Call { f: bx!(ex!(val!("x"))), arguments: vec![] })])))])); + vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })])))])); let multiline2 = r#" fn a(x) { @@ -1374,11 +1389,11 @@ fn a(x) { #[test] fn parsing_bindings() { - parse_test!("let mut a = 10", AST(vec![Meta::new(Declaration(Binding { name: rc!(a), constant: false, type_anno: None, expr: ex!(NatLiteral(10)) } ))])); - parse_test!("let a = 2 + 2", AST(vec![Meta::new(Declaration(Binding { name: rc!(a), constant: true, type_anno: None, expr: ex!(binexp!("+", NatLiteral(2), NatLiteral(2))) }) )])); + parse_test!("let mut a = 10", AST(vec![Meta::new(Declaration(Binding { name: rc!(a), constant: false, type_anno: None, expr: ex!(m NatLiteral(10)) } ))])); + parse_test!("let a = 2 + 2", AST(vec![Meta::new(Declaration(Binding { name: rc!(a), constant: true, type_anno: None, expr: ex!(m binexp!("+", NatLiteral(2), NatLiteral(2))) }) )])); parse_test!("let a: Nat = 2 + 2", AST(vec![Meta::new(Declaration( Binding { name: rc!(a), constant: true, type_anno: Some(Singleton(TypeSingletonName { name: rc!(Nat), params: vec![] })), - expr: ex!(binexp!("+", NatLiteral(2), NatLiteral(2))) } + expr: Meta::new(ex!(binexp!("+", NatLiteral(2), NatLiteral(2)))) } ))])); } @@ -1388,11 +1403,11 @@ fn a(x) { "if a() then { b(); c() }", AST(vec![exst!( IfExpression { discriminator: bx! { - Discriminator::Simple(ex!(Call { f: bx!(ex!(val!("a"))), arguments: vec![]})) + Discriminator::Simple(ex!(Call { f: bx!(ex!(m val!("a"))), arguments: vec![]})) }, body: bx! { IfExpressionBody::SimpleConditional( - vec![exst!(Call { f: bx!(ex!(val!("b"))), arguments: vec![]}), exst!(Call { f: bx!(ex!(val!("c"))), arguments: vec![] })], + vec![exst!(Call { f: bx!(ex!(m val!("b"))), arguments: vec![]}), exst!(Call { f: bx!(ex!(m val!("c"))), arguments: vec![] })], None ) } @@ -1404,11 +1419,11 @@ fn a(x) { "if a() then { b(); c() } else { q }", AST(vec![exst!( IfExpression { discriminator: bx! { - Discriminator::Simple(ex!(Call { f: bx!(ex!(val!("a"))), arguments: vec![]})) + Discriminator::Simple(ex!(Call { f: bx!(ex!(m val!("a"))), arguments: vec![]})) }, body: bx! { IfExpressionBody::SimpleConditional( - vec![exst!(Call { f: bx!(ex!(val!("b"))), arguments: vec![]}), exst!(Call { f: bx!(ex!(val!("c"))), arguments: vec![] })], + vec![exst!(Call { f: bx!(ex!(m val!("b"))), arguments: vec![]}), exst!(Call { f: bx!(ex!(m val!("c"))), arguments: vec![] })], Some( vec![exst!(val!("q"))], ) @@ -1508,7 +1523,7 @@ fn a(x) { parse_test!("let a = b : Int", AST(vec![ Meta::new( Declaration(Binding { name: rc!(a), constant: true, type_anno: None, expr: - Expression(val!("b"), Some(ty!("Int"))) }))])); + ex!(m val!("b"), ty!("Int")) }))])); parse_test!("a : Int", AST(vec![ exst!(val!("a"), ty!("Int")) @@ -1547,7 +1562,7 @@ fn a(x) { ])); parse_test!(r#"\(x){y}(1)"#, AST(vec![ - exst!(Call { f: bx!(ex!( + exst!(Call { f: bx!(ex!(m Lambda { params: vec![(rc!(x), None)], type_anno: None, @@ -1594,7 +1609,7 @@ fn a(x) { exst!(s r"fn wahoo() { let a = 10; \(x) { x + a } }"), exst! { Call { - f: bx!(ex!(Call { f: bx!(ex!(val!("wahoo"))), arguments: vec![] })), + f: bx!(ex!(m Call { f: bx!(ex!(m val!("wahoo"))), arguments: vec![] })), arguments: vec![ex!(s "3").into()], } } @@ -1606,7 +1621,7 @@ fn a(x) { fn list_literals() { parse_test! { "[1,2]", AST(vec![ - exst!(ListLiteral(vec![ex!(NatLiteral(1)), ex!(NatLiteral(2))]))]) + exst!(ListLiteral(vec![ex!(m NatLiteral(1)), ex!(m NatLiteral(2))]))]) }; } @@ -1619,7 +1634,7 @@ fn a(x) { parse_test! { "while a == b { }", AST(vec![ - exst!(WhileExpression { condition: Some(bx![ex![binexp!("==", val!("a"), val!("b"))]]), body: vec![] })]) + exst!(WhileExpression { condition: Some(bx![ex![m binexp!("==", val!("a"), val!("b"))]]), body: vec![] })]) } } @@ -1628,14 +1643,14 @@ fn a(x) { parse_test! { "for { a <- maybeValue } return 1", AST(vec![ exst!(ForExpression { - enumerators: vec![Enumerator { id: rc!(a), generator: ex!(val!("maybeValue")) }], - body: bx!(MonadicReturn(ex!(s "1"))) + enumerators: vec![Enumerator { id: rc!(a), generator: ex!(m val!("maybeValue")) }], + body: bx!(MonadicReturn(Meta::new(ex!(s "1")))) })]) } parse_test! { "for n <- someRange { f(n); }", AST(vec![ - exst!(ForExpression { enumerators: vec![Enumerator { id: rc!(n), generator: ex!(val!("someRange"))}], + exst!(ForExpression { enumerators: vec![Enumerator { id: rc!(n), generator: ex!(m val!("someRange"))}], body: bx!(ForBody::StatementBlock(vec![exst!(s "f(n)")])) })]) } diff --git a/schala-lang/language/src/reduced_ast.rs b/schala-lang/language/src/reduced_ast.rs index cbd1335..b85659d 100644 --- a/schala-lang/language/src/reduced_ast.rs +++ b/schala-lang/language/src/reduced_ast.rs @@ -139,7 +139,7 @@ impl Expression { _ => Expr::Val(name.clone()), }, Call { f, arguments } => Expr::Call { - f: Box::new(f.reduce(symbol_table)), + f: Box::new(f.node().reduce(symbol_table)), args: arguments.iter().map(|arg| arg.node().reduce(symbol_table)).collect(), }, TupleLiteral(exprs) => Expr::Tuple(exprs.iter().map(|e| e.node().reduce(symbol_table)).collect()), @@ -358,7 +358,7 @@ impl Declaration { use self::Declaration::*; use crate::ast::Signature; match self { - Binding {name, constant, expr, .. } => Stmt::Binding { name: name.clone(), constant: *constant, expr: expr.reduce(symbol_table) }, + Binding {name, constant, expr, .. } => Stmt::Binding { name: name.clone(), constant: *constant, expr: expr.node().reduce(symbol_table) }, FuncDecl(Signature { name, params, .. }, statements) => Stmt::PreBinding { name: name.clone(), func: Func::UserDefined { diff --git a/schala-lang/language/src/typechecking.rs b/schala-lang/language/src/typechecking.rs index 7584731..e64ad05 100644 --- a/schala-lang/language/src/typechecking.rs +++ b/schala-lang/language/src/typechecking.rs @@ -227,7 +227,7 @@ impl<'a> TypeContext<'a> { use self::Declaration::*; match decl { Binding { name, expr, .. } => { - let ty = self.expr(expr)?; + let ty = self.expr(expr.node())?; self.variable_map.insert(name.clone(), ty); }, _ => (),