main
Alpha Chen 2 years ago
parent 613c419b5c
commit 71f19068a7

@ -7,6 +7,7 @@ module Lox
@interpreter = interpreter @interpreter = interpreter
@scopes = [] @scopes = []
@current_func = :NONE
end end
def resolve(*resolvees) def resolve(*resolvees)
@ -29,7 +30,7 @@ module Lox
declare(stmt.name) declare(stmt.name)
define(stmt.name) define(stmt.name)
resolve_function(stmt) resolve_function(stmt, :FUNCTION)
nil nil
end end
@ -40,6 +41,7 @@ module Lox
def visit_print(stmt) = resolve(stmt.expr) def visit_print(stmt) = resolve(stmt.expr)
def visit_return(stmt) def visit_return(stmt)
raise ResolverError.new(stmt.keyword, "Can't return from top-level code.") if @current_func == :NONE
resolve(stmt.value) if stmt.value resolve(stmt.value) if stmt.value
end end
@ -106,15 +108,26 @@ module Lox
@interpreter.resolve(expr, depth) @interpreter.resolve(expr, depth)
end end
def resolve_function(fn) def resolve_function(fn, type)
with_scope do with_func_type(type) do
fn.params.each do |param| with_scope do
declare(param) fn.params.each do |param|
define(param) declare(param)
define(param)
end
resolve(*fn.body)
end end
resolve(*fn.body)
end end
end end
def with_func_type(type)
enclosing_func = @current_func
@current_func = type
yield
@current_func = enclosing_func
end
end end
end end

@ -51,6 +51,14 @@ class TestResolver < Lox::Test
end end
end end
def test_returning_from_top_level
assert_raises Lox::ResolverError do
resolve(<<~SRC)
return;
SRC
end
end
private private
def assert_resolved(expected, src) def assert_resolved(expected, src)

Loading…
Cancel
Save