for expressions
This commit is contained in:
parent
4ec2585d25
commit
87141fcca3
@ -262,7 +262,7 @@ pub enum PatternLiteral {
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Enumerator {
|
||||
pub id: Rc<String>,
|
||||
pub id: Rc<String>, //TODO rename this field
|
||||
pub generator: Expression,
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ peg::parser! {
|
||||
pub rule program() -> AST =
|
||||
n:(statement() ** delimiter() ) { AST { id: Default::default(), statements: n.into() } }
|
||||
|
||||
rule delimiter() = ";" / "\n"
|
||||
rule delimiter() = (";" / "\n")+
|
||||
|
||||
rule statement() -> Statement =
|
||||
_ expr:expression() { Statement {
|
||||
@ -24,6 +24,9 @@ peg::parser! {
|
||||
pub rule expression() -> Expression =
|
||||
_ kind:expression_kind() { Expression { id: Default::default(), type_anno: None, kind: kind } }
|
||||
|
||||
pub rule expression_no_struct() -> Expression =
|
||||
_ kind:expression_kind_no_struct() { Expression { id: Default::default(), type_anno: None, kind: kind } }
|
||||
|
||||
rule expression_kind() -> ExpressionKind =
|
||||
precedence_expr(true)
|
||||
|
||||
@ -123,11 +126,34 @@ peg::parser! {
|
||||
|
||||
|
||||
rule primary(struct_ok: bool) -> ExpressionKind =
|
||||
while_expr() / float_literal() / nat_literal() / bool_literal() / string_literal() / paren_expr() /
|
||||
while_expr() / for_expr() / float_literal() / nat_literal() / bool_literal() / string_literal() / paren_expr() /
|
||||
list_expr() / if_expr() /
|
||||
item:named_struct() {? if struct_ok { Ok(item) } else { Err("no-struct-allowed") } } /
|
||||
identifier_expr()
|
||||
|
||||
rule for_expr() -> ExpressionKind =
|
||||
"for" _ enumerators:for_enumerators() _ body:for_body() {
|
||||
ExpressionKind::ForExpression { enumerators, body }
|
||||
}
|
||||
|
||||
rule for_enumerators() -> Vec<Enumerator> =
|
||||
"{" _ enumerators:(enumerator() ++ ",") _ "}" { enumerators } /
|
||||
enumerator:enumerator() { vec![enumerator] }
|
||||
|
||||
//TODO add guards, etc.
|
||||
rule enumerator() -> Enumerator =
|
||||
ident:identifier() _ "<-" _ generator:expression_no_struct() {
|
||||
Enumerator { id: Rc::new(ident.to_string()), generator }
|
||||
} /
|
||||
//TODO need to distinguish these two cases in AST
|
||||
ident:identifier() _ "=" _ generator:expression_no_struct() {
|
||||
Enumerator { id: Rc::new(ident.to_string()), generator }
|
||||
}
|
||||
|
||||
rule for_body() -> Box<ForBody> =
|
||||
"return" _ expr:expression() { Box::new(ForBody::MonadicReturn(expr)) } /
|
||||
body:block() { Box::new(ForBody::StatementBlock(body)) }
|
||||
|
||||
rule while_expr() -> ExpressionKind =
|
||||
"while" _ cond:expression_kind_no_struct()? _ body:block() {
|
||||
ExpressionKind::WhileExpression {
|
||||
|
@ -379,7 +379,7 @@ fn while_expression() {
|
||||
fn for_expression() {
|
||||
use ExpressionKind::*;
|
||||
|
||||
assert_expr!(
|
||||
assert_expr2!(
|
||||
"for { a <- garodzny::maybeValue } return 1",
|
||||
expr(ForExpression {
|
||||
enumerators: vec![Enumerator { id: rc("a"), generator: expr(Value(qn!(garodzny, maybeValue))) }],
|
||||
@ -387,8 +387,9 @@ fn for_expression() {
|
||||
})
|
||||
);
|
||||
|
||||
assert_expr!(
|
||||
"for n <- someRange { f(n); }",
|
||||
assert_expr2!(
|
||||
//TODO make "for n <- someRange { f(n); }" work!!
|
||||
"for n <- someRange { f(n) }",
|
||||
expr(ForExpression {
|
||||
enumerators: vec![Enumerator { id: rc("n"), generator: expr(Value(qn!(someRange))) }],
|
||||
body: bx(ForBody::StatementBlock(
|
||||
|
Loading…
Reference in New Issue
Block a user