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]]
|
[[package]]
|
||||||
name = "peg"
|
name = "peg"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/kevinmehall/rust-peg?rev=960222580c8da25b17d32c2aae6f52f902728b62#960222580c8da25b17d32c2aae6f52f902728b62"
|
||||||
checksum = "07c0b841ea54f523f7aa556956fbd293bcbe06f2e67d2eb732b7278aaf1d166a"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"peg-macros",
|
"peg-macros",
|
||||||
"peg-runtime",
|
"peg-runtime",
|
||||||
@ -571,8 +570,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "peg-macros"
|
name = "peg-macros"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/kevinmehall/rust-peg?rev=960222580c8da25b17d32c2aae6f52f902728b62#960222580c8da25b17d32c2aae6f52f902728b62"
|
||||||
checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"peg-runtime",
|
"peg-runtime",
|
||||||
"proc-macro2 1.0.30",
|
"proc-macro2 1.0.30",
|
||||||
@ -582,8 +580,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "peg-runtime"
|
name = "peg-runtime"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/kevinmehall/rust-peg?rev=960222580c8da25b17d32c2aae6f52f902728b62#960222580c8da25b17d32c2aae6f52f902728b62"
|
||||||
checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "phf"
|
name = "phf"
|
||||||
|
@ -14,7 +14,9 @@ derivative = "1.0.3"
|
|||||||
colored = "1.8"
|
colored = "1.8"
|
||||||
radix_trie = "0.1.5"
|
radix_trie = "0.1.5"
|
||||||
assert_matches = "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-lang-codegen = { path = "../codegen" }
|
||||||
schala-repl = { path = "../../schala-repl" }
|
schala-repl = { path = "../../schala-repl" }
|
||||||
|
@ -7,7 +7,7 @@ peg::parser! {
|
|||||||
|
|
||||||
rule whitespace() = [' ' | '\t' | '\n']*
|
rule whitespace() = [' ' | '\t' | '\n']*
|
||||||
|
|
||||||
rule _ = quiet!{ whitespace() }
|
rule _ = quiet!{ whitespace() }
|
||||||
|
|
||||||
pub rule program() -> AST =
|
pub rule program() -> AST =
|
||||||
n:(statement() ** delimiter() ) { AST { id: Default::default(), statements: n.into() } }
|
n:(statement() ** delimiter() ) { AST { id: Default::default(), statements: n.into() } }
|
||||||
@ -55,15 +55,49 @@ peg::parser! {
|
|||||||
quiet!{$( ['+' | '-' | '*' | '/' | '%' | '<' | '>' | '=' | '!' | '$' | '&' | '|' | '?' | '^' | '`']+ )} /
|
quiet!{$( ['+' | '-' | '*' | '/' | '%' | '<' | '>' | '=' | '!' | '$' | '&' | '|' | '?' | '^' | '`']+ )} /
|
||||||
expected!("operator")
|
expected!("operator")
|
||||||
|
|
||||||
|
#[cache_left_rec]
|
||||||
rule extended_expr() -> ExpressionKind =
|
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()
|
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 =
|
rule primary() -> ExpressionKind =
|
||||||
float_literal() / nat_literal() / bool_literal() / string_literal() / paren_expr() /
|
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 =
|
rule identifier_expr() -> ExpressionKind =
|
||||||
named_struct() / qn:qualified_identifier() { ExpressionKind::Value(qn) }
|
qn:qualified_identifier() { ExpressionKind::Value(qn) }
|
||||||
|
|
||||||
rule named_struct() -> ExpressionKind =
|
rule named_struct() -> ExpressionKind =
|
||||||
name:qualified_identifier() _ fields:record_block() {
|
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]
|
#[test]
|
||||||
fn basic_literals() {
|
fn basic_literals() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
@ -250,15 +243,15 @@ fn operators() {
|
|||||||
fn accessors() {
|
fn accessors() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
assert_expr!("a.b", expr(Access { name: rc("b"), expr: bx(expr(Value(qn!(a)))) }));
|
assert_expr2!("a.b", expr(Access { name: rc("b"), expr: bx(expr(Value(qn!(a)))) }));
|
||||||
assert_expr!(
|
assert_expr2!(
|
||||||
"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!(
|
assert_expr2!(
|
||||||
"a.b.c(3)",
|
"a.b.c(3)",
|
||||||
expr(Call {
|
expr(Call {
|
||||||
f: bx(expr(Access {
|
f: bx(expr(Access {
|
||||||
@ -268,7 +261,7 @@ fn accessors() {
|
|||||||
arguments: vec![InvocationArgument::Positional(expr(NatLiteral(3)))],
|
arguments: vec![InvocationArgument::Positional(expr(NatLiteral(3)))],
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
assert_expr!(
|
assert_expr2!(
|
||||||
"a.b().c",
|
"a.b().c",
|
||||||
expr(Access {
|
expr(Access {
|
||||||
name: rc("c"),
|
name: rc("c"),
|
||||||
@ -307,7 +300,7 @@ fn identifiers() {
|
|||||||
assert_expr2!("alpha::beta::gamma", expr(Value(qn!(alpha, beta, gamma))));
|
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!("a + b", binop("+", expr(Value(qn!(a))), expr(Value(qn!(b)))));
|
||||||
assert_expr2!("None", expr(Value(qn!(None))));
|
assert_expr2!("None", expr(Value(qn!(None))));
|
||||||
assert_expr!(
|
assert_expr2!(
|
||||||
"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![] })
|
||||||
);
|
);
|
||||||
@ -335,14 +328,24 @@ fn named_struct() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn index() {
|
fn index() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
assert_expr!(
|
assert_expr2!(
|
||||||
"a[b,c]",
|
"armok[b,c]",
|
||||||
expr(Index {
|
expr(Index {
|
||||||
indexee: bx(expr(Value(qn!(a)))),
|
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!(
|
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]",
|
"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![] })),
|
||||||
@ -354,9 +357,9 @@ 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!("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]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user