Skip to content
Snippets Groups Projects
Verified Commit b5a9dad9 authored by Louis's avatar Louis :fire:
Browse files

Support empty conditionals, assignment, variable declarations, ident-as-value

parent 850e7e89
No related branches found
No related tags found
No related merge requests found
Pipeline #486 passed with stages
in 1 minute and 7 seconds
...@@ -18,7 +18,18 @@ pub struct ExpressionList { ...@@ -18,7 +18,18 @@ pub struct ExpressionList {
pub expressions: Vec<Expression>, pub expressions: Vec<Expression>,
pub is_void: bool, pub is_void: bool,
} }
impl Default for ExpressionList {
fn default() -> Self {
ExpressionList::empty()
}
}
impl ExpressionList { impl ExpressionList {
pub fn empty() -> Self {
ExpressionList {
expressions: Vec::new(),
is_void: true,
}
}
pub fn production(expressions: Vec<Expression>) -> Self { pub fn production(expressions: Vec<Expression>) -> Self {
ExpressionList { ExpressionList {
expressions, expressions,
...@@ -155,6 +166,7 @@ pub enum ValueExpression { ...@@ -155,6 +166,7 @@ pub enum ValueExpression {
DeclareIdentifier(DeclareIdent), DeclareIdentifier(DeclareIdent),
Assignment(Assignment), Assignment(Assignment),
ConditionalBlock(Conditional), ConditionalBlock(Conditional),
Identifier(Identifier),
} }
#[derive(Clone)] #[derive(Clone)]
......
...@@ -29,19 +29,26 @@ peg::parser! { ...@@ -29,19 +29,26 @@ peg::parser! {
rule value_expression() -> ValueExpression rule value_expression() -> ValueExpression
= "(" ex:value_expression() ")" { ValueExpression::Grouped(GroupedExpression { inner: Box::new(ex) }) } = "(" ex:value_expression() ")" { ValueExpression::Grouped(GroupedExpression { inner: Box::new(ex) }) }
/ co:conditional() { ValueExpression::ConditionalBlock(co) } / co:conditional() { ValueExpression::ConditionalBlock(co) }
/ decl:declare_variable() { ValueExpression::DeclareIdentifier(decl) }
/ left:value_expression() op:binary_operator() right:value_expression() / left:value_expression() op:binary_operator() right:value_expression()
{ ValueExpression::Binary { lhs: Box::new(left), rhs: Box::new(right), operator: op } } { ValueExpression::Binary { lhs: Box::new(left), rhs: Box::new(right), operator: op } }
/ op:unary_operator() operand:value_expression() / op:unary_operator() operand:value_expression()
{ ValueExpression::Unary { operator: op, operand: Box::new(operand) } } { ValueExpression::Unary { operator: op, operand: Box::new(operand) } }
/ ident:bare_identifier() { ValueExpression::Identifier(ident) }
/ li:literal() { ValueExpression::Literal(li) } / li:literal() { ValueExpression::Literal(li) }
rule print() -> Print rule print() -> Print
= "print" ex:value_expression() { ex.into() } = "print" ex:value_expression() { ex.into() }
rule declare_variable() -> DeclareIdent
= "let" assign:assignment() { DeclareIdent::WithValue(assign) }
/ "let" ident:bare_identifier() { DeclareIdent::WithoutValue(ident) }
rule condition_loop() -> ConditionalLoop rule condition_loop() -> ConditionalLoop
= "while" guard:value_expression() "{" block:expression_list() "}" { ConditionalLoop { block: GuardedBlock { guard: Box::new(guard), block}, fallback: None } } = "while" guard:value_expression() "{" block:expression_list()? "}"
/ "while" guard:value_expression() "{" block:expression_list() "}" "else" "{" fallback:expression_list() "}" { ConditionalLoop { block: GuardedBlock { guard: Box::new(guard), block: block.unwrap_or_default() }, fallback: None } }
{ ConditionalLoop { block: GuardedBlock { guard: Box::new(guard), block}, fallback: Some(fallback) } } / "while" guard:value_expression() "{" block:expression_list()? "}" "else" "{" fallback:expression_list()? "}"
{ ConditionalLoop { block: GuardedBlock { guard: Box::new(guard), block: block.unwrap_or_default() }, fallback } }
rule conditional() -> Conditional rule conditional() -> Conditional
// = bl:guarded_block() { Conditional { fallback: None, blocks: vec![bl] } } // = bl:guarded_block() { Conditional { fallback: None, blocks: vec![bl] } }
...@@ -54,8 +61,11 @@ peg::parser! { ...@@ -54,8 +61,11 @@ peg::parser! {
/ blocks:(guarded_block() ++ "else") { Conditional { fallback: None, blocks, } } / blocks:(guarded_block() ++ "else") { Conditional { fallback: None, blocks, } }
rule guarded_block() -> GuardedBlock rule guarded_block() -> GuardedBlock
= "if" guard:value_expression() "{" block:expression_list() "}" = "if" guard:value_expression() "{" block:expression_list()? "}"
{ GuardedBlock { block, guard: Box::new(guard) } } { GuardedBlock { block: block.unwrap_or_default(), guard: Box::new(guard) } }
rule assignment() -> Assignment
= ident:bare_identifier() "=" expr:value_expression() { Assignment { ident, value: Box::new(expr) } }
rule binary_operator() -> BinaryOp rule binary_operator() -> BinaryOp
= "+" { BinaryOp::Add } = "+" { BinaryOp::Add }
......
...@@ -140,6 +140,9 @@ impl Visitor for TreePrinter { ...@@ -140,6 +140,9 @@ impl Visitor for TreePrinter {
self.evaluate_value_expression(inner.as_ref()); self.evaluate_value_expression(inner.as_ref());
self.write(")"); self.write(")");
} }
ValueExpression::Identifier(ident) => {
self.write(ident);
}
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment