Change design of Statement AST node

This commit is contained in:
greg 2019-09-17 02:25:11 -07:00
parent 08da787aae
commit b91c3c9da5
7 changed files with 67 additions and 54 deletions

View File

@ -50,8 +50,13 @@ pub struct AST {
} }
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub enum Statement { pub struct Statement {
ExpressionStatement(Meta<Expression>), pub kind: StatementKind,
}
#[derive(Debug, PartialEq, Clone)]
pub enum StatementKind {
Expression(Meta<Expression>),
Declaration(Declaration), //TODO Declaration should also be Meta-wrapped; only Expression and Declaration are Meta-wrapped maybe? Declaration(Declaration), //TODO Declaration should also be Meta-wrapped; only Expression and Declaration are Meta-wrapped maybe?
} }

View File

@ -341,14 +341,15 @@ impl Parser {
#[recursive_descent_method] #[recursive_descent_method]
fn statement(&mut self) -> ParseResult<Statement> { fn statement(&mut self) -> ParseResult<Statement> {
//TODO handle error recovery here //TODO handle error recovery here
match self.token_handler.peek().get_kind() { let kind = match self.token_handler.peek().get_kind() {
Keyword(Type) => self.type_declaration().map(|decl| { Statement::Declaration(decl) }), Keyword(Type) => self.type_declaration().map(|decl| { StatementKind::Declaration(decl) }),
Keyword(Func)=> self.func_declaration().map(|func| { Statement::Declaration(func) }), Keyword(Func)=> self.func_declaration().map(|func| { StatementKind::Declaration(func) }),
Keyword(Let) => self.binding_declaration().map(|decl| Statement::Declaration(decl)), Keyword(Let) => self.binding_declaration().map(|decl| StatementKind::Declaration(decl)),
Keyword(Interface) => self.interface_declaration().map(|decl| Statement::Declaration(decl)), Keyword(Interface) => self.interface_declaration().map(|decl| StatementKind::Declaration(decl)),
Keyword(Impl) => self.impl_declaration().map(|decl| Statement::Declaration(decl)), Keyword(Impl) => self.impl_declaration().map(|decl| StatementKind::Declaration(decl)),
_ => self.expression().map(|expr| { Statement::ExpressionStatement(expr.into()) } ), _ => self.expression().map(|expr| { StatementKind::Expression(expr.into()) } ),
} }?;
Ok(Statement { kind })
} }
#[recursive_descent_method] #[recursive_descent_method]
@ -1060,7 +1061,8 @@ impl Parser {
LCurlyBrace => self.block(), LCurlyBrace => self.block(),
_ => { _ => {
let expr = self.expression()?; let expr = self.expression()?;
Ok(vec![Meta::new(Statement::ExpressionStatement(expr.into()))]) let s = Statement { kind: StatementKind::Expression(expr.into()) };
Ok(vec![Meta::new(s)])
} }
} }
} }

View File

