diff --git a/components/lox-execute/src/vm.rs b/components/lox-execute/src/vm.rs index 7ce1a6c..288eca8 100644 --- a/components/lox-execute/src/vm.rs +++ b/components/lox-execute/src/vm.rs @@ -235,8 +235,8 @@ impl VM { self.push(value.clone()); } bytecode::Code::Assign(name) => { - let value = self.pop(); - self.globals.insert(name, value); + let value = self.peek(); + self.globals.insert(name, value.clone()); } } if let Some(step_inspect) = &mut step_inspect { @@ -255,6 +255,10 @@ impl VM { self.stack.pop().unwrap() } + fn peek(&self) -> &Value { + self.stack.last().unwrap() + } + fn push(&mut self, value: T) where T: Into, diff --git a/lox_tests/assignment.lox b/lox_tests/assignment.lox index b084feb..579a08e 100644 --- a/lox_tests/assignment.lox +++ b/lox_tests/assignment.lox @@ -1,3 +1,8 @@ var a = 1; a = 2; -print a; \ No newline at end of file +print a; +print a = 3; +var b = a; +var c; +c = b; +print c; \ No newline at end of file diff --git a/lox_tests/assignment/bytecode b/lox_tests/assignment/bytecode index 39edff4..854d3f5 100644 --- a/lox_tests/assignment/bytecode +++ b/lox_tests/assignment/bytecode @@ -20,5 +20,34 @@ Chunk { "a", ), Print, + Constant( + F64( + 3.0, + ), + ), + Assign( + "a", + ), + Print, + Variable( + "a", + ), + VarDeclaration( + "b", + ), + Nil, + VarDeclaration( + "c", + ), + Variable( + "b", + ), + Assign( + "c", + ), + Variable( + "c", + ), + Print, ], } \ No newline at end of file diff --git a/lox_tests/assignment/execute b/lox_tests/assignment/execute index d00dec7..bcf5531 100644 --- a/lox_tests/assignment/execute +++ b/lox_tests/assignment/execute @@ -28,7 +28,11 @@ stack: [ execute: Assign( "a", ) -stack: [] +stack: [ + Number( + 2.0, + ), +] execute: Variable( "a", @@ -37,8 +41,135 @@ stack: [ Number( 2.0, ), + Number( + 2.0, + ), ] execute: Print -stack: [] +stack: [ + Number( + 2.0, + ), +] + +execute: Constant( + F64( + 3.0, + ), +) +stack: [ + Number( + 2.0, + ), + Number( + 3.0, + ), +] + +execute: Assign( + "a", +) +stack: [ + Number( + 2.0, + ), + Number( + 3.0, + ), +] + +execute: Print +stack: [ + Number( + 2.0, + ), +] + +execute: Variable( + "a", +) +stack: [ + Number( + 2.0, + ), + Number( + 3.0, + ), +] + +execute: VarDeclaration( + "b", +) +stack: [ + Number( + 2.0, + ), +] + +execute: Nil +stack: [ + Number( + 2.0, + ), + Nil, +] + +execute: VarDeclaration( + "c", +) +stack: [ + Number( + 2.0, + ), +] + +execute: Variable( + "b", +) +stack: [ + Number( + 2.0, + ), + Number( + 3.0, + ), +] + +execute: Assign( + "c", +) +stack: [ + Number( + 2.0, + ), + Number( + 3.0, + ), +] + +execute: Variable( + "c", +) +stack: [ + Number( + 2.0, + ), + Number( + 3.0, + ), + Number( + 3.0, + ), +] + +execute: Print +stack: [ + Number( + 2.0, + ), + Number( + 3.0, + ), +] diff --git a/lox_tests/assignment/syntax b/lox_tests/assignment/syntax index 40510c2..22211be 100644 --- a/lox_tests/assignment/syntax +++ b/lox_tests/assignment/syntax @@ -13,3 +13,28 @@ Expr { Print { expr: Variable(a), } +Print { + expr: Assign { + name: "a", + value: NumberLiteral(3), + }, +} +Var { + name: "b", + initializer: Some( + Variable(a), + ), +} +Var { + name: "c", + initializer: None, +} +Expr { + expr: Assign { + name: "c", + value: Variable(b), + }, +} +Print { + expr: Variable(c), +} diff --git a/lox_tests/assignment/token b/lox_tests/assignment/token index 25cf12c..e63f65b 100644 --- a/lox_tests/assignment/token +++ b/lox_tests/assignment/token @@ -1,5 +1,5 @@ TokenTree { - source text: "var a = 1;\na = 2;\nprint a;", + source text: "var a = 1;\na = 2;\nprint a;\nprint a = 3;\nvar b = a;\nvar c;\nc = b;\nprint c;", tokens: [ Alphabetic(var), Whitespace(' '), @@ -21,5 +21,40 @@ TokenTree { Whitespace(' '), Alphabetic(a), Semicolon, + Whitespace('\n'), + Alphabetic(print), + Whitespace(' '), + Alphabetic(a), + Whitespace(' '), + Op(=), + Whitespace(' '), + Number(3), + Semicolon, + Whitespace('\n'), + Alphabetic(var), + Whitespace(' '), + Alphabetic(b), + Whitespace(' '), + Op(=), + Whitespace(' '), + Alphabetic(a), + Semicolon, + Whitespace('\n'), + Alphabetic(var), + Whitespace(' '), + Alphabetic(c), + Semicolon, + Whitespace('\n'), + Alphabetic(c), + Whitespace(' '), + Op(=), + Whitespace(' '), + Alphabetic(b), + Semicolon, + Whitespace('\n'), + Alphabetic(print), + Whitespace(' '), + Alphabetic(c), + Semicolon, ], } \ No newline at end of file