diff --git a/lib/risc/builtin.rb b/lib/risc/builtin.rb index b87b8813..988ec2a0 100644 --- a/lib/risc/builtin.rb +++ b/lib/risc/builtin.rb @@ -1,4 +1,4 @@ -module Risc + module Risc module Builtin module CompileHelper @@ -44,7 +44,7 @@ module Risc word_type = space.get_type_by_class_name(:Word) [:putstring , :get_internal_byte , :set_internal_byte ].each do |f| - #compilers << compiler_for( word_type , Word , f) + compilers << compiler_for( word_type , Word , f) end int_type = space.get_type_by_class_name(:Integer) diff --git a/lib/risc/builtin/word.rb b/lib/risc/builtin/word.rb index d67d72ef..54e4f9b0 100644 --- a/lib/risc/builtin/word.rb +++ b/lib/risc/builtin/word.rb @@ -12,17 +12,21 @@ module Risc # - emit_syscall (which does the return of an integer, see there) def putstring( context) compiler = compiler_for(:Word , :putstring ,{}) - builder = compiler.builder(compiler.source) - builder.prepare_int_return # makes integer_tmp variable as return - builder.build do - word! << message[:receiver] - integer! << word[Parfait::Word.get_length_index] - end - Risc::Builtin::Object.emit_syscall( builder , :putstring ) - compiler.add_mom( Mom::ReturnSequence.new) - compiler + compiler.add_code Putstring.new("putstring") + return compiler + end + class Putstring < ::Mom::Instruction + def to_risc(compiler) + builder = compiler.builder(compiler.source) + builder.prepare_int_return # makes integer_tmp variable as return + builder.build do + word! << message[:receiver] + integer! << word[Parfait::Word.get_length_index] + end + Risc::Builtin.emit_syscall( builder , :putstring ) + compiler + end end - # self[index] basically. Index is the first arg > 0 # return a word sized new int, in return_value # @@ -30,39 +34,47 @@ module Risc # Which means the returned integer could be passed in, instead of allocated. def get_internal_byte( context) compiler = compiler_for(:Word , :get_internal_byte , {at: :Integer}) - builder = compiler.builder(compiler.source) - integer_tmp = builder.allocate_int - builder.build do - object! << message[:receiver] - integer! << message[:arguments] - integer << integer[Parfait::NamedList.type_length + 0] #"at" is at index 0 - integer.reduce_int - object <= object[integer] - integer_tmp[Parfait::Integer.integer_index] << object - message[:return_value] << integer_tmp - end - compiler.add_mom( Mom::ReturnSequence.new) + compiler.add_code GetInternalByte.new("get_internal_byte") return compiler end - + class GetInternalByte < ::Mom::Instruction + def to_risc(compiler) + builder = compiler.builder(compiler.source) + integer_tmp = builder.allocate_int + builder.build do + object! << message[:receiver] + integer! << message[:arguments] + integer << integer[Parfait::NamedList.type_length + 0] #"at" is at index 0 + integer.reduce_int + object <= object[integer] + integer_tmp[Parfait::Integer.integer_index] << object + message[:return_value] << integer_tmp + end + return compiler + end + end # self[index] = val basically. Index is the first arg ( >0 , unchecked), # value the second, which is also returned def set_internal_byte( context ) compiler = compiler_for(:Word, :set_internal_byte , {at: :Integer , value: :Integer} ) - compiler.builder(compiler.source).build do - word! << message[:receiver] - integer! << message[:arguments] - integer_reg! << integer[Parfait::NamedList.type_length + 1] #"value" is at index 1 - message[:return_value] << integer_reg - integer << integer[Parfait::NamedList.type_length + 0] #"at" is at index 0 - integer.reduce_int - integer_reg.reduce_int - word[integer] <= integer_reg - end - compiler.add_mom( Mom::ReturnSequence.new) + compiler.add_code SetInternalByte.new("set_internal_byte") return compiler end - + class SetInternalByte < ::Mom::Instruction + def to_risc(compiler) + compiler.builder(compiler.source).build do + word! << message[:receiver] + integer! << message[:arguments] + integer_reg! << integer[Parfait::NamedList.type_length + 1] #"value" is at index 1 + message[:return_value] << integer_reg + integer << integer[Parfait::NamedList.type_length + 0] #"at" is at index 0 + integer.reduce_int + integer_reg.reduce_int + word[integer] <= integer_reg + end + return compiler + end + end end extend ClassMethods end diff --git a/test/risc/builtin/test_word.rb b/test/risc/builtin/test_word.rb new file mode 100644 index 00000000..e257f578 --- /dev/null +++ b/test/risc/builtin/test_word.rb @@ -0,0 +1,60 @@ +require_relative "helper" + +module Risc + module Builtin + class TestWordPut < BootTest + def setup + super + @method = get_compiler(:putstring) + end + def test_has_get_internal + assert_equal Mom::MethodCompiler , @method.class + end + def test_mom_length + assert_equal 5 , @method.mom_instructions.length + end + def test_compile + assert_equal Risc::MethodCompiler , @method.to_risc.class + end + def test_risc_length + assert_equal 50 , @method.to_risc.risc_instructions.length + end + end + class TestWordGet < BootTest + def setup + super + @method = get_compiler(:get_internal_byte) + end + def test_has_get_internal + assert_equal Mom::MethodCompiler , @method.class + end + def test_mom_length + assert_equal 5 , @method.mom_instructions.length + end + def test_compile + assert_equal Risc::MethodCompiler , @method.to_risc.class + end + def test_risc_length + assert_equal 48 , @method.to_risc.risc_instructions.length + end + end + class TestWordSet < BootTest + def setup + super + @method = get_compiler(:set_internal_byte) + end + def test_has_get_internal + assert_equal Mom::MethodCompiler , @method.class + end + def test_mom_length + assert_equal 5 , @method.mom_instructions.length + end + def test_compile + assert_equal Risc::MethodCompiler , @method.to_risc.class + end + def test_risc_length + assert_equal 22 , @method.to_risc.risc_instructions.length + end + end + end +end diff --git a/test/risc/test_builtin.rb b/test/risc/test_builtin.rb index d6ab2055..eb26f545 100644 --- a/test/risc/test_builtin.rb +++ b/test/risc/test_builtin.rb @@ -14,7 +14,7 @@ module Risc assert_equal Array, @functions.class end def test_boot_function_length - assert_equal 6, @functions.length + assert_equal 9, @functions.length end def test_boot_function_first assert_equal Mom::MethodCompiler, @functions.first.class