Parse while expressions
Decided to add while expressions to the language to make for-parsing easier. Plus some other random notes
This commit is contained in:
parent
24b532df06
commit
532c8c45b4
@ -56,7 +56,7 @@ prefix_expr := prefix_op call_expr
|
|||||||
prefix_op := '+' | '-' | '!' | '~'
|
prefix_op := '+' | '-' | '!' | '~'
|
||||||
call_expr := index_expr ( '(' expr_list ')' )*
|
call_expr := index_expr ( '(' expr_list ')' )*
|
||||||
index_expr := primary ( '[' (expression (',' (expression)* | ε) ']' )*
|
index_expr := primary ( '[' (expression (',' (expression)* | ε) ']' )*
|
||||||
primary := literal | paren_expr | if_expr | match_expr | for_expr | identifier_expr | curly_brace_expr | list_expr
|
primary := literal | paren_expr | if_expr | match_expr | for_expr | while_expr | identifier_expr | curly_brace_expr | list_expr
|
||||||
curly_brace_expr := lambda_expr | anonymous_struct //TODO
|
curly_brace_expr := lambda_expr | anonymous_struct //TODO
|
||||||
list_expr := '[' (expression, ',')* ']'
|
list_expr := '[' (expression, ',')* ']'
|
||||||
lambda_expr := '{' '|' (formal_param ',')* '|' (type_anno)* (statement)* '}'
|
lambda_expr := '{' '|' (formal_param ',')* '|' (type_anno)* (statement)* '}'
|
||||||
@ -83,7 +83,14 @@ block := '{' (statement)* '}'
|
|||||||
|
|
||||||
expr_list := expression (',' expression)* | ε
|
expr_list := expression (',' expression)* | ε
|
||||||
|
|
||||||
for_expr := 'for' ... ????
|
while_expr := 'while' while_cond '{' (statement)* '}'
|
||||||
|
while_cond := ε | expression | expression 'is' pattern //TODO maybe is-expresions should be primary
|
||||||
|
|
||||||
|
for_expr := 'for' (enumerator | '{' enumerators '}') for_expr_body
|
||||||
|
for_expr_body := expression | 'return' expression | '{' (expression)* '}
|
||||||
|
enumerators := enumerator (',' enumerators)*
|
||||||
|
enumerator := ??? //TODO flesh this out
|
||||||
|
|
||||||
|
|
||||||
// a float_literal can still be assigned to an int in type-checking
|
// a float_literal can still be assigned to an int in type-checking
|
||||||
number_literal := int_literal | float_literal
|
number_literal := int_literal | float_literal
|
||||||
@ -253,7 +260,13 @@ pub enum ExpressionType {
|
|||||||
},
|
},
|
||||||
IfExpression(Box<Expression>, Block, Option<Block>),
|
IfExpression(Box<Expression>, Block, Option<Block>),
|
||||||
MatchExpression(Box<Expression>, Vec<MatchArm>),
|
MatchExpression(Box<Expression>, Vec<MatchArm>),
|
||||||
ForExpression,
|
WhileExpression {
|
||||||
|
condition: Option<Box<Expression>>,
|
||||||
|
body: Block,
|
||||||
|
},
|
||||||
|
ForExpression {
|
||||||
|
|
||||||
|
},
|
||||||
Lambda {
|
Lambda {
|
||||||
params: Vec<FormalParam>,
|
params: Vec<FormalParam>,
|
||||||
body: Block,
|
body: Block,
|
||||||
@ -621,6 +634,7 @@ impl Parser {
|
|||||||
Keyword(Kw::If) => self.if_expr(),
|
Keyword(Kw::If) => self.if_expr(),
|
||||||
Keyword(Kw::Match) => self.match_expr(),
|
Keyword(Kw::Match) => self.match_expr(),
|
||||||
Keyword(Kw::For) => self.for_expr(),
|
Keyword(Kw::For) => self.for_expr(),
|
||||||
|
Keyword(Kw::While) => self.while_expr(),
|
||||||
Identifier(_) => self.identifier_expr(),
|
Identifier(_) => self.identifier_expr(),
|
||||||
_ => self.literal(),
|
_ => self.literal(),
|
||||||
}
|
}
|
||||||
@ -744,9 +758,29 @@ impl Parser {
|
|||||||
Ok(Pattern(identifier))
|
Ok(Pattern(identifier))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
parse_method!(while_expr(&mut self) -> ParseResult<Expression> {
|
||||||
|
use self::ExpressionType::*;
|
||||||
|
expect!(self, Keyword(Kw::While), "'while'");
|
||||||
|
let condition = {
|
||||||
|
self.restrictions.no_struct_literal = true;
|
||||||
|
let x = self.while_cond();
|
||||||
|
self.restrictions.no_struct_literal = false;
|
||||||
|
x?.map(|expr| bx!(expr))
|
||||||
|
};
|
||||||
|
let body = self.block()?;
|
||||||
|
Ok(Expression(WhileExpression {condition, body}, None))
|
||||||
|
});
|
||||||
|
|
||||||
|
parse_method!(while_cond(&mut self) -> ParseResult<Option<Expression>> {
|
||||||
|
Ok(match self.peek() {
|
||||||
|
LCurlyBrace => None,
|
||||||
|
_ => Some(self.expression()?),
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
parse_method!(for_expr(&mut self) -> ParseResult<Expression> {
|
parse_method!(for_expr(&mut self) -> ParseResult<Expression> {
|
||||||
expect!(self, Keyword(Kw::For), "'for'");
|
expect!(self, Keyword(Kw::For), "'for'");
|
||||||
Ok(Expression(ExpressionType::ForExpression, None))
|
Ok(Expression(ExpressionType::ForExpression { }, None))
|
||||||
});
|
});
|
||||||
|
|
||||||
parse_method!(identifier(&mut self) -> ParseResult<Rc<String>> {
|
parse_method!(identifier(&mut self) -> ParseResult<Rc<String>> {
|
||||||
@ -1236,4 +1270,17 @@ fn a(x) {
|
|||||||
exprstatement!(ListLiteral(vec![ex!(NatLiteral(1)), ex!(NatLiteral(2))]))])
|
exprstatement!(ListLiteral(vec![ex!(NatLiteral(1)), ex!(NatLiteral(2))]))])
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn while_expr() {
|
||||||
|
parse_test! {
|
||||||
|
"while { }", AST(vec![
|
||||||
|
exprstatement!(WhileExpression { condition: None, body: vec![] })])
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_test! {
|
||||||
|
"while a == b { }", AST(vec![
|
||||||
|
exprstatement!(WhileExpression { condition: Some(bx![ex![binexp!("==", val!("a"), val!("b"))]]), body: vec![] })])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ impl fmt::Display for TokenType {
|
|||||||
pub enum Kw {
|
pub enum Kw {
|
||||||
If, Else,
|
If, Else,
|
||||||
Func,
|
Func,
|
||||||
For,
|
For, While,
|
||||||
Match,
|
Match,
|
||||||
Var, Const, Let, In,
|
Var, Const, Let, In,
|
||||||
Return,
|
Return,
|
||||||
@ -64,6 +64,7 @@ lazy_static! {
|
|||||||
"else" => Kw::Else,
|
"else" => Kw::Else,
|
||||||
"fn" => Kw::Func,
|
"fn" => Kw::Func,
|
||||||
"for" => Kw::For,
|
"for" => Kw::For,
|
||||||
|
"while" => Kw::While,
|
||||||
"match" => Kw::Match,
|
"match" => Kw::Match,
|
||||||
"var" => Kw::Var,
|
"var" => Kw::Var,
|
||||||
"const" => Kw::Const,
|
"const" => Kw::Const,
|
||||||
|
@ -35,19 +35,26 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for {
|
/* for/while loop topics */
|
||||||
|
|
||||||
//infinite loop
|
//infinite loop
|
||||||
|
while {
|
||||||
|
if x() { break }
|
||||||
|
...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//conditional loop
|
||||||
|
while conditionHolds() {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//iteration over a variable
|
//iteration over a variable
|
||||||
for i <- [1..1000] {
|
for i <- [1..1000] {
|
||||||
|
|
||||||
} //return type is return type of block
|
} //return type is return type of block
|
||||||
|
|
||||||
//while loop
|
|
||||||
for a != 3 || fuckTard() {
|
|
||||||
break
|
|
||||||
} //return type is return type of block
|
|
||||||
|
|
||||||
//monadic decomposition
|
//monadic decomposition
|
||||||
for {
|
for {
|
||||||
@ -57,22 +64,24 @@ fn main() {
|
|||||||
a + s
|
a + s
|
||||||
} //return type is Monad<return type of block>
|
} //return type is Monad<return type of block>
|
||||||
|
|
||||||
// let statements too!!
|
/* end of for loops */
|
||||||
for (a = 20
|
|
||||||
b = fuck) {
|
|
||||||
a + b
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// pattern-matching
|
|
||||||
match <expr> {
|
|
||||||
Some(a) => {
|
|
||||||
|
|
||||||
|
/* conditionals/pattern matching */
|
||||||
|
|
||||||
|
// "is" operator for "does this pattern match"
|
||||||
|
|
||||||
|
x is Some(t) // type bool
|
||||||
|
|
||||||
|
if x {
|
||||||
|
is Some(t) => {
|
||||||
},
|
},
|
||||||
None => {
|
is None => {
|
||||||
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//syntax is, I guess, for <expr> <brace-block>, where <expr> is a bool, or a <arrow-expr>
|
//syntax is, I guess, for <expr> <brace-block>, where <expr> is a bool, or a <arrow-expr>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user