diff --git a/lib/mom/instruction/basic_values.rb b/lib/mom/instruction/basic_values.rb index 91dde587..91565faf 100644 --- a/lib/mom/instruction/basic_values.rb +++ b/lib/mom/instruction/basic_values.rb @@ -10,6 +10,11 @@ module Mom def initialize(value) @value = value end + def to_parfait(compiler) + value = Parfait::Integer.new(@value) + compiler.add_constant(value) + value + end def ct_type Parfait.object_space.get_class_by_name(:Integer).instance_type end diff --git a/lib/mom/instruction/slot_load.rb b/lib/mom/instruction/slot_load.rb index ff6b5d4f..5ae24710 100644 --- a/lib/mom/instruction/slot_load.rb +++ b/lib/mom/instruction/slot_load.rb @@ -108,7 +108,11 @@ module Mom type = known_object.respond_to?(:ct_type) ? known_object.ct_type : :int right = compiler.use_reg( type ) case known_object - when Constant , Parfait::Object , Risc::Label + when Constant + parfait = known_object.to_parfait(compiler) + const = Risc.load_constant(instruction, parfait , right) + raise "Can't have slots into Constants" if slots.length > 0 + when Parfait::Object , Risc::Label const = Risc.load_constant(instruction, known_object , right) if slots.length > 0 # desctructively replace the existing value to be loaded if more slots diff --git a/lib/parfait/integer.rb b/lib/parfait/integer.rb index 05165791..5618a14f 100644 --- a/lib/parfait/integer.rb +++ b/lib/parfait/integer.rb @@ -9,6 +9,12 @@ module Parfait class Integer < Data2 + #FIXME: this is "just" for compilation + def initialize(value) + @value = value + end + attr_reader :value + # :integer?, :odd?, :even?, :upto, :downto, :times, :succ, :next, :pred, :chr, :ord, :to_i, :to_int, :floor, # :ceil, :truncate, :round, :gcd, :lcm, :gcdlcm, :numerator, :denominator, :to_r, :rationalize, # :singleton_method_added, :coerce, :i, :+@, :-@, :fdiv, :div, :divmod, :%, :modulo, :remainder, :abs, :magnitude, diff --git a/lib/risc/machine.rb b/lib/risc/machine.rb index 6d476b20..8d923f94 100644 --- a/lib/risc/machine.rb +++ b/lib/risc/machine.rb @@ -55,6 +55,11 @@ module Risc @objects ||= Collector.collect_space end + # add a constant (which get created during compilatio and need to be linked) + def add_constant(const) + raise "Must be Parfait #{const}" unless const.is_a?(Parfait::Object) + @constants << const + end # To create binaries, objects (and labels) need to have a position # (so objects can be loaded and branches know where to jump) # diff --git a/lib/risc/method_compiler.rb b/lib/risc/method_compiler.rb index 50ae327f..2205f72b 100644 --- a/lib/risc/method_compiler.rb +++ b/lib/risc/method_compiler.rb @@ -92,7 +92,7 @@ module Risc # for computationally building code (ie writing assembler) these short cuts # help to instantiate risc instructions and add them immediately - [:label, :reg_to_slot , :slot_to_reg , :load_constant, :load_data, + [:label, :reg_to_slot , :slot_to_reg , :load_constant, :load_data, :function_return , :function_call, :transfer , :reg_to_slot , :byte_to_reg , :reg_to_byte].each do |method| define_method("add_#{method}".to_sym) do |*args| @@ -132,5 +132,8 @@ module Risc @regs.clear end + def add_constant(const) + Risc.machine.add_constant(const) + end end end diff --git a/test/risc/test_machine.rb b/test/risc/test_machine.rb index 81ef1b59..f9aa0e40 100644 --- a/test/risc/test_machine.rb +++ b/test/risc/test_machine.rb @@ -11,6 +11,12 @@ module Risc assert_equal Hash , objects.class assert 350 < objects.length end + def test_constant_fail + assert_raises {@machine.add_constant( 1 )} + end + def test_constant + assert @machine.add_constant( Parfait::Integer.new(5) ) + end end class TestMachinePositions < MiniTest::Test def setup