From cbbb0c2f072183f275546ccdd1fd954202dba3b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20R=C3=BCger?= Date: Sat, 5 Oct 2019 19:37:24 +0300 Subject: [PATCH] More on slot assignment which turn into slot_load --- lib/slot_language/code/resolve_method.slot | 2 +- lib/slot_language/load_maker.rb | 12 ++++++++++++ lib/slot_language/slot_compiler.rb | 18 +++++++++++++++--- lib/slot_language/slot_maker.rb | 16 +++++++++++++++- test/slot_language/test_slot_compiler.rb | 17 +++++++++++++---- 5 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 lib/slot_language/load_maker.rb diff --git a/lib/slot_language/code/resolve_method.slot b/lib/slot_language/code/resolve_method.slot index 6c05b06e..7fc665a0 100644 --- a/lib/slot_language/code/resolve_method.slot +++ b/lib/slot_language/code/resolve_method.slot @@ -19,4 +19,4 @@ exit_label MethodMissing.new(compiler.source_name , word.symbol).to_risc(compiler) ok_label -cache_entry.cached_method == callable_method +cache_entry.cached_method = callable_method diff --git a/lib/slot_language/load_maker.rb b/lib/slot_language/load_maker.rb new file mode 100644 index 00000000..e0bf2961 --- /dev/null +++ b/lib/slot_language/load_maker.rb @@ -0,0 +1,12 @@ +module SlotLanguage + class LoadMaker + attr_reader :left , :right + + def initialize(left , right) + @left = left + @right = right + raise "No Slot #{left}" unless left.is_a?(SlotMaker) + raise "No Slot #{right}" unless right.is_a?(SlotMaker) + end + end +end diff --git a/lib/slot_language/slot_compiler.rb b/lib/slot_language/slot_compiler.rb index a2788d9b..0eaf2945 100644 --- a/lib/slot_language/slot_compiler.rb +++ b/lib/slot_language/slot_compiler.rb @@ -16,18 +16,23 @@ module SlotLanguage not_implemented(node) end def on_send(statement) + #puts "Send #{statement}" kids = statement.children.dup receiver = process(kids.shift) || MessageSlot.new name = kids.shift return label(name) if(name.to_s.end_with?("_label")) return goto(name,kids) if(name == :goto) return check(name,receiver, kids) if(name == :==) + return assign(receiver, name , kids) if(name.to_s.end_with?("=")) SlotMaker.new( name , receiver ) end + def on_lvar(lvar) + SlotMaker.new(lvar.children.first , nil) + end def on_lvasgn expression name = expression.children[0] value = process(expression.children[1]) - Sol::LocalAssignment.new(name,value) + LoadMaker.new(SlotMaker.new(name,nil),value) end def on_if(expression) condition = process(expression.children[0]) @@ -38,7 +43,7 @@ module SlotLanguage process(exp.first) end def on_ivar expression - Sol::InstanceVariable.new(instance_name(expression.children.first)) + SlotMaker.new(instance_name(expression.children.first),nil) end private @@ -56,13 +61,20 @@ module SlotLanguage def check(name , receiver , kids) raise "Only ==, not #{name}" unless name == :== raise "Familiy too large #{kids}" if kids.length > 1 - puts "Kids " + kids.to_s + #puts "Kids " + kids.to_s right = process(kids.first) CheckMaker.new(name , receiver , right) end + def assign(receiver , name , kids) + name = name.to_s[0...-1].to_sym + receiver.add_slot_name(name) + right = process kids.first + LoadMaker.new(receiver,right) + end end end require_relative "named_slot" require_relative "message_slot" require_relative "slot_maker" +require_relative "load_maker" require_relative "check_maker" diff --git a/lib/slot_language/slot_maker.rb b/lib/slot_language/slot_maker.rb index 7fce2759..fa0dbc37 100644 --- a/lib/slot_language/slot_maker.rb +++ b/lib/slot_language/slot_maker.rb @@ -1,8 +1,22 @@ module SlotLanguage class SlotMaker - attr_reader :name + attr_reader :name , :leaps + def initialize(name , more) @name = name + if(more.is_a?(Array)) + @leaps = more + else + @leaps = [more] if more + end + end + + def add_slot_name(name) + if(@leaps) + @leaps << name + else + @leaps = [name] + end end end end diff --git a/test/slot_language/test_slot_compiler.rb b/test/slot_language/test_slot_compiler.rb index d3b2715c..cff68650 100644 --- a/test/slot_language/test_slot_compiler.rb +++ b/test/slot_language/test_slot_compiler.rb @@ -10,16 +10,13 @@ module SlotLanguage def test_compile assert_equal SlotMaker , compile("a").class end - # def test_fail_args - # assert_raises{ compile("a(1)")} - # 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 - assert_equal Sol::LocalAssignment , compile_class("a = @b") + assert_equal LoadMaker , compile_class("a = @b") end def test_goto assert_equal SlotMachine::Jump , compile_class("goto(exit_label)") @@ -29,5 +26,17 @@ module SlotLanguage assert_equal CheckMaker , check.class assert_equal SlotMachine::Jump , check.goto.class end + def test_assign + assign = compile("c = d") + assert_equal LoadMaker , assign.class + end + def test_assign1 + assign = compile("c = c.next") + assert_equal LoadMaker , assign.class + end + def test_assign2 + assign = compile("c.next = d") + assert_equal LoadMaker , assign.class + end end end