8.4.1
FossilOrigin-Name: f908d358ac9f54ee9935ba8f2b55c54e072cdda14ed3693b6959a828aef34a65
diff --git a/ruby/lib/lox/ast_printer.rb b/ruby/lib/lox/ast_printer.rb
index be30643..d394311 100644
--- a/ruby/lib/lox/ast_printer.rb
+++ b/ruby/lib/lox/ast_printer.rb
@@ -8,7 +8,14 @@ module Lox
def visit_unary(expr) = parenthesize(expr.op.lexeme, expr.right)
def visit_print(expr) = parenthesize("print", expr.expr)
- def visit_var(expr) = "(var #{expr.name.lexeme} #{expr.initializer.value})"
+
+ def visit_var(expr)
+ if init = expr.initializer
+ "(assign #{expr.name.lexeme} #{expr.initializer.value})"
+ else
+ "(var #{expr.name.lexeme})"
+ end
+ end
private
diff --git a/ruby/lib/lox/expr.rb b/ruby/lib/lox/expr.rb
index 0f81c8f..606e5dd 100644
--- a/ruby/lib/lox/expr.rb
+++ b/ruby/lib/lox/expr.rb
@@ -2,6 +2,10 @@ require_relative "visitable"
module Lox
module Expr
+ Assign = Struct.new(:name, :value) do
+ include Visitable
+ end
+
Binary = Struct.new(:left, :op, :right) do
include Visitable
end
diff --git a/ruby/lib/lox/parser.rb b/ruby/lib/lox/parser.rb
index c263624..a2dc1dd 100644
--- a/ruby/lib/lox/parser.rb
+++ b/ruby/lib/lox/parser.rb
@@ -54,6 +54,21 @@ module Lox
Stmt::Expr.new(value)
end
+ def assignment
+ expr = equality
+
+ if match?(:EQUAL)
+ eq = prev
+ value = assignment
+
+ raise ParseError.new(eq, "Invalid assignment target.") unless expr.instance_of?(Expr::Variable)
+
+ Expr::Assign.new(expr.name, value)
+ end
+
+ expr
+ end
+
def expression = equality
def equality
diff --git a/ruby/test/lox/test_parser.rb b/ruby/test/lox/test_parser.rb
index cc9f1e9..579676e 100644
--- a/ruby/test/lox/test_parser.rb
+++ b/ruby/test/lox/test_parser.rb
@@ -52,7 +52,11 @@ class TestParser < Lox::Test
end
def test_var
- assert_parsed "(var foo 42.0)", :declaration, "var foo = 42.0;"
+ assert_parsed "(var foo)", :declaration, "var foo;"
+ end
+
+ def test_assign
+ assert_parsed "(assign foo 42.0)", :declaration, "var foo = 42.0;"
end
private