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() {
let arr = [1, 2, 3, 4, 5]
let arr = [1, 4, 2, 5, 3]
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) => {
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::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 {
format!("{} = {}", name, generate_expression(expr))
fn generate_assign(name: Expression, expr: Expression) -> String {
format!(
"{} = {}",
generate_expression(name),
generate_expression(expr)
)
}

3
src/parser/node_type.rs

@ -38,7 +38,7 @@ pub struct Variable {
pub enum Statement {
Block(Vec<Statement>),
Declare(Variable, Option<Expression>),
Assign(String, Box<Expression>),
Assign(Box<Expression>, Box<Expression>),
Return(Option<Expression>),
If(Expression, Box<Statement>, Option<Box<Statement>>),
While(Expression, Box<Statement>),
@ -49,7 +49,6 @@ pub enum Statement {
pub enum Expression {
Int(u32),
Str(String),
Char(u8),
Bool(bool),
Array(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))?;
Ok(Statement::Exp(state))
} 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)
} else if let Ok(_) = self.peek_token(TokenKind::SquareBraceOpen) {
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 {
let state = Statement::Exp(Expression::Variable(ident.into()));
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 {
Some(name) => name,
None => self.match_identifier()?,
None => Expression::Variable(self.match_identifier()?),
};
self.match_token(TokenKind::Assign)?;
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]
#[ignore]
fn test_array_position_assignment() {
let raw = "
fn main() {
new_arr[i] = arr[j]
}
new_arr[i] = 1
}
";
let tokens = tokenize(raw);

Loading…
Cancel
Save