diff --git a/examples/playground.sb b/examples/playground.sb index 4986ae5..16dd4d9 100644 --- a/examples/playground.sb +++ b/examples/playground.sb @@ -1,17 +1,5 @@ // There are no nested expressions yet, so we have to hack a little bit fn main() { - let year = 2020 - - let divisibleBy4 = year % 4 == 0 - let divisibleBy100 = year % 100 != 0 - let divisibleBy400 = year % 400 == 0 - - let ly = divisibleBy4 && divisibleBy100 - - if ly || divisibleBy400 { - return "Leap year" - } else { - return "Not a leap year" - } + let arr = ["Foo", "Bar", "Baz"] } \ No newline at end of file diff --git a/src/generator/js.rs b/src/generator/js.rs index f402e18..964859e 100644 --- a/src/generator/js.rs +++ b/src/generator/js.rs @@ -84,10 +84,28 @@ fn generate_expression(expr: Expression) -> String { Expression::Char(_) => todo!(), Expression::FunctionCall(name, e) => generate_function_call(name, e), Expression::Assign(_, _) => todo!(), + Expression::Array(els) => generate_array(els), Expression::BinOp(left, op, right) => generate_bin_op(*left, op, *right), } } +fn generate_array(elements: Vec) -> String { + let mut out_str = String::from("["); + + out_str += &elements + .iter() + .map(|el| match el { + Expression::Int(x) => x.to_string(), + Expression::Str(x) => x.to_string(), + _ => todo!("Not yet implemented"), + }) + .collect::>() + .join(", "); + + out_str += "]"; + out_str +} + fn generate_conditional( expr: Expression, if_state: Statement, @@ -133,6 +151,7 @@ fn generate_function_call(func: String, args: Vec) -> String { Expression::FunctionCall(n, a) => generate_function_call(n, a), Expression::Str(s) | Expression::Variable(s) => s, Expression::Assign(_, _) => todo!(), + Expression::Array(_) => todo!(), Expression::BinOp(left, op, right) => generate_bin_op(*left, op, *right), }) .collect::>() diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 6bcf147..dbe9fc9 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -320,10 +320,33 @@ impl Parser { }; Ok(state) } + TokenKind::SquareBraceOpen => self.parse_array(), other => Err(format!("Expected Expression, found {:?}", other)), } } + fn parse_array(&mut self) -> Result { + let mut elements = Vec::new(); + loop { + let next = self.next().ok_or_else(|| "Expected identifier")?; + match next.kind { + TokenKind::Literal(Value::Int) => { + let value = next.raw.parse::().map_err(|e| e.to_string())?; + elements.push(Expression::Int(value)); + } + _ => return Err(self.make_error(TokenKind::Identifier("Argument".into()), next)), + }; + if self.peek_token(TokenKind::SquareBraceClose).is_ok() { + break; + } + self.match_token(TokenKind::Comma)?; + } + + self.match_token(TokenKind::SquareBraceClose)?; + + Ok(Expression::Array(elements)) + } + fn parse_conditional_statement(&mut self) -> Result { self.match_keyword(Keyword::If)?; let condition = self.parse_expression()?; diff --git a/src/parser/node_type.rs b/src/parser/node_type.rs index 609a38a..a926a54 100644 --- a/src/parser/node_type.rs +++ b/src/parser/node_type.rs @@ -49,6 +49,7 @@ pub enum Expression { Int(u32), Str(String), Char(u8), + Array(Vec), FunctionCall(String, Vec), Variable(String), Assign(String, Box), diff --git a/src/parser/tests.rs b/src/parser/tests.rs index 12e8946..7c6b2b9 100644 --- a/src/parser/tests.rs +++ b/src/parser/tests.rs @@ -351,3 +351,29 @@ fn test_parse_conditional_elseif_else_branch() { let tree = parse(tokens, Some(raw.to_string())); assert!(tree.is_ok()) } + +#[test] +fn test_int_array() { + let raw = " + fn main(n) { + let arr = [1, 2, 3] + return arr + } + "; + let tokens = tokenize(raw); + let tree = parse(tokens, Some(raw.to_string())); + assert!(tree.is_ok()) +} + +#[test] +#[ignore] +fn test_string_array() { + let raw = " + fn main(n) { + return [\"Foo\", \"Bar\", \"Baz\"] + } + "; + let tokens = tokenize(raw); + let tree = parse(tokens, Some(raw.to_string())); + assert!(tree.is_ok()) +}