Imports
This commit is contained in:
parent
8365690860
commit
69d857e94d
@ -7,7 +7,7 @@ use nom::{
|
|||||||
complete::{alpha1, alphanumeric0, char, line_ending, none_of, not_line_ending, one_of, space1},
|
complete::{alpha1, alphanumeric0, char, line_ending, none_of, not_line_ending, one_of, space1},
|
||||||
is_alphanumeric,
|
is_alphanumeric,
|
||||||
},
|
},
|
||||||
combinator::{cond, flat_map, map, not, opt, peek, recognize, value},
|
combinator::{cut, map, not, opt, peek, recognize, value},
|
||||||
error::{context, ParseError, VerboseError},
|
error::{context, ParseError, VerboseError},
|
||||||
multi::{many0, many1, separated_list0, separated_list1},
|
multi::{many0, many1, separated_list0, separated_list1},
|
||||||
sequence::{delimited, pair, preceded, separated_pair, tuple},
|
sequence::{delimited, pair, preceded, separated_pair, tuple},
|
||||||
@ -126,6 +126,7 @@ fn statement(input: Span) -> ParseResult<Statement> {
|
|||||||
"Parsing-statement",
|
"Parsing-statement",
|
||||||
alt((
|
alt((
|
||||||
map(flow, StatementKind::Flow),
|
map(flow, StatementKind::Flow),
|
||||||
|
map(import, StatementKind::Import),
|
||||||
map(declaration, StatementKind::Declaration),
|
map(declaration, StatementKind::Declaration),
|
||||||
map(expression, StatementKind::Expression),
|
map(expression, StatementKind::Expression),
|
||||||
)),
|
)),
|
||||||
@ -133,6 +134,42 @@ fn statement(input: Span) -> ParseResult<Statement> {
|
|||||||
Ok((rest, Statement { id, location, kind }))
|
Ok((rest, Statement { id, location, kind }))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn import(input: Span) -> ParseResult<ImportSpecifier> {
|
||||||
|
fn path_components(input: Span) -> ParseResult<Vec<Rc<String>>> {
|
||||||
|
map(
|
||||||
|
tuple((opt(tag("::")), identifier, many0(preceded(tag("::"), identifier_span)))),
|
||||||
|
|(_maybe_root, first, rest)| {
|
||||||
|
let mut components = vec![rc_string(first.fragment())];
|
||||||
|
components.extend(rest.into_iter().map(|n| rc_string(n.fragment())));
|
||||||
|
components
|
||||||
|
},
|
||||||
|
)(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn import_suffix(input: Span) -> ParseResult<ImportedNames> {
|
||||||
|
alt((
|
||||||
|
value(ImportedNames::All, tag("::*")),
|
||||||
|
map(
|
||||||
|
preceded(
|
||||||
|
tag("::"),
|
||||||
|
delimited(char('{'), separated_list0(tok(char(',')), identifier), char('}')),
|
||||||
|
),
|
||||||
|
|names| ImportedNames::List(names.into_iter().map(|n| rc_string(n.fragment())).collect()),
|
||||||
|
),
|
||||||
|
))(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
let id = fresh_id(&input);
|
||||||
|
map(
|
||||||
|
preceded(kw("import"), cut(pair(path_components, opt(import_suffix)))),
|
||||||
|
move |(path_components, suffix)| ImportSpecifier {
|
||||||
|
id,
|
||||||
|
path_components,
|
||||||
|
imported_names: suffix.unwrap_or(ImportedNames::LastOfPath),
|
||||||
|
},
|
||||||
|
)(input)
|
||||||
|
}
|
||||||
|
|
||||||
fn flow(input: Span) -> ParseResult<FlowControl> {
|
fn flow(input: Span) -> ParseResult<FlowControl> {
|
||||||
alt((
|
alt((
|
||||||
map(kw("continue"), |_| FlowControl::Continue),
|
map(kw("continue"), |_| FlowControl::Continue),
|
||||||
@ -693,7 +730,7 @@ fn bare_string_literal(input: Span) -> ParseResult<String> {
|
|||||||
alt((value("\\", tag("\\")), value("\"", tag("\"")), value("\n", tag("n")), value("\t", tag("t"))));
|
alt((value("\\", tag("\\")), value("\"", tag("\"")), value("\n", tag("n")), value("\t", tag("t"))));
|
||||||
alt((
|
alt((
|
||||||
map(tag(r#""""#), |_| String::new()),
|
map(tag(r#""""#), |_| String::new()),
|
||||||
delimited(char('"'), escaped_transform(none_of(r#""\"#), '\\', string_escape_transforms), char('"'))
|
delimited(char('"'), escaped_transform(none_of(r#""\"#), '\\', string_escape_transforms), char('"')),
|
||||||
))(input)
|
))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,6 @@ peg::parser! {
|
|||||||
"::*" { ImportedNames::All } /
|
"::*" { ImportedNames::All } /
|
||||||
"::{" __ names:(identifier() ** (_ "," _)) __ "}" { ImportedNames::List(names.into_iter().map(rc_string).collect()) }
|
"::{" __ names:(identifier() ** (_ "," _)) __ "}" { ImportedNames::List(names.into_iter().map(rc_string).collect()) }
|
||||||
|
|
||||||
|
|
||||||
rule declaration(parser: &mut Parser) -> Declaration =
|
rule declaration(parser: &mut Parser) -> Declaration =
|
||||||
binding(parser) / type_decl(parser) / annotation(parser) / func(parser) / interface(parser) /
|
binding(parser) / type_decl(parser) / annotation(parser) / func(parser) / interface(parser) /
|
||||||
implementation(parser) / module(parser)
|
implementation(parser) / module(parser)
|
||||||
|
@ -119,6 +119,7 @@ macro_rules! assert_fail {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
macro_rules! assert_expr {
|
macro_rules! assert_expr {
|
||||||
($input:expr, $correct:expr) => {
|
($input:expr, $correct:expr) => {
|
||||||
let mut parser = Parser::new();
|
let mut parser = Parser::new();
|
||||||
@ -130,8 +131,9 @@ macro_rules! assert_expr {
|
|||||||
assert_eq!(expr.unwrap(), $correct);
|
assert_eq!(expr.unwrap(), $correct);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
macro_rules! assert_expr_comb {
|
macro_rules! assert_expr {
|
||||||
($input:expr, $correct:expr) => {
|
($input:expr, $correct:expr) => {
|
||||||
let mut parser = Parser::new();
|
let mut parser = Parser::new();
|
||||||
let expr = parser.expression_comb($input.trim_start());
|
let expr = parser.expression_comb($input.trim_start());
|
||||||
@ -155,35 +157,35 @@ macro_rules! assert_fail_expr {
|
|||||||
fn basic_literals() {
|
fn basic_literals() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
assert_expr_comb!(".2", expr(FloatLiteral(0.2)));
|
assert_expr!(".2", expr(FloatLiteral(0.2)));
|
||||||
assert_expr_comb!("8.1", expr(FloatLiteral(8.1)));
|
assert_expr!("8.1", expr(FloatLiteral(8.1)));
|
||||||
assert_expr_comb!("0b010", expr(NatLiteral(2)));
|
assert_expr!("0b010", expr(NatLiteral(2)));
|
||||||
assert_expr_comb!("0b0_1_0", expr(NatLiteral(2)));
|
assert_expr!("0b0_1_0", expr(NatLiteral(2)));
|
||||||
assert_expr_comb!("0xff", expr(NatLiteral(255)));
|
assert_expr!("0xff", expr(NatLiteral(255)));
|
||||||
assert_expr_comb!("0x032f", expr(NatLiteral(815)));
|
assert_expr!("0x032f", expr(NatLiteral(815)));
|
||||||
assert_expr_comb!("0xf_f_", expr(NatLiteral(255)));
|
assert_expr!("0xf_f_", expr(NatLiteral(255)));
|
||||||
assert_expr_comb!("false", expr(BoolLiteral(false)));
|
assert_expr!("false", expr(BoolLiteral(false)));
|
||||||
assert_expr_comb!("true", expr(BoolLiteral(true)));
|
assert_expr!("true", expr(BoolLiteral(true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn string_literals() {
|
fn string_literals() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
assert_expr_comb!(r#""""#, expr(StringLiteral(rc(""))));
|
assert_expr!(r#""""#, expr(StringLiteral(rc(""))));
|
||||||
assert_expr_comb!(r#""hello""#, expr(StringLiteral(rc("hello"))));
|
assert_expr!(r#""hello""#, expr(StringLiteral(rc("hello"))));
|
||||||
assert_expr_comb!(r#"b"some bytestring""#, expr(StringLiteral(rc("some bytestring"))));
|
assert_expr!(r#"b"some bytestring""#, expr(StringLiteral(rc("some bytestring"))));
|
||||||
//NOTE I'm not 100% sure this case is correct, but I'll deal with it later
|
//NOTE I'm not 100% sure this case is correct, but I'll deal with it later
|
||||||
assert_expr_comb!(r#""Do \n \" escapes work\t""#, expr(StringLiteral(rc("Do \n \" escapes work\t"))));
|
assert_expr!(r#""Do \n \" escapes work\t""#, expr(StringLiteral(rc("Do \n \" escapes work\t"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn list_literals() {
|
fn list_literals() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
assert_expr_comb!("[]", expr(ListLiteral(vec![])));
|
assert_expr!("[]", expr(ListLiteral(vec![])));
|
||||||
assert_expr_comb!("[1,2]", expr(ListLiteral(vec![expr(NatLiteral(1)), expr(NatLiteral(2)),])));
|
assert_expr!("[1,2]", expr(ListLiteral(vec![expr(NatLiteral(1)), expr(NatLiteral(2)),])));
|
||||||
assert_expr_comb!("[1, /*no*/2]", expr(ListLiteral(vec![expr(NatLiteral(1)), expr(NatLiteral(2)),])));
|
assert_expr!("[1, /*no*/2]", expr(ListLiteral(vec![expr(NatLiteral(1)), expr(NatLiteral(2)),])));
|
||||||
assert_fail_expr!("[1,,2]", "some failure");
|
assert_fail_expr!("[1,,2]", "some failure");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +194,7 @@ fn binexps() {
|
|||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
use StatementKind::Expression;
|
use StatementKind::Expression;
|
||||||
|
|
||||||
assert_expr_comb!("0xf_f+1", binop("+", expr(NatLiteral(255)), expr(NatLiteral(1))));
|
assert_expr!("0xf_f+1", binop("+", expr(NatLiteral(255)), expr(NatLiteral(1))));
|
||||||
assert_ast_comb!(
|
assert_ast_comb!(
|
||||||
"3; 4; 4.3",
|
"3; 4; 4.3",
|
||||||
vec![
|
vec![
|
||||||
@ -202,16 +204,16 @@ fn binexps() {
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"1 + 2 * 3",
|
"1 + 2 * 3",
|
||||||
binop("+", expr(NatLiteral(1)), binop("*", expr(NatLiteral(2)), expr(NatLiteral(3))))
|
binop("+", expr(NatLiteral(1)), binop("*", expr(NatLiteral(2)), expr(NatLiteral(3))))
|
||||||
);
|
);
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"1 * 2 + 3",
|
"1 * 2 + 3",
|
||||||
binop("+", binop("*", expr(NatLiteral(1)), expr(NatLiteral(2))), expr(NatLiteral(3)))
|
binop("+", binop("*", expr(NatLiteral(1)), expr(NatLiteral(2))), expr(NatLiteral(3)))
|
||||||
);
|
);
|
||||||
assert_expr_comb!("1 && 2", binop("&&", expr(NatLiteral(1)), expr(NatLiteral(2))));
|
assert_expr!("1 && 2", binop("&&", expr(NatLiteral(1)), expr(NatLiteral(2))));
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"1 + 2 * 3 + 4",
|
"1 + 2 * 3 + 4",
|
||||||
binop(
|
binop(
|
||||||
"+",
|
"+",
|
||||||
@ -219,48 +221,48 @@ fn binexps() {
|
|||||||
expr(NatLiteral(4))
|
expr(NatLiteral(4))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"(1 + 2) * 3",
|
"(1 + 2) * 3",
|
||||||
binop("*", binop("+", expr(NatLiteral(1)), expr(NatLiteral(2))), expr(NatLiteral(3)))
|
binop("*", binop("+", expr(NatLiteral(1)), expr(NatLiteral(2))), expr(NatLiteral(3)))
|
||||||
);
|
);
|
||||||
assert_expr_comb!(".1 + .2", binop("+", expr(FloatLiteral(0.1)), expr(FloatLiteral(0.2))));
|
assert_expr!(".1 + .2", binop("+", expr(FloatLiteral(0.1)), expr(FloatLiteral(0.2))));
|
||||||
assert_expr_comb!("1 / 2.", binop("/", expr(NatLiteral(1)), expr(FloatLiteral(2.))));
|
assert_expr!("1 / 2.", binop("/", expr(NatLiteral(1)), expr(FloatLiteral(2.))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn prefix_exps() {
|
fn prefix_exps() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
assert_expr_comb!("-3", prefixop("-", expr(NatLiteral(3))));
|
assert_expr!("-3", prefixop("-", expr(NatLiteral(3))));
|
||||||
assert_expr_comb!("-0.2", prefixop("-", expr(FloatLiteral(0.2))));
|
assert_expr!("-0.2", prefixop("-", expr(FloatLiteral(0.2))));
|
||||||
assert_expr_comb!("!3", prefixop("!", expr(NatLiteral(3))));
|
assert_expr!("!3", prefixop("!", expr(NatLiteral(3))));
|
||||||
assert_expr_comb!("!t", prefixop("!", expr(Value(qn!(t)))));
|
assert_expr!("!t", prefixop("!", expr(Value(qn!(t)))));
|
||||||
assert_expr_comb!("a <- -b", binop("<-", expr(Value(qn!(a))), prefixop("-", expr(Value(qn!(b))))));
|
assert_expr!("a <- -b", binop("<-", expr(Value(qn!(a))), prefixop("-", expr(Value(qn!(b))))));
|
||||||
assert_expr_comb!("a <--b", binop("<--", expr(Value(qn!(a))), expr(Value(qn!(b)))));
|
assert_expr!("a <--b", binop("<--", expr(Value(qn!(a))), expr(Value(qn!(b)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn operators() {
|
fn operators() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
assert_expr_comb!("a <- 1", binop("<-", expr(Value(qn!(a))), expr(NatLiteral(1))));
|
assert_expr!("a <- 1", binop("<-", expr(Value(qn!(a))), expr(NatLiteral(1))));
|
||||||
assert_expr_comb!("a || 1", binop("||", expr(Value(qn!(a))), expr(NatLiteral(1))));
|
assert_expr!("a || 1", binop("||", expr(Value(qn!(a))), expr(NatLiteral(1))));
|
||||||
assert_expr_comb!("a <> 1", binop("<>", expr(Value(qn!(a))), expr(NatLiteral(1))));
|
assert_expr!("a <> 1", binop("<>", expr(Value(qn!(a))), expr(NatLiteral(1))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn accessors() {
|
fn accessors() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
assert_expr_comb!("a.b", expr(Access { name: rc("b"), expr: bx(expr(Value(qn!(a)))) }));
|
assert_expr!("a.b", expr(Access { name: rc("b"), expr: bx(expr(Value(qn!(a)))) }));
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"a.b.c",
|
"a.b.c",
|
||||||
expr(Access {
|
expr(Access {
|
||||||
name: rc("c"),
|
name: rc("c"),
|
||||||
expr: bx(expr(Access { name: rc("b"), expr: bx(expr(Value(qn!(a)))) }))
|
expr: bx(expr(Access { name: rc("b"), expr: bx(expr(Value(qn!(a)))) }))
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"a.b.c(3)",
|
"a.b.c(3)",
|
||||||
expr(Call {
|
expr(Call {
|
||||||
f: bx(expr(Access {
|
f: bx(expr(Access {
|
||||||
@ -270,7 +272,7 @@ fn accessors() {
|
|||||||
arguments: vec![InvocationArgument::Positional(expr(NatLiteral(3)))],
|
arguments: vec![InvocationArgument::Positional(expr(NatLiteral(3)))],
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"a.b().c",
|
"a.b().c",
|
||||||
expr(Access {
|
expr(Access {
|
||||||
name: rc("c"),
|
name: rc("c"),
|
||||||
@ -286,12 +288,12 @@ fn accessors() {
|
|||||||
fn tuples() {
|
fn tuples() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
assert_expr_comb!("()", expr(TupleLiteral(vec![])));
|
assert_expr!("()", expr(TupleLiteral(vec![])));
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
r#"("hella", 34)"#,
|
r#"("hella", 34)"#,
|
||||||
expr(TupleLiteral(vec![expr(StringLiteral(rc("hella"))), expr(NatLiteral(34))]))
|
expr(TupleLiteral(vec![expr(StringLiteral(rc("hella"))), expr(NatLiteral(34))]))
|
||||||
);
|
);
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
r#"(1+2, "slough")"#,
|
r#"(1+2, "slough")"#,
|
||||||
expr(TupleLiteral(vec![
|
expr(TupleLiteral(vec![
|
||||||
binop("+", expr(NatLiteral(1)), expr(NatLiteral(2))),
|
binop("+", expr(NatLiteral(1)), expr(NatLiteral(2))),
|
||||||
@ -304,12 +306,12 @@ fn tuples() {
|
|||||||
fn identifiers() {
|
fn identifiers() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
assert_expr_comb!("a", expr(Value(qn!(a))));
|
assert_expr!("a", expr(Value(qn!(a))));
|
||||||
assert_expr_comb!("some_value", expr(Value(qn!(some_value))));
|
assert_expr!("some_value", expr(Value(qn!(some_value))));
|
||||||
assert_expr_comb!("alpha::beta::gamma", expr(Value(qn!(alpha, beta, gamma))));
|
assert_expr!("alpha::beta::gamma", expr(Value(qn!(alpha, beta, gamma))));
|
||||||
assert_expr_comb!("a + b", binop("+", expr(Value(qn!(a))), expr(Value(qn!(b)))));
|
assert_expr!("a + b", binop("+", expr(Value(qn!(a))), expr(Value(qn!(b)))));
|
||||||
assert_expr_comb!("None", expr(Value(qn!(None))));
|
assert_expr!("None", expr(Value(qn!(None))));
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"thing::item::call()",
|
"thing::item::call()",
|
||||||
expr(Call { f: bx(expr(Value(qn!(thing, item, call)))), arguments: vec![] })
|
expr(Call { f: bx(expr(Value(qn!(thing, item, call)))), arguments: vec![] })
|
||||||
);
|
);
|
||||||
@ -318,14 +320,14 @@ fn identifiers() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn named_struct() {
|
fn named_struct() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"Pandas { a: x + y }",
|
"Pandas { a: x + y }",
|
||||||
expr(NamedStruct {
|
expr(NamedStruct {
|
||||||
name: qn!(Pandas),
|
name: qn!(Pandas),
|
||||||
fields: vec![(rc("a"), binop("+", expr(Value(qn!(x))), expr(Value(qn!(y)))))]
|
fields: vec![(rc("a"), binop("+", expr(Value(qn!(x))), expr(Value(qn!(y)))))]
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"Trousers { a:1, b:800 }",
|
"Trousers { a:1, b:800 }",
|
||||||
expr(NamedStruct {
|
expr(NamedStruct {
|
||||||
name: qn!(Trousers),
|
name: qn!(Trousers),
|
||||||
@ -337,14 +339,14 @@ fn named_struct() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn index() {
|
fn index() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"armok[b,c]",
|
"armok[b,c]",
|
||||||
expr(Index {
|
expr(Index {
|
||||||
indexee: bx(expr(Value(qn!(armok)))),
|
indexee: bx(expr(Value(qn!(armok)))),
|
||||||
indexers: vec![expr(Value(qn!(b))), expr(Value(qn!(c)))]
|
indexers: vec![expr(Value(qn!(b))), expr(Value(qn!(c)))]
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"a[b,c][1]",
|
"a[b,c][1]",
|
||||||
expr(Index {
|
expr(Index {
|
||||||
indexee: bx(expr(Index {
|
indexee: bx(expr(Index {
|
||||||
@ -354,7 +356,7 @@ fn index() {
|
|||||||
indexers: vec![expr(NatLiteral(1))]
|
indexers: vec![expr(NatLiteral(1))]
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"perspicacity()[a]",
|
"perspicacity()[a]",
|
||||||
expr(Index {
|
expr(Index {
|
||||||
indexee: bx(expr(Call { f: bx(expr(Value(qn!(perspicacity)))), arguments: vec![] })),
|
indexee: bx(expr(Call { f: bx(expr(Value(qn!(perspicacity)))), arguments: vec![] })),
|
||||||
@ -366,7 +368,7 @@ fn index() {
|
|||||||
let b = expr(Index { indexee: bx(a), indexers: vec![expr(Value(qn!(b)))] });
|
let b = expr(Index { indexee: bx(a), indexers: vec![expr(Value(qn!(b)))] });
|
||||||
let c = expr(Call { f: bx(b), arguments: vec![] });
|
let c = expr(Call { f: bx(b), arguments: vec![] });
|
||||||
let d = expr(Index { indexee: bx(c), indexers: vec![expr(Value(qn!(d)))] });
|
let d = expr(Index { indexee: bx(c), indexers: vec![expr(Value(qn!(d)))] });
|
||||||
assert_expr_comb!("a()[b]()[d]", d);
|
assert_expr!("a()[b]()[d]", d);
|
||||||
|
|
||||||
assert_fail_expr!("a[]", "Empty index expressions are not allowed");
|
assert_fail_expr!("a[]", "Empty index expressions are not allowed");
|
||||||
}
|
}
|
||||||
@ -376,7 +378,7 @@ fn while_expression() {
|
|||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
// assert_expr_comb!("while { }", expr(WhileExpression { condition: None, body: Block::default() }));
|
// assert_expr_comb!("while { }", expr(WhileExpression { condition: None, body: Block::default() }));
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"while a == b { }",
|
"while a == b { }",
|
||||||
expr(WhileExpression {
|
expr(WhileExpression {
|
||||||
condition: Some(bx(binop("==", expr(Value(qn!(a))), expr(Value(qn!(b)))))),
|
condition: Some(bx(binop("==", expr(Value(qn!(a))), expr(Value(qn!(b)))))),
|
||||||
@ -389,7 +391,7 @@ fn while_expression() {
|
|||||||
fn for_expression() {
|
fn for_expression() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"for { a <- garodzny::maybeValue } return 1",
|
"for { a <- garodzny::maybeValue } return 1",
|
||||||
expr(ForExpression {
|
expr(ForExpression {
|
||||||
enumerators: vec![Enumerator { id: rc("a"), generator: expr(Value(qn!(garodzny, maybeValue))) }],
|
enumerators: vec![Enumerator { id: rc("a"), generator: expr(Value(qn!(garodzny, maybeValue))) }],
|
||||||
@ -397,7 +399,7 @@ fn for_expression() {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"for n <- someRange { f(n) ; }",
|
"for n <- someRange { f(n) ; }",
|
||||||
expr(ForExpression {
|
expr(ForExpression {
|
||||||
enumerators: vec![Enumerator { id: rc("n"), generator: expr(Value(qn!(someRange))) }],
|
enumerators: vec![Enumerator { id: rc("n"), generator: expr(Value(qn!(someRange))) }],
|
||||||
@ -416,7 +418,7 @@ fn for_expression() {
|
|||||||
fn lambda_expressions() {
|
fn lambda_expressions() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
r#"\(x) { x + 1}"#,
|
r#"\(x) { x + 1}"#,
|
||||||
expr(Lambda {
|
expr(Lambda {
|
||||||
params: vec![FormalParam { name: rc!(x), anno: None, default: None }],
|
params: vec![FormalParam { name: rc!(x), anno: None, default: None }],
|
||||||
@ -427,7 +429,7 @@ fn lambda_expressions() {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
r#"\ (x: Int, y) { a;b;c;}"#,
|
r#"\ (x: Int, y) { a;b;c;}"#,
|
||||||
expr(Lambda {
|
expr(Lambda {
|
||||||
params: vec![
|
params: vec![
|
||||||
@ -444,7 +446,7 @@ fn lambda_expressions() {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
r#"\(x){y}(1)"#,
|
r#"\(x){y}(1)"#,
|
||||||
expr(Call {
|
expr(Call {
|
||||||
f: bx(expr(Lambda {
|
f: bx(expr(Lambda {
|
||||||
@ -456,7 +458,7 @@ fn lambda_expressions() {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
r#"\(x: Int): String { "q" }"#,
|
r#"\(x: Int): String { "q" }"#,
|
||||||
expr(Lambda {
|
expr(Lambda {
|
||||||
params: vec![FormalParam { name: rc!(x), anno: Some(ty_simple("Int")), default: None },],
|
params: vec![FormalParam { name: rc!(x), anno: Some(ty_simple("Int")), default: None },],
|
||||||
@ -473,7 +475,7 @@ fn lambda_expressions() {
|
|||||||
fn single_param_lambda() {
|
fn single_param_lambda() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
r#"\x { x + 10 }"#,
|
r#"\x { x + 10 }"#,
|
||||||
expr(Lambda {
|
expr(Lambda {
|
||||||
params: vec![FormalParam { name: rc!(x), anno: None, default: None },],
|
params: vec![FormalParam { name: rc!(x), anno: None, default: None },],
|
||||||
@ -487,7 +489,7 @@ fn single_param_lambda() {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
r#"\x: Int { x + 10 }"#,
|
r#"\x: Int { x + 10 }"#,
|
||||||
expr(Lambda {
|
expr(Lambda {
|
||||||
params: vec![FormalParam { name: rc!(x), anno: Some(ty_simple("Int")), default: None },],
|
params: vec![FormalParam { name: rc!(x), anno: Some(ty_simple("Int")), default: None },],
|
||||||
@ -561,11 +563,11 @@ fn type_annotations() {
|
|||||||
})]
|
})]
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"a: Int",
|
"a: Int",
|
||||||
expr_anno(Value(qn!(a)), Singleton(TypeSingletonName { name: rc("Int"), params: vec![] }))
|
expr_anno(Value(qn!(a)), Singleton(TypeSingletonName { name: rc("Int"), params: vec![] }))
|
||||||
);
|
);
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"a: Option<Int>",
|
"a: Option<Int>",
|
||||||
expr_anno(
|
expr_anno(
|
||||||
Value(qn!(a)),
|
Value(qn!(a)),
|
||||||
@ -575,7 +577,7 @@ fn type_annotations() {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"a: KoreanBBQSpecifier<Kimchi, Option<Bulgogi> >",
|
"a: KoreanBBQSpecifier<Kimchi, Option<Bulgogi> >",
|
||||||
expr_anno(
|
expr_anno(
|
||||||
Value(qn!(a)),
|
Value(qn!(a)),
|
||||||
@ -591,7 +593,7 @@ fn type_annotations() {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"a: (Int, Yolo<a>)",
|
"a: (Int, Yolo<a>)",
|
||||||
expr_anno(
|
expr_anno(
|
||||||
Value(qn!(a)),
|
Value(qn!(a)),
|
||||||
@ -797,7 +799,7 @@ fn functions() {
|
|||||||
vec![stmt(StatementKind::Expression(expr(Call { f: bx(expr(Value(qn!(oi)))), arguments: vec![] })))]
|
vec![stmt(StatementKind::Expression(expr(Call { f: bx(expr(Value(qn!(oi)))), arguments: vec![] })))]
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"oi(a, 2+2)",
|
"oi(a, 2+2)",
|
||||||
expr(Call {
|
expr(Call {
|
||||||
f: bx(expr(Value(qn!(oi)))),
|
f: bx(expr(Value(qn!(oi)))),
|
||||||
@ -1056,7 +1058,7 @@ fn modules() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn imports() {
|
fn imports() {
|
||||||
assert_ast! {
|
assert_ast_comb! {
|
||||||
"import harbinger::draughts::Norgleheim",
|
"import harbinger::draughts::Norgleheim",
|
||||||
vec![stmt(StatementKind::Import(ImportSpecifier {
|
vec![stmt(StatementKind::Import(ImportSpecifier {
|
||||||
id: ItemId::default(),
|
id: ItemId::default(),
|
||||||
@ -1065,7 +1067,7 @@ fn imports() {
|
|||||||
}))]
|
}))]
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_ast! {
|
assert_ast_comb! {
|
||||||
"import harbinger::draughts::{Norgleheim, Xraksenlaigar}",
|
"import harbinger::draughts::{Norgleheim, Xraksenlaigar}",
|
||||||
vec![stmt(StatementKind::Import(ImportSpecifier {
|
vec![stmt(StatementKind::Import(ImportSpecifier {
|
||||||
id: ItemId::default(),
|
id: ItemId::default(),
|
||||||
@ -1075,7 +1077,8 @@ fn imports() {
|
|||||||
}))]
|
}))]
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_ast! {
|
//TODO this shouldn't be legal
|
||||||
|
assert_ast_comb! {
|
||||||
"import bespouri::{}",
|
"import bespouri::{}",
|
||||||
vec![stmt(StatementKind::Import(ImportSpecifier {
|
vec![stmt(StatementKind::Import(ImportSpecifier {
|
||||||
id: Default::default(),
|
id: Default::default(),
|
||||||
@ -1084,7 +1087,7 @@ fn imports() {
|
|||||||
}))]
|
}))]
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_ast! {
|
assert_ast_comb! {
|
||||||
"import bespouri::*",
|
"import bespouri::*",
|
||||||
vec![stmt(StatementKind::Import(ImportSpecifier {
|
vec![stmt(StatementKind::Import(ImportSpecifier {
|
||||||
id: Default::default(),
|
id: Default::default(),
|
||||||
@ -1097,7 +1100,7 @@ fn imports() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn if_exprs() {
|
fn if_exprs() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"if a() then { tuah(); }",
|
"if a() then { tuah(); }",
|
||||||
expr(IfExpression {
|
expr(IfExpression {
|
||||||
discriminator: Some(bx(expr(Call { f: bx(expr(Value(qn!(a)))), arguments: vec![] }))),
|
discriminator: Some(bx(expr(Call { f: bx(expr(Value(qn!(a)))), arguments: vec![] }))),
|
||||||
@ -1109,7 +1112,7 @@ fn if_exprs() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
//TODO add tests for named expressions
|
//TODO add tests for named expressions
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"if a then b else c",
|
"if a then b else c",
|
||||||
expr(IfExpression {
|
expr(IfExpression {
|
||||||
discriminator: Some(bx(expr(Value(qn!(a))))),
|
discriminator: Some(bx(expr(Value(qn!(a))))),
|
||||||
@ -1120,7 +1123,7 @@ fn if_exprs() {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
r#"if true then {
|
r#"if true then {
|
||||||
let a = 10
|
let a = 10
|
||||||
b
|
b
|
||||||
@ -1151,7 +1154,7 @@ fn pattern_matching() {
|
|||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
for item in ["if x is Some(a) then { 4 } else { 9 }", "if x is Some(a) then 4 else 9"] {
|
for item in ["if x is Some(a) then { 4 } else { 9 }", "if x is Some(a) then 4 else 9"] {
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
item,
|
item,
|
||||||
expr(IfExpression {
|
expr(IfExpression {
|
||||||
discriminator: Some(bx(expr(Value(qn!(x))))),
|
discriminator: Some(bx(expr(Value(qn!(x))))),
|
||||||
@ -1164,7 +1167,7 @@ fn pattern_matching() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"if x is Something { a, b: x } then { 4 } else { 9 }",
|
"if x is Something { a, b: x } then { 4 } else { 9 }",
|
||||||
expr(IfExpression {
|
expr(IfExpression {
|
||||||
discriminator: Some(bx(expr(Value(qn!(x))))),
|
discriminator: Some(bx(expr(Value(qn!(x))))),
|
||||||
@ -1179,7 +1182,7 @@ fn pattern_matching() {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"if x is -1 then 1 else 2",
|
"if x is -1 then 1 else 2",
|
||||||
expr(IfExpression {
|
expr(IfExpression {
|
||||||
discriminator: Some(bx(expr(Value(qn!(x))))),
|
discriminator: Some(bx(expr(Value(qn!(x))))),
|
||||||
@ -1191,7 +1194,7 @@ fn pattern_matching() {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"if x is true then 1 else 2",
|
"if x is true then 1 else 2",
|
||||||
expr(IfExpression {
|
expr(IfExpression {
|
||||||
discriminator: Some(bx(expr(Value(qn!(x))))),
|
discriminator: Some(bx(expr(Value(qn!(x))))),
|
||||||
@ -1203,7 +1206,7 @@ fn pattern_matching() {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
"if x { is 1 then 5; else 20 }",
|
"if x { is 1 then 5; else 20 }",
|
||||||
expr(IfExpression {
|
expr(IfExpression {
|
||||||
discriminator: Some(bx(expr(Value(qn!(x))))),
|
discriminator: Some(bx(expr(Value(qn!(x))))),
|
||||||
@ -1225,7 +1228,7 @@ fn pattern_matching() {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_expr_comb!(
|
assert_expr!(
|
||||||
r#"if x is "gnosticism" then 1 else 2"#,
|
r#"if x is "gnosticism" then 1 else 2"#,
|
||||||
expr(IfExpression {
|
expr(IfExpression {
|
||||||
discriminator: Some(bx(expr(Value(qn!(x))))),
|
discriminator: Some(bx(expr(Value(qn!(x))))),
|
||||||
@ -1237,7 +1240,7 @@ fn pattern_matching() {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_expr_comb! {
|
assert_expr! {
|
||||||
r#"
|
r#"
|
||||||
if (45, "panda", false, 2.2) {
|
if (45, "panda", false, 2.2) {
|
||||||
is (49, "pablo", _, 28.4) then "no"
|
is (49, "pablo", _, 28.4) then "no"
|
||||||
@ -1400,7 +1403,7 @@ fn comments() {
|
|||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
let source = "1 + /* hella /* bro */ */ 2";
|
let source = "1 + /* hella /* bro */ */ 2";
|
||||||
assert_expr_comb!(source, binop("+", expr(NatLiteral(1)), expr(NatLiteral(2))));
|
assert_expr!(source, binop("+", expr(NatLiteral(1)), expr(NatLiteral(2))));
|
||||||
|
|
||||||
//TODO make sure this error message makes sense
|
//TODO make sure this error message makes sense
|
||||||
let source = "1 + /* hella /* bro */ 2";
|
let source = "1 + /* hella /* bro */ 2";
|
||||||
|
Loading…
Reference in New Issue
Block a user