diff --git a/forge-script-lang/src/parser/ast.rs b/forge-script-lang/src/parser/ast.rs index f6b8f55a6f2a9585ba75ed2fe5f62f2d4b1f78b4..739cacb5a1623d5bad9ec1259b199233bff32121 100644 --- a/forge-script-lang/src/parser/ast.rs +++ b/forge-script-lang/src/parser/ast.rs @@ -18,7 +18,18 @@ pub struct ExpressionList { pub expressions: Vec<Expression>, pub is_void: bool, } +impl Default for ExpressionList { + fn default() -> Self { + ExpressionList::empty() + } +} impl ExpressionList { + pub fn empty() -> Self { + ExpressionList { + expressions: Vec::new(), + is_void: true, + } + } pub fn production(expressions: Vec<Expression>) -> Self { ExpressionList { expressions, @@ -155,6 +166,7 @@ pub enum ValueExpression { DeclareIdentifier(DeclareIdent), Assignment(Assignment), ConditionalBlock(Conditional), + Identifier(Identifier), } #[derive(Clone)] diff --git a/forge-script-lang/src/parser/grammar.rs b/forge-script-lang/src/parser/grammar.rs index 9e5fdba9edf985b955e350650ac2b22bf7ce71ba..30cbd86d5a05a3d9b0c3de6889a6aff7a2a73c78 100644 --- a/forge-script-lang/src/parser/grammar.rs +++ b/forge-script-lang/src/parser/grammar.rs @@ -29,19 +29,26 @@ peg::parser! { rule value_expression() -> ValueExpression = "(" ex:value_expression() ")" { ValueExpression::Grouped(GroupedExpression { inner: Box::new(ex) }) } / co:conditional() { ValueExpression::ConditionalBlock(co) } + / decl:declare_variable() { ValueExpression::DeclareIdentifier(decl) } / left:value_expression() op:binary_operator() right:value_expression() { ValueExpression::Binary { lhs: Box::new(left), rhs: Box::new(right), operator: op } } / op:unary_operator() operand:value_expression() { ValueExpression::Unary { operator: op, operand: Box::new(operand) } } + / ident:bare_identifier() { ValueExpression::Identifier(ident) } / li:literal() { ValueExpression::Literal(li) } rule print() -> Print = "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 - = "while" guard:value_expression() "{" block:expression_list() "}" { ConditionalLoop { block: GuardedBlock { guard: Box::new(guard), block}, fallback: None } } - / "while" guard:value_expression() "{" block:expression_list() "}" "else" "{" fallback:expression_list() "}" - { ConditionalLoop { block: GuardedBlock { guard: Box::new(guard), block}, fallback: Some(fallback) } } + = "while" guard:value_expression() "{" block:expression_list()? "}" + { ConditionalLoop { block: GuardedBlock { guard: Box::new(guard), block: block.unwrap_or_default() }, fallback: None } } + / "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 // = bl:guarded_block() { Conditional { fallback: None, blocks: vec![bl] } } @@ -54,8 +61,11 @@ peg::parser! { / blocks:(guarded_block() ++ "else") { Conditional { fallback: None, blocks, } } rule guarded_block() -> GuardedBlock - = "if" guard:value_expression() "{" block:expression_list() "}" - { GuardedBlock { block, guard: Box::new(guard) } } + = "if" guard:value_expression() "{" block:expression_list()? "}" + { 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 = "+" { BinaryOp::Add } diff --git a/forge-script-lang/src/runtime/executor/printer.rs b/forge-script-lang/src/runtime/executor/printer.rs index 7431492631847e844c0072e18160bdbf46a2001b..0c05b5de9599b556b3220556d9687b6f6a4d0a33 100644 --- a/forge-script-lang/src/runtime/executor/printer.rs +++ b/forge-script-lang/src/runtime/executor/printer.rs @@ -140,6 +140,9 @@ impl Visitor for TreePrinter { self.evaluate_value_expression(inner.as_ref()); self.write(")"); } + ValueExpression::Identifier(ident) => { + self.write(ident); + } } }