|
|
|
@ -4,8 +4,7 @@ use std::str::FromStr;
|
|
|
|
|
|
|
|
|
|
use super::tokenize;
|
|
|
|
|
use super::ParseResult;
|
|
|
|
|
use crate::ast::{AST, Meta, Expression, Statement, IfExpressionBody, Discriminator, Pattern, PatternLiteral, TypeBody, Enumerator, ForBody, InvocationArgument, FormalParam, PrefixOp, BinOp, QualifiedName};
|
|
|
|
|
use super::Statement::*;
|
|
|
|
|
use crate::ast::{AST, Meta, Expression, Statement, StatementKind, IfExpressionBody, Discriminator, Pattern, PatternLiteral, TypeBody, Enumerator, ForBody, InvocationArgument, FormalParam, PrefixOp, BinOp, QualifiedName};
|
|
|
|
|
use super::Declaration::*;
|
|
|
|
|
use super::Signature;
|
|
|
|
|
use super::TypeIdentifier::*;
|
|
|
|
@ -39,6 +38,12 @@ macro_rules! tys {
|
|
|
|
|
($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 {
|
|
|
|
|
($expr_type:expr) => { 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())) }
|
|
|
|
|
}
|
|
|
|
|
macro_rules! exst {
|
|
|
|
|
($expr_type:expr) => { Meta::new(Statement::ExpressionStatement(Expression::new($expr_type).into())) };
|
|
|
|
|
($expr_type:expr, $type_anno:expr) => { Meta::new(Statement::ExpressionStatement(Expression::with_anno($expr_type, $type_anno).into())) };
|
|
|
|
|
($op:expr, $lhs:expr, $rhs:expr) => { Meta::new(Statement::ExpressionStatement(ex!(binexp!($op, $lhs, $rhs)))) };
|
|
|
|
|
($expr_type:expr) => { Meta::new(Statement { kind: StatementKind::Expression(Expression::new($expr_type).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 { kind: StatementKind::Expression(ex!(binexp!($op, $lhs, $rhs)))}
|
|
|
|
|
)};
|
|
|
|
|
(s $statement_text:expr) => {
|
|
|
|
|
{
|
|
|
|
|
let tokens: Vec<crate::tokenizing::Token> = tokenize($statement_text);
|
|
|
|
@ -168,7 +175,7 @@ fn parsing_identifiers() {
|
|
|
|
|
fn qualified_identifiers() {
|
|
|
|
|
parse_test_wrap_ast! {
|
|
|
|
|
"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)]))))),
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
@ -203,7 +210,7 @@ fn parsing_complicated_operators() {
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
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(a, 2 + 2)", exst!(Call
|
|
|
|
|
{ f: bx!(ex!(m val!("oi"))),
|
|
|
|
@ -211,17 +218,17 @@ fn parsing_functions() {
|
|
|
|
|
}));
|
|
|
|
|
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![
|
|
|
|
|
FormalParam { name: rc!(b), anno: None, default: None },
|
|
|
|
|
FormalParam { name: rc!(c), anno: Some(ty!("Int")), default: None }
|
|
|
|
|
], 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 },
|
|
|
|
|
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 },
|
|
|
|
|
vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })]))));
|
|
|
|
|
|
|
|
|
@ -230,7 +237,7 @@ fn a(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 },
|
|
|
|
|
vec![exst!(Call { f: bx!(ex!(m val!("x"))), arguments: vec![] })]))));
|
|
|
|
|
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 },
|
|
|
|
|
vec![exst!(s "x()")]))));
|
|
|
|
|
}
|
|
|
|
@ -249,7 +256,7 @@ x()
|
|
|
|
|
fn functions_with_default_args() {
|
|
|
|
|
parse_test_wrap_ast! {
|
|
|
|
|
"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![
|
|
|
|
|
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")) }
|
|
|
|
@ -271,11 +278,11 @@ fn parsing_strings() {
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
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 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 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(decl!(TypeDecl { name: tys!("Yolo"), body: TypeBody(vec![UnitStruct(rc!(Yolo))]), mutable: true} )));
|
|
|
|
|
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 }",
|
|
|
|
|
Meta::new(Declaration(TypeDecl {
|
|
|
|
|
Meta::new(decl!(TypeDecl {
|
|
|
|
|
name: tys!("Sanchez"),
|
|
|
|
|
body: TypeBody(vec![
|
|
|
|
|
UnitStruct(rc!(Miguel)),
|
|
|
|
@ -296,7 +303,7 @@ fn parsing_types() {
|
|
|
|
|
|
|
|
|
|
parse_test_wrap_ast! {
|
|
|
|
|
"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![] })] },
|
|
|
|
|
body: TypeBody(vec![UnitStruct(rc!(Diego)), TupleStruct(rc!(Kike), vec![Singleton(TypeSingletonName { name: rc!(a), params: vec![] })])]),
|
|
|
|
|
mutable: false
|
|
|
|
@ -307,9 +314,9 @@ fn parsing_types() {
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
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 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(
|
|
|
|
|
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(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(decl!(
|
|
|
|
|
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)))) }
|
|
|
|
|
)));
|
|
|
|
@ -365,7 +372,7 @@ fn parsing_block_expressions() {
|
|
|
|
|
c
|
|
|
|
|
}"#,
|
|
|
|
|
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)))],
|
|
|
|
|
Some(vec![exst!(val!(rc!(c)))])))])
|
|
|
|
|
);
|
|
|
|
@ -386,7 +393,7 @@ fn parsing_block_expressions() {
|
|
|
|
|
#[test]
|
|
|
|
|
fn parsing_interfaces() {
|
|
|
|
|
parse_test_wrap_ast!("interface Unglueable { fn unglue(a: Glue); fn mar(): Glue }",
|
|
|
|
|
Meta::new(Declaration(Interface {
|
|
|
|
|
Meta::new(decl!(Interface {
|
|
|
|
|
name: rc!(Unglueable),
|
|
|
|
|
signatures: vec![
|
|
|
|
|
Signature {
|
|
|
|
@ -407,7 +414,7 @@ fn parsing_interfaces() {
|
|
|
|
|
fn parsing_impls() {
|
|
|
|
|
parse_test_wrap_ast!("impl Heh { fn yolo(); fn swagg(); }",
|
|
|
|
|
Meta::new(
|
|
|
|
|
Declaration(Impl {
|
|
|
|
|
decl!(Impl {
|
|
|
|
|
type_name: ty!("Heh"),
|
|
|
|
|
interface_name: None,
|
|
|
|
|
block: vec![
|
|
|
|
@ -416,7 +423,7 @@ fn parsing_impls() {
|
|
|
|
|
] })));
|
|
|
|
|
|
|
|
|
|
parse_test_wrap_ast!("impl Mondai for Lollerino { fn yolo(); fn swagg(); }",
|
|
|
|
|
Meta::new(Declaration(Impl {
|
|
|
|
|
Meta::new(decl!(Impl {
|
|
|
|
|
type_name: ty!("Lollerino"),
|
|
|
|
|
interface_name: Some(TypeSingletonName { name: rc!(Mondai), params: vec![] }),
|
|
|
|
|
block: vec![
|
|
|
|
@ -425,7 +432,7 @@ fn parsing_impls() {
|
|
|
|
|
] })));
|
|
|
|
|
|
|
|
|
|
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")]),
|
|
|
|
|
interface_name: Some(TypeSingletonName { name: rc!(Hella), params: vec![ty!("T")] }),
|
|
|
|
|
block: vec![]
|
|
|
|
@ -434,7 +441,7 @@ fn parsing_impls() {
|
|
|
|
|
|
|
|
|
|
parse_test_wrap_ast!("impl Option<WTFMate> { fn oi() }",
|
|
|
|
|
Meta::new(
|
|
|
|
|
Declaration(Impl {
|
|
|
|
|
decl!(Impl {
|
|
|
|
|
type_name: Singleton(TypeSingletonName { name: rc!(Option), params: vec![ty!("WTFMate")]}),
|
|
|
|
|
interface_name: None,
|
|
|
|
|
block: vec![
|
|
|
|
@ -447,7 +454,7 @@ fn parsing_impls() {
|
|
|
|
|
fn parsing_type_annotations() {
|
|
|
|
|
parse_test_wrap_ast!("let a = b : Int",
|
|
|
|
|
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")) })));
|
|
|
|
|
|
|
|
|
|
parse_test_wrap_ast!("a : Int",
|
|
|
|
|