Move rest of parse tests over to new format
This commit is contained in:
parent
8db9176fce
commit
81bfe22974
@ -117,7 +117,7 @@ pub enum Declaration {
|
||||
FuncSig(Signature),
|
||||
FuncDecl(Signature, Block),
|
||||
TypeDecl { name: TypeSingletonName, body: TypeBody, mutable: bool },
|
||||
//TODO this needs to be more sophisticated
|
||||
//TODO TypeAlias `original` needs to be a more complex type definition
|
||||
TypeAlias { alias: Rc<String>, original: Rc<String> },
|
||||
Binding { name: Rc<String>, constant: bool, type_anno: Option<TypeIdentifier>, expr: Expression },
|
||||
Impl { type_name: TypeIdentifier, interface_name: Option<TypeSingletonName>, block: Vec<Declaration> },
|
||||
@ -133,6 +133,7 @@ pub struct Signature {
|
||||
pub type_anno: Option<TypeIdentifier>,
|
||||
}
|
||||
|
||||
//TODO I can probably get rid of TypeBody
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct TypeBody(pub Vec<Variant>);
|
||||
|
||||
@ -158,6 +159,7 @@ pub struct Expression {
|
||||
#[derivative(PartialEq = "ignore")]
|
||||
pub id: ItemId,
|
||||
pub kind: ExpressionKind,
|
||||
//TODO this should only allow singletons, not tuples
|
||||
pub type_anno: Option<TypeIdentifier>,
|
||||
}
|
||||
|
||||
|
@ -689,6 +689,13 @@ impl Parser {
|
||||
|
||||
#[recursive_descent_method]
|
||||
fn prefix_expr(&mut self) -> ParseResult<Expression> {
|
||||
loop {
|
||||
match self.token_handler.peek_kind() {
|
||||
Semicolon | Newline => { self.token_handler.next(); },
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
|
||||
match self.token_handler.peek_kind() {
|
||||
Operator(ref op) if PrefixOp::is_prefix(&*op) => {
|
||||
let sigil = match self.token_handler.next().kind {
|
||||
|
@ -33,6 +33,14 @@ fn stmt(kind: StatementKind) -> Statement {
|
||||
Statement { location: Location::default(), id: ItemId::default(), kind }
|
||||
}
|
||||
|
||||
fn exst(kind: ExpressionKind) -> Statement {
|
||||
Statement {
|
||||
location: Location::default(),
|
||||
id: ItemId::default(),
|
||||
kind: StatementKind::Expression(expr(kind)),
|
||||
}
|
||||
}
|
||||
|
||||
fn decl(declaration: Declaration) -> Statement {
|
||||
Statement {
|
||||
location: Location::default(),
|
||||
@ -85,8 +93,8 @@ macro_rules! qn {
|
||||
};
|
||||
}
|
||||
|
||||
fn int_anno() -> TypeIdentifier {
|
||||
TypeIdentifier::Singleton(TypeSingletonName { name: rc("Int"), params: vec![] })
|
||||
fn ty_simple(name: &str) -> TypeIdentifier {
|
||||
TypeIdentifier::Singleton(TypeSingletonName { name: rc(name), params: vec![] })
|
||||
}
|
||||
|
||||
macro_rules! assert_ast {
|
||||
@ -136,6 +144,14 @@ fn basic_literals() {
|
||||
assert_expr!(r#""hello""#, expr(StringLiteral(rc("hello"))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn list_literals() {
|
||||
use ExpressionKind::*;
|
||||
|
||||
assert_expr!("[]", expr(ListLiteral(vec![])));
|
||||
assert_expr!("[1,2]", expr(ListLiteral(vec![expr(NatLiteral(1)), expr(NatLiteral(2)),])));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn binexps() {
|
||||
use ExpressionKind::*;
|
||||
@ -374,7 +390,7 @@ fn lambda_expressions() {
|
||||
r#"\ (x: Int, y) { a;b;c;}"#,
|
||||
expr(Lambda {
|
||||
params: vec![
|
||||
FormalParam { name: rc!(x), anno: Some(int_anno()), default: None },
|
||||
FormalParam { name: rc!(x), anno: Some(ty_simple("Int")), default: None },
|
||||
FormalParam { name: rc!(y), anno: None, default: None },
|
||||
],
|
||||
type_anno: None,
|
||||
@ -402,7 +418,7 @@ fn lambda_expressions() {
|
||||
assert_expr!(
|
||||
r#"\(x: Int): String { "q" }"#,
|
||||
expr(Lambda {
|
||||
params: vec![FormalParam { name: rc!(x), anno: Some(int_anno()), default: None },],
|
||||
params: vec![FormalParam { name: rc!(x), anno: Some(ty_simple("Int")), default: None },],
|
||||
type_anno: Some(TypeIdentifier::Singleton(TypeSingletonName {
|
||||
name: rc("String"),
|
||||
params: vec![]
|
||||
@ -433,7 +449,7 @@ fn single_param_lambda() {
|
||||
assert_expr!(
|
||||
r#"\x: Int { x + 10 }"#,
|
||||
expr(Lambda {
|
||||
params: vec![FormalParam { name: rc!(x), anno: Some(int_anno()), default: None },],
|
||||
params: vec![FormalParam { name: rc!(x), anno: Some(ty_simple("Int")), default: None },],
|
||||
type_anno: None,
|
||||
body: vec![stmt(StatementKind::Expression(binop(
|
||||
"+",
|
||||
@ -548,18 +564,131 @@ fn type_annotations() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn type_declarations() {
|
||||
use Declaration::TypeDecl;
|
||||
assert_ast! {
|
||||
"type Alpha = Alpha", vec![
|
||||
decl(TypeDecl {
|
||||
name: TypeSingletonName { name: rc("Alpha"), params: vec![] },
|
||||
mutable: false,
|
||||
body: TypeBody(vec![
|
||||
Variant {
|
||||
id: Default::default(),
|
||||
name: rc("Alpha"),
|
||||
kind: VariantKind::UnitStruct
|
||||
}
|
||||
])
|
||||
})
|
||||
]
|
||||
};
|
||||
|
||||
assert_ast!(
|
||||
"type mut Kuah = Kuah",
|
||||
decl(TypeDecl {
|
||||
name: TypeSingletonName { name: rc("Kuah"), params: vec![] },
|
||||
mutable: true,
|
||||
body: TypeBody(vec![Variant {
|
||||
id: Default::default(),
|
||||
name: rc("Kuah"),
|
||||
kind: VariantKind::UnitStruct
|
||||
}])
|
||||
})
|
||||
);
|
||||
|
||||
//TODO support this
|
||||
let specs = ["type Alpha = Alpha { a: Int, b: Int }" /* "type Alpha = { a: Int, b: Int }"*/];
|
||||
for spec in specs {
|
||||
assert_ast! {
|
||||
spec, vec![decl(TypeDecl {
|
||||
name: TypeSingletonName { name: rc("Alpha"), params: vec![] },
|
||||
mutable: false,
|
||||
body: TypeBody(vec![
|
||||
Variant {
|
||||
id: Default::default(),
|
||||
name: rc("Alpha"),
|
||||
kind: VariantKind::Record(vec![
|
||||
(rc("a"), ty_simple("Int")),
|
||||
(rc("b"), ty_simple("Int"))
|
||||
])
|
||||
}
|
||||
])
|
||||
})]
|
||||
};
|
||||
}
|
||||
|
||||
assert_ast!(
|
||||
"type Option<T> = None | Some(T)",
|
||||
vec![decl(TypeDecl {
|
||||
name: TypeSingletonName {
|
||||
name: rc("Option"),
|
||||
params: vec![TypeIdentifier::Singleton(TypeSingletonName { name: rc("T"), params: vec![] })]
|
||||
},
|
||||
mutable: false,
|
||||
body: TypeBody(vec![
|
||||
Variant { id: Default::default(), name: rc("None"), kind: VariantKind::UnitStruct },
|
||||
Variant {
|
||||
id: Default::default(),
|
||||
name: rc("Some"),
|
||||
kind: VariantKind::TupleStruct(vec![TypeIdentifier::Singleton(TypeSingletonName {
|
||||
name: rc("T"),
|
||||
params: vec![]
|
||||
})])
|
||||
},
|
||||
])
|
||||
})]
|
||||
);
|
||||
|
||||
assert_ast!(
|
||||
"type alias Alpha = Beta",
|
||||
decl(Declaration::TypeAlias { alias: rc("Alpha"), original: rc("Beta") })
|
||||
);
|
||||
|
||||
assert_ast!("type Complex<T, U> = Unit | Record { field: AnotherType<Bool>, field2: (Nat, Int), field3: T } | Tuple(Int, (String, T))",
|
||||
decl(TypeDecl {
|
||||
name: TypeSingletonName { name: rc("Complex"), params: vec![
|
||||
TypeIdentifier::Singleton(TypeSingletonName { name: rc("T"), params: vec![] }),
|
||||
TypeIdentifier::Singleton(TypeSingletonName { name: rc("U"), params: vec![] }),
|
||||
] },
|
||||
mutable: false,
|
||||
body: TypeBody(vec![
|
||||
Variant { id: Default::default(), name: rc("Unit"), kind: VariantKind::UnitStruct },
|
||||
Variant { id: Default::default(), name: rc("Record"), kind: VariantKind::Record(
|
||||
vec![
|
||||
(rc("field"), TypeIdentifier::Singleton(TypeSingletonName { name: rc("AnotherType"), params: vec![TypeIdentifier::Singleton(TypeSingletonName { name: rc("Bool"), params: vec![] })] })),
|
||||
(rc("field2"), TypeIdentifier::Tuple(vec![
|
||||
TypeIdentifier::Singleton(TypeSingletonName { name: rc("Nat"), params: vec![] }),
|
||||
TypeIdentifier::Singleton(TypeSingletonName { name: rc("Int"), params: vec![] }),
|
||||
]
|
||||
)),
|
||||
(rc("field3"), TypeIdentifier::Singleton(TypeSingletonName { name: rc("T"), params: vec![] })),
|
||||
]
|
||||
)},
|
||||
Variant { id: Default::default(), name: rc("Tuple"), kind: VariantKind::TupleStruct(
|
||||
vec![
|
||||
TypeIdentifier::Singleton(TypeSingletonName { name: rc("Int"), params: vec![] }),
|
||||
TypeIdentifier::Tuple(vec![
|
||||
TypeIdentifier::Singleton(TypeSingletonName { name: rc("String"), params: vec![] }),
|
||||
TypeIdentifier::Singleton(TypeSingletonName { name: rc("T"), params: vec![] }),
|
||||
])
|
||||
]
|
||||
)},
|
||||
]),
|
||||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn declarations() {
|
||||
use ExpressionKind::*;
|
||||
|
||||
assert_ast!(
|
||||
"let q_q = Yolo::Swaggins",
|
||||
vec![stmt(StatementKind::Declaration(Declaration::Binding {
|
||||
vec![decl(Declaration::Binding {
|
||||
name: rc("q_q"),
|
||||
constant: true,
|
||||
type_anno: None,
|
||||
expr: expr(Value(qn!(Yolo, Swaggins)))
|
||||
}))]
|
||||
})]
|
||||
);
|
||||
}
|
||||
|
||||
@ -699,8 +828,12 @@ fn functions_with_default_args() {
|
||||
operator: false,
|
||||
type_anno: None,
|
||||
params: vec![
|
||||
FormalParam { name: rc("x"), anno: Some(int_anno()), default: None },
|
||||
FormalParam { name: rc("y"), anno: Some(int_anno()), default: Some(expr(NatLiteral(4))) },
|
||||
FormalParam { name: rc("x"), anno: Some(ty_simple("Int")), default: None },
|
||||
FormalParam {
|
||||
name: rc("y"),
|
||||
anno: Some(ty_simple("Int")),
|
||||
default: Some(expr(NatLiteral(4)))
|
||||
},
|
||||
],
|
||||
},
|
||||
vec![].into()
|
||||
@ -728,6 +861,59 @@ fn interface() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn impls() {
|
||||
use Declaration::{FuncSig, Impl};
|
||||
|
||||
assert_ast!(
|
||||
"impl Heh { fn yolo(); fn swagg(); }",
|
||||
vec![decl(Impl {
|
||||
type_name: ty_simple("Heh"),
|
||||
interface_name: None,
|
||||
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 })
|
||||
]
|
||||
})]
|
||||
);
|
||||
|
||||
assert_ast!(
|
||||
"impl Heh<X> { fn yolo(); fn swagg(); }",
|
||||
vec![decl(Impl {
|
||||
type_name: TypeIdentifier::Singleton(TypeSingletonName {
|
||||
name: rc("Heh"),
|
||||
params: vec![ty_simple("X")]
|
||||
}),
|
||||
interface_name: None,
|
||||
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 })
|
||||
]
|
||||
})]
|
||||
);
|
||||
|
||||
assert_ast!(
|
||||
"impl Heh for Saraz { fn yolo(); fn swagg(); }",
|
||||
vec![decl(Impl {
|
||||
type_name: ty_simple("Saraz"),
|
||||
interface_name: Some(TypeSingletonName { name: rc("Heh"), 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 })
|
||||
]
|
||||
})]
|
||||
);
|
||||
|
||||
assert_ast!(
|
||||
"impl Heh<T> for (Int, Codepoint) {}",
|
||||
vec![decl(Impl {
|
||||
type_name: TypeIdentifier::Tuple(vec![ty_simple("Int"), ty_simple("Codepoint")]),
|
||||
interface_name: Some(TypeSingletonName { name: rc("Heh"), params: vec![ty_simple("T")] }),
|
||||
block: vec![]
|
||||
})]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn annotations() {
|
||||
use ExpressionKind::*;
|
||||
@ -825,3 +1011,197 @@ fn imports() {
|
||||
}))]
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn if_exprs() {
|
||||
use ExpressionKind::*;
|
||||
assert_expr!(
|
||||
"if a() then { tuah(); }",
|
||||
expr(IfExpression {
|
||||
discriminator: Some(bx(expr(Call { f: bx(expr(Value(qn!(a)))), arguments: vec![] }))),
|
||||
body: bx(IfExpressionBody::SimpleConditional {
|
||||
then_case: vec![exst(Call { f: bx(expr(Value(qn!(tuah)))), arguments: vec![] })].into(),
|
||||
else_case: None,
|
||||
})
|
||||
})
|
||||
);
|
||||
|
||||
assert_expr!(
|
||||
"if a then b else c",
|
||||
expr(IfExpression {
|
||||
discriminator: Some(bx(expr(Value(qn!(a))))),
|
||||
body: bx(IfExpressionBody::SimpleConditional {
|
||||
then_case: vec![exst(Value(qn!(b)))].into(),
|
||||
else_case: Some(vec![exst(Value(qn!(c)))].into()),
|
||||
})
|
||||
})
|
||||
);
|
||||
|
||||
assert_expr!(
|
||||
r#"
|
||||
if true then {
|
||||
let a = 10
|
||||
b
|
||||
} else {
|
||||
c
|
||||
}"#,
|
||||
expr(IfExpression {
|
||||
discriminator: Some(bx(expr(BoolLiteral(true)))),
|
||||
body: bx(IfExpressionBody::SimpleConditional {
|
||||
then_case: vec![
|
||||
decl(Declaration::Binding {
|
||||
name: rc("a"),
|
||||
constant: true,
|
||||
type_anno: None,
|
||||
expr: expr(NatLiteral(10))
|
||||
}),
|
||||
exst(Value(qn!(b))),
|
||||
]
|
||||
.into(),
|
||||
else_case: Some(vec![exst(Value(qn!(c))),].into())
|
||||
})
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pattern_matching() {
|
||||
use ExpressionKind::*;
|
||||
|
||||
for item in ["if x is Some(a) then { 4 } else { 9 }", "if x is Some(a) then 4 else 9"] {
|
||||
assert_expr!(
|
||||
item,
|
||||
expr(IfExpression {
|
||||
discriminator: Some(bx(expr(Value(qn!(x))))),
|
||||
body: bx(IfExpressionBody::SimplePatternMatch {
|
||||
pattern: Pattern::TupleStruct(qn!(Some), vec![Pattern::VarOrName(qn!(a))]),
|
||||
then_case: vec![exst(NatLiteral(4))].into(),
|
||||
else_case: Some(vec![exst(NatLiteral(9))].into()),
|
||||
})
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
assert_expr!(
|
||||
"if x is Something { a, b: x } then { 4 } else { 9 }",
|
||||
expr(IfExpression {
|
||||
discriminator: Some(bx(expr(Value(qn!(x))))),
|
||||
body: bx(IfExpressionBody::SimplePatternMatch {
|
||||
pattern: Pattern::Record(
|
||||
qn!(Something),
|
||||
vec![
|
||||
(rc("a"), Pattern::Literal(PatternLiteral::StringPattern(rc("a")))),
|
||||
(rc("b"), Pattern::VarOrName(qn!(x)))
|
||||
]
|
||||
),
|
||||
then_case: vec![exst(NatLiteral(4))].into(),
|
||||
else_case: Some(vec![exst(NatLiteral(9))].into()),
|
||||
})
|
||||
})
|
||||
);
|
||||
|
||||
assert_expr!(
|
||||
"if x is -1 then 1 else 2",
|
||||
expr(IfExpression {
|
||||
discriminator: Some(bx(expr(Value(qn!(x))))),
|
||||
body: bx(IfExpressionBody::SimplePatternMatch {
|
||||
pattern: Pattern::Literal(PatternLiteral::NumPattern { neg: true, num: NatLiteral(1) }),
|
||||
then_case: vec![exst(NatLiteral(1))].into(),
|
||||
else_case: Some(vec![exst(NatLiteral(2))].into()),
|
||||
})
|
||||
})
|
||||
);
|
||||
|
||||
assert_expr!(
|
||||
"if x is true then 1 else 2",
|
||||
expr(IfExpression {
|
||||
discriminator: Some(bx(expr(Value(qn!(x))))),
|
||||
body: bx(IfExpressionBody::SimplePatternMatch {
|
||||
pattern: Pattern::Literal(PatternLiteral::BoolPattern(true)),
|
||||
then_case: vec![exst(NatLiteral(1))].into(),
|
||||
else_case: Some(vec![exst(NatLiteral(2))].into()),
|
||||
})
|
||||
})
|
||||
);
|
||||
|
||||
assert_expr!(
|
||||
"if x { is 1 then 5, else 20 }",
|
||||
expr(IfExpression {
|
||||
discriminator: Some(bx(expr(Value(qn!(x))))),
|
||||
body: bx(IfExpressionBody::CondList(vec![
|
||||
ConditionArm {
|
||||
condition: Condition::Pattern(Pattern::Literal(PatternLiteral::NumPattern {
|
||||
neg: false,
|
||||
num: NatLiteral(1)
|
||||
})),
|
||||
guard: None,
|
||||
body: vec![exst(NatLiteral(5))].into(),
|
||||
},
|
||||
ConditionArm {
|
||||
condition: Condition::Else,
|
||||
guard: None,
|
||||
body: vec![exst(NatLiteral(20))].into(),
|
||||
},
|
||||
]))
|
||||
})
|
||||
);
|
||||
|
||||
assert_expr!(
|
||||
r#"if x is "gnosticism" then 1 else 2"#,
|
||||
expr(IfExpression {
|
||||
discriminator: Some(bx(expr(Value(qn!(x))))),
|
||||
body: bx(IfExpressionBody::SimplePatternMatch {
|
||||
pattern: Pattern::Literal(PatternLiteral::StringPattern(rc("gnosticism"))),
|
||||
then_case: vec![exst(NatLiteral(1))].into(),
|
||||
else_case: Some(vec![exst(NatLiteral(2))].into()),
|
||||
})
|
||||
})
|
||||
);
|
||||
|
||||
assert_expr! {
|
||||
r#"
|
||||
if (45, "panda", false, 2.2) {
|
||||
is (49, "pablo", _, 28.4) then "no"
|
||||
is (_, "panda", _, -2.2) then "yes"
|
||||
is _ then "maybe"
|
||||
}"#,
|
||||
expr(
|
||||
IfExpression {
|
||||
discriminator: Some(bx(expr(TupleLiteral(vec![
|
||||
expr(NatLiteral(45)), expr(StringLiteral(rc("panda"))), expr(BoolLiteral(false)), expr(FloatLiteral(2.2))
|
||||
])))),
|
||||
body: bx(IfExpressionBody::CondList(vec![
|
||||
ConditionArm {
|
||||
condition: Condition::Pattern(Pattern::TuplePattern(
|
||||
vec![
|
||||
Pattern::Literal(PatternLiteral::NumPattern { neg: false, num: NatLiteral(49) }),
|
||||
Pattern::Literal(PatternLiteral::StringPattern(rc("pablo"))),
|
||||
Pattern::Ignored,
|
||||
Pattern::Literal(PatternLiteral::NumPattern { neg: false, num: FloatLiteral(28.4) }),
|
||||
]
|
||||
)),
|
||||
guard: None,
|
||||
body: vec![stmt(StatementKind::Expression(expr(StringLiteral(rc("no")))))].into(),
|
||||
},
|
||||
ConditionArm {
|
||||
condition: Condition::Pattern(Pattern::TuplePattern(
|
||||
vec![
|
||||
Pattern::Ignored,
|
||||
Pattern::Literal(PatternLiteral::StringPattern(rc!(panda))),
|
||||
Pattern::Ignored,
|
||||
Pattern::Literal(PatternLiteral::NumPattern { neg: true, num: FloatLiteral(2.2) }),
|
||||
]
|
||||
)),
|
||||
guard: None,
|
||||
body: vec![stmt(StatementKind::Expression(expr(StringLiteral(rc("yes")))))].into(),
|
||||
},
|
||||
ConditionArm {
|
||||
condition: Condition::Pattern(Pattern::Ignored),
|
||||
guard: None,
|
||||
body: vec![exst(StringLiteral(rc("maybe")))].into(),
|
||||
},
|
||||
]))
|
||||
}
|
||||
)
|
||||
};
|
||||
}
|
||||
|
@ -100,48 +100,6 @@ macro_rules! exst {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parsing_types() {
|
||||
parse_test_wrap_ast!("type Yolo = Yolo", decl!(TypeDecl { name: tys!("Yolo"), body: TypeBody(vec![Variant { id: ItemId::default(), kind: UnitStruct, name: rc!(Yolo) }]), mutable: false} ));
|
||||
parse_test_wrap_ast!("type mut Yolo = Yolo", decl!(TypeDecl { name: tys!("Yolo"), body: TypeBody(vec![Variant { id: ItemId::default(), kind: UnitStruct, name: rc!(Yolo) }]), mutable: true} ));
|
||||
parse_test_wrap_ast!("type alias Sex = Drugs", decl!(TypeAlias { alias: rc!(Sex), original: rc!(Drugs) }));
|
||||
parse_test_wrap_ast!("type Sanchez = Miguel | Alejandro(Int, Option<a>) | Esperanza { a: Int, b: String }",
|
||||
decl!(TypeDecl {
|
||||
name: tys!("Sanchez"),
|
||||
body: TypeBody(vec![
|
||||
Variant {
|
||||
id: ItemId::default(),
|
||||
kind: UnitStruct, name: rc!(Miguel) },
|
||||
Variant {
|
||||
id: ItemId::default(),
|
||||
name: rc!(Alejandro),
|
||||
kind: TupleStruct(vec![
|
||||
Singleton(TypeSingletonName { name: rc!(Int), params: vec![] }),
|
||||
Singleton(TypeSingletonName { name: rc!(Option), params: vec![Singleton(TypeSingletonName { name: rc!(a), params: vec![] })] }),
|
||||
])
|
||||
},
|
||||
Variant {
|
||||
id: ItemId::default(),
|
||||
name: rc!(Esperanza),
|
||||
kind: Record(vec![
|
||||
(rc!(a), Singleton(TypeSingletonName { name: rc!(Int), params: vec![] })),
|
||||
(rc!(b), Singleton(TypeSingletonName { name: rc!(String), params: vec![] })),
|
||||
])
|
||||
}
|
||||
]),
|
||||
mutable: false
|
||||
}));
|
||||
|
||||
parse_test_wrap_ast! {
|
||||
"type Jorge<a> = Diego | Kike(a)",
|
||||
decl!(TypeDecl{
|
||||
name: TypeSingletonName { name: rc!(Jorge), params: vec![Singleton(TypeSingletonName { name: rc!(a), params: vec![] })] },
|
||||
body: TypeBody(vec![Variant{ id: ItemId::default(), kind: UnitStruct, name: rc!(Diego) }, Variant { id: ItemId::default(), name: rc!(Kike), kind: TupleStruct( vec![Singleton(TypeSingletonName { name: rc!(a), params: vec![] })]) }]),
|
||||
mutable: false
|
||||
}
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parsing_block_expressions() {
|
||||
@ -212,227 +170,4 @@ fn parsing_block_expressions() {
|
||||
|
||||
#[test]
|
||||
fn parsing_impls() {
|
||||
parse_test_wrap_ast!("impl Heh { fn yolo(); fn swagg(); }",
|
||||
decl!(Impl {
|
||||
type_name: ty!("Heh"),
|
||||
interface_name: None,
|
||||
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_wrap_ast!("impl Mondai for Lollerino { fn yolo(); fn swagg(); }",
|
||||
decl!(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_wrap_ast!("impl Hella<T> for (Alpha, Omega) { }",
|
||||
decl!(Impl {
|
||||
type_name: Tuple(vec![ty!("Alpha"), ty!("Omega")]),
|
||||
interface_name: Some(TypeSingletonName { name: rc!(Hella), params: vec![ty!("T")] }),
|
||||
block: vec![]
|
||||
})
|
||||
);
|
||||
|
||||
parse_test_wrap_ast!("impl Option<WTFMate> { fn oi() }",
|
||||
decl!(Impl {
|
||||
type_name: Singleton(TypeSingletonName { name: rc!(Option), params: vec![ty!("WTFMate")]}),
|
||||
interface_name: None,
|
||||
block: vec![
|
||||
FuncSig(Signature { name: rc!(oi), operator: false, params: vec![], type_anno: None }),
|
||||
]
|
||||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn list_literals() {
|
||||
parse_test_wrap_ast! {
|
||||
"[1,2]",
|
||||
exst!(ListLiteral(vec![ex!(NatLiteral(1)), ex!(NatLiteral(2))]))
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn patterns() {
|
||||
parse_test_wrap_ast! {
|
||||
"if x is Some(a) then { 4 } else { 9 }", exst!(
|
||||
IfExpression {
|
||||
discriminator: Some(bx!(ex!(s "x"))),
|
||||
body: bx!(IfExpressionBody::SimplePatternMatch {
|
||||
pattern: Pattern::TupleStruct(qname!(Some), vec![Pattern::VarOrName(qname!(a))]),
|
||||
then_case: vec![exst!(s "4")].into(),
|
||||
else_case: Some(vec![exst!(s "9")].into()) })
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
parse_test_wrap_ast! {
|
||||
"if x is Some(a) then 4 else 9", exst!(
|
||||
IfExpression {
|
||||
discriminator: Some(bx!(ex!(s "x"))),
|
||||
body: bx!(IfExpressionBody::SimplePatternMatch {
|
||||
pattern: Pattern::TupleStruct(qname!(Some), vec![Pattern::VarOrName(qname!(a))]),
|
||||
then_case: vec![exst!(s "4")].into(),
|
||||
else_case: Some(vec![exst!(s "9")].into()) }
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
parse_test_wrap_ast! {
|
||||
"if x is Something { a, b: x } then { 4 } else { 9 }", exst!(
|
||||
IfExpression {
|
||||
discriminator: Some(bx!(ex!(s "x"))),
|
||||
body: bx!(IfExpressionBody::SimplePatternMatch {
|
||||
pattern: Pattern::Record(qname!(Something), vec![
|
||||
(rc!(a),Pattern::Literal(PatternLiteral::StringPattern(rc!(a)))),
|
||||
(rc!(b),Pattern::VarOrName(qname!(x)))
|
||||
]),
|
||||
then_case: vec![exst!(s "4")].into(),
|
||||
else_case: Some(vec![exst!(s "9")].into())
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pattern_literals() {
|
||||
parse_test_wrap_ast! {
|
||||
"if x is -1 then 1 else 2",
|
||||
exst!(
|
||||
IfExpression {
|
||||
discriminator: Some(bx!(ex!(s "x"))),
|
||||
body: bx!(IfExpressionBody::SimplePatternMatch {
|
||||
pattern: Pattern::Literal(PatternLiteral::NumPattern { neg: true, num: NatLiteral(1) }),
|
||||
then_case: vec![exst!(NatLiteral(1))].into(),
|
||||
else_case: Some(vec![exst!(NatLiteral(2))].into()),
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
parse_test_wrap_ast! {
|
||||
"if x is 1 then 1 else 2",
|
||||
exst!(
|
||||
IfExpression {
|
||||
discriminator: Some(bx!(ex!(s "x"))),
|
||||
body: bx!(IfExpressionBody::SimplePatternMatch {
|
||||
pattern: Pattern::Literal(PatternLiteral::NumPattern { neg: false, num: NatLiteral(1) }),
|
||||
then_case: vec![exst!(s "1")].into(),
|
||||
else_case: Some(vec![exst!(s "2")].into()),
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
parse_test_wrap_ast! {
|
||||
"if x is true then 1 else 2",
|
||||
exst!(
|
||||
IfExpression {
|
||||
discriminator: Some(bx!(ex!(s "x"))),
|
||||
body: bx!(
|
||||
IfExpressionBody::SimplePatternMatch {
|
||||
pattern: Pattern::Literal(PatternLiteral::BoolPattern(true)),
|
||||
then_case: vec![exst!(NatLiteral(1))].into(),
|
||||
else_case: Some(vec![exst!(NatLiteral(2))].into()),
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
parse_test_wrap_ast! {
|
||||
"if x is \"gnosticism\" then 1 else 2",
|
||||
exst!(
|
||||
IfExpression {
|
||||
discriminator: Some(bx!(ex!(s "x"))),
|
||||
body: bx!(IfExpressionBody::SimplePatternMatch {
|
||||
pattern: Pattern::Literal(PatternLiteral::StringPattern(rc!(gnosticism))),
|
||||
then_case: vec![exst!(s "1")].into(),
|
||||
else_case: Some(vec![exst!(s "2")].into()),
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn if_expr() {
|
||||
parse_test_wrap_ast! {
|
||||
"if x { is 1 then 5, else 20 }",
|
||||
exst! {
|
||||
IfExpression {
|
||||
discriminator: Some(bx!(ex!(s "x"))),
|
||||
body: bx!(IfExpressionBody::CondList(
|
||||
vec![
|
||||
ConditionArm {
|
||||
condition: Condition::Pattern(Pattern::Literal(PatternLiteral::NumPattern { neg: false, num: NatLiteral(1)})),
|
||||
guard: None,
|
||||
body: vec![exst!(s "5")].into(),
|
||||
},
|
||||
ConditionArm {
|
||||
condition: Condition::Else,
|
||||
guard: None,
|
||||
body: vec![exst!(s "20")].into(),
|
||||
},
|
||||
]
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn advanced_if_expr() {
|
||||
|
||||
parse_test_wrap_ast! {
|
||||
r#"
|
||||
if (45, "panda", false, 2.2) {
|
||||
is (49, "pablo", _, 28.4) then "no"
|
||||
is (_, "panda", _, -2.2) then "yes"
|
||||
is _ then "maybe"
|
||||
}"#,
|
||||
exst!(
|
||||
IfExpression {
|
||||
discriminator: Some(bx!(ex!(s r#"(45, "panda", false, 2.2)"#))),
|
||||
body: bx!(IfExpressionBody::CondList(vec![
|
||||
ConditionArm {
|
||||
condition: Condition::Pattern(Pattern::TuplePattern(
|
||||
vec![
|
||||
Pattern::Literal(PatternLiteral::NumPattern { neg: false, num: NatLiteral(49) }),
|
||||
Pattern::Literal(PatternLiteral::StringPattern(rc!(pablo))),
|
||||
Pattern::Ignored,
|
||||
Pattern::Literal(PatternLiteral::NumPattern { neg: false, num: FloatLiteral(28.4) }),
|
||||
]
|
||||
)),
|
||||
guard: None,
|
||||
body: vec![exst!(s r#""no""#)].into(),
|
||||
},
|
||||
ConditionArm {
|
||||
condition: Condition::Pattern(Pattern::TuplePattern(
|
||||
vec![
|
||||
Pattern::Ignored,
|
||||
Pattern::Literal(PatternLiteral::StringPattern(rc!(panda))),
|
||||
Pattern::Ignored,
|
||||
Pattern::Literal(PatternLiteral::NumPattern { neg: true, num: FloatLiteral(2.2) }),
|
||||
]
|
||||
)),
|
||||
guard: None,
|
||||
body: vec![exst!(s r#""yes""#)].into(),
|
||||
},
|
||||
ConditionArm {
|
||||
condition: Condition::Pattern(Pattern::Ignored),
|
||||
guard: None,
|
||||
body: vec![exst!(s r#""maybe""#)].into(),
|
||||
},
|
||||
]))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user