Browse Source

Fix array access as assignment

github-actions
Garrit Franke 3 years ago
parent
commit
13a88a0e76
  1. 3
      examples/playground.sb
  2. 10
      src/generator/js.rs
  3. 3
      src/parser/node_type.rs
  4. 15
      src/parser/rules.rs
  5. 4
      src/parser/tests.rs

3
examples/playground.sb

@ -1,5 +1,4 @@
fn main() { fn main() {
let arr = [1, 2, 3, 4, 5] let arr = [1, 4, 2, 5, 3]
println(rev(arr)) println(rev(arr))
} }

10
src/generator/js.rs

@ -79,7 +79,7 @@ fn generate_statement(statement: Statement) -> String {
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::Assign(name, state) => generate_assign(name, *state), Statement::Assign(name, state) => generate_assign(*name, *state),
Statement::Block(_) => generate_block(statement), Statement::Block(_) => generate_block(statement),
Statement::While(expr, body) => generate_while_loop(expr, *body), Statement::While(expr, body) => generate_while_loop(expr, *body),
}; };
@ -215,6 +215,10 @@ fn generate_bin_op(left: Expression, op: BinOp, right: Expression) -> String {
) )
} }
fn generate_assign(name: String, expr: Expression) -> String { fn generate_assign(name: Expression, expr: Expression) -> String {
format!("{} = {}", name, generate_expression(expr)) format!(
"{} = {}",
generate_expression(name),
generate_expression(expr)
)
} }

3
src/parser/node_type.rs

@ -38,7 +38,7 @@ pub struct Variable {
pub enum Statement { pub enum Statement {
Block(Vec<Statement>), Block(Vec<Statement>),
Declare(Variable, Option<Expression>), Declare(Variable, Option<Expression>),
Assign(String, Box<Expression>), Assign(Box<Expression>, Box<Expression>),
Return(Option<Expression>), Return(Option<Expression>),
If(Expression, Box<Statement>, Option<Box<Statement>>), If(Expression, Box<Statement>, Option<Box<Statement>>),
While(Expression, Box<Statement>), While(Expression, Box<Statement>),
@ -49,7 +49,6 @@ pub enum Statement {
pub enum Expression { pub enum Expression {
Int(u32), Int(u32),
Str(String), Str(String),
Char(u8),
Bool(bool), Bool(bool),
Array(Vec<Expression>), Array(Vec<Expression>),
FunctionCall(String, Vec<Expression>), FunctionCall(String, Vec<Expression>),

15
src/parser/rules.rs

@ -104,11 +104,16 @@ impl Parser {
let state = self.parse_function_call(Some(ident))?; let state = self.parse_function_call(Some(ident))?;
Ok(Statement::Exp(state)) Ok(Statement::Exp(state))
} else if let Ok(_) = self.peek_token(TokenKind::Assign) { } else if let Ok(_) = self.peek_token(TokenKind::Assign) {
let state = self.parse_assignent(Some(ident))?; let state = self.parse_assignent(Some(Expression::Variable(ident)))?;
Ok(state) Ok(state)
} else if let Ok(_) = self.peek_token(TokenKind::SquareBraceOpen) { } else if let Ok(_) = self.peek_token(TokenKind::SquareBraceOpen) {
let expr = self.parse_array_access(Some(ident))?; let expr = self.parse_array_access(Some(ident))?;
Ok(Statement::Exp(expr))
let next = self.peek()?;
match next.kind {
TokenKind::Assign => self.parse_assignent(Some(expr)),
_ => Ok(Statement::Exp(expr)),
}
} else { } else {
let state = Statement::Exp(Expression::Variable(ident.into())); let state = Statement::Exp(Expression::Variable(ident.into()));
Ok(state) Ok(state)
@ -339,16 +344,16 @@ impl Parser {
} }
} }
fn parse_assignent(&mut self, name: Option<String>) -> Result<Statement, String> { fn parse_assignent(&mut self, name: Option<Expression>) -> Result<Statement, String> {
let name = match name { let name = match name {
Some(name) => name, Some(name) => name,
None => self.match_identifier()?, None => Expression::Variable(self.match_identifier()?),
}; };
self.match_token(TokenKind::Assign)?; self.match_token(TokenKind::Assign)?;
let expr = self.parse_expression()?; let expr = self.parse_expression()?;
Ok(Statement::Assign(name, Box::new(expr))) Ok(Statement::Assign(Box::new(name), Box::new(expr)))
} }
} }

4
src/parser/tests.rs

@ -556,12 +556,10 @@ fn test_function_multiple_args() {
} }
#[test] #[test]
#[ignore]
fn test_array_position_assignment() { fn test_array_position_assignment() {
let raw = " let raw = "
fn main() { fn main() {
new_arr[i] = arr[j] new_arr[i] = 1
}
} }
"; ";
let tokens = tokenize(raw); let tokens = tokenize(raw);

Loading…
Cancel
Save