diff --git a/lib/slot_language/code/resolve_method.slot b/lib/slot_language/code/resolve_method.slot index f777898b..77d8ece0 100644 --- a/lib/slot_language/code/resolve_method.slot +++ b/lib/slot_language/code/resolve_method.slot @@ -2,7 +2,7 @@ word! = name_ cache_entry! = cache_entry_ # local var assignment -callable_method = cache_entry.cached_type.methods +callable_method! = cache_entry.cached_type.methods while_start_label diff --git a/lib/slot_language/goto.rb b/lib/slot_language/goto.rb new file mode 100644 index 00000000..80d33314 --- /dev/null +++ b/lib/slot_language/goto.rb @@ -0,0 +1,10 @@ +module SlotLanguage + class Goto + attr_reader :label + + def initialize(label) + @label = label + end + + end +end diff --git a/lib/slot_language/slot_compiler.rb b/lib/slot_language/slot_compiler.rb index 4ca3532e..759cad33 100644 --- a/lib/slot_language/slot_compiler.rb +++ b/lib/slot_language/slot_compiler.rb @@ -10,6 +10,10 @@ module SlotLanguage self.new.process(ast) end + def initialize + @labels = {} + end + def not_implemented(node) raise "Not implemented #{node.type}" end @@ -60,13 +64,18 @@ module SlotLanguage private def label(name) - SlotMachine::Label.new(name.to_s , name) + raise "no label #{name}" unless(name.to_s.end_with?("_label")) + if @labels.has_key?(name) + return @labels[name] + else + @labels[name] = SlotMachine::Label.new(name.to_s , name) + end end def goto(name , args) # error handling would not hurt puts "goto #{name} , #{args}" if DEBUG label = process(args.first) - SlotMachine::Jump.new( label ) + Goto.new( label ) end def check(name , receiver , kids) raise "Only ==, not #{name}" unless name == :== @@ -90,3 +99,4 @@ require_relative "slot_maker" require_relative "load_maker" require_relative "check_maker" require_relative "macro_maker" +require_relative "goto" diff --git a/test/slot_language/test_goto.rb b/test/slot_language/test_goto.rb new file mode 100644 index 00000000..a18cb769 --- /dev/null +++ b/test/slot_language/test_goto.rb @@ -0,0 +1,36 @@ +require_relative "helper" + +module SlotLanguage + class TestGoto < MiniTest::Test + include SlotHelper + + def test_goto_class + assert_equal Goto , compile_class("goto(exit_label)") + end + def test_goto_label + goto = compile("goto(exit_label)") + assert_equal SlotMachine::Label , goto.label.class + assert_equal :exit_label , goto.label.name + end + + def test_label + label = compile("while_label") + assert_equal SlotMachine::Label , label.class + assert_equal :while_label , label.name + end + + def test_2_label + labels = compile("exit_label;exit_label") + assert_equal :exit_label , labels[0].name + assert_equal :exit_label , labels[1].name + assert_equal labels[0].object_id , labels[1].object_id + end + + def test_goto_with_label + gotos = compile("exit_label;goto(exit_label)") + assert_equal :exit_label , gotos[0].name + assert_equal :exit_label , gotos[1].label.name + assert_equal gotos[0].object_id , gotos[1].label.object_id + end + end +end diff --git a/test/slot_language/test_slot_compiler.rb b/test/slot_language/test_slot_compiler.rb index 7bcc851c..e6eec83e 100644 --- a/test/slot_language/test_slot_compiler.rb +++ b/test/slot_language/test_slot_compiler.rb @@ -10,11 +10,6 @@ module SlotLanguage def test_compile assert_equal SlotMaker , compile("a").class end - def test_label - label = compile("while_label") - assert_equal SlotMachine::Label , label.class - assert_equal :while_label , label.name - end def test_slot_load_rinst assert_equal LoadMaker , compile_class("a = @b") end @@ -30,13 +25,10 @@ module SlotLanguage def test_slot_load_linst_trav2 assert_equal LoadMaker , compile_class("@a.c = b.c") end - def test_goto - assert_equal SlotMachine::Jump , compile_class("goto(exit_label)") - end def test_if check = compile("goto(exit_label) if(a == b)") assert_equal CheckMaker , check.class - assert_equal SlotMachine::Jump , check.goto.class + assert_equal Goto , check.goto.class end def test_assign assign = compile("c = d") @@ -54,7 +46,7 @@ module SlotLanguage multi = compile("start_label;c = c.next;goto(start_label)") assert_equal Array , multi.class assert_equal SlotMachine::Label , multi.first.class - assert_equal SlotMachine::Jump , multi.last.class + assert_equal Goto , multi.last.class end def test_shift load = compile("word = name.member")