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/space"
require_relative "builtin/integer" require_relative "builtin/integer"
require_relative "builtin/object" require_relative "builtin/object"
@ -25,22 +37,23 @@ module Risc
end end
obj_type = space.get_type_by_class_name(:Object) obj_type = space.get_type_by_class_name(:Object)
[ :get_internal_word , :set_internal_word , :_method_missing, [ :get_internal_word , #:set_internal_word , :_method_missing,
:exit , :__init__].each do |f| #:exit , :__init__
].each do |f|
compilers << compiler_for( obj_type , Object , f) compilers << compiler_for( obj_type , Object , f)
end end
word_type = space.get_type_by_class_name(:Word) word_type = space.get_type_by_class_name(:Word)
[:putstring , :get_internal_byte , :set_internal_byte ].each do |f| [: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 end
int_type = space.get_type_by_class_name(:Integer) int_type = space.get_type_by_class_name(:Integer)
Risc.operators.each do |op| Risc.operators.each do |op|
compilers << operator_compiler( int_type , op) #compilers << operator_compiler( int_type , op)
end end
[:putint, :div4, :div10 , :<,:<= , :>=, :>].each do |f| #div4 is just a forward declaration [: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 end
compilers compilers
end 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,17 +8,21 @@ module Risc
# return is stored in return_value # return is stored in return_value
def get_internal_word( context ) def get_internal_word( context )
compiler = compiler_for(:Object , :get_internal_word ,{at: :Integer}) compiler = compiler_for(:Object , :get_internal_word ,{at: :Integer})
compiler.builder(compiler.source).build do compiler.add_code GetInternalWord.new("get_internal_word")
object! << message[:receiver]
integer! << message[:arguments]
integer << integer[Parfait::NamedList.type_length + 0] #"at" is at index 0
integer.reduce_int
object << object[integer]
message[:return_value] << object
end
compiler.add_mom( Mom::ReturnSequence.new)
return compiler return compiler
end end
class GetInternalWord < ::Mom::Instruction
def to_risc(compiler)
compiler.builder(compiler.source).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]
message[:return_value] << object
end
end
end
# self[index] = val basically. Index is the first arg , value the second # self[index] = val basically. Index is the first arg , value the second
# return the value passed in # return the value passed in

View File

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

View File

@ -34,7 +34,7 @@ module Risc
# #
# return compiler_for_type with the resolved type # 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 raise "create_method #{class_name}.#{class_name.class}" unless class_name.is_a? Symbol
clazz = Parfait.object_space.get_class_by_name! class_name clazz = Parfait.object_space.get_class_by_name! class_name
compiler_for_type( clazz.instance_type , method_name , args , frame) 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 # args a hash that will be converted to a type
# the created method is set as the current and the given type too # the created method is set as the current and the given type too
# return the compiler # 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 "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 "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 raise "create_method #{method_name}.#{method_name.class}" unless method_name.is_a? Symbol

View File

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

View File

@ -7,5 +7,15 @@ module Risc
def setup def setup
end end
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
end end

View File

@ -1,5 +1,6 @@
require_relative "helper" require_relative "helper"
# TODO move these to interpreter dir
module Risc module Risc
module Builtin module Builtin
class IntCmp < BuiltinTest 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 def setup
Parfait.boot!(Parfait.default_test_options) Parfait.boot!(Parfait.default_test_options)
@functions = Builtin.boot_functions
end end
def test_has_boot_function def test_has_boot_function
assert Builtin.boot_functions assert @functions
end end
def test_boot_function_type def test_boot_function_type
assert_equal Array, Builtin.boot_functions.class assert_equal Array, @functions.class
end end
def test_boot_function_length def test_boot_function_length
assert_equal 23, Builtin.boot_functions.length assert_equal 2, @functions.length
end end
def test_boot_function_first def test_boot_function_first
assert_equal MethodCompiler, Builtin.boot_functions.first.class assert_equal Mom::MethodCompiler, @functions.first.class
end end
end end
end end