Browse Source

Allow multiple statements in if conditional

github-actions
Garrit Franke 3 years ago
parent
commit
7d8883ed63
  1. 9
      src/generator/js.rs
  2. 11
      src/parser/mod.rs
  3. 2
      src/parser/node_type.rs
  4. 29
      src/parser/tests.rs

9
src/generator/js.rs

@ -44,7 +44,7 @@ fn generate_statement(statement: Statement) -> String {
Statement::Declare(_, _) => todo!(), Statement::Declare(_, _) => todo!(),
Statement::Exp(val) => generate_expression(val), Statement::Exp(val) => generate_expression(val),
Statement::If(expr, if_state, else_state) => { Statement::If(expr, if_state, else_state) => {
generate_conditional(expr, *if_state, else_state.map(|x| *x)) generate_conditional(expr, if_state, else_state.map(|x| *x))
} }
Statement::While(_, _) => todo!(), Statement::While(_, _) => todo!(),
} }
@ -63,16 +63,17 @@ fn generate_expression(expr: Expression) -> String {
fn generate_conditional( fn generate_conditional(
expr: Expression, expr: Expression,
if_state: Statement, if_state: Vec<Statement>,
else_state: Option<Statement>, else_state: Option<Statement>,
) -> String { ) -> String {
let expr_str = generate_expression(expr); let expr_str = generate_expression(expr);
let if_str = generate_statement(if_state);
let mut outcome = format!("if ({})", expr_str); let mut outcome = format!("if ({})", expr_str);
outcome += "{\n"; outcome += "{\n";
outcome += &if_str; for statement in if_state {
outcome += &generate_statement(statement);
}
outcome += "}"; outcome += "}";
outcome outcome
} }

11
src/parser/mod.rs

@ -307,10 +307,17 @@ impl Parser {
self.match_keyword(Keyword::If)?; self.match_keyword(Keyword::If)?;
let condition = self.parse_expression()?; let condition = self.parse_expression()?;
self.match_token(TokenKind::CurlyBracesOpen)?; self.match_token(TokenKind::CurlyBracesOpen)?;
let state = self.parse_statement()?;
let mut statements = Vec::new();
while let Err(_) = self.peek_token(TokenKind::CurlyBracesClose) {
let statement = self.parse_statement()?;
dbg!("{:?}", &statement);
statements.push(statement);
}
self.match_token(TokenKind::CurlyBracesClose)?; self.match_token(TokenKind::CurlyBracesClose)?;
Ok(Statement::If(condition, Box::new(state), None)) Ok(Statement::If(condition, statements, None))
} }
/// In some occurences a complex expression has been evaluated before a binary operation is encountered. /// In some occurences a complex expression has been evaluated before a binary operation is encountered.

2
src/parser/node_type.rs

@ -23,7 +23,7 @@ pub struct Variable {
pub enum Statement { pub enum Statement {
Declare(Variable, Option<Expression>), Declare(Variable, Option<Expression>),
Return(Option<Expression>), Return(Option<Expression>),
If(Expression, Box<Statement>, Option<Box<Statement>>), If(Expression, Vec<Statement>, Option<Box<Statement>>),
While(Expression, Box<Statement>), While(Expression, Box<Statement>),
Exp(Expression), Exp(Expression),
} }

29
src/parser/tests.rs

@ -234,3 +234,32 @@ fn test_parse_compound_ops_return() {
let tree = parse(tokens, Some(raw.to_string())); let tree = parse(tokens, Some(raw.to_string()));
assert!(tree.is_ok()) assert!(tree.is_ok())
} }
#[test]
fn test_parse_basic_conditional() {
let raw = "
main :: (n) {
if n {
return n
}
}
";
let tokens = tokenize(raw);
let tree = parse(tokens, Some(raw.to_string()));
assert!(tree.is_ok())
}
#[test]
fn test_parse_basic_conditional_with_multiple_statements() {
let raw = "
main :: (n) {
if n {
let x = 2 * n
return x
}
}
";
let tokens = tokenize(raw);
let tree = parse(tokens, Some(raw.to_string()));
assert!(tree.is_ok())
}

Loading…
Cancel
Save