@ -4,8 +4,7 @@ use std::str::FromStr;
use super::tokenize; use super::tokenize;
use super::ParseResult; use super::ParseResult;
use crate::ast::{AST, Meta, Expression, Statement, IfExpressionBody, Discriminator, Pattern, PatternLiteral, TypeBody, Enumerator, ForBody, InvocationArgument, FormalParam, PrefixOp, BinOp, QualifiedName}; use crate::ast::{AST, Meta, Expression, Statement, StatementKind, IfExpressionBody, Discriminator, Pattern, PatternLiteral, TypeBody, Enumerator, ForBody, InvocationArgument, FormalParam, PrefixOp, BinOp, QualifiedName};
use super::Statement::*;
use super::Declaration::*; use super::Declaration::*;
use super::Signature; use super::Signature;
use super::TypeIdentifier::*; use super::TypeIdentifier::*;
@ -39,6 +38,12 @@ macro_rules! tys {
($name:expr) => { TypeSingletonName { name: Rc::new($name.to_string()), params: vec![] } }; ($name:expr) => { TypeSingletonName { name: Rc::new($name.to_string()), params: vec![] } };
} }
macro_rules! decl {
($expr_type:expr) => {
Statement { kind: StatementKind::Declaration($expr_type) }
};
}
macro_rules! ex { macro_rules! ex {
($expr_type:expr) => { Expression::new($expr_type) }; ($expr_type:expr) => { Expression::new($expr_type) };
(m $expr_type:expr) => { Meta::new(Expression::new($expr_type)) }; (m $expr_type:expr) => { Meta::new(Expression::new($expr_type)) };
@ -63,9 +68,11 @@ macro_rules! prefexp {
($op:expr, $lhs:expr) => { PrefixExp(PrefixOp::from_str($op).unwrap(), bx!(Expression::new($lhs).into())) } ($op:expr, $lhs:expr) => { PrefixExp(PrefixOp::from_str($op).unwrap(), bx!(Expression::new($lhs).into())) }
} }
macro_rules! exst { macro_rules! exst {
($expr_type:expr) => { Meta::new(Statement::ExpressionStatement(Expression::new($expr_type).into())) }; ($expr_type:expr) => { Meta::new(Statement { kind: StatementKind::Expression(Expression::new($expr_type).into())}) };
($expr_type:expr, $type_anno:expr) => { Meta::new(Statement::ExpressionStatement(Expression::with_anno($expr_type, $type_anno).into())) }; ($expr_type:expr, $type_anno:expr) => { Meta::new(Statement { kind: StatementKind::Expression(Expression::with_anno($expr_type, $type_anno).into())}) };
($op:expr, $lhs:expr, $rhs:expr) => { Meta::new(Statement::ExpressionStatement(ex!(binexp!($op, $lhs, $rhs)))) }; ($op:expr, $lhs:expr, $rhs:expr) => { Meta::new(
Statement { kind: StatementKind::Expression(ex!(binexp!($op, $lhs, $rhs)))}
)};
(s $statement_text:expr) => { (s $statement_text:expr) => {
{ {
let tokens: Vec<crate::tokenizing::Token> = tokenize($statement_text); let tokens: Vec<crate::tokenizing::Token> = tokenize($statement_text);
@ -168,7 +175,7 @@ fn parsing_identifiers() {
fn qualified_identifiers() { fn qualified_identifiers() {
parse_test_wrap_ast! { parse_test_wrap_ast! {
"let q_q = Yolo::Swaggins", "let q_q = Yolo::Swaggins",
Meta::new(Declaration(Binding { name: rc!(q_q), constant: true, type_anno: None, Meta::new(decl!(Binding { name: rc!(q_q), constant: true, type_anno: None,
expr: Meta::new(Expression::new(Value(Meta::new(QualifiedName(vec![rc!(Yolo), rc!(Swaggins)]))))), expr: Meta::new(Expression::new(Value(Meta::new(QualifiedName(vec![rc!(Yolo), rc!(Swaggins)]))))),
})) }))
} }
@ -203,7 +210,7 @@ fn parsing_complicated_operators() {
#[test] #[test]
fn parsing_functions() { fn parsing_functions() {
parse_test_wrap_ast!("fn oi()", Meta::new(Declaration(FuncSig(Signature { name: rc!(oi), operator: false, params: vec![], type_anno: None })))); parse_test_wrap_ast!("fn oi()", Meta::new(decl!(FuncSig(Signature { name: rc!(oi), operator: false, params: vec![], type_anno: None }))));
parse_test_wrap_ast!("oi()", exst!(Call { f: bx!(ex!(m val!("oi"))), arguments: vec![] })); parse_test_wrap_ast!("oi()", exst!(Call { f: bx!(ex!(m val!("oi"))), arguments: vec![] }));
parse_test_wrap_ast!("oi(a, 2 + 2)", exst!(Call parse_test_wrap_ast!("oi(a, 2 + 2)", exst!(Call
{ f: bx!(ex!(m val!("oi"))), { f: bx!(ex!(m val!("oi"))),
@ -211,17 +218,17 @@ fn parsing_functions() {
})); }));
parse_error!("a(b,,c)"); parse_error!("a(b,,c)");
parse_test_wrap_ast!("fn a(b, c: Int): Int", Meta::new(Declaration( parse_test_wrap_ast!("fn a(b, c: Int): Int", Meta::new(decl!(
FuncSig(Signature { name: rc!(a), operator: false, params: vec![ FuncSig(Signature { name: rc!(a), operator: false, params: vec![
FormalParam { name: rc!(b), anno: None, default: None }, FormalParam { name: rc!(b), anno: None, default: None },
FormalParam { name: rc!(c), anno: Some(ty!("Int")), default: None } FormalParam { name: rc!(c), anno: Some(ty!("Int")), default: None }
], type_anno: Some(ty!("Int")) })))); ], type_anno: Some(ty!("Int")) }))));
parse_test_wrap_ast!("fn a(x) { x() }", Meta::new(Declaration( parse_test_wrap_ast!("fn a(x) { x() }", Meta::new(decl!(
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![FormalParam { name: rc!(x), anno: None, default: None }], type_anno: None }, FuncDecl(Signature { name: rc!(a), operator: false, params: vec![FormalParam { name: rc!(x), anno: None, default: None }], type_anno: None },
vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })])))); vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })]))));
parse_test_wrap_ast!("fn a(x) {\n x() }", Meta::new(Declaration( parse_test_wrap_ast!("fn a(x) {\n x() }", Meta::new(decl!(
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![FormalParam { name: rc!(x), anno: None, default: None }], type_anno: None }, FuncDecl(Signature { name: rc!(a), operator: false, params: vec![FormalParam { name: rc!(x), anno: None, default: None }], type_anno: None },
vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })])))); vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })]))));
@ -230,7 +237,7 @@ fn a(x) {
x() x()
} }
"#; "#;
parse_test_wrap_ast!(multiline, Meta::new(Declaration( parse_test_wrap_ast!(multiline, Meta::new(decl!(
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![FormalParam { name: rc!(x), default: None, anno: None }], type_anno: None }, FuncDecl(Signature { name: rc!(a), operator: false, params: vec![FormalParam { name: rc!(x), default: None, anno: None }], type_anno: None },
vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })])))); vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })]))));
let multiline2 = r#" let multiline2 = r#"
@ -240,7 +247,7 @@ x()
} }
"#; "#;
parse_test_wrap_ast!(multiline2, Meta::new(Declaration( parse_test_wrap_ast!(multiline2, Meta::new(decl!(
FuncDecl(Signature { name: rc!(a), operator: false, params: vec![FormalParam { name: rc!(x), default: None, anno: None }], type_anno: None }, FuncDecl(Signature { name: rc!(a), operator: false, params: vec![FormalParam { name: rc!(x), default: None, anno: None }], type_anno: None },
vec![exst!(s "x()")])))); vec![exst!(s "x()")]))));
} }
@ -249,7 +256,7 @@ x()
fn functions_with_default_args() { fn functions_with_default_args() {
parse_test_wrap_ast! { parse_test_wrap_ast! {
"fn func(x: Int, y: Int = 4) { }", "fn func(x: Int, y: Int = 4) { }",
Meta::new(Declaration( Meta::new(decl!(
FuncDecl(Signature { name: rc!(func), operator: false, type_anno: None, params: vec![ FuncDecl(Signature { name: rc!(func), operator: false, type_anno: None, params: vec![
FormalParam { name: rc!(x), default: None, anno: Some(ty!("Int")) }, FormalParam { name: rc!(x), default: None, anno: Some(ty!("Int")) },
FormalParam { name: rc!(y), default: Some(Meta::new(ex!(s "4"))), anno: Some(ty!("Int")) } FormalParam { name: rc!(y), default: Some(Meta::new(ex!(s "4"))), anno: Some(ty!("Int")) }
@ -271,11 +278,11 @@ fn parsing_strings() {
#[test] #[test]
fn parsing_types() { fn parsing_types() {
parse_test_wrap_ast!("type Yolo = Yolo", Meta::new(Declaration(TypeDecl { name: tys!("Yolo"), body: TypeBody(vec![UnitStruct(rc!(Yolo))]), mutable: false} ))); parse_test_wrap_ast!("type Yolo = Yolo", Meta::new(decl!(TypeDecl { name: tys!("Yolo"), body: TypeBody(vec![UnitStruct(rc!(Yolo))]), mutable: false} )));
parse_test_wrap_ast!("type mut Yolo = Yolo", Meta::new(Declaration(TypeDecl { name: tys!("Yolo"), body: TypeBody(vec![UnitStruct(rc!(Yolo))]), mutable: true} ))); parse_test_wrap_ast!("type mut Yolo = Yolo", Meta::new(decl!(TypeDecl { name: tys!("Yolo"), body: TypeBody(vec![UnitStruct(rc!(Yolo))]), mutable: true} )));
parse_test_wrap_ast!("type alias Sex = Drugs", Meta::new(Declaration(TypeAlias(rc!(Sex), rc!(Drugs))))); parse_test_wrap_ast!("type alias Sex = Drugs", Meta::new(decl!(TypeAlias(rc!(Sex), rc!(Drugs)))));
parse_test_wrap_ast!("type Sanchez = Miguel | Alejandro(Int, Option<a>) | Esperanza { a: Int, b: String }", parse_test_wrap_ast!("type Sanchez = Miguel | Alejandro(Int, Option<a>) | Esperanza { a: Int, b: String }",
Meta::new(Declaration(TypeDecl { Meta::new(decl!(TypeDecl {
name: tys!("Sanchez"), name: tys!("Sanchez"),
body: TypeBody(vec![ body: TypeBody(vec![
UnitStruct(rc!(Miguel)), UnitStruct(rc!(Miguel)),
@ -296,7 +303,7 @@ fn parsing_types() {
parse_test_wrap_ast! { parse_test_wrap_ast! {
"type Jorge<a> = Diego | Kike(a)", "type Jorge<a> = Diego | Kike(a)",
Meta::new(Declaration(TypeDecl{ Meta::new(decl!(TypeDecl{
name: TypeSingletonName { name: rc!(Jorge), params: vec![Singleton(TypeSingletonName { name: rc!(a), params: vec![] })] }, name: TypeSingletonName { name: rc!(Jorge), params: vec![Singleton(TypeSingletonName { name: rc!(a), params: vec![] })] },
body: TypeBody(vec![UnitStruct(rc!(Diego)), TupleStruct(rc!(Kike), vec![Singleton(TypeSingletonName { name: rc!(a), params: vec![] })])]), body: TypeBody(vec![UnitStruct(rc!(Diego)), TupleStruct(rc!(Kike), vec![Singleton(TypeSingletonName { name: rc!(a), params: vec![] })])]),
mutable: false mutable: false
@ -307,9 +314,9 @@ fn parsing_types() {
#[test] #[test]
fn parsing_bindings() { fn parsing_bindings() {
parse_test_wrap_ast!("let mut a = 10", Meta::new(Declaration(Binding { name: rc!(a), constant: false, type_anno: None, expr: ex!(m NatLiteral(10)) } ))); parse_test_wrap_ast!("let mut a = 10", Meta::new(decl!(Binding { name: rc!(a), constant: false, type_anno: None, expr: ex!(m NatLiteral(10)) } )));
parse_test_wrap_ast!("let a = 2 + 2", Meta::new(Declaration(Binding { name: rc!(a), constant: true, type_anno: None, expr: ex!(m binexp!("+", NatLiteral(2), NatLiteral(2))) }) )); parse_test_wrap_ast!("let a = 2 + 2", Meta::new(decl!(Binding { name: rc!(a), constant: true, type_anno: None, expr: ex!(m binexp!("+", NatLiteral(2), NatLiteral(2))) }) ));
parse_test_wrap_ast!("let a: Nat = 2 + 2", Meta::new(Declaration( parse_test_wrap_ast!("let a: Nat = 2 + 2", Meta::new(decl!(
Binding { name: rc!(a), constant: true, type_anno: Some(Singleton(TypeSingletonName { name: rc!(Nat), params: vec![] })), Binding { name: rc!(a), constant: true, type_anno: Some(Singleton(TypeSingletonName { name: rc!(Nat), params: vec![] })),
expr: Meta::new(ex!(binexp!("+", NatLiteral(2), NatLiteral(2)))) } expr: Meta::new(ex!(binexp!("+", NatLiteral(2), NatLiteral(2)))) }
))); )));
@ -365,7 +372,7 @@ fn parsing_block_expressions() {
c c
}"#, }"#,
AST(vec![exst!(IfExpression(bx!(ex!(BoolLiteral(true))), AST(vec![exst!(IfExpression(bx!(ex!(BoolLiteral(true))),
vec![Declaration(Binding { name: rc!(a), constant: true, expr: ex!(NatLiteral(10)) }), vec![decl!(Binding { name: rc!(a), constant: true, expr: ex!(NatLiteral(10)) }),
exst!(val!(rc!(b)))], exst!(val!(rc!(b)))],
Some(vec![exst!(val!(rc!(c)))])))]) Some(vec![exst!(val!(rc!(c)))])))])
); );
@ -386,7 +393,7 @@ fn parsing_block_expressions() {
#[test] #[test]
fn parsing_interfaces() { fn parsing_interfaces() {
parse_test_wrap_ast!("interface Unglueable { fn unglue(a: Glue); fn mar(): Glue }", parse_test_wrap_ast!("interface Unglueable { fn unglue(a: Glue); fn mar(): Glue }",
Meta::new(Declaration(Interface { Meta::new(decl!(Interface {
name: rc!(Unglueable), name: rc!(Unglueable),
signatures: vec![ signatures: vec![
Signature { Signature {
@ -407,7 +414,7 @@ fn parsing_interfaces() {
fn parsing_impls() { fn parsing_impls() {
parse_test_wrap_ast!("impl Heh { fn yolo(); fn swagg(); }", parse_test_wrap_ast!("impl Heh { fn yolo(); fn swagg(); }",
Meta::new( Meta::new(
Declaration(Impl { decl!(Impl {
type_name: ty!("Heh"), type_name: ty!("Heh"),
interface_name: None, interface_name: None,
block: vec![ block: vec![
@ -416,7 +423,7 @@ fn parsing_impls() {
] }))); ] })));
parse_test_wrap_ast!("impl Mondai for Lollerino { fn yolo(); fn swagg(); }", parse_test_wrap_ast!("impl Mondai for Lollerino { fn yolo(); fn swagg(); }",
Meta::new(Declaration(Impl { Meta::new(decl!(Impl {
type_name: ty!("Lollerino"), type_name: ty!("Lollerino"),
interface_name: Some(TypeSingletonName { name: rc!(Mondai), params: vec![] }), interface_name: Some(TypeSingletonName { name: rc!(Mondai), params: vec![] }),
block: vec![ block: vec![
@ -425,7 +432,7 @@ fn parsing_impls() {
] }))); ] })));
parse_test_wrap_ast!("impl Hella<T> for (Alpha, Omega) { }", parse_test_wrap_ast!("impl Hella<T> for (Alpha, Omega) { }",
Meta::new(Declaration(Impl { Meta::new(decl!(Impl {
type_name: Tuple(vec![ty!("Alpha"), ty!("Omega")]), type_name: Tuple(vec![ty!("Alpha"), ty!("Omega")]),
interface_name: Some(TypeSingletonName { name: rc!(Hella), params: vec![ty!("T")] }), interface_name: Some(TypeSingletonName { name: rc!(Hella), params: vec![ty!("T")] }),
block: vec![] block: vec![]
@ -434,7 +441,7 @@ fn parsing_impls() {
parse_test_wrap_ast!("impl Option<WTFMate> { fn oi() }", parse_test_wrap_ast!("impl Option<WTFMate> { fn oi() }",
Meta::new( Meta::new(
Declaration(Impl { decl!(Impl {
type_name: Singleton(TypeSingletonName { name: rc!(Option), params: vec![ty!("WTFMate")]}), type_name: Singleton(TypeSingletonName { name: rc!(Option), params: vec![ty!("WTFMate")]}),
interface_name: None, interface_name: None,
block: vec![ block: vec![
@ -447,7 +454,7 @@ fn parsing_impls() {
fn parsing_type_annotations() { fn parsing_type_annotations() {
parse_test_wrap_ast!("let a = b : Int", parse_test_wrap_ast!("let a = b : Int",
Meta::new( Meta::new(
Declaration(Binding { name: rc!(a), constant: true, type_anno: None, expr: decl!(Binding { name: rc!(a), constant: true, type_anno: None, expr:
ex!(m val!("b"), ty!("Int")) }))); ex!(m val!("b"), ty!("Int")) })));
parse_test_wrap_ast!("a : Int", parse_test_wrap_ast!("a : Int",

View File

@ -126,10 +126,9 @@ impl<'a> Reducer<'a> {
} }
fn statement(&mut self, stmt: &Meta<Statement>) -> Stmt { fn statement(&mut self, stmt: &Meta<Statement>) -> Stmt {
use crate::ast::Statement::*; match &stmt.node().kind {
match stmt.node() { StatementKind::Expression(expr) => Stmt::Expr(self.expression(&expr)),
ExpressionStatement(expr) => Stmt::Expr(self.expression(expr)), StatementKind::Declaration(decl) => self.declaration(&decl),
Declaration(decl) => self.declaration(decl),
} }
} }

View File

@ -11,9 +11,9 @@ impl<'a> ScopeResolver<'a> {
} }
pub fn resolve(&mut self, ast: &mut AST) -> Result<(), String> { pub fn resolve(&mut self, ast: &mut AST) -> Result<(), String> {
for statement in ast.statements.iter_mut() { for statement in ast.statements.iter_mut() {
match statement.mut_node() { match statement.mut_node().kind {
Statement::Declaration(ref mut decl) => self.decl(decl), StatementKind::Declaration(ref mut decl) => self.decl(decl),
Statement::ExpressionStatement(ref mut expr) => self.expr(expr), StatementKind::Expression(ref mut expr) => self.expr(expr),
}?; }?;
} }
Ok(()) Ok(())
@ -29,9 +29,9 @@ impl<'a> ScopeResolver<'a> {
} }
fn block(&mut self, block: &mut Block) -> Result<(), String> { fn block(&mut self, block: &mut Block) -> Result<(), String> {
for statement in block.iter_mut() { for statement in block.iter_mut() {
match statement.mut_node() { match statement.mut_node().kind {
Statement::Declaration(ref mut decl) => self.decl(decl), StatementKind::Declaration(ref mut decl) => self.decl(decl),
Statement::ExpressionStatement(ref mut expr) => self.expr(expr), StatementKind::Expression(ref mut expr) => self.expr(expr),
}?; }?;
} }
Ok(()) Ok(())

View File

@ -5,7 +5,7 @@ use std::fmt;
use std::fmt::Write; use std::fmt::Write;
use crate::ast; use crate::ast;
use crate::ast::{Meta, TypeBody, TypeSingletonName, Signature, Statement}; use crate::ast::{Meta, TypeBody, TypeSingletonName, Signature, Statement, StatementKind};
use crate::typechecking::TypeName; use crate::typechecking::TypeName;
type LineNumber = u32; type LineNumber = u32;
@ -175,7 +175,7 @@ impl SymbolTable {
for meta in statements.iter() { for meta in statements.iter() {
let statement = meta.node(); let statement = meta.node();
if let Statement::Declaration(decl) = statement { if let Statement { kind: StatementKind::Declaration(decl), .. } = statement {
match decl { match decl {
FuncSig(ref signature) => { FuncSig(ref signature) => {
insert_and_check_duplicate_symbol(&mut seen_identifiers, &signature.name)?; insert_and_check_duplicate_symbol(&mut seen_identifiers, &signature.name)?;

View File

@ -271,9 +271,9 @@ impl<'a> TypeContext<'a> {
} }
fn statement(&mut self, statement: &Statement) -> InferResult<Type> { fn statement(&mut self, statement: &Statement) -> InferResult<Type> {
match statement { match &statement.kind {
Statement::ExpressionStatement(e) => self.expr(e.node()), StatementKind::Expression(e) => self.expr(e.node()),
Statement::Declaration(decl) => self.decl(decl), StatementKind::Declaration(decl) => self.decl(&decl),
} }
} }