Add number of registers to platform
This commit is contained in:
parent
8df2e4bf08
commit
8832df3221
@ -10,5 +10,8 @@ module Arm
|
||||
def padding
|
||||
0x11000 - loaded_at
|
||||
end
|
||||
def num_registers
|
||||
16
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -10,6 +10,9 @@ module Risc
|
||||
def padding
|
||||
0x100 - loaded_at
|
||||
end
|
||||
def num_registers
|
||||
16
|
||||
end
|
||||
end
|
||||
class Instruction
|
||||
def nil_next
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
require_relative "../helper"
|
||||
|
||||
module Sol
|
||||
class TestSendCachedSimpleSlotMachine < MiniTest::Test
|
||||
class TestNotFoundSlotMachine < MiniTest::Test
|
||||
include SolCompile
|
||||
|
||||
def setup
|
||||
|
Loading…
Reference in New Issue
Block a user