More types of expr
This commit is contained in:
parent
6a318257d6
commit
76b1e9c0dc
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -561,8 +561,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "peg"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07c0b841ea54f523f7aa556956fbd293bcbe06f2e67d2eb732b7278aaf1d166a"
|
||||
source = "git+https://github.com/kevinmehall/rust-peg?rev=960222580c8da25b17d32c2aae6f52f902728b62#960222580c8da25b17d32c2aae6f52f902728b62"
|
||||
dependencies = [
|
||||
"peg-macros",
|
||||
"peg-runtime",
|
||||
@ -571,8 +570,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "peg-macros"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c"
|
||||
source = "git+https://github.com/kevinmehall/rust-peg?rev=960222580c8da25b17d32c2aae6f52f902728b62#960222580c8da25b17d32c2aae6f52f902728b62"
|
||||
dependencies = [
|
||||
"peg-runtime",
|
||||
"proc-macro2 1.0.30",
|
||||
@ -582,8 +580,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "peg-runtime"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088"
|
||||
source = "git+https://github.com/kevinmehall/rust-peg?rev=960222580c8da25b17d32c2aae6f52f902728b62#960222580c8da25b17d32c2aae6f52f902728b62"
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
|
@ -14,7 +14,9 @@ derivative = "1.0.3"
|
||||
colored = "1.8"
|
||||
radix_trie = "0.1.5"
|
||||
assert_matches = "1.5"
|
||||
peg = "0.7.0"
|
||||
#peg = "0.7.0"
|
||||
peg = { git = "https://github.com/kevinmehall/rust-peg", rev = "960222580c8da25b17d32c2aae6f52f902728b62" }
|
||||
|
||||
|
||||
schala-lang-codegen = { path = "../codegen" }
|
||||
schala-repl = { path = "../../schala-repl" }
|
||||
|
@ -55,15 +55,49 @@ peg::parser! {
|
||||
quiet!{$( ['+' | '-' | '*' | '/' | '%' | '<' | '>' | '=' | '!' | '$' | '&' | '|' | '?' | '^' | '`']+ )} /
|
||||
expected!("operator")
|
||||
|
||||
#[cache_left_rec]
|
||||
rule extended_expr() -> ExpressionKind =
|
||||
indexee:extended_expr() indexers:index_part() {
|
||||
ExpressionKind::Index {
|
||||
indexee: Box::new(Expression::new(Default::default(), indexee)),
|
||||
indexers,
|
||||
}
|
||||
} /
|
||||
f:extended_expr() arguments:call_part() {
|
||||
ExpressionKind::Call {
|
||||
f: Box::new(Expression::new(Default::default(), f)),
|
||||
arguments,
|
||||
}
|
||||
|
||||
} /
|
||||
expr:extended_expr() "." name:identifier() { ExpressionKind::Access {
|
||||
name: Rc::new(name.to_string()),
|
||||
expr: Box::new(Expression::new(Default::default(),expr)),
|
||||
} } /
|
||||
primary()
|
||||
|
||||
rule index_part() -> Vec<Expression> =
|
||||
"[" indexers:(expression() ++ ",") "]" { indexers }
|
||||
|
||||
rule call_part() -> Vec<InvocationArgument> =
|
||||
"(" arguments:(invocation_argument() ** ",") ")" { arguments }
|
||||
|
||||
//TODO this shouldn't be an expression b/c type annotations disallowed here
|
||||
rule invocation_argument() -> InvocationArgument =
|
||||
_ "_" _ { InvocationArgument::Ignored } /
|
||||
_ ident:identifier() _ "=" _ expr:expression() { InvocationArgument::Keyword {
|
||||
name: Rc::new(ident.to_string()),
|
||||
expr
|
||||
} } /
|
||||
_ expr:expression() _ { InvocationArgument::Positional(expr) }
|
||||
|
||||
|
||||
rule primary() -> ExpressionKind =
|
||||
float_literal() / nat_literal() / bool_literal() / string_literal() / paren_expr() /
|
||||
list_expr() / if_expr() / identifier_expr()
|
||||
list_expr() / if_expr() / named_struct() / identifier_expr()
|
||||
|
||||
rule identifier_expr() -> ExpressionKind =
|
||||
named_struct() / qn:qualified_identifier() { ExpressionKind::Value(qn) }
|
||||
qn:qualified_identifier() { ExpressionKind::Value(qn) }
|
||||
|
||||
rule named_struct() -> ExpressionKind =
|
||||
name:qualified_identifier() _ fields:record_block() {
|
||||
|
@ -152,13 +152,6 @@ macro_rules! assert_fail_expr2 {
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! assert_fail_expr {
|
||||
($input:expr, $failure:expr) => {
|
||||
let mut parser = make_parser($input);
|
||||
let err = parser.expression().unwrap_err();
|
||||
assert_eq!(err.msg, $failure);
|
||||
};
|
||||
}
|
||||
#[test]
|
||||
fn basic_literals() {
|
||||
use ExpressionKind::*;
|
||||
@ -250,15 +243,15 @@ fn operators() {
|
||||
fn accessors() {
|
||||
use ExpressionKind::*;
|
||||
|
||||
assert_expr!("a.b", expr(Access { name: rc("b"), expr: bx(expr(Value(qn!(a)))) }));
|
||||
assert_expr!(
|
||||
assert_expr2!("a.b", expr(Access { name: rc("b"), expr: bx(expr(Value(qn!(a)))) }));
|
||||
assert_expr2!(
|
||||
"a.b.c",
|
||||
expr(Access {
|
||||
name: rc("c"),
|
||||
expr: bx(expr(Access { name: rc("b"), expr: bx(expr(Value(qn!(a)))) }))
|
||||
})
|
||||
);
|
||||
assert_expr!(
|
||||
assert_expr2!(
|
||||
"a.b.c(3)",
|
||||
expr(Call {
|
||||
f: bx(expr(Access {
|
||||
@ -268,7 +261,7 @@ fn accessors() {
|
||||
arguments: vec![InvocationArgument::Positional(expr(NatLiteral(3)))],
|
||||
})
|
||||
);
|
||||
assert_expr!(
|
||||
assert_expr2!(
|
||||
"a.b().c",
|
||||
expr(Access {
|
||||
name: rc("c"),
|
||||
@ -307,7 +300,7 @@ fn identifiers() {
|
||||
assert_expr2!("alpha::beta::gamma", expr(Value(qn!(alpha, beta, gamma))));
|
||||
assert_expr2!("a + b", binop("+", expr(Value(qn!(a))), expr(Value(qn!(b)))));
|
||||
assert_expr2!("None", expr(Value(qn!(None))));
|
||||
assert_expr!(
|
||||
assert_expr2!(
|
||||
"thing::item::call()",
|
||||
expr(Call { f: bx(expr(Value(qn!(thing, item, call)))), arguments: vec![] })
|
||||
);
|
||||
@ -335,14 +328,24 @@ fn named_struct() {
|
||||
#[test]
|
||||
fn index() {
|
||||
use ExpressionKind::*;
|
||||
assert_expr!(
|
||||
"a[b,c]",
|
||||
assert_expr2!(
|
||||
"armok[b,c]",
|
||||
expr(Index {
|
||||
indexee: bx(expr(Value(qn!(a)))),
|
||||
indexee: bx(expr(Value(qn!(armok)))),
|
||||
indexers: vec![expr(Value(qn!(b))), expr(Value(qn!(c)))]
|
||||
})
|
||||
);
|
||||
assert_expr!(
|
||||
assert_expr2!(
|
||||
"a[b,c][1]",
|
||||
expr(Index {
|
||||
indexee: bx(expr(Index {
|
||||
indexee: bx(expr(Value(qn!(a)))),
|
||||
indexers: vec![expr(Value(qn!(b))), expr(Value(qn!(c)))]
|
||||
})),
|
||||
indexers: vec![expr(NatLiteral(1))]
|
||||
})
|
||||
);
|
||||
assert_expr2!(
|
||||
"perspicacity()[a]",
|
||||
expr(Index {
|
||||
indexee: bx(expr(Call { f: bx(expr(Value(qn!(perspicacity)))), arguments: vec![] })),
|
||||
@ -354,9 +357,9 @@ fn index() {
|
||||
let b = expr(Index { indexee: bx(a), indexers: vec![expr(Value(qn!(b)))] });
|
||||
let c = expr(Call { f: bx(b), arguments: vec![] });
|
||||
let d = expr(Index { indexee: bx(c), indexers: vec![expr(Value(qn!(d)))] });
|
||||
assert_expr!("a()[b]()[d]", d);
|
||||
assert_expr2!("a()[b]()[d]", d);
|
||||
|
||||
assert_fail_expr!("a[]", "Empty index expressions are not allowed");
|
||||
assert_fail_expr2!("a[]", "Empty index expressions are not allowed");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
Loading…
Reference in New Issue
Block a user