for expressions

This commit is contained in:
Greg Shuflin 2021-11-05 12:52:41 -07:00
parent 4ec2585d25
commit 87141fcca3
3 changed files with 33 additions and 6 deletions

View File

@ -262,7 +262,7 @@ pub enum PatternLiteral {
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct Enumerator { pub struct Enumerator {
pub id: Rc<String>, pub id: Rc<String>, //TODO rename this field
pub generator: Expression, pub generator: Expression,
} }

View File

@ -12,7 +12,7 @@ peg::parser! {
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() } }
rule delimiter() = ";" / "\n" rule delimiter() = (";" / "\n")+
rule statement() -> Statement = rule statement() -> Statement =
_ expr:expression() { Statement { _ expr:expression() { Statement {
@ -24,6 +24,9 @@ peg::parser! {
pub rule expression() -> Expression = pub rule expression() -> Expression =
_ kind:expression_kind() { Expression { id: Default::default(), type_anno: None, kind: kind } } _ 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 = rule expression_kind() -> ExpressionKind =
precedence_expr(true) precedence_expr(true)
@ -123,11 +126,34 @@ peg::parser! {
rule primary(struct_ok: bool) -> ExpressionKind = 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() / list_expr() / if_expr() /
item:named_struct() {? if struct_ok { Ok(item) } else { Err("no-struct-allowed") } } / item:named_struct() {? if struct_ok { Ok(item) } else { Err("no-struct-allowed") } } /
identifier_expr() 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 = rule while_expr() -> ExpressionKind =
"while" _ cond:expression_kind_no_struct()? _ body:block() { "while" _ cond:expression_kind_no_struct()? _ body:block() {
ExpressionKind::WhileExpression { ExpressionKind::WhileExpression {

View File

@ -379,7 +379,7 @@ fn while_expression() {
fn for_expression() { fn for_expression() {
use ExpressionKind::*; use ExpressionKind::*;
assert_expr!( assert_expr2!(
"for { a <- garodzny::maybeValue } return 1", "for { a <- garodzny::maybeValue } return 1",
expr(ForExpression { expr(ForExpression {
enumerators: vec![Enumerator { id: rc("a"), generator: expr(Value(qn!(garodzny, maybeValue))) }], enumerators: vec![Enumerator { id: rc("a"), generator: expr(Value(qn!(garodzny, maybeValue))) }],
@ -387,8 +387,9 @@ fn for_expression() {
}) })
); );
assert_expr!( assert_expr2!(
"for n <- someRange { f(n); }", //TODO make "for n <- someRange { f(n); }" work!!
"for n <- someRange { f(n) }",
expr(ForExpression { expr(ForExpression {
enumerators: vec![Enumerator { id: rc("n"), generator: expr(Value(qn!(someRange))) }], enumerators: vec![Enumerator { id: rc("n"), generator: expr(Value(qn!(someRange))) }],
body: bx(ForBody::StatementBlock( body: bx(ForBody::StatementBlock(