You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
1.6 KiB

require_relative "../test_helper"
require "lox/ast_printer"
require "lox/parser"
require "lox/resolver"
require "lox/scanner"
class TestResolver < Lox::Test
def test_resolver
assert_resolved [
["(var j)", 0],
["(var j)", 2],
["(var j)", 1],
["(assign j (+ (var j) 1.0))", 1],
["(var k)", 0],
["(var k)", 2],
["(var k)", 1],
["(assign k (+ (var k) 1.0))", 1],
], <<~SRC
var i = 0;
while (i < 3) {
print i;
i = i + 1;
}
for(var j=0; j<3; j=j+1) {
print j;
}
{
var k = 0;
while (k < 3) {
{
print k;
}
k = k + 1;
}
}
SRC
end
def test_same_var_name_in_scope
assert_raises Lox::ResolverError do
resolve(<<~SRC)
fun bad() {
var a = "first";
var a = "second";
}
SRC
end
end
def test_returning_from_top_level
assert_raises Lox::ResolverError do
resolve(<<~SRC)
return;
SRC
end
end
private
def assert_resolved(expected, src)
resolves = resolve(src)
ast_printer = Lox::AstPrinter.new
assert_equal expected, resolves.map {|expr, depth|
[ast_printer.print(expr), depth]
}
end
def resolve(src)
stmts = Lox::Parser.new(Lox::Scanner.new.scan(src)).parse!
interpreter = Interpreter.new
Lox::Resolver.new(interpreter).resolve(*stmts)
interpreter.resolves
end
class Interpreter
attr_reader :resolves
def initialize
@resolves = []
end
def resolve(expr, depth)
resolves << [expr, depth]
end
end
end