Add number of registers to platform

This commit is contained in:
Torsten 2020-02-26 19:01:01 +02:00
parent 8df2e4bf08
commit 8832df3221
13 changed files with 63 additions and 33 deletions

View File

@ -10,5 +10,8 @@ module Arm
def padding
0x11000 - loaded_at
end
def num_registers
16
end
end
end

View File

@ -1,7 +1,8 @@
module Risc
# A BlockCompiler is much like a MethodCompiler, exept for it's for blocks
# This only changes scoping for variables, lsee slot_type
# This only changes scoping for variables, see slot_type
# (dynamic resolve, as needed when the block is passed, is not implemented)
#
class BlockCompiler < CallableCompiler

View File

@ -25,6 +25,7 @@ module Risc
end
attr_reader :risc_instructions , :constants , :callable , :current
# find the return label. Every methd should have exactly one
def return_label
@risc_instructions.each do |ins|
next unless ins.is_a?(Label)
@ -33,6 +34,7 @@ module Risc
end
# add a constant (which get created during compilation and need to be linked)
# constants must be Parfait instances
def add_constant(const)
raise "Must be Parfait #{const}" unless const.is_a?(Parfait::Object)
@constants << const

View File

@ -29,7 +29,7 @@ module Risc
@registers = {}
@flags = { :zero => false , :plus => false ,
:minus => false , :overflow => false }
(0...12).each do |reg|
(0...InterpreterPlatform.new.num_registers).each do |reg|
set_register "r#{reg}".to_sym , "r#{reg}:unknown"
end
@linker = linker

View File

@ -10,6 +10,9 @@ module Risc
def padding
0x100 - loaded_at
end
def num_registers
16
end
end
class Instruction
def nil_next

View File

@ -13,6 +13,11 @@ module Risc
# return an integer where the binary is loaded
def loaded_at
end
# return the number of registers the platform supports
def num_registers
end
# Factory method to create a Platform object according to the platform
# string given.
# Currently only "Arm" and "Interpreter"

View File

@ -1,6 +1,10 @@
module SlotMachine
# A BlockCompiler is much like a MehtodCompiler, exept for blocks
# A BlockCompiler is much like a MethodCompiler, except for blocks
# Blocks are much like methods (hence the base classes) , just the
# scope for accessing variables is different. (This only applies to static
# blocks, not ones being passed around. That is undone because it needs runtime
# code to resolve variables)
#
class BlockCompiler < CallableCompiler
@ -16,6 +20,8 @@ module SlotMachine
"#{@method.self_type.name}.init"
end
# Create the risc equivalent, which is a also a (Risc) BlockCompiler
# sintructions are converted from slot to risc in instructions_to_risc (in base class)
def to_risc
risc_compiler = Risc::BlockCompiler.new(@callable , @method , slot_instructions)
instructions_to_risc(risc_compiler)

View File

@ -6,6 +6,9 @@ module SlotMachine
# - slot_instructions: The sequence of slot level instructions that was compiled to
# Instructions derive from class Instruction and form a linked list
# Since we have many different compilers, and they are kept in lists, the
# Util CompilerList encapsulates the list behaviour
#
class CallableCompiler
include Util::CompilerList
@ -21,6 +24,8 @@ module SlotMachine
end
attr_reader :slot_instructions , :constants , :callable , :current
# find the return_label, every method should have exactly one (see constructor)
# used during return sequence code generation
def return_label
@slot_instructions.each do |ins|
next unless ins.is_a?(Label)

View File

@ -5,6 +5,30 @@ module SlotMachine
class MethodCompiler < CallableCompiler
# helper method for builtin mainly
# the class_name is a symbol, which is resolved to the instance_type of that class
#
# return compiler_for_type with the resolved type
#
def self.compiler_for_class( 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)
end
# create a method for the given type ( Parfait type object)
# method_name is a Symbol
# 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)
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
method = type.create_method( method_name , args , frame)
self.new(method)
end
def initialize( method )
super(method)
end
@ -30,38 +54,13 @@ module SlotMachine
risc_compiler
end
# helper method for builtin mainly
# the class_name is a symbol, which is resolved to the instance_type of that class
#
# return compiler_for_type with the resolved type
#
def self.compiler_for_class( 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)
end
def add_method_to( target )
target.add_method( @callable )
end
# create a block in the scope of the method.
# Blocks are like other constants, exept with code.
# They need to be compiled, so a list of them is kept
def create_block(arg_type , frame_type)
@callable.create_block(arg_type ,frame_type)
end
# create a method for the given type ( Parfait type object)
# method_name is a Symbol
# 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)
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
method = type.create_method( method_name , args , frame)
self.new(method)
end
# determine how given name need to be accsessed.
# For methods the options are args or frame
def slot_type_for(name)

View File

@ -14,5 +14,8 @@ module Arm
def test_platform_loaded_class
assert_equal ::Integer , @arm.loaded_at.class
end
def test_registers
assert_equal 16 , @arm.num_registers
end
end
end

View File

@ -20,7 +20,7 @@ module Risc
assert_equal :stopped , Interpreter.new(@linker).state
end
def test_has_regs
assert_equal 12 , Interpreter.new(@linker).registers.length
assert_equal 16 , Interpreter.new(@linker).registers.length
end
def test_has_r0
assert_equal :r0 , Interpreter.new(@linker).registers.keys.first

View File

@ -17,6 +17,9 @@ module Risc
def test_translator
assert IdentityTranslator.new
end
def test_registers
assert_equal 16 , @inter.num_registers
end
end
class TestIdentityTranslator < MiniTest::Test

View File

@ -1,7 +1,7 @@
require_relative "../helper"
module Sol
class TestSendCachedSimpleSlotMachine < MiniTest::Test
class TestNotFoundSlotMachine < MiniTest::Test
include SolCompile
def setup