diff --git a/ruby/lib/lox.rb b/ruby/lib/lox.rb index 9a7ce98..cff3742 100644 --- a/ruby/lib/lox.rb +++ b/ruby/lib/lox.rb @@ -40,9 +40,7 @@ module Lox def run(src) super - rescue Lox::ParseError => e - STDERR.puts e.message - rescue Lox::RuntimeError => e + rescue Lox::ParseError, Lox::RuntimeError => e STDERR.puts e.message end diff --git a/ruby/lib/lox/environment.rb b/ruby/lib/lox/environment.rb index 15cf9cc..91366c6 100644 --- a/ruby/lib/lox/environment.rb +++ b/ruby/lib/lox/environment.rb @@ -14,11 +14,13 @@ module Lox def get(token) name = token.lexeme - @values.fetch(name) { - raise RuntimeError.new(token, "Undefined variable '#{name}'.") if @enclosing.nil? - + if @values.has_key?(name) + @values[name] + elsif @enclosing @enclosing.get(token) - } + else + raise RuntimeError.new(token, "Undefined variable '#{name}'.") + end end def assign(name, value) @@ -26,15 +28,11 @@ module Lox if @values.has_key?(lexeme) @values[lexeme] = value - return - end - - unless @enclosing.nil? + elsif @enclosing @enclosing.assign(name, value) - return + else + raise RuntimeError.new(name, "Undefined variable '#{lexeme}'.") end - - raise RuntimeError.new(name, "Undefined variable '#{lexeme}'.") end end end diff --git a/ruby/test/lox/test_interpreter.rb b/ruby/test/lox/test_interpreter.rb index 10605cf..53b8113 100644 --- a/ruby/test/lox/test_interpreter.rb +++ b/ruby/test/lox/test_interpreter.rb @@ -150,13 +150,19 @@ class TestInterpreter < Lox::Test SRC end + def test_uninitialized_vars_are_nil + assert_interpreted <<~EXPECTED.chomp, <<~SRC + nil + EXPECTED + var a; + print a; + SRC + end + private def assert_interpreted(expected, src) - output = with_stdout { - stmts = Lox::Parser.new(@scanner.scan(src)).parse! - @interpreter.interpret(stmts) - } + output = interpret(src) assert_equal expected, output end @@ -175,4 +181,11 @@ class TestInterpreter < Lox::Test output end + def interpret(src) + with_stdout { + stmts = Lox::Parser.new(@scanner.scan(src)).parse! + @interpreter.interpret(stmts) + } + end + end