Paramaterize struct-related functions

This commit is contained in:
Greg Shuflin 2021-11-05 03:16:44 -07:00
parent 8aa306746a
commit 4ec2585d25

View File

@ -25,31 +25,22 @@ peg::parser! {
_ kind:expression_kind() { Expression { id: Default::default(), type_anno: None, kind: kind } } _ kind:expression_kind() { Expression { id: Default::default(), type_anno: None, kind: kind } }
rule expression_kind() -> ExpressionKind = rule expression_kind() -> ExpressionKind =
precedence_expr() precedence_expr(true)
rule expression_kind_no_struct() -> ExpressionKind = rule expression_kind_no_struct() -> ExpressionKind =
precedence_expr_no_struct() precedence_expr(false)
rule precedence_expr() -> ExpressionKind = rule precedence_expr(struct_ok: bool) -> ExpressionKind =
first:prefix_expr() _ next:(precedence_continuation())* { first:prefix_expr(struct_ok) _ next:(precedence_continuation(struct_ok))* {
let next = next.into_iter().map(|(sigil, expr)| (BinOp::from_sigil(sigil), expr)).collect(); let next = next.into_iter().map(|(sigil, expr)| (BinOp::from_sigil(sigil), expr)).collect();
BinopSequence { first, next }.do_precedence() BinopSequence { first, next }.do_precedence()
} }
rule precedence_continuation() -> (&'input str, ExpressionKind) = rule precedence_continuation(struct_ok: bool) -> (&'input str, ExpressionKind) =
op:operator() _ expr:prefix_expr() _ { (op, expr) } op:operator() _ expr:prefix_expr(struct_ok) _ { (op, expr) }
rule precedence_expr_no_struct() -> ExpressionKind = rule prefix_expr(struct_ok: bool) -> ExpressionKind =
first:prefix_expr() _ next:(precedence_continuation_no_struct())* { prefix:prefix()? expr:extended_expr(struct_ok) {
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 { if let Some(p) = prefix {
let expr = Expression::new(Default::default(), expr); let expr = Expression::new(Default::default(), expr);
let prefix = PrefixOp::from_sigil(p); let prefix = PrefixOp::from_sigil(p);
@ -59,16 +50,6 @@ 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 = rule prefix() -> &'input str =
$(['+' | '-' | '!' ]) $(['+' | '-' | '!' ])
@ -78,47 +59,52 @@ peg::parser! {
quiet!{$( ['+' | '-' | '*' | '/' | '%' | '<' | '>' | '=' | '!' | '$' | '&' | '|' | '?' | '^' | '`']+ )} / quiet!{$( ['+' | '-' | '*' | '/' | '%' | '<' | '>' | '=' | '!' | '$' | '&' | '|' | '?' | '^' | '`']+ )} /
expected!("operator") expected!("operator")
rule extended_expr(struct_ok: bool) -> ExpressionKind =
item:extended_expr_ok_struct() {? if struct_ok { Ok(item) } else { Err("no-struct-allowed") } } /
item:extended_expr_no_struct() {? if !struct_ok { Ok(item) } else { Err("!no-struct-allowed") } }
#[cache_left_rec] #[cache_left_rec]
rule extended_expr() -> ExpressionKind = rule extended_expr_ok_struct() -> ExpressionKind =
indexee:extended_expr() indexers:index_part() { indexee:extended_expr_ok_struct() indexers:index_part() {
ExpressionKind::Index { ExpressionKind::Index {
indexee: Box::new(Expression::new(Default::default(), indexee)), indexee: Box::new(Expression::new(Default::default(), indexee)),
indexers, indexers,
} }
} / } /
f:extended_expr() arguments:call_part() { f:extended_expr_ok_struct() arguments:call_part() {
ExpressionKind::Call { ExpressionKind::Call {
f: Box::new(Expression::new(Default::default(), f)), f: Box::new(Expression::new(Default::default(), f)),
arguments, arguments,
} }
} / } /
expr:extended_expr() "." name:identifier() { ExpressionKind::Access { expr:extended_expr_ok_struct() "." name:identifier() { ExpressionKind::Access {
name: Rc::new(name.to_string()), name: Rc::new(name.to_string()),
expr: Box::new(Expression::new(Default::default(),expr)), expr: Box::new(Expression::new(Default::default(),expr)),
} } / } } /
primary() primary(true)
#[cache_left_rec] #[cache_left_rec]
rule extended_expr_no_struct() -> ExpressionKind = rule extended_expr_no_struct() -> ExpressionKind =
indexee:extended_expr() indexers:index_part() { indexee:extended_expr_no_struct() indexers:index_part() {
ExpressionKind::Index { ExpressionKind::Index {
indexee: Box::new(Expression::new(Default::default(), indexee)), indexee: Box::new(Expression::new(Default::default(), indexee)),
indexers, indexers,
} }
} / } /
f:extended_expr() arguments:call_part() { f:extended_expr_no_struct() arguments:call_part() {
ExpressionKind::Call { ExpressionKind::Call {
f: Box::new(Expression::new(Default::default(), f)), f: Box::new(Expression::new(Default::default(), f)),
arguments, arguments,
} }
} / } /
expr:extended_expr() "." name:identifier() { ExpressionKind::Access { expr:extended_expr_no_struct() "." name:identifier() { ExpressionKind::Access {
name: Rc::new(name.to_string()), name: Rc::new(name.to_string()),
expr: Box::new(Expression::new(Default::default(),expr)), expr: Box::new(Expression::new(Default::default(),expr)),
} } / } } /
primary_no_struct() primary(false)
rule index_part() -> Vec<Expression> = rule index_part() -> Vec<Expression> =
"[" indexers:(expression() ++ ",") "]" { indexers } "[" indexers:(expression() ++ ",") "]" { indexers }
@ -136,13 +122,11 @@ peg::parser! {
_ expr:expression() _ { InvocationArgument::Positional(expr) } _ expr:expression() _ { InvocationArgument::Positional(expr) }
rule primary_no_struct() -> ExpressionKind = rule primary(struct_ok: bool) -> ExpressionKind =
while_expr() / 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() / identifier_expr() list_expr() / if_expr() /
item:named_struct() {? if struct_ok { Ok(item) } else { Err("no-struct-allowed") } } /
rule primary() -> ExpressionKind = identifier_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 = rule while_expr() -> ExpressionKind =
"while" _ cond:expression_kind_no_struct()? _ body:block() { "while" _ cond:expression_kind_no_struct()? _ body:block() {