While-parsing passing
Albeit with a lot of code duplication
This commit is contained in:
parent
4f3ef5c850
commit
8aa306746a
@ -19,7 +19,7 @@ peg::parser! {
|
||||
id: Default::default(), location: Default::default(), kind: StatementKind::Expression(expr) }
|
||||
}
|
||||
|
||||
rule block() -> Block = "{" items:(statement() ** delimiter()) "}" { items.into() }
|
||||
rule block() -> Block = "{" _ items:(statement() ** delimiter()) _ "}" { items.into() }
|
||||
|
||||
pub rule expression() -> Expression =
|
||||
_ kind:expression_kind() { Expression { id: Default::default(), type_anno: None, kind: kind } }
|
||||
@ -27,6 +27,9 @@ peg::parser! {
|
||||
rule expression_kind() -> ExpressionKind =
|
||||
precedence_expr()
|
||||
|
||||
rule expression_kind_no_struct() -> ExpressionKind =
|
||||
precedence_expr_no_struct()
|
||||
|
||||
rule precedence_expr() -> ExpressionKind =
|
||||
first:prefix_expr() _ next:(precedence_continuation())* {
|
||||
let next = next.into_iter().map(|(sigil, expr)| (BinOp::from_sigil(sigil), expr)).collect();
|
||||
@ -36,6 +39,15 @@ peg::parser! {
|
||||
rule precedence_continuation() -> (&'input str, ExpressionKind) =
|
||||
op:operator() _ expr:prefix_expr() _ { (op, expr) }
|
||||
|
||||
rule precedence_expr_no_struct() -> ExpressionKind =
|
||||
first:prefix_expr() _ next:(precedence_continuation_no_struct())* {
|
||||
let next = next.into_iter().map(|(sigil, expr)| (BinOp::from_sigil(sigil), expr)).collect();
|
||||
BinopSequence { first, next }.do_precedence()
|
||||
}
|
||||
|
||||
rule precedence_continuation_no_struct() -> (&'input str, ExpressionKind) =
|
||||
op:operator() _ expr:prefix_expr_no_struct() _ { (op, expr) }
|
||||
|
||||
rule prefix_expr() -> ExpressionKind =
|
||||
prefix:prefix()? expr:extended_expr() {
|
||||
if let Some(p) = prefix {
|
||||
@ -47,6 +59,17 @@ peg::parser! {
|
||||
}
|
||||
}
|
||||
|
||||
rule prefix_expr_no_struct() -> ExpressionKind =
|
||||
prefix:prefix()? expr:extended_expr_no_struct() {
|
||||
if let Some(p) = prefix {
|
||||
let expr = Expression::new(Default::default(), expr);
|
||||
let prefix = PrefixOp::from_sigil(p);
|
||||
ExpressionKind::PrefixExp(prefix, Box::new(expr))
|
||||
} else {
|
||||
expr
|
||||
}
|
||||
}
|
||||
|
||||
rule prefix() -> &'input str =
|
||||
$(['+' | '-' | '!' ])
|
||||
|
||||
@ -76,6 +99,27 @@ peg::parser! {
|
||||
} } /
|
||||
primary()
|
||||
|
||||
#[cache_left_rec]
|
||||
rule extended_expr_no_struct() -> 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_no_struct()
|
||||
|
||||
rule index_part() -> Vec<Expression> =
|
||||
"[" indexers:(expression() ++ ",") "]" { indexers }
|
||||
|
||||
@ -92,10 +136,23 @@ peg::parser! {
|
||||
_ expr:expression() _ { InvocationArgument::Positional(expr) }
|
||||
|
||||
|
||||
rule primary_no_struct() -> ExpressionKind =
|
||||
while_expr() / float_literal() / nat_literal() / bool_literal() / string_literal() / paren_expr() /
|
||||
list_expr() / if_expr() / identifier_expr()
|
||||
|
||||
rule primary() -> ExpressionKind =
|
||||
float_literal() / nat_literal() / bool_literal() / string_literal() / paren_expr() /
|
||||
while_expr() / float_literal() / nat_literal() / bool_literal() / string_literal() / paren_expr() /
|
||||
list_expr() / if_expr() / named_struct() / identifier_expr()
|
||||
|
||||
rule while_expr() -> ExpressionKind =
|
||||
"while" _ cond:expression_kind_no_struct()? _ body:block() {
|
||||
ExpressionKind::WhileExpression {
|
||||
condition: cond.map(|kind| Box::new(Expression::new(Default::default(), kind))),
|
||||
body,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
rule identifier_expr() -> ExpressionKind =
|
||||
qn:qualified_identifier() { ExpressionKind::Value(qn) }
|
||||
|
||||
|
@ -365,8 +365,8 @@ fn index() {
|
||||
fn while_expression() {
|
||||
use ExpressionKind::*;
|
||||
|
||||
assert_expr!("while { }", expr(WhileExpression { condition: None, body: Block::default() }));
|
||||
assert_expr!(
|
||||
assert_expr2!("while { }", expr(WhileExpression { condition: None, body: Block::default() }));
|
||||
assert_expr2!(
|
||||
"while a == b { }",
|
||||
expr(WhileExpression {
|
||||
condition: Some(bx(binop("==", expr(Value(qn!(a))), expr(Value(qn!(b)))))),
|
||||
|
Loading…
Reference in New Issue
Block a user