Make AST a struct

This commit is contained in:
greg 2019-09-11 19:06:00 -07:00
parent d6f2fe6e02
commit 08da787aae
7 changed files with 159 additions and 156 deletions

View File

@ -45,7 +45,9 @@ impl From<Expression> for Meta<Expression> {
}
#[derive(Debug, PartialEq)]
pub struct AST(pub Vec<Meta<Statement>>);
pub struct AST {
pub statements: Vec<Meta<Statement>>
}
#[derive(Debug, PartialEq, Clone)]
pub enum Statement {

View File

@ -334,7 +334,7 @@ impl Parser {
),
}
}
Ok(AST(statements))
Ok(AST { statements })
}
/// `statement := expression | declaration`

View File

@ -24,7 +24,7 @@ macro_rules! parse_test {
($string:expr, $correct:expr) => { assert_eq!(parse($string).unwrap(), $correct) };
}
macro_rules! parse_test_wrap_ast {
($string:expr, $correct:expr) => { parse_test!($string, AST(vec![$correct])) }
($string:expr, $correct:expr) => { parse_test!($string, AST { statements: vec![$correct] }) }
}
macro_rules! parse_error {
($string:expr) => { assert!(parse($string).is_err()) }
@ -88,54 +88,54 @@ fn parsing_number_literals_and_binexps() {
parse_test_wrap_ast! {"0xf_f_+1", exst!(binexp!("+", NatLiteral(255), NatLiteral(1))) };
parse_test! {"3; 4; 4.3", AST(
vec![exst!(NatLiteral(3)), exst!(NatLiteral(4)),
exst!(FloatLiteral(4.3))])
parse_test! {"3; 4; 4.3",
AST {
statements: vec![exst!(NatLiteral(3)), exst!(NatLiteral(4)),
exst!(FloatLiteral(4.3))]
}
};
parse_test!("1 + 2 * 3", AST(vec!
[
exst!(binexp!("+", NatLiteral(1), binexp!("*", NatLiteral(2), NatLiteral(3))))
]));
parse_test_wrap_ast!("1 + 2 * 3",
exst!(binexp!("+", NatLiteral(1), binexp!("*", NatLiteral(2), NatLiteral(3))))
);
parse_test!("1 * 2 + 3", AST(vec!
[
exst!(binexp!("+", binexp!("*", NatLiteral(1), NatLiteral(2)), NatLiteral(3)))
]));
parse_test_wrap_ast!("1 * 2 + 3",
exst!(binexp!("+", binexp!("*", NatLiteral(1), NatLiteral(2)), NatLiteral(3)))
) ;
parse_test!("1 && 2", AST(vec![exst!(binexp!("&&", NatLiteral(1), NatLiteral(2)))]));
parse_test_wrap_ast!("1 && 2", exst!(binexp!("&&", NatLiteral(1), NatLiteral(2))));
parse_test!("1 + 2 * 3 + 4", AST(vec![exst!(
parse_test_wrap_ast!("1 + 2 * 3 + 4", exst!(
binexp!("+",
binexp!("+", NatLiteral(1), binexp!("*", NatLiteral(2), NatLiteral(3))),
NatLiteral(4)))]));
NatLiteral(4))));
parse_test!("(1 + 2) * 3", AST(vec!
[exst!(binexp!("*", binexp!("+", NatLiteral(1), NatLiteral(2)), NatLiteral(3)))]));
parse_test_wrap_ast!("(1 + 2) * 3",
exst!(binexp!("*", binexp!("+", NatLiteral(1), NatLiteral(2)), NatLiteral(3))));
parse_test!(".1 + .2", AST(vec![exst!(binexp!("+", FloatLiteral(0.1), FloatLiteral(0.2)))]));
parse_test!("1 / 2", AST(vec![exst!(binexp!("/", NatLiteral(1), NatLiteral(2)))]));
parse_test_wrap_ast!(".1 + .2", exst!(binexp!("+", FloatLiteral(0.1), FloatLiteral(0.2))));
parse_test_wrap_ast!("1 / 2", exst!(binexp!("/", NatLiteral(1), NatLiteral(2))));
}
#[test]
fn parsing_tuples() {
parse_test!("()", AST(vec![exst!(TupleLiteral(vec![]))]));
parse_test!("(\"hella\", 34)", AST(vec![exst!(
parse_test_wrap_ast!("()", exst!(TupleLiteral(vec![])));
parse_test_wrap_ast!("(\"hella\", 34)", exst!(
TupleLiteral(
vec![ex!(s r#""hella""#).into(), ex!(s "34").into()]
)
)]));
parse_test!("((1+2), \"slough\")", AST(vec![exst!(TupleLiteral(vec![
));
parse_test_wrap_ast!("((1+2), \"slough\")", exst!(TupleLiteral(vec![
ex!(binexp!("+", NatLiteral(1), NatLiteral(2))).into(),
ex!(StringLiteral(rc!(slough))).into(),
]))]))
])))
}
#[test]
fn parsing_identifiers() {
parse_test!("a", AST(vec![exst!(val!("a"))]));
parse_test!("some_value", AST(vec![exst!(val!("some_value"))]));
parse_test!("a + b", AST(vec![exst!(binexp!("+", val!("a"), val!("b")))]));
parse_test_wrap_ast!("a", exst!(val!("a")));
parse_test_wrap_ast!("some_value", exst!(val!("some_value")));
parse_test_wrap_ast!("a + b", exst!(binexp!("+", val!("a"), val!("b"))));
//parse_test!("a[b]", AST(vec![Expression(
//parse_test!("a[]", <- TODO THIS NEEDS TO FAIL
//parse_test("a()[b]()[d]")
@ -146,22 +146,20 @@ fn parsing_identifiers() {
indexee: bx!(ex!(Call { f: bx!(ex!(val!("perspicacity"))), arguments: vec![] })),
indexers: vec![ex!(val!("a"))]
})
])
])
}
*/
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_wrap_ast!("a[b,c]", 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![
parse_test_wrap_ast!("None", exst!(val!("None")));
parse_test_wrap_ast!("Pandas { a: x + y }",
exst!(NamedStruct { name: Meta::new(QualifiedName(vec![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: Meta::new(QualifiedName(vec![rc!(Pandas)])), fields:
vec![(rc!(a), ex!(m val!("n"))), (rc!(b), ex!(m val!("q")))]
}
)
])
);
parse_test_wrap_ast! { "Pandas { a: n, b: q, }",
exst!(NamedStruct { name: Meta::new(QualifiedName(vec![rc!(Pandas)])), fields:
vec![(rc!(a), ex!(m val!("n"))), (rc!(b), ex!(m val!("q")))]
}
)
};
}
@ -188,53 +186,53 @@ fn reserved_words() {
#[test]
fn parsing_complicated_operators() {
parse_test!("a <- b", AST(vec![exst!(binexp!("<-", val!("a"), val!("b")))]));
parse_test!("a || b", AST(vec![exst!(binexp!("||", val!("a"), val!("b")))]));
parse_test!("a<>b", AST(vec![exst!(binexp!("<>", val!("a"), val!("b")))]));
parse_test!("a.b.c.d", AST(vec![exst!(binexp!(".",
parse_test_wrap_ast!("a <- b", exst!(binexp!("<-", val!("a"), val!("b"))));
parse_test_wrap_ast!("a || b", exst!(binexp!("||", val!("a"), val!("b"))));
parse_test_wrap_ast!("a<>b", exst!(binexp!("<>", val!("a"), val!("b"))));
parse_test_wrap_ast!("a.b.c.d", exst!(binexp!(".",
binexp!(".",
binexp!(".", val!("a"), val!("b")),
val!("c")),
val!("d")))]));
parse_test!("-3", AST(vec![exst!(prefexp!("-", NatLiteral(3)))]));
parse_test!("-0.2", AST(vec![exst!(prefexp!("-", FloatLiteral(0.2)))]));
parse_test!("!3", AST(vec![exst!(prefexp!("!", NatLiteral(3)))]));
parse_test!("a <- -b", AST(vec![exst!(binexp!("<-", val!("a"), prefexp!("-", val!("b"))))]));
parse_test!("a <--b", AST(vec![exst!(binexp!("<--", val!("a"), val!("b")))]));
val!("d"))));
parse_test_wrap_ast!("-3", exst!(prefexp!("-", NatLiteral(3))));
parse_test_wrap_ast!("-0.2", exst!(prefexp!("-", FloatLiteral(0.2))));
parse_test_wrap_ast!("!3", exst!(prefexp!("!", NatLiteral(3))));
parse_test_wrap_ast!("a <- -b", exst!(binexp!("<-", val!("a"), prefexp!("-", val!("b")))));
parse_test_wrap_ast!("a <--b", exst!(binexp!("<--", val!("a"), val!("b"))));
}
#[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!(m val!("oi"))), arguments: vec![] })]));
parse_test!("oi(a, 2 + 2)", AST(vec![exst!(Call
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!("oi()", exst!(Call { f: bx!(ex!(m val!("oi"))), arguments: vec![] }));
parse_test_wrap_ast!("oi(a, 2 + 2)", exst!(Call
{ f: bx!(ex!(m val!("oi"))),
arguments: vec![inv!(ex!(m val!("a"))), inv!(ex!(m binexp!("+", NatLiteral(2), NatLiteral(2)))).into()]
})]));
}));
parse_error!("a(b,,c)");
parse_test!("fn a(b, c: Int): Int", AST(vec![Meta::new(Declaration(
parse_test_wrap_ast!("fn a(b, c: Int): Int", Meta::new(Declaration(
FuncSig(Signature { name: rc!(a), operator: false, params: vec![
FormalParam { name: rc!(b), anno: None, default: None },
FormalParam { name: rc!(c), anno: Some(ty!("Int")), default: None }
], type_anno: Some(ty!("Int")) })))]));
], type_anno: Some(ty!("Int")) }))));
parse_test!("fn a(x) { x() }", AST(vec![Meta::new(Declaration(
parse_test_wrap_ast!("fn a(x) { x() }", Meta::new(Declaration(
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![] })])))]));
parse_test!("fn a(x) {\n x() }", AST(vec![Meta::new(Declaration(
vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })]))));
parse_test_wrap_ast!("fn a(x) {\n x() }", Meta::new(Declaration(
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![] })]))));
let multiline = r#"
fn a(x) {
x()
}
"#;
parse_test!(multiline, AST(vec![Meta::new(Declaration(
parse_test_wrap_ast!(multiline, Meta::new(Declaration(
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#"
fn a(x) {
@ -242,44 +240,42 @@ x()
}
"#;
parse_test!(multiline2, AST(vec![Meta::new(Declaration(
parse_test_wrap_ast!(multiline2, Meta::new(Declaration(
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()")]))));
}
#[test]
fn functions_with_default_args() {
parse_test! {
parse_test_wrap_ast! {
"fn func(x: Int, y: Int = 4) { }",
AST(vec![
Meta::new(Declaration(
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!(y), default: Some(Meta::new(ex!(s "4"))), anno: Some(ty!("Int")) }
]}, vec![])
))
])
Meta::new(Declaration(
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!(y), default: Some(Meta::new(ex!(s "4"))), anno: Some(ty!("Int")) }
]}, vec![])
))
};
}
#[test]
fn parsing_bools() {
parse_test!("false", AST(vec![exst!(BoolLiteral(false))]));
parse_test!("true", AST(vec![exst!(BoolLiteral(true))]));
parse_test_wrap_ast!("false", exst!(BoolLiteral(false)));
parse_test_wrap_ast!("true", exst!(BoolLiteral(true)));
}
#[test]
fn parsing_strings() {
parse_test!(r#""hello""#, AST(vec![exst!(StringLiteral(rc!(hello)))]));
parse_test_wrap_ast!(r#""hello""#, exst!(StringLiteral(rc!(hello))));
}
#[test]
fn parsing_types() {
parse_test!("type Yolo = Yolo", AST(vec![Meta::new(Declaration(TypeDecl { name: tys!("Yolo"), body: TypeBody(vec![UnitStruct(rc!(Yolo))]), mutable: false} ))]));
parse_test!("type mut Yolo = Yolo", AST(vec![Meta::new(Declaration(TypeDecl { name: tys!("Yolo"), body: TypeBody(vec![UnitStruct(rc!(Yolo))]), mutable: true} ))]));
parse_test!("type alias Sex = Drugs", AST(vec![Meta::new(Declaration(TypeAlias(rc!(Sex), rc!(Drugs))))]));
parse_test!("type Sanchez = Miguel | Alejandro(Int, Option<a>) | Esperanza { a: Int, b: String }",
AST(vec![Meta::new(Declaration(TypeDecl{
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 mut Yolo = Yolo", Meta::new(Declaration(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 Sanchez = Miguel | Alejandro(Int, Option<a>) | Esperanza { a: Int, b: String }",
Meta::new(Declaration(TypeDecl {
name: tys!("Sanchez"),
body: TypeBody(vec![
UnitStruct(rc!(Miguel)),
@ -296,31 +292,33 @@ fn parsing_types() {
}
]),
mutable: false
}))]));
})));
parse_test!("type Jorge<a> = Diego | Kike(a)", AST(vec![
parse_test_wrap_ast! {
"type Jorge<a> = Diego | Kike(a)",
Meta::new(Declaration(TypeDecl{
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![] })])]),
mutable: false
}
))]));
))
};
}
#[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!(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(
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 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: Nat = 2 + 2", Meta::new(Declaration(
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)))) }
))]));
)));
}
#[test]
fn parsing_block_expressions() {
parse_test! {
"if a() then { b(); c() }", AST(vec![exst!(
parse_test_wrap_ast! {
"if a() then { b(); c() }", exst!(
IfExpression {
discriminator: bx! {
Discriminator::Simple(ex!(m Call { f: bx!(ex!(m val!("a"))), arguments: vec![]}))
@ -332,11 +330,11 @@ fn parsing_block_expressions() {
)
}
}
)])
)
};
parse_test! {
"if a() then { b(); c() } else { q }", AST(vec![exst!(
parse_test_wrap_ast! {
"if a() then { b(); c() } else { q }", exst!(
IfExpression {
discriminator: bx! {
Discriminator::Simple(ex!(m Call { f: bx!(ex!(m val!("a"))), arguments: vec![]}))
@ -350,7 +348,7 @@ fn parsing_block_expressions() {
)
}
}
)])
)
};
/*
@ -387,7 +385,7 @@ fn parsing_block_expressions() {
}
#[test]
fn parsing_interfaces() {
parse_test!("interface Unglueable { fn unglue(a: Glue); fn mar(): Glue }", AST(vec![
parse_test_wrap_ast!("interface Unglueable { fn unglue(a: Glue); fn mar(): Glue }",
Meta::new(Declaration(Interface {
name: rc!(Unglueable),
signatures: vec![
@ -402,12 +400,12 @@ fn parsing_interfaces() {
Signature { name: rc!(mar), operator: false, params: vec![], type_anno: Some(Singleton(TypeSingletonName { name: rc!(Glue), params: vec![] })) },
]
}))
]));
);
}
#[test]
fn parsing_impls() {
parse_test!("impl Heh { fn yolo(); fn swagg(); }", AST(vec![
parse_test_wrap_ast!("impl Heh { fn yolo(); fn swagg(); }",
Meta::new(
Declaration(Impl {
type_name: ty!("Heh"),
@ -415,26 +413,26 @@ fn parsing_impls() {
block: vec![
FuncSig(Signature { name: rc!(yolo), operator: false, params: vec![], type_anno: None }),
FuncSig(Signature { name: rc!(swagg), operator: false, params: vec![], type_anno: None })
] }))]));
] })));
parse_test!("impl Mondai for Lollerino { fn yolo(); fn swagg(); }", AST(vec![
parse_test_wrap_ast!("impl Mondai for Lollerino { fn yolo(); fn swagg(); }",
Meta::new(Declaration(Impl {
type_name: ty!("Lollerino"),
interface_name: Some(TypeSingletonName { name: rc!(Mondai), params: vec![] }),
block: vec![
FuncSig(Signature { name: rc!(yolo), operator: false, params: vec![], type_anno: None}),
FuncSig(Signature { name: rc!(swagg), operator: false, params: vec![], type_anno: None })
] }))]));
] })));
parse_test!("impl Hella<T> for (Alpha, Omega) { }", AST(vec![
parse_test_wrap_ast!("impl Hella<T> for (Alpha, Omega) { }",
Meta::new(Declaration(Impl {
type_name: Tuple(vec![ty!("Alpha"), ty!("Omega")]),
interface_name: Some(TypeSingletonName { name: rc!(Hella), params: vec![ty!("T")] }),
block: vec![]
}))
]));
);
parse_test!("impl Option<WTFMate> { fn oi() }", AST(vec![
parse_test_wrap_ast!("impl Option<WTFMate> { fn oi() }",
Meta::new(
Declaration(Impl {
type_name: Singleton(TypeSingletonName { name: rc!(Option), params: vec![ty!("WTFMate")]}),
@ -442,35 +440,35 @@ fn parsing_impls() {
block: vec![
FuncSig(Signature { name: rc!(oi), operator: false, params: vec![], type_anno: None }),
]
}))]));
})));
}
#[test]
fn parsing_type_annotations() {
parse_test!("let a = b : Int", AST(vec![
parse_test_wrap_ast!("let a = b : Int",
Meta::new(
Declaration(Binding { name: rc!(a), constant: true, type_anno: None, expr:
ex!(m val!("b"), ty!("Int")) }))]));
ex!(m val!("b"), ty!("Int")) })));
parse_test!("a : Int", AST(vec![
parse_test_wrap_ast!("a : Int",
exst!(val!("a"), ty!("Int"))
]));
);
parse_test!("a : Option<Int>", AST(vec![
parse_test_wrap_ast!("a : Option<Int>",
exst!(val!("a"), Singleton(TypeSingletonName { name: rc!(Option), params: vec![ty!("Int")] }))
]));
);
parse_test!("a : KoreanBBQSpecifier<Kimchi, Option<Bulgogi> >", AST(vec![
parse_test_wrap_ast!("a : KoreanBBQSpecifier<Kimchi, Option<Bulgogi> >",
exst!(val!("a"), Singleton(TypeSingletonName { name: rc!(KoreanBBQSpecifier), params: vec![
ty!("Kimchi"), Singleton(TypeSingletonName { name: rc!(Option), params: vec![ty!("Bulgogi")] })
] }))
]));
);
parse_test!("a : (Int, Yolo<a>)", AST(vec![
parse_test_wrap_ast!("a : (Int, Yolo<a>)",
exst!(val!("a"), Tuple(
vec![ty!("Int"), Singleton(TypeSingletonName {
name: rc!(Yolo), params: vec![ty!("a")]
})]))]));
})])));
}
#[test]
@ -480,7 +478,7 @@ fn parsing_lambdas() {
)
}
parse_test!(r#"\ (x: Int, y) { a;b;c;}"#, AST(vec![
parse_test_wrap_ast!(r#"\ (x: Int, y) { a;b;c;}"#,
exst!(Lambda {
params: vec![
FormalParam { name: rc!(x), anno: Some(ty!("Int")), default: None },
@ -489,9 +487,9 @@ fn parsing_lambdas() {
type_anno: None,
body: vec![exst!(s "a"), exst!(s "b"), exst!(s "c")]
})
]));
);
parse_test!(r#"\(x){y}(1)"#, AST(vec![
parse_test_wrap_ast! { r#"\(x){y}(1)"#,
exst!(Call { f: bx!(ex!(m
Lambda {
params: vec![
@ -500,7 +498,8 @@ fn parsing_lambdas() {
type_anno: None,
body: vec![exst!(s "y")] }
)),
arguments: vec![inv!(ex!(m NatLiteral(1))).into()] })]));
arguments: vec![inv!(ex!(m NatLiteral(1))).into()] })
};
parse_test_wrap_ast! {
r#"\(x: Int): String { "q" }"#,
@ -539,54 +538,57 @@ fn single_param_lambda() {
fn more_advanced_lambdas() {
parse_test! {
r#"fn wahoo() { let a = 10; \(x) { x + a } };
wahoo()(3) "#, AST(vec![
exst!(s r"fn wahoo() { let a = 10; \(x) { x + a } }"),
exst! {
wahoo()(3) "#,
AST {
statements: vec![
exst!(s r"fn wahoo() { let a = 10; \(x) { x + a } }"),
exst! {
Call {
f: bx!(ex!(m Call { f: bx!(ex!(m val!("wahoo"))), arguments: vec![] })),
arguments: vec![inv!(ex!(m NatLiteral(3))).into()],
}
}
])
]
}
}
}
#[test]
fn list_literals() {
parse_test! {
"[1,2]", AST(vec![
exst!(ListLiteral(vec![ex!(m NatLiteral(1)), ex!(m NatLiteral(2))]))])
parse_test_wrap_ast! {
"[1,2]",
exst!(ListLiteral(vec![ex!(m NatLiteral(1)), ex!(m NatLiteral(2))]))
};
}
#[test]
fn while_expr() {
parse_test! {
"while { }", AST(vec![
exst!(WhileExpression { condition: None, body: vec![] })])
parse_test_wrap_ast! {
"while { }",
exst!(WhileExpression { condition: None, body: vec![] })
}
parse_test! {
"while a == b { }", AST(vec![
exst!(WhileExpression { condition: Some(bx![ex![m binexp!("==", val!("a"), val!("b"))]]), body: vec![] })])
parse_test_wrap_ast! {
"while a == b { }",
exst!(WhileExpression { condition: Some(bx![ex![m binexp!("==", val!("a"), val!("b"))]]), body: vec![] })
}
}
#[test]
fn for_expr() {
parse_test! {
"for { a <- maybeValue } return 1", AST(vec![
parse_test_wrap_ast! {
"for { a <- maybeValue } return 1",
exst!(ForExpression {
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![
parse_test_wrap_ast! {
"for n <- someRange { f(n); }",
exst!(ForExpression { enumerators: vec![Enumerator { id: rc!(n), generator: ex!(m val!("someRange"))}],
body: bx!(ForBody::StatementBlock(vec![exst!(s "f(n)")]))
})])
})
}
}
@ -655,19 +657,18 @@ fn pattern_literals() {
)
}
parse_test! {
"if x is true then 1 else 2", AST(vec![
exst!(
IfExpression {
discriminator: bx!(Discriminator::Simple(Meta::new(ex!(s "x")))),
body: bx!(IfExpressionBody::SimplePatternMatch(
Pattern::Literal(PatternLiteral::BoolPattern(true)),
vec![exst!(NatLiteral(1))],
Some(vec![exst!(NatLiteral(2))]),
))
}
)
])
parse_test_wrap_ast! {
"if x is true then 1 else 2",
exst!(
IfExpression {
discriminator: bx!(Discriminator::Simple(Meta::new(ex!(s "x")))),
body: bx!(IfExpressionBody::SimplePatternMatch(
Pattern::Literal(PatternLiteral::BoolPattern(true)),
vec![exst!(NatLiteral(1))],
Some(vec![exst!(NatLiteral(2))]),
))
}
)
}
parse_test_wrap_ast! {

View File

@ -117,9 +117,9 @@ struct Reducer<'a> {
}
impl<'a> Reducer<'a> {
fn ast(&mut self, input: &AST) -> ReducedAST {
fn ast(&mut self, ast: &AST) -> ReducedAST {
let mut output = vec![];
for statement in input.0.iter() {
for statement in ast.statements.iter() {
output.push(self.statement(statement));
}
ReducedAST(output)

View File

@ -10,7 +10,7 @@ impl<'a> ScopeResolver<'a> {
ScopeResolver { symbol_table }
}
pub fn resolve(&mut self, ast: &mut AST) -> Result<(), String> {
for statement in ast.0.iter_mut() {
for statement in ast.statements.iter_mut() {
match statement.mut_node() {
Statement::Declaration(ref mut decl) => self.decl(decl),
Statement::ExpressionStatement(ref mut expr) => self.expr(expr),

View File

@ -151,7 +151,7 @@ impl SymbolTable {
pub fn add_top_level_symbols(&mut self, ast: &ast::AST) -> Result<(), String> {
let mut scope_name_stack = Vec::new();
self.add_symbols_from_scope(&ast.0, &mut scope_name_stack)
self.add_symbols_from_scope(&ast.statements, &mut scope_name_stack)
}
fn add_symbols_from_scope<'a>(&'a mut self, statements: &Vec<Meta<Statement>>, scope_name_stack: &mut Vec<ScopeSegment>) -> Result<(), String> {

View File

@ -264,7 +264,7 @@ impl<'a> TypeContext<'a> {
/// the AST to ReducedAST
pub fn typecheck(&mut self, ast: &AST) -> Result<Type, TypeError> {
let mut returned_type = Type::Const(TypeConst::Unit);
for statement in ast.0.iter() {
for statement in ast.statements.iter() {
returned_type = self.statement(statement.node())?;
}
Ok(returned_type)