starting to fix builtin

start at Object get_interna_word
using the pattern to replace the whole risc method with a single mom instruction. Copying the original risc code into the instrucitons to_risc
also adding some very basic tests
This commit is contained in:
Torsten Rüger 2019-08-11 14:31:00 +03:00
parent 0b59c95218
commit 0725f02e9a
10 changed files with 76 additions and 37 deletions

View File

@ -1,4 +1,16 @@
require_relative "builtin/compile_helper"
module Risc
module Builtin
module CompileHelper
def compiler_for( clazz_name , method_name , arguments , locals = {})
frame = Parfait::NamedList.type_for( locals )
args = Parfait::NamedList.type_for( arguments )
Mom::MethodCompiler.compiler_for_class(clazz_name , method_name , args, frame )
end
end
end
end
require_relative "builtin/space"
require_relative "builtin/integer"
require_relative "builtin/object"
@ -25,22 +37,23 @@ module Risc
end
obj_type = space.get_type_by_class_name(:Object)
[ :get_internal_word , :set_internal_word , :_method_missing,
:exit , :__init__].each do |f|
[ :get_internal_word , #:set_internal_word , :_method_missing,
#:exit , :__init__
].each do |f|
compilers << compiler_for( obj_type , Object , f)
end
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)
Risc.operators.each do |op|
compilers << operator_compiler( int_type , op)
#compilers << operator_compiler( int_type , op)
end
[:putint, :div4, :div10 , :<,:<= , :>=, :>].each do |f| #div4 is just a forward declaration
compilers << compiler_for( int_type , Integer , f)
#compilers << compiler_for( int_type , Integer , f)
end
compilers
end

View File

@ -1,14 +0,0 @@
module Risc
module Builtin
module CompileHelper
def compiler_for( clazz_name , method_name , arguments , locals = {})
frame = Parfait::NamedList.type_for( locals )
args = Parfait::NamedList.type_for( arguments )
MethodCompiler.compiler_for_class(clazz_name , method_name , args, frame )
end
end
end
end

View File

@ -8,6 +8,11 @@ module Risc
# return is stored in return_value
def get_internal_word( context )
compiler = compiler_for(:Object , :get_internal_word ,{at: :Integer})
compiler.add_code GetInternalWord.new("get_internal_word")
return compiler
end
class GetInternalWord < ::Mom::Instruction
def to_risc(compiler)
compiler.builder(compiler.source).build do
object! << message[:receiver]
integer! << message[:arguments]
@ -16,8 +21,7 @@ module Risc
object << object[integer]
message[:return_value] << object
end
compiler.add_mom( Mom::ReturnSequence.new)
return compiler
end
end
# self[index] = val basically. Index is the first arg , value the second

View File

@ -8,7 +8,6 @@ module Risc
# defined here as empty, to be redefined
def main(context)
compiler = compiler_for(:Space , :main ,{args: :Integer})
compiler.add_mom( Mom::ReturnSequence.new)
return compiler
end

View File

@ -34,7 +34,7 @@ module Risc
#
# return compiler_for_type with the resolved type
#
def self.compiler_for_class( class_name , method_name , args , frame )
def self.compiler_for_clazz( class_name , method_name , args , frame )
raise "create_method #{class_name}.#{class_name.class}" unless class_name.is_a? Symbol
clazz = Parfait.object_space.get_class_by_name! class_name
compiler_for_type( clazz.instance_type , method_name , args , frame)
@ -53,7 +53,7 @@ module Risc
# args a hash that will be converted to a type
# the created method is set as the current and the given type too
# return the compiler
def self.compiler_for_type( type , method_name , args , frame)
def self.compiler_for_typez( type , method_name , args , frame)
raise "create_method #{type.inspect} is not a Type" unless type.is_a? Parfait::Type
raise "Args must be Type #{args}" unless args.is_a?(Parfait::Type)
raise "create_method #{method_name}.#{method_name.class}" unless method_name.is_a? Symbol

View File

@ -1,11 +1,12 @@
require "rx-file"
require "util/logging"
require "util/list"
require_relative "elf/object_writer"
require_relative "mom/mom"
require_relative "risc"
require_relative "arm/arm_machine"
require_relative "arm/arm_platform"
require_relative "vool/statement"
require_relative "ruby"
require_relative "rubyx/rubyx_compiler"
require_relative "mom/mom"

View File

@ -7,5 +7,15 @@ module Risc
def setup
end
end
class BootTest < MiniTest::Test
def setup
Parfait.boot!(Parfait.default_test_options)
@functions = Builtin.boot_functions
end
def get_compiler( name )
@functions.each.find{|meth|
meth.callable.name == name}
end
end
end
end

View File

@ -1,5 +1,6 @@
require_relative "helper"
# TODO move these to interpreter dir
module Risc
module Builtin
class IntCmp < BuiltinTest

View File

@ -0,0 +1,24 @@
require_relative "helper"
module Risc
module Builtin
class TestObjectFunction1 < BootTest
def setup
super
@method = get_compiler(:get_internal_word)
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 20 , @method.to_risc.risc_instructions.length
end
end
end
end

View File

@ -5,18 +5,19 @@ module Risc
def setup
Parfait.boot!(Parfait.default_test_options)
@functions = Builtin.boot_functions
end
def test_has_boot_function
assert Builtin.boot_functions
assert @functions
end
def test_boot_function_type
assert_equal Array, Builtin.boot_functions.class
assert_equal Array, @functions.class
end
def test_boot_function_length
assert_equal 23, Builtin.boot_functions.length
assert_equal 2, @functions.length
end
def test_boot_function_first
assert_equal MethodCompiler, Builtin.boot_functions.first.class
assert_equal Mom::MethodCompiler, @functions.first.class
end
end
end