diff --git a/examples/test.lua b/examples/test.lua index 9170a8c..9d705da 100644 --- a/examples/test.lua +++ b/examples/test.lua @@ -9,4 +9,7 @@ function test() end local a, b, c = add(10)(15) + +b = 10 + local pr = print(a, b, c) \ No newline at end of file diff --git a/src/ast.rs b/src/ast.rs index 16eefb3..6526472 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -206,7 +206,7 @@ impl Parse for Block { #[derive(Debug, Clone)] pub enum Statement { - Assignment(AccessModifier, Vec>, ExpressionList), + Assignment(Option, Vec>, ExpressionList), Return(ExpressionList), If(Node, Block), } @@ -218,7 +218,7 @@ impl Parse for Statement { let function = stream.parse::>()?; if let Some(name) = function.kind.name { Ok(Self::Assignment( - AccessModifier::Global, + None, vec![name], ExpressionList(vec![Node { kind: Expression::FunctionDefinition( @@ -255,14 +255,14 @@ impl Parse for Statement { } stream.expect(Token::Symbol('='))?; let expr = stream.parse()?; - Ok(Statement::Assignment(access_modifier, names, expr)) + Ok(Statement::Assignment(Some(access_modifier), names, expr)) } else if let Some(Token::Word(_)) = peeked && stream.peek2() == Some(Token::Symbol('=')) { let name = stream.parse()?; stream.expect(Token::Symbol('='))?; Ok(Self::Assignment( - AccessModifier::Global, + None, vec![name], ExpressionList(vec![stream.parse()?]), )) diff --git a/src/compile.rs b/src/compile.rs index 7385f3a..3bf4895 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -70,10 +70,16 @@ impl Statement { match self { Statement::Assignment(access, names, expr_list) => { let mut constants = HashSet::new(); - if *access == AccessModifier::Global { + if *access == Some(AccessModifier::Global) { for name in names { constants.insert(Constant::String(name.kind.clone())); } + } else if *access == None { + for name in names { + if !scope.locals.contains_key(&name.kind) { + constants.insert(Constant::String(name.kind.clone())); + } + } } else { for name in names { scope.locals.insert(name.kind.clone(), 0); @@ -125,7 +131,7 @@ impl Statement { expr_regs.extend(regs); } match access_modifier { - AccessModifier::Local => { + Some(AccessModifier::Local) => { for (i, name) in names.iter().enumerate() { scope.locals.insert( name.kind.clone(), @@ -137,10 +143,39 @@ impl Statement { } dbg!(&scope.locals); } - AccessModifier::Global => { - for (name, reg) in names.iter().zip(expr_regs) { + Some(AccessModifier::Global) => { + for (i, name) in names.iter().enumerate() { let global = state.get_constant(&Constant::String(name.kind.clone())); - instructions.push(Instruction::SetGlobal(reg, global)); + instructions.push(Instruction::SetGlobal( + expr_regs + .get(i) + .cloned() + .unwrap_or(scope.register_counter.0 + i as u16), + global, + )); + } + } + None => { + for (i, name) in names.iter().enumerate() { + if scope.locals.contains_key(&name.kind) { + scope.locals.insert( + name.kind.clone(), + expr_regs + .get(i) + .cloned() + .unwrap_or(scope.register_counter.0 + i as u16), + ); + } else { + let global = + state.get_constant(&Constant::String(name.kind.clone())); + instructions.push(Instruction::SetGlobal( + expr_regs + .get(i) + .cloned() + .unwrap_or(scope.register_counter.0 + i as u16), + global, + )); + } } } }