fold last of the virtual into register
This commit is contained in:
parent
f658ecf425
commit
dcbd3c7091
@ -1,6 +1,6 @@
|
|||||||
GIT
|
GIT
|
||||||
remote: git://github.com/salama/salama-arm.git
|
remote: git://github.com/salama/salama-arm.git
|
||||||
revision: c278f7eec20e9d62a55394bb7691e976980cbbe9
|
revision: 3fcf596a028d48ab5fa2f31babafbc5f97a6edab
|
||||||
specs:
|
specs:
|
||||||
salama-arm (0.3.0)
|
salama-arm (0.3.0)
|
||||||
|
|
||||||
|
@ -80,13 +80,13 @@ it's main purpose is to have an oo system language to compile to.
|
|||||||
I spent some time on the parse testing framework, so it is safe to fiddle and add.
|
I spent some time on the parse testing framework, so it is safe to fiddle and add.
|
||||||
In fact it is very modular and easy to add to.
|
In fact it is very modular and easy to add to.
|
||||||
|
|
||||||
### Virtual: Compile the Ast
|
### Register: Compile the Ast
|
||||||
|
|
||||||
Since we now have an Abstact syntax tree, it needs to be compiled to a virtual machine Instruction format.
|
Since we now have an Abstact syntax tree, it needs to be compiled to a virtual machine Instruction format.
|
||||||
For the parsed subset that's almost done.
|
For the parsed subset that's almost done.
|
||||||
|
|
||||||
It took me a while to come up with a decent but simple machine model. I had tried to map straight to hardware
|
It took me a while to come up with a decent but simple machine model. I had tried to map straight to hardware
|
||||||
but failed. The current Virtual directory represent a machine with basic oo features.
|
but failed. The current Register directory represent a machine with basic oo features.
|
||||||
|
|
||||||
### Parfait - the runtime
|
### Parfait - the runtime
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ module Interpreter
|
|||||||
|
|
||||||
def object_for reg
|
def object_for reg
|
||||||
id = get_register(reg)
|
id = get_register(reg)
|
||||||
object = Virtual.machine.objects[id]
|
object = Register.machine.objects[id]
|
||||||
object.nil? ? id : object
|
object.nil? ? id : object
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ module Parfait
|
|||||||
|
|
||||||
# in a non-booting version this should map to _add_singleton_method
|
# in a non-booting version this should map to _add_singleton_method
|
||||||
# def add_function function
|
# def add_function function
|
||||||
# raise "not a function #{function}" unless function.is_a? Virtual::Function
|
# raise "not a function #{function}" unless function.is_a? Register::Function
|
||||||
# raise "syserr " unless function.name.is_a? Symbol
|
# raise "syserr " unless function.name.is_a? Symbol
|
||||||
# self.functions << function
|
# self.functions << function
|
||||||
# end
|
# end
|
||||||
|
@ -13,7 +13,7 @@ module Parfait
|
|||||||
# known local variable names
|
# known local variable names
|
||||||
# executable code
|
# executable code
|
||||||
|
|
||||||
# ps, the compiler injects its own info, see Virtual::MethodSource
|
# ps, the compiler injects its own info, see Register::MethodSource
|
||||||
|
|
||||||
|
|
||||||
class Method < Object
|
class Method < Object
|
||||||
|
@ -2,7 +2,7 @@ module Parfait
|
|||||||
class Variable < Object
|
class Variable < Object
|
||||||
|
|
||||||
def initialize type , name , value = nil
|
def initialize type , name , value = nil
|
||||||
raise "not type #{type}" unless Virtual.machine.space.get_class_by_name(type)
|
raise "not type #{type}" unless Register.machine.space.get_class_by_name(type)
|
||||||
self.type , self.name , self.value = type , name , value
|
self.type , self.name , self.value = type , name , value
|
||||||
self.value = 0 if self.type == :Integer and value == nil
|
self.value = 0 if self.type == :Integer and value == nil
|
||||||
raise "must give name for variable" unless name
|
raise "must give name for variable" unless name
|
||||||
|
@ -16,7 +16,7 @@ module Parfait
|
|||||||
class Word < Object
|
class Word < Object
|
||||||
# initialize with length. For now we try to keep all non-parfait (including String) out
|
# initialize with length. For now we try to keep all non-parfait (including String) out
|
||||||
# String will contain spaces for non-zero length
|
# String will contain spaces for non-zero length
|
||||||
# Virtual provides methods to create Parfait objects from ruby
|
# Register provides methods to create Parfait objects from ruby
|
||||||
def initialize len
|
def initialize len
|
||||||
super()
|
super()
|
||||||
raise "Must init with int, not #{len.class}" unless len.kind_of? Fixnum
|
raise "Must init with int, not #{len.class}" unless len.kind_of? Fixnum
|
||||||
|
@ -34,10 +34,10 @@ module Phisol
|
|||||||
end
|
end
|
||||||
|
|
||||||
# now we have to resolve the method name (+ receiver) into a callable method
|
# now we have to resolve the method name (+ receiver) into a callable method
|
||||||
clazz = Virtual.machine.space.get_class_by_name(me.type)
|
clazz = Register.machine.space.get_class_by_name(me.type)
|
||||||
raise "No such class #{me.type}" unless clazz
|
raise "No such class #{me.type}" unless clazz
|
||||||
method = clazz.get_instance_method(name)
|
method = clazz.get_instance_method(name)
|
||||||
#puts Virtual.machine.space.get_class_by_name(:Integer).method_names.to_a
|
#puts Register.machine.space.get_class_by_name(:Integer).method_names.to_a
|
||||||
raise "Method not implemented #{me.type}.#{name}" unless method
|
raise "Method not implemented #{me.type}.#{name}" unless method
|
||||||
Register.issue_call( @method , method )
|
Register.issue_call( @method , method )
|
||||||
ret = use_reg( method.source.return_type )
|
ret = use_reg( method.source.return_type )
|
||||||
|
@ -19,7 +19,7 @@ module Phisol
|
|||||||
if( r != :self)
|
if( r != :self)
|
||||||
raise "unimplemented case in function #{r}"
|
raise "unimplemented case in function #{r}"
|
||||||
else
|
else
|
||||||
r = Virtual::Self.new()
|
r = Register::Self.new()
|
||||||
class_name = method.for_class.name
|
class_name = method.for_class.name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -34,7 +34,7 @@ module Phisol
|
|||||||
#TODO check args / type compatibility
|
#TODO check args / type compatibility
|
||||||
@method.source.init @method
|
@method.source.init @method
|
||||||
else
|
else
|
||||||
@method = Virtual::MethodSource.create_method(class_name, return_type, name , args )
|
@method = Register::MethodSource.create_method(class_name, return_type, name , args )
|
||||||
@method.for_class.add_instance_method @method
|
@method.for_class.add_instance_method @method
|
||||||
end
|
end
|
||||||
@method.source.receiver = r
|
@method.source.receiver = r
|
||||||
|
20
lib/register.rb
Normal file
20
lib/register.rb
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
require "parfait"
|
||||||
|
require "register/machine"
|
||||||
|
#if we are in the ruby run-time / generating an executable
|
||||||
|
require "register/positioned"
|
||||||
|
require "register/padding"
|
||||||
|
require "register/parfait_adapter"
|
||||||
|
|
||||||
|
require "phisol/compiler"
|
||||||
|
require "register/method_source"
|
||||||
|
|
||||||
|
|
||||||
|
class Fixnum
|
||||||
|
def fits_u8?
|
||||||
|
self >= 0 and self <= 255
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
require "register/instruction"
|
||||||
|
require "register/register_value"
|
||||||
|
require "register/assembler"
|
@ -238,5 +238,5 @@ module Register
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Sof::Volotile.add(Register::Assembler , [:objects])
|
Sof::Volotile.add(Assembler , [:objects])
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
module Virtual
|
module Register
|
||||||
|
|
||||||
# Think flowcharts: blocks are the boxes. The smallest unit of linear code
|
# Think flowcharts: blocks are the boxes. The smallest unit of linear code
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
module Virtual
|
module Register
|
||||||
|
|
||||||
# Booting is a complicated, so it is extracted into this file, even it has only one entry point
|
# Booting is a complicated, so it is extracted into this file, even it has only one entry point
|
||||||
|
|
||||||
@ -147,19 +147,19 @@ module Virtual
|
|||||||
# TODO go through the virtual parfait layer and adjust function names to what they really are
|
# TODO go through the virtual parfait layer and adjust function names to what they really are
|
||||||
obj = @space.get_class_by_name(:Object)
|
obj = @space.get_class_by_name(:Object)
|
||||||
[:main , :_get_instance_variable , :_set_instance_variable].each do |f|
|
[:main , :_get_instance_variable , :_set_instance_variable].each do |f|
|
||||||
obj.add_instance_method Register::Builtin::Object.send(f , nil)
|
obj.add_instance_method Builtin::Object.send(f , nil)
|
||||||
end
|
end
|
||||||
obj = @space.get_class_by_name(:Kernel)
|
obj = @space.get_class_by_name(:Kernel)
|
||||||
# create __init__ main first, __init__ calls it
|
# create __init__ main first, __init__ calls it
|
||||||
[:exit,:__send , :__init__ ].each do |f|
|
[:exit,:__send , :__init__ ].each do |f|
|
||||||
obj.add_instance_method Register::Builtin::Kernel.send(f , nil)
|
obj.add_instance_method Builtin::Kernel.send(f , nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
@space.get_class_by_name(:Word).add_instance_method Register::Builtin::Word.send(:putstring , nil)
|
@space.get_class_by_name(:Word).add_instance_method Builtin::Word.send(:putstring , nil)
|
||||||
|
|
||||||
obj = @space.get_class_by_name(:Integer)
|
obj = @space.get_class_by_name(:Integer)
|
||||||
[:putint,:fibo , :plus].each do |f|
|
[:putint,:fibo , :plus].each do |f|
|
||||||
obj.add_instance_method Register::Builtin::Integer.send(f , nil)
|
obj.add_instance_method Builtin::Integer.send(f , nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -4,9 +4,9 @@ The Builtin module contains functions that can not be coded in ruby.
|
|||||||
It is the other side of the parfait coin, part of the runtime.
|
It is the other side of the parfait coin, part of the runtime.
|
||||||
|
|
||||||
The functions are organized by their respective class and get loaded in boot_classes! ,
|
The functions are organized by their respective class and get loaded in boot_classes! ,
|
||||||
right at the start. (see virtual/boot.rb)
|
right at the start. (see register/boot.rb)
|
||||||
|
|
||||||
These functions return their code, ie a Parfait::Method with a Virtual::MethodSource object,
|
These functions return their code, ie a Parfait::Method with a MethodSource object,
|
||||||
which can then be called by ruby code as if it were a "normal" function.
|
which can then be called by ruby code as if it were a "normal" function.
|
||||||
|
|
||||||
A normal ruby function is one that is parsed and transformed to code. But not all functionality can
|
A normal ruby function is one that is parsed and transformed to code. But not all functionality can
|
||||||
|
@ -5,7 +5,7 @@ module Register
|
|||||||
module ClassMethods
|
module ClassMethods
|
||||||
include AST::Sexp
|
include AST::Sexp
|
||||||
def plus c
|
def plus c
|
||||||
plus_function = Virtual::MethodSource.create_method(:Integer,:Integer,:plus , [:Integer] )
|
plus_function = MethodSource.create_method(:Integer,:Integer,:plus , [:Integer] )
|
||||||
plus_function.source.set_return_type :Integer
|
plus_function.source.set_return_type :Integer
|
||||||
plus_function.source.receiver = :Integer
|
plus_function.source.receiver = :Integer
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ module Register
|
|||||||
|
|
||||||
me = Register.tmp_reg :Integer
|
me = Register.tmp_reg :Integer
|
||||||
plus_function.source.add_code Register.get_slot(plus_function , :message , :receiver , me )
|
plus_function.source.add_code Register.get_slot(plus_function , :message , :receiver , me )
|
||||||
add = Register::OperatorInstruction.new( plus_function, :add , me , tmp )
|
add = OperatorInstruction.new( plus_function, :add , me , tmp )
|
||||||
plus_function.source.add_code add
|
plus_function.source.add_code add
|
||||||
plus_function.source.add_code Register.set_slot(plus_function , me , :message , :return_value )
|
plus_function.source.add_code Register.set_slot(plus_function , me , :message , :return_value )
|
||||||
return plus_function
|
return plus_function
|
||||||
@ -28,14 +28,14 @@ module Register
|
|||||||
# As we write before we recurse (save a push) we write the number backwards
|
# As we write before we recurse (save a push) we write the number backwards
|
||||||
# arguments: string address , integer
|
# arguments: string address , integer
|
||||||
# def utoa context
|
# def utoa context
|
||||||
# utoa_function = Virtual::MethodSource.create_method(:Integer ,:utoa , [ :Integer ] )
|
# utoa_function = MethodSource.create_method(:Integer ,:utoa , [ :Integer ] )
|
||||||
# function.source.return_type = :Integer
|
# function.source.return_type = :Integer
|
||||||
# function.source.receiver = :Integer
|
# function.source.receiver = :Integer
|
||||||
# return utoa_function
|
# return utoa_function
|
||||||
# # str_addr = utoa_function.receiver
|
# # str_addr = utoa_function.receiver
|
||||||
# # number = utoa_function.args.first
|
# # number = utoa_function.args.first
|
||||||
# # remainder = utoa_function.new_local
|
# # remainder = utoa_function.new_local
|
||||||
# # Virtual::RegisterMachine.instance.div10( utoa_function , number , remainder )
|
# # RegisterMachine.instance.div10( utoa_function , number , remainder )
|
||||||
# # # make char out of digit (by using ascii encoding) 48 == "0"
|
# # # make char out of digit (by using ascii encoding) 48 == "0"
|
||||||
# # utoa_function.instance_eval do
|
# # utoa_function.instance_eval do
|
||||||
# # add( remainder , remainder , 48)
|
# # add( remainder , remainder , 48)
|
||||||
@ -48,7 +48,7 @@ module Register
|
|||||||
# end
|
# end
|
||||||
|
|
||||||
def putint context
|
def putint context
|
||||||
putint_function = Virtual::MethodSource.create_method(:Integer,:Integer,:putint , [] )
|
putint_function = MethodSource.create_method(:Integer,:Integer,:putint , [] )
|
||||||
putint_function.source.set_return_type :Integer
|
putint_function.source.set_return_type :Integer
|
||||||
putint_function.source.receiver = :Integer
|
putint_function.source.receiver = :Integer
|
||||||
return putint_function
|
return putint_function
|
||||||
@ -68,7 +68,7 @@ module Register
|
|||||||
# add( int , buffer , nil ) # string to write to
|
# add( int , buffer , nil ) # string to write to
|
||||||
# mov( moved_int , buffer.length )
|
# mov( moved_int , buffer.length )
|
||||||
# end
|
# end
|
||||||
# Virtual::RegisterMachine.instance.write_stdout(putint_function)
|
# RegisterMachine.instance.write_stdout(putint_function)
|
||||||
# putint_function
|
# putint_function
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ module Register
|
|||||||
# a hand coded version of the fibonachi numbers
|
# a hand coded version of the fibonachi numbers
|
||||||
# not my hand off course, found in the net http://www.peter-cockerell.net/aalp/html/ch-5.html
|
# not my hand off course, found in the net http://www.peter-cockerell.net/aalp/html/ch-5.html
|
||||||
def fibo context
|
def fibo context
|
||||||
fibo_function = Virtual::MethodSource.create_method(:Integer,:Integer,:fibo , [] )
|
fibo_function = MethodSource.create_method(:Integer,:Integer,:fibo , [] )
|
||||||
fibo_function.source.set_return_type :Integer
|
fibo_function.source.set_return_type :Integer
|
||||||
fibo_function.source.receiver = :Integer
|
fibo_function.source.receiver = :Integer
|
||||||
return fibo_function
|
return fibo_function
|
||||||
|
@ -6,7 +6,7 @@ module Register
|
|||||||
# it isn't really a function, ie it is jumped to (not called), exits and may not return
|
# it isn't really a function, ie it is jumped to (not called), exits and may not return
|
||||||
# so it is responsible for initial setup
|
# so it is responsible for initial setup
|
||||||
def __init__ context
|
def __init__ context
|
||||||
function = Virtual::MethodSource.create_method(:Kernel,:Integer,:__init__ , [])
|
function = MethodSource.create_method(:Kernel,:Integer,:__init__ , [])
|
||||||
function.source.set_return_type :Integer
|
function.source.set_return_type :Integer
|
||||||
# no method enter or return (automatically added), remove
|
# no method enter or return (automatically added), remove
|
||||||
function.source.blocks.first.codes.pop # no Method enter
|
function.source.blocks.first.codes.pop # no Method enter
|
||||||
@ -21,20 +21,20 @@ module Register
|
|||||||
# And store the space as the new self (so the call can move it back as self)
|
# And store the space as the new self (so the call can move it back as self)
|
||||||
function.source.add_code Register.set_slot( function, space_reg , :new_message , :receiver)
|
function.source.add_code Register.set_slot( function, space_reg , :new_message , :receiver)
|
||||||
# now we are set up to issue a call to the main
|
# now we are set up to issue a call to the main
|
||||||
Register.issue_call( function , Virtual.machine.space.get_main)
|
Register.issue_call( function , Register.machine.space.get_main)
|
||||||
emit_syscall( function , :exit )
|
emit_syscall( function , :exit )
|
||||||
return function
|
return function
|
||||||
end
|
end
|
||||||
def exit context
|
def exit context
|
||||||
function = Virtual::MethodSource.create_method(:Kernel,:Integer,:exit , [])
|
function = MethodSource.create_method(:Kernel,:Integer,:exit , [])
|
||||||
function.source.set_return_type :Integer
|
function.source.set_return_type :Integer
|
||||||
return function
|
return function
|
||||||
ret = Virtual::RegisterMachine.instance.exit(function)
|
ret = RegisterMachine.instance.exit(function)
|
||||||
function.set_return ret
|
function.set_return ret
|
||||||
function
|
function
|
||||||
end
|
end
|
||||||
def __send context
|
def __send context
|
||||||
function = Virtual::MethodSource.create_method(:Kernel,:Integer ,:__send , [] )
|
function = MethodSource.create_method(:Kernel,:Integer ,:__send , [] )
|
||||||
function.source.set_return_type :Integer
|
function.source.set_return_type :Integer
|
||||||
return function
|
return function
|
||||||
end
|
end
|
||||||
|
@ -6,7 +6,7 @@ module Register
|
|||||||
# main entry point, ie __init__ calls this
|
# main entry point, ie __init__ calls this
|
||||||
# defined here as empty, to be redefined
|
# defined here as empty, to be redefined
|
||||||
def main context
|
def main context
|
||||||
function = Virtual::MethodSource.create_method(:Object, :Integer , :main , [])
|
function = MethodSource.create_method(:Object, :Integer , :main , [])
|
||||||
return function
|
return function
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -18,13 +18,13 @@ module Register
|
|||||||
# The at_index is just "below" the api, something we need but don't want to expose,
|
# The at_index is just "below" the api, something we need but don't want to expose,
|
||||||
# so we can't code the above in ruby
|
# so we can't code the above in ruby
|
||||||
def _get_instance_variable context , name = :Integer
|
def _get_instance_variable context , name = :Integer
|
||||||
get_function = Virtual::MethodSource.create_method(:Object,:Integer, :_get_instance_variable , [ ] )
|
get_function = MethodSource.create_method(:Object,:Integer, :_get_instance_variable , [ ] )
|
||||||
return get_function
|
return get_function
|
||||||
# me = get_function.receiver
|
# me = get_function.receiver
|
||||||
# var_name = get_function.args.first
|
# var_name = get_function.args.first
|
||||||
# return_to = get_function.return_type
|
# return_to = get_function.return_type
|
||||||
#
|
#
|
||||||
# index_function = ::Virtual.machine.space.get_class_by_name(:Object).resolve_method(:index_of)
|
# index_function = ::Register.machine.space.get_class_by_name(:Object).resolve_method(:index_of)
|
||||||
# # get_function.push( [me] )
|
# # get_function.push( [me] )
|
||||||
# # index = get_function.call( index_function )
|
# # index = get_function.call( index_function )
|
||||||
#
|
#
|
||||||
@ -39,7 +39,7 @@ module Register
|
|||||||
end
|
end
|
||||||
|
|
||||||
def _set_instance_variable(context , name = :Integer , value = :Integer )
|
def _set_instance_variable(context , name = :Integer , value = :Integer )
|
||||||
set_function = Virtual::MethodSource.create_method(:Object,:Integer,:_set_instance_variable ,[] )
|
set_function = MethodSource.create_method(:Object,:Integer,:_set_instance_variable ,[] )
|
||||||
return set_function
|
return set_function
|
||||||
# receiver set_function
|
# receiver set_function
|
||||||
# me = set_function.receiver
|
# me = set_function.receiver
|
||||||
|
@ -3,7 +3,7 @@ module Register
|
|||||||
module Word
|
module Word
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
def putstring context
|
def putstring context
|
||||||
function = Virtual::MethodSource.create_method(:Word,:Integer , :putstring , [] )
|
function = MethodSource.create_method(:Word,:Integer , :putstring , [] )
|
||||||
function.source.add_code Register.get_slot( function , :message , :receiver , :new_message )
|
function.source.add_code Register.get_slot( function , :message , :receiver , :new_message )
|
||||||
Kernel.emit_syscall( function , :putstring )
|
Kernel.emit_syscall( function , :putstring )
|
||||||
function
|
function
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
module Virtual
|
module Register
|
||||||
|
|
||||||
# collect anything that is in the space but and reachable from init
|
# collect anything that is in the space but and reachable from init
|
||||||
module Collector
|
module Collector
|
@ -24,8 +24,8 @@ module Register
|
|||||||
@index = index
|
@index = index
|
||||||
@register = register
|
@register = register
|
||||||
raise "not integer #{index}" unless index.is_a? Numeric
|
raise "not integer #{index}" unless index.is_a? Numeric
|
||||||
raise "Not register #{register}" unless Register::RegisterValue.look_like_reg(register)
|
raise "Not register #{register}" unless RegisterValue.look_like_reg(register)
|
||||||
raise "Not register #{array}" unless Register::RegisterValue.look_like_reg(array)
|
raise "Not register #{array}" unless RegisterValue.look_like_reg(array)
|
||||||
end
|
end
|
||||||
attr_accessor :array , :index , :register
|
attr_accessor :array , :index , :register
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@ module Register
|
|||||||
@array = array
|
@array = array
|
||||||
@index = index
|
@index = index
|
||||||
raise "not integer #{index}" unless index.is_a? Numeric
|
raise "not integer #{index}" unless index.is_a? Numeric
|
||||||
raise "Not register #{register}" unless Register::RegisterValue.look_like_reg(register)
|
raise "Not register #{register}" unless RegisterValue.look_like_reg(register)
|
||||||
raise "Not register #{array}" unless Register::RegisterValue.look_like_reg(array)
|
raise "Not register #{array}" unless RegisterValue.look_like_reg(array)
|
||||||
end
|
end
|
||||||
attr_accessor :register , :array , :index
|
attr_accessor :register , :array , :index
|
||||||
def to_s
|
def to_s
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
require 'parslet/convenience'
|
require 'parslet/convenience'
|
||||||
require_relative "collector"
|
require_relative "collector"
|
||||||
module Virtual
|
module Register
|
||||||
# The Virtual Machine is a object based virtual machine in which ruby is implemented.
|
# The Register Machine is a object based virtual machine in which ruby is implemented.
|
||||||
#
|
#
|
||||||
# It is minimal and realistic and low level
|
# It is minimal and realistic and low level
|
||||||
# - minimal means that if one thing can be implemented by another, it is left out. This is quite
|
# - minimal means that if one thing can be implemented by another, it is left out. This is quite
|
||||||
@ -118,7 +118,7 @@ module Virtual
|
|||||||
def boot
|
def boot
|
||||||
boot_parfait!
|
boot_parfait!
|
||||||
@init = Block.new("init", :__init__ )
|
@init = Block.new("init", :__init__ )
|
||||||
branch = Register::Branch.new( "__init__" , self.space.get_init.source.blocks.first )
|
branch = Branch.new( "__init__" , self.space.get_init.source.blocks.first )
|
||||||
@init.add_code branch
|
@init.add_code branch
|
||||||
@booted = true
|
@booted = true
|
||||||
self
|
self
|
@ -1,6 +1,6 @@
|
|||||||
require_relative "block"
|
require_relative "block"
|
||||||
|
|
||||||
module Virtual
|
module Register
|
||||||
# the static info of a method (with its compiled code, argument names etc ) is part of the
|
# the static info of a method (with its compiled code, argument names etc ) is part of the
|
||||||
# runtime, ie found in Parfait::Method
|
# runtime, ie found in Parfait::Method
|
||||||
|
|
||||||
@ -35,17 +35,17 @@ module Virtual
|
|||||||
def self.create_method( class_name , return_type , method_name , args)
|
def self.create_method( class_name , return_type , method_name , args)
|
||||||
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
|
||||||
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
|
||||||
clazz = Virtual.machine.space.get_class_by_name class_name
|
clazz = Register.machine.space.get_class_by_name class_name
|
||||||
raise "No such class #{class_name}" unless clazz
|
raise "No such class #{class_name}" unless clazz
|
||||||
arguments = []
|
arguments = []
|
||||||
args.each_with_index do | arg , index |
|
args.each_with_index do | arg , index |
|
||||||
unless arg.is_a? Parfait::Variable
|
unless arg.is_a? Parfait::Variable
|
||||||
raise "not type #{arg}:#{arg.class}" unless Virtual.machine.space.get_class_by_name arg
|
raise "not type #{arg}:#{arg.class}" unless Register.machine.space.get_class_by_name arg
|
||||||
arg = Parfait::Variable.new arg , "arg#{index}".to_sym
|
arg = Parfait::Variable.new arg , "arg#{index}".to_sym
|
||||||
end
|
end
|
||||||
arguments << arg
|
arguments << arg
|
||||||
end
|
end
|
||||||
method = clazz.create_instance_method( method_name , Virtual.new_list(arguments))
|
method = clazz.create_instance_method( method_name , Register.new_list(arguments))
|
||||||
method.source = MethodSource.new(method , return_type)
|
method.source = MethodSource.new(method , return_type)
|
||||||
method
|
method
|
||||||
end
|
end
|
||||||
@ -63,11 +63,11 @@ module Virtual
|
|||||||
@current = enter
|
@current = enter
|
||||||
ret = new_block("return")
|
ret = new_block("return")
|
||||||
# move the current message to new_message
|
# move the current message to new_message
|
||||||
ret.add_code Register::RegisterTransfer.new(self, Register.message_reg , Register.new_message_reg )
|
ret.add_code RegisterTransfer.new(self, Register.message_reg , Register.new_message_reg )
|
||||||
# and restore the message from saved value in new_message
|
# and restore the message from saved value in new_message
|
||||||
ret.add_code Register.get_slot(self,:new_message , :caller , :message )
|
ret.add_code Register.get_slot(self,:new_message , :caller , :message )
|
||||||
#load the return address into pc, affecting return. (other cpus have commands for this, but not arm)
|
#load the return address into pc, affecting return. (other cpus have commands for this, but not arm)
|
||||||
ret.add_code Register::FunctionReturn.new( self , Register.new_message_reg , Register.resolve_index(:message , :return_address) )
|
ret.add_code FunctionReturn.new( self , Register.new_message_reg , Register.resolve_index(:message , :return_address) )
|
||||||
@constants = []
|
@constants = []
|
||||||
end
|
end
|
||||||
attr_reader :blocks , :constants , :return_type
|
attr_reader :blocks , :constants , :return_type
|
||||||
@ -75,13 +75,13 @@ module Virtual
|
|||||||
|
|
||||||
def set_return_type type
|
def set_return_type type
|
||||||
return if type.nil?
|
return if type.nil?
|
||||||
raise "not type #{type}" unless Virtual.machine.space.get_class_by_name type
|
raise "not type #{type}" unless Register.machine.space.get_class_by_name type
|
||||||
@return_type = type
|
@return_type = type
|
||||||
end
|
end
|
||||||
# add an instruction after the current (insertion point)
|
# add an instruction after the current (insertion point)
|
||||||
# the added instruction will become the new insertion point
|
# the added instruction will become the new insertion point
|
||||||
def add_code instruction
|
def add_code instruction
|
||||||
unless instruction.is_a?(Register::Instruction)
|
unless instruction.is_a?(Instruction)
|
||||||
raise instruction.to_s
|
raise instruction.to_s
|
||||||
end
|
end
|
||||||
@current.add_code(instruction) #insert after current
|
@current.add_code(instruction) #insert after current
|
||||||
@ -93,7 +93,7 @@ module Virtual
|
|||||||
def locals_at l_block
|
def locals_at l_block
|
||||||
used =[]
|
used =[]
|
||||||
# call assigns the return register, but as it is in l_block, it is not asked.
|
# call assigns the return register, but as it is in l_block, it is not asked.
|
||||||
assigned = [ Register::RegisterValue.new(Virtual::RegisterMachine.instance.return_register) ]
|
assigned = [ RegisterValue.new(RegisterMachine.instance.return_register) ]
|
||||||
l_block.reachable.each do |b|
|
l_block.reachable.each do |b|
|
||||||
b.uses.each {|u|
|
b.uses.each {|u|
|
||||||
(used << u) unless assigned.include?(u)
|
(used << u) unless assigned.include?(u)
|
@ -1,4 +1,4 @@
|
|||||||
module Virtual
|
module Register
|
||||||
|
|
||||||
# Remove all functions that are not called
|
# Remove all functions that are not called
|
||||||
# Not called is approximated by the fact that the method name doesn't show up
|
# Not called is approximated by the fact that the method name doesn't show up
|
||||||
@ -11,7 +11,7 @@ module Virtual
|
|||||||
@gonners << f
|
@gonners << f
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
keep Virtual.machine.space.get_init
|
keep Register.machine.space.get_init
|
||||||
remove_remaining
|
remove_remaining
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ module Virtual
|
|||||||
@gonners.delete function
|
@gonners.delete function
|
||||||
function.source.blocks.each do |block|
|
function.source.blocks.each do |block|
|
||||||
block.codes.each do |code|
|
block.codes.each do |code|
|
||||||
keep code.method if code.is_a? Register::FunctionCall
|
keep code.method if code.is_a? FunctionCall
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -4,7 +4,7 @@
|
|||||||
# To stay sane, we use the same classes that we use later, but "adapt" them to work in ruby
|
# To stay sane, we use the same classes that we use later, but "adapt" them to work in ruby
|
||||||
# This affects mainly memory layout
|
# This affects mainly memory layout
|
||||||
|
|
||||||
module Virtual
|
module Register
|
||||||
def self.new_list array
|
def self.new_list array
|
||||||
list = Parfait::List.new
|
list = Parfait::List.new
|
||||||
list.set_length array.length
|
list.set_length array.length
|
||||||
@ -24,7 +24,7 @@ class Symbol
|
|||||||
true
|
true
|
||||||
end
|
end
|
||||||
def get_layout
|
def get_layout
|
||||||
l = Virtual.machine.space.classes[:Word].object_layout
|
l = Register.machine.space.classes[:Word].object_layout
|
||||||
#puts "LL #{l.class}"
|
#puts "LL #{l.class}"
|
||||||
l
|
l
|
||||||
end
|
end
|
||||||
@ -42,7 +42,7 @@ class Symbol
|
|||||||
pos = cache_positions[self]
|
pos = cache_positions[self]
|
||||||
if pos == nil
|
if pos == nil
|
||||||
str = "position accessed but not set, "
|
str = "position accessed but not set, "
|
||||||
str += "Machine has object=#{Virtual.machine.objects.has_key?(self.object_id)} "
|
str += "Machine has object=#{Register.machine.objects.has_key?(self.object_id)} "
|
||||||
raise str + " for Symbol:#{self}"
|
raise str + " for Symbol:#{self}"
|
||||||
end
|
end
|
||||||
pos
|
pos
|
@ -3,7 +3,7 @@
|
|||||||
module Positioned
|
module Positioned
|
||||||
def position
|
def position
|
||||||
if @position.nil?
|
if @position.nil?
|
||||||
str = "IN machine #{Virtual.machine.objects.has_key?(self.object_id)}, at #{self.object_id.to_s(16)}\n"
|
str = "IN machine #{Register.machine.objects.has_key?(self.object_id)}, at #{self.object_id.to_s(16)}\n"
|
||||||
raise str + "position not set for #{self.class} len #{word_length} for #{self.inspect[0...100]}"
|
raise str + "position not set for #{self.class} len #{word_length} for #{self.inspect[0...100]}"
|
||||||
end
|
end
|
||||||
@position
|
@position
|
@ -1,7 +0,0 @@
|
|||||||
require_relative "instruction"
|
|
||||||
require_relative "register_value"
|
|
||||||
require_relative "assembler"
|
|
||||||
|
|
||||||
# So the memory model of the machine allows for indexed access into an "object" .
|
|
||||||
# A fixed number of objects exist (ie garbage collection is reclaming, not destroying and
|
|
||||||
# recreating) although there may be a way to increase that number.
|
|
@ -10,7 +10,6 @@ end
|
|||||||
|
|
||||||
require 'parser/transform'
|
require 'parser/transform'
|
||||||
require "salama-object-file"
|
require "salama-object-file"
|
||||||
require "virtual"
|
require "register"
|
||||||
require "register/register"
|
|
||||||
require "register/builtin/object"
|
require "register/builtin/object"
|
||||||
require "arm/arm_machine"
|
require "arm/arm_machine"
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
require "parfait"
|
|
||||||
require "virtual/machine"
|
|
||||||
#if we are in the ruby run-time / generating an executable
|
|
||||||
require "virtual/positioned"
|
|
||||||
require "virtual/padding"
|
|
||||||
require "virtual/parfait_adapter"
|
|
||||||
|
|
||||||
require "phisol/compiler"
|
|
||||||
require "virtual/method_source"
|
|
||||||
|
|
||||||
|
|
||||||
class Fixnum
|
|
||||||
def fits_u8?
|
|
||||||
self >= 0 and self <= 255
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,62 +0,0 @@
|
|||||||
### Virtual OO Machine
|
|
||||||
|
|
||||||
This is really an OV (object value) not object oriented machine.
|
|
||||||
|
|
||||||
Integers and References are Values. We make them look like objects, sure, but they are not.
|
|
||||||
Symbols have similar properties and those are:
|
|
||||||
|
|
||||||
- equality means identity
|
|
||||||
- no change over lifetime
|
|
||||||
|
|
||||||
It's like with Atoms: they used to be the smallest possible physical unit. Now we have electrons,
|
|
||||||
proton and neutrons. And so objects are made up of Values (not objects), integers, floats ,
|
|
||||||
references and possibly more.
|
|
||||||
|
|
||||||
Values have type in the same way objects have a class. We keep track of the type of a value at runtime,
|
|
||||||
also in an similar way that objects have their classes at runtime.
|
|
||||||
|
|
||||||
### Layers
|
|
||||||
|
|
||||||
*Ast* instances get created by the [salama-reader](https://github.com/salama/salama-reader) gem from
|
|
||||||
source. Here we add compile functions to ast classes and compile the AST layer into
|
|
||||||
Virtual::Objects and Parfait::Values
|
|
||||||
|
|
||||||
The main objects are Space (lots of objects), Parfait::Class ,
|
|
||||||
Method and MethodSource (with Blocks and Instruction).
|
|
||||||
|
|
||||||
**Virtual** Instructions get further transformed into **register** instructions.
|
|
||||||
This is done by an abstractly defined Register Machine with basic Intructions.
|
|
||||||
A concrete implementation (like Arm) derives and creates derived Instructions.
|
|
||||||
|
|
||||||
The transformation is implemented as **passes** to make it easier to understand what is going on.
|
|
||||||
Also this makes it easier to add functionality and optimisations from external (to the gem) sources.
|
|
||||||
|
|
||||||
The final transformation assigns Positions to all boot objects (Linker) and assembles them into a
|
|
||||||
binary representation. The data- part is then a representation of classes in the **parfait** runtime.
|
|
||||||
And the instrucions make up the funtions.
|
|
||||||
|
|
||||||
### Accessible Objects
|
|
||||||
|
|
||||||
Object oriented systems have data hiding. So we have access to the inner state of only four objects:
|
|
||||||
|
|
||||||
- Self
|
|
||||||
- Message (arguments, method name, self)
|
|
||||||
- Frame (local and tmp variables)
|
|
||||||
- NewMessage ( to build the next message sent)
|
|
||||||
|
|
||||||
A single instructions (Set) allows movement of data between these.
|
|
||||||
There are compare, branch and call intructions too.
|
|
||||||
|
|
||||||
### Micro
|
|
||||||
|
|
||||||
The micro-kernel idea is well stated by: If you can leave it out, do.
|
|
||||||
|
|
||||||
|
|
||||||
As such we are aiming for integer and reference (type) support, and a minimal class system
|
|
||||||
(object/class/aray/hash/string). It is possible to add types to the system in a similar way as we add classes,
|
|
||||||
and also implement very machine dependent functionality which nevertheless is fully wrapped as OO.
|
|
||||||
|
|
||||||
**Parfait** is that part of the runtime that can be coded in ruby.
|
|
||||||
It is parsed, like any other code and always included in the resulting binary.
|
|
||||||
**Builtin** is the part of the runtime that can not be coded in ruby (but is still needed).
|
|
||||||
This is coded by construction MethodSource in code and necessarily machine dependant.
|
|
@ -1,6 +1,6 @@
|
|||||||
module Virtual
|
module Register
|
||||||
|
|
||||||
class Constant < ::Virtual::Object
|
class Constant < ::Register::Object
|
||||||
end
|
end
|
||||||
class TrueConstant < Constant
|
class TrueConstant < Constant
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
module Virtual
|
module Register
|
||||||
# So when an object calls a method, or sends a message, this is what it sends: a Message
|
# So when an object calls a method, or sends a message, this is what it sends: a Message
|
||||||
|
|
||||||
# A message contains the sender, return and exceptional return addresses,the arguments,
|
# A message contains the sender, return and exceptional return addresses,the arguments,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
module Virtual
|
module Register
|
||||||
# Plock (Proc-Block) is mostly a Block but also somewhat Proc-ish: A Block that carries data.
|
# Plock (Proc-Block) is mostly a Block but also somewhat Proc-ish: A Block that carries data.
|
||||||
#
|
#
|
||||||
# Data in a Block is usefull in the same way data in objects is. Plocks being otherwise just code.
|
# Data in a Block is usefull in the same way data in objects is. Plocks being otherwise just code.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
module Virtual
|
module Register
|
||||||
# A slot is a slot in an object. It is the storage location for a value.
|
# A slot is a slot in an object. It is the storage location for a value.
|
||||||
# (Remember, values are typed)
|
# (Remember, values are typed)
|
||||||
# From a memory perspective a slot is an index into an array (the object)
|
# From a memory perspective a slot is an index into an array (the object)
|
||||||
|
@ -3,7 +3,7 @@ require 'parslet/convenience'
|
|||||||
|
|
||||||
Phisol::Compiler.class_eval do
|
Phisol::Compiler.class_eval do
|
||||||
def set_main main
|
def set_main main
|
||||||
@clazz = Virtual.machine.space.get_class_by_name :Object
|
@clazz = Register.machine.space.get_class_by_name :Object
|
||||||
@method = main
|
@method = main
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -11,10 +11,10 @@ end
|
|||||||
module CompilerHelper
|
module CompilerHelper
|
||||||
|
|
||||||
def set_main compiler
|
def set_main compiler
|
||||||
compiler.set_main Virtual.machine.space.get_main
|
compiler.set_main Register.machine.space.get_main
|
||||||
end
|
end
|
||||||
def check
|
def check
|
||||||
machine = Virtual.machine
|
machine = Register.machine
|
||||||
machine.boot unless machine.booted
|
machine.boot unless machine.booted
|
||||||
parser = Parser::Salama.new
|
parser = Parser::Salama.new
|
||||||
parser = parser.send @root
|
parser = parser.send @root
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
require_relative "compiler_helper"
|
require_relative "compiler_helper"
|
||||||
|
|
||||||
module Virtual
|
module Register
|
||||||
class TestCall < MiniTest::Test
|
class TestCall < MiniTest::Test
|
||||||
include CompilerHelper
|
include CompilerHelper
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
Virtual.machine.boot
|
Register.machine.boot
|
||||||
@root = :call_site
|
@root = :call_site
|
||||||
@output = Register::RegisterValue
|
@output = Register::RegisterValue
|
||||||
end
|
end
|
||||||
@ -31,7 +31,7 @@ module Virtual
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_call_main_op
|
def test_call_main_op
|
||||||
Virtual.machine.space.get_main.ensure_local(:bar , :Integer)
|
Register.machine.space.get_main.ensure_local(:bar , :Integer)
|
||||||
@string_input = 'main( bar )'
|
@string_input = 'main( bar )'
|
||||||
check
|
check
|
||||||
end
|
end
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
require_relative "compiler_helper"
|
require_relative "compiler_helper"
|
||||||
|
|
||||||
module Virtual
|
module Register
|
||||||
class TestFields < MiniTest::Test
|
class TestFields < MiniTest::Test
|
||||||
include CompilerHelper
|
include CompilerHelper
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
Virtual.machine.boot
|
Register.machine.boot
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_field_not_defined
|
def test_field_not_defined
|
||||||
@ -17,7 +17,7 @@ HERE
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_field
|
def test_field
|
||||||
Virtual.machine.space.get_class_by_name(:Object).object_layout.add_instance_variable(:bro)
|
Register.machine.space.get_class_by_name(:Object).object_layout.add_instance_variable(:bro)
|
||||||
@root = :field_access
|
@root = :field_access
|
||||||
@string_input = <<HERE
|
@string_input = <<HERE
|
||||||
self.bro
|
self.bro
|
||||||
@ -27,7 +27,7 @@ HERE
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_local
|
def test_local
|
||||||
Virtual.machine.space.get_main.ensure_local(:bar , :Integer)
|
Register.machine.space.get_main.ensure_local(:bar , :Integer)
|
||||||
@root = :name
|
@root = :name
|
||||||
@string_input = 'bar '
|
@string_input = 'bar '
|
||||||
@output = Register::RegisterValue
|
@output = Register::RegisterValue
|
||||||
@ -35,7 +35,7 @@ HERE
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_args
|
def test_args
|
||||||
Virtual.machine.space.get_main.arguments.push Parfait::Variable.new(:Integer , :bar)
|
Register.machine.space.get_main.arguments.push Parfait::Variable.new(:Integer , :bar)
|
||||||
@root = :name
|
@root = :name
|
||||||
@string_input = 'bar '
|
@string_input = 'bar '
|
||||||
@output = Register::RegisterValue
|
@output = Register::RegisterValue
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
require_relative "compiler_helper"
|
require_relative "compiler_helper"
|
||||||
|
|
||||||
module Virtual
|
module Register
|
||||||
class TestOps < MiniTest::Test
|
class TestOps < MiniTest::Test
|
||||||
include CompilerHelper
|
include CompilerHelper
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
Virtual.machine.boot
|
Register.machine.boot
|
||||||
@root = :operator_value
|
@root = :operator_value
|
||||||
@output = Register::RegisterValue
|
@output = Register::RegisterValue
|
||||||
end
|
end
|
||||||
@ -20,24 +20,24 @@ module Virtual
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
def test_local_int
|
def test_local_int
|
||||||
Virtual.machine.space.get_main.ensure_local(:bar , :Integer)
|
Register.machine.space.get_main.ensure_local(:bar , :Integer)
|
||||||
@string_input = 'bar + 3'
|
@string_input = 'bar + 3'
|
||||||
check
|
check
|
||||||
end
|
end
|
||||||
def test_int_local
|
def test_int_local
|
||||||
Virtual.machine.space.get_main.ensure_local(:bar , :Integer)
|
Register.machine.space.get_main.ensure_local(:bar , :Integer)
|
||||||
@string_input = '3 + bar'
|
@string_input = '3 + bar'
|
||||||
check
|
check
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_field_int
|
def test_field_int
|
||||||
Virtual.machine.space.get_class_by_name(:Object).object_layout.add_instance_variable(:bro)
|
Register.machine.space.get_class_by_name(:Object).object_layout.add_instance_variable(:bro)
|
||||||
@string_input = "self.bro + 3"
|
@string_input = "self.bro + 3"
|
||||||
check
|
check
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_int_field
|
def test_int_field
|
||||||
Virtual.machine.space.get_class_by_name(:Object).object_layout.add_instance_variable(:bro)
|
Register.machine.space.get_class_by_name(:Object).object_layout.add_instance_variable(:bro)
|
||||||
@string_input = "3 + self.bro"
|
@string_input = "3 + self.bro"
|
||||||
check
|
check
|
||||||
end
|
end
|
||||||
|
@ -13,7 +13,7 @@ module Fragments
|
|||||||
@stdout = ""
|
@stdout = ""
|
||||||
end
|
end
|
||||||
def check
|
def check
|
||||||
machine = Virtual.machine.boot
|
machine = Register.machine.boot
|
||||||
machine.parse_and_compile @string_input
|
machine.parse_and_compile @string_input
|
||||||
machine.collect
|
machine.collect
|
||||||
interpreter = Interpreter::Interpreter.new
|
interpreter = Interpreter::Interpreter.new
|
||||||
|
@ -16,8 +16,8 @@ class Object
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
HERE
|
HERE
|
||||||
@expect = [ [SaveReturn,Register::GetSlot,Virtual::Set,Virtual::Set,
|
@expect = [ [SaveReturn,Register::GetSlot,Register::Set,Register::Set,
|
||||||
Virtual::Set,Virtual::Set,RegisterTransfer,FunctionCall] ,[RegisterTransfer,GetSlot,FunctionReturn] ]
|
Register::Set,Register::Set,RegisterTransfer,FunctionCall] ,[RegisterTransfer,GetSlot,FunctionReturn] ]
|
||||||
check
|
check
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class Object
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
HERE
|
HERE
|
||||||
@expect = [[SaveReturn,Register::GetSlot,Virtual::Set,Virtual::Set,RegisterTransfer,FunctionCall] ,
|
@expect = [[SaveReturn,Register::GetSlot,Register::Set,Register::Set,RegisterTransfer,FunctionCall] ,
|
||||||
[RegisterTransfer,GetSlot,FunctionReturn]]
|
[RegisterTransfer,GetSlot,FunctionReturn]]
|
||||||
check
|
check
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@ class Object
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
HERE
|
HERE
|
||||||
@expect = [[SaveReturn,Virtual::Set,Register::GetSlot,Virtual::Set,
|
@expect = [[SaveReturn,Register::Set,Register::GetSlot,Register::Set,
|
||||||
Virtual::Set,RegisterTransfer,FunctionCall] ,[RegisterTransfer,GetSlot,FunctionReturn]]
|
Register::Set,RegisterTransfer,FunctionCall] ,[RegisterTransfer,GetSlot,FunctionReturn]]
|
||||||
check
|
check
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -16,8 +16,8 @@ class Object
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
HERE
|
HERE
|
||||||
@expect = [ [SaveReturn,Virtual::Set,Register::GetSlot,Virtual::Set,
|
@expect = [ [SaveReturn,Register::Set,Register::GetSlot,Register::Set,
|
||||||
Virtual::Set,RegisterTransfer,FunctionCall] ,[RegisterTransfer,GetSlot,FunctionReturn] ]
|
Register::Set,RegisterTransfer,FunctionCall] ,[RegisterTransfer,GetSlot,FunctionReturn] ]
|
||||||
check
|
check
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -27,8 +27,8 @@ class Object
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
HERE
|
HERE
|
||||||
@expect = [[SaveReturn,Register::GetSlot,Virtual::Set,Virtual::Set,
|
@expect = [[SaveReturn,Register::GetSlot,Register::Set,Register::Set,
|
||||||
Virtual::Set,Virtual::Set,RegisterTransfer,FunctionCall] , [RegisterTransfer,GetSlot,FunctionReturn]]
|
Register::Set,Register::Set,RegisterTransfer,FunctionCall] , [RegisterTransfer,GetSlot,FunctionReturn]]
|
||||||
check
|
check
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -24,20 +24,20 @@ class Object
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
HERE
|
HERE
|
||||||
@expect = [ [SaveReturn,Register::GetSlot,Virtual::Set,Virtual::Set,
|
@expect = [ [SaveReturn,Register::GetSlot,Register::Set,Register::Set,
|
||||||
Virtual::Set,Virtual::Set,RegisterTransfer,FunctionCall] ,[RegisterTransfer,GetSlot,FunctionReturn] ]
|
Register::Set,Register::Set,RegisterTransfer,FunctionCall] ,[RegisterTransfer,GetSlot,FunctionReturn] ]
|
||||||
check
|
check
|
||||||
end
|
end
|
||||||
|
|
||||||
# a hand coded version of the fibonachi numbers (moved to kernel to be able to call it)
|
# a hand coded version of the fibonachi numbers (moved to kernel to be able to call it)
|
||||||
# not my hand off course, found in the net from a basic introduction
|
# not my hand off course, found in the net from a basic introduction
|
||||||
def ttest_kernel_fibo
|
def ttest_kernel_fibo
|
||||||
int = Register::Integer.new(Virtual::RegisterMachine.instance.receiver_register)
|
int = Register::Integer.new(Register::RegisterMachine.instance.receiver_register)
|
||||||
fibo = @object_space.get_class_by_name(:Object).resolve_method(:fibo)
|
fibo = @object_space.get_class_by_name(:Object).resolve_method(:fibo)
|
||||||
main = @object_space.main
|
main = @object_space.main
|
||||||
main.mov int , 10
|
main.mov int , 10
|
||||||
main.call( fibo )
|
main.call( fibo )
|
||||||
main.mov( Virtual::RegisterMachine.instance.receiver_register , Virtual::RegisterMachine.instance.return_register )
|
main.mov( Register::RegisterMachine.instance.receiver_register , Register::RegisterMachine.instance.return_register )
|
||||||
putint = @object_space.get_class_by_name(:Object).resolve_method(:putint)
|
putint = @object_space.get_class_by_name(:Object).resolve_method(:putint)
|
||||||
main.call( putint )
|
main.call( putint )
|
||||||
@should = [0x0,0x40,0x2d,0xe9,0x1,0x0,0x52,0xe3,0x2,0x0,0xa0,0xd1,0x7,0x0,0x0,0xda,0x1,0x30,0xa0,0xe3,0x0,0x40,0xa0,0xe3,0x4,0x30,0x83,0xe0,0x4,0x40,0x43,0xe0,0x1,0x20,0x42,0xe2,0x1,0x0,0x52,0xe3,0xfa,0xff,0xff,0x1a,0x3,0x0,0xa0,0xe1,0x0,0x80,0xbd,0xe8]
|
@should = [0x0,0x40,0x2d,0xe9,0x1,0x0,0x52,0xe3,0x2,0x0,0xa0,0xd1,0x7,0x0,0x0,0xda,0x1,0x30,0xa0,0xe3,0x0,0x40,0xa0,0xe3,0x4,0x30,0x83,0xe0,0x4,0x40,0x43,0xe0,0x1,0x20,0x42,0xe2,0x1,0x0,0x52,0xe3,0xfa,0xff,0xff,0x1a,0x3,0x0,0xa0,0xe1,0x0,0x80,0xbd,0xe8]
|
||||||
|
@ -4,10 +4,10 @@ require_relative '../../helper'
|
|||||||
module Statements
|
module Statements
|
||||||
|
|
||||||
def check
|
def check
|
||||||
machine = Virtual.machine
|
machine = Register.machine
|
||||||
machine.boot unless machine.booted
|
machine.boot unless machine.booted
|
||||||
machine.parse_and_compile @string_input
|
machine.parse_and_compile @string_input
|
||||||
produced = Virtual.machine.space.get_main.source
|
produced = Register.machine.space.get_main.source
|
||||||
assert @expect , "No output given"
|
assert @expect , "No output given"
|
||||||
assert_equal @expect.length , produced.blocks.length , "Block length"
|
assert_equal @expect.length , produced.blocks.length , "Block length"
|
||||||
produced.blocks.each_with_index do |b,i|
|
produced.blocks.each_with_index do |b,i|
|
||||||
|
@ -5,7 +5,7 @@ class TestAssignStatement < MiniTest::Test
|
|||||||
include Statements
|
include Statements
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
Virtual.machine.boot
|
Register.machine.boot
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_assign_op
|
def test_assign_op
|
||||||
@ -77,7 +77,7 @@ HERE
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_assign_arg
|
def test_assign_arg
|
||||||
Virtual.machine.space.get_main.arguments.push Parfait::Variable.new(:Integer , :bar)
|
Register.machine.space.get_main.arguments.push Parfait::Variable.new(:Integer , :bar)
|
||||||
@string_input = <<HERE
|
@string_input = <<HERE
|
||||||
class Object
|
class Object
|
||||||
int main(int bar)
|
int main(int bar)
|
||||||
@ -109,7 +109,7 @@ HERE
|
|||||||
|
|
||||||
def test_arg_get
|
def test_arg_get
|
||||||
# have to define bar externally, just because redefining main. Otherwise that would be automatic
|
# have to define bar externally, just because redefining main. Otherwise that would be automatic
|
||||||
Virtual.machine.space.get_main.arguments.push Parfait::Variable.new(:Integer , :bar)
|
Register.machine.space.get_main.arguments.push Parfait::Variable.new(:Integer , :bar)
|
||||||
@string_input = <<HERE
|
@string_input = <<HERE
|
||||||
class Object
|
class Object
|
||||||
int main(int bar)
|
int main(int bar)
|
||||||
|
@ -3,7 +3,7 @@ require_relative "../helper"
|
|||||||
class HelloTest < MiniTest::Test
|
class HelloTest < MiniTest::Test
|
||||||
|
|
||||||
def check
|
def check
|
||||||
machine = Virtual.machine.boot
|
machine = Register.machine.boot
|
||||||
Parfait::Space.object_space.get_class_by_name(:Integer).remove_instance_method :plus
|
Parfait::Space.object_space.get_class_by_name(:Integer).remove_instance_method :plus
|
||||||
#TODO remove this hack: write proper aliases
|
#TODO remove this hack: write proper aliases
|
||||||
statements = machine.parse_and_compile @string_input
|
statements = machine.parse_and_compile @string_input
|
||||||
|
@ -19,7 +19,7 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'test'))
|
|||||||
|
|
||||||
require 'salama'
|
require 'salama'
|
||||||
|
|
||||||
module Virtual
|
module Register
|
||||||
# Functions to generate parfait objects
|
# Functions to generate parfait objects
|
||||||
def self.new_word( string )
|
def self.new_word( string )
|
||||||
string = string.to_s if string.is_a? Symbol
|
string = string.to_s if string.is_a? Symbol
|
||||||
|
@ -5,7 +5,7 @@ class AddTest < MiniTest::Test
|
|||||||
include Ticker
|
include Ticker
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
machine = Virtual.machine.boot
|
machine = Register.machine.boot
|
||||||
code = s(:class, :Object,
|
code = s(:class, :Object,
|
||||||
s(:derives, nil),
|
s(:derives, nil),
|
||||||
s(:statements,
|
s(:statements,
|
||||||
@ -21,7 +21,7 @@ class AddTest < MiniTest::Test
|
|||||||
Phisol::Compiler.compile( code )
|
Phisol::Compiler.compile( code )
|
||||||
machine.collect
|
machine.collect
|
||||||
@interpreter = Interpreter::Interpreter.new
|
@interpreter = Interpreter::Interpreter.new
|
||||||
@interpreter.start Virtual.machine.init
|
@interpreter.start Register.machine.init
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_branch
|
def test_branch
|
||||||
@ -31,7 +31,7 @@ class AddTest < MiniTest::Test
|
|||||||
end
|
end
|
||||||
def test_load
|
def test_load
|
||||||
assert_equal Register::LoadConstant , ticks(2).class
|
assert_equal Register::LoadConstant , ticks(2).class
|
||||||
assert_equal Parfait::Space , Virtual.machine.objects[ @interpreter.get_register(:r2)].class
|
assert_equal Parfait::Space , Register.machine.objects[ @interpreter.get_register(:r2)].class
|
||||||
assert_equal :r2, @interpreter.instruction.array.symbol
|
assert_equal :r2, @interpreter.instruction.array.symbol
|
||||||
end
|
end
|
||||||
def test_get
|
def test_get
|
||||||
|
@ -20,16 +20,16 @@ class Object
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
HERE
|
HERE
|
||||||
machine = Virtual.machine.boot
|
machine = Register.machine.boot
|
||||||
syntax = Parser::Salama.new.parse_with_debug(@string_input)
|
syntax = Parser::Salama.new.parse_with_debug(@string_input)
|
||||||
parts = Parser::Transform.new.apply(syntax)
|
parts = Parser::Transform.new.apply(syntax)
|
||||||
#puts parts.inspect
|
#puts parts.inspect
|
||||||
Phisol::Compiler.compile( parts )
|
Phisol::Compiler.compile( parts )
|
||||||
machine.collect
|
machine.collect
|
||||||
# statements = Virtual.machine.boot.parse_and_compile @string_input
|
# statements = Register.machine.boot.parse_and_compile @string_input
|
||||||
# Phisol::Compiler.compile( statements , Virtual.machine.space.get_main )
|
# Phisol::Compiler.compile( statements , Register.machine.space.get_main )
|
||||||
@interpreter = Interpreter::Interpreter.new
|
@interpreter = Interpreter::Interpreter.new
|
||||||
@interpreter.start Virtual.machine.init
|
@interpreter.start Register.machine.init
|
||||||
#show_ticks # get output of what is
|
#show_ticks # get output of what is
|
||||||
["Branch","LoadConstant","GetSlot","SetSlot","RegisterTransfer",
|
["Branch","LoadConstant","GetSlot","SetSlot","RegisterTransfer",
|
||||||
"FunctionCall","SaveReturn","GetSlot","GetSlot","SetSlot",
|
"FunctionCall","SaveReturn","GetSlot","GetSlot","SetSlot",
|
||||||
|
@ -48,16 +48,16 @@ class Object
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
HERE
|
HERE
|
||||||
machine = Virtual.machine.boot
|
machine = Register.machine.boot
|
||||||
syntax = Parser::Salama.new.parse_with_debug(@string_input)
|
syntax = Parser::Salama.new.parse_with_debug(@string_input)
|
||||||
parts = Parser::Transform.new.apply(syntax)
|
parts = Parser::Transform.new.apply(syntax)
|
||||||
#puts parts.inspect
|
#puts parts.inspect
|
||||||
Phisol::Compiler.compile( parts )
|
Phisol::Compiler.compile( parts )
|
||||||
machine.collect
|
machine.collect
|
||||||
# statements = Virtual.machine.boot.parse_and_compile @string_input
|
# statements = Register.machine.boot.parse_and_compile @string_input
|
||||||
# Phisol::Compiler.compile( statements , Virtual.machine.space.get_main )
|
# Phisol::Compiler.compile( statements , Register.machine.space.get_main )
|
||||||
@interpreter = Interpreter::Interpreter.new
|
@interpreter = Interpreter::Interpreter.new
|
||||||
@interpreter.start Virtual.machine.init
|
@interpreter.start Register.machine.init
|
||||||
#show_ticks # get output of what is
|
#show_ticks # get output of what is
|
||||||
["Branch","LoadConstant","GetSlot","SetSlot","RegisterTransfer",
|
["Branch","LoadConstant","GetSlot","SetSlot","RegisterTransfer",
|
||||||
"FunctionCall","SaveReturn","GetSlot","LoadConstant","SetSlot",
|
"FunctionCall","SaveReturn","GetSlot","LoadConstant","SetSlot",
|
||||||
|
@ -4,7 +4,7 @@ class TestPuts < MiniTest::Test
|
|||||||
include AST::Sexp
|
include AST::Sexp
|
||||||
include Ticker
|
include Ticker
|
||||||
def setup
|
def setup
|
||||||
machine = Virtual.machine.boot
|
machine = Register.machine.boot
|
||||||
code = s(:class, :Object,
|
code = s(:class, :Object,
|
||||||
s(:derives, nil),
|
s(:derives, nil),
|
||||||
s(:statements,
|
s(:statements,
|
||||||
@ -21,7 +21,7 @@ class TestPuts < MiniTest::Test
|
|||||||
Phisol::Compiler.compile( code )
|
Phisol::Compiler.compile( code )
|
||||||
machine.collect
|
machine.collect
|
||||||
@interpreter = Interpreter::Interpreter.new
|
@interpreter = Interpreter::Interpreter.new
|
||||||
@interpreter.start Virtual.machine.init
|
@interpreter.start Register.machine.init
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_branch
|
def test_branch
|
||||||
@ -31,7 +31,7 @@ class TestPuts < MiniTest::Test
|
|||||||
end
|
end
|
||||||
def test_load
|
def test_load
|
||||||
assert_equal Register::LoadConstant , ticks(2).class
|
assert_equal Register::LoadConstant , ticks(2).class
|
||||||
assert_equal Parfait::Space , Virtual.machine.objects[ @interpreter.get_register(:r2)].class
|
assert_equal Parfait::Space , Register.machine.objects[ @interpreter.get_register(:r2)].class
|
||||||
assert_equal :r2, @interpreter.instruction.array.symbol
|
assert_equal :r2, @interpreter.instruction.array.symbol
|
||||||
end
|
end
|
||||||
def test_get
|
def test_get
|
||||||
@ -78,7 +78,7 @@ class TestPuts < MiniTest::Test
|
|||||||
def test_return
|
def test_return
|
||||||
done = ticks(24)
|
done = ticks(24)
|
||||||
assert_equal Register::FunctionReturn , done.class
|
assert_equal Register::FunctionReturn , done.class
|
||||||
assert @interpreter.block.is_a?(Virtual::Block)
|
assert @interpreter.block.is_a?(Register::Block)
|
||||||
assert @interpreter.instruction.is_a?(Register::Instruction) , "not instruction #{@interpreter.instruction}"
|
assert @interpreter.instruction.is_a?(Register::Instruction) , "not instruction #{@interpreter.instruction}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ require_relative "../helper"
|
|||||||
class TestAttributes < MiniTest::Test
|
class TestAttributes < MiniTest::Test
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@mess = Virtual.machine.boot.space.first_message
|
@mess = Register.machine.boot.space.first_message
|
||||||
@layout = @mess.get_layout
|
@layout = @mess.get_layout
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
require_relative "../helper"
|
require_relative "../helper"
|
||||||
|
|
||||||
class TestDictionary < MiniTest::Test
|
class TestDictionary < MiniTest::Test
|
||||||
Virtual.machine.boot #have to book, otherwise layouts etc not set
|
Register.machine.boot #have to book, otherwise layouts etc not set
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@lookup = ::Parfait::Dictionary.new
|
@lookup = ::Parfait::Dictionary.new
|
||||||
|
@ -3,7 +3,7 @@ require_relative "../helper"
|
|||||||
class TestLayout < MiniTest::Test
|
class TestLayout < MiniTest::Test
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@mess = Virtual.machine.boot.space.first_message
|
@mess = Register.machine.boot.space.first_message
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_message_layout
|
def test_message_layout
|
||||||
@ -46,7 +46,7 @@ class TestLayout < MiniTest::Test
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_class_layout
|
def test_class_layout
|
||||||
oc = Virtual.machine.boot.space.get_class_by_name( :Object )
|
oc = Register.machine.boot.space.get_class_by_name( :Object )
|
||||||
assert_equal Parfait::Class , oc.class
|
assert_equal Parfait::Class , oc.class
|
||||||
layout = oc.object_layout
|
layout = oc.object_layout
|
||||||
assert_equal Parfait::Layout , layout.class
|
assert_equal Parfait::Layout , layout.class
|
||||||
|
@ -3,14 +3,14 @@ require_relative "../helper"
|
|||||||
class TestList < MiniTest::Test
|
class TestList < MiniTest::Test
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
Virtual.machine.boot unless Virtual.machine.booted
|
Register.machine.boot unless Register.machine.booted
|
||||||
@list = ::Parfait::List.new
|
@list = ::Parfait::List.new
|
||||||
end
|
end
|
||||||
def test_old_layout
|
def test_old_layout
|
||||||
assert_equal Parfait::Layout , Virtual.machine.space.classes.keys.get_layout.class
|
assert_equal Parfait::Layout , Register.machine.space.classes.keys.get_layout.class
|
||||||
end
|
end
|
||||||
def test_old_layout_push
|
def test_old_layout_push
|
||||||
list = Virtual.machine.space.classes.keys
|
list = Register.machine.space.classes.keys
|
||||||
list.push(1)
|
list.push(1)
|
||||||
assert_equal Parfait::Layout , list.get_layout.class
|
assert_equal Parfait::Layout , list.get_layout.class
|
||||||
end
|
end
|
||||||
@ -26,7 +26,7 @@ class TestList < MiniTest::Test
|
|||||||
assert_equal 1 , layout.variable_index(:layout)
|
assert_equal 1 , layout.variable_index(:layout)
|
||||||
end
|
end
|
||||||
def notest_layout_is_first_old
|
def notest_layout_is_first_old
|
||||||
layout = Virtual.machine.space.classes.keys.get_layout
|
layout = Register.machine.space.classes.keys.get_layout
|
||||||
assert_equal 1 , layout.variable_index(:layout)
|
assert_equal 1 , layout.variable_index(:layout)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ require_relative "../helper"
|
|||||||
class TestMethod < MiniTest::Test
|
class TestMethod < MiniTest::Test
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
obj = Virtual.machine.boot.space.get_class_by_name(:Object)
|
obj = Register.machine.boot.space.get_class_by_name(:Object)
|
||||||
args = Virtual.new_list [ Parfait::Variable.new(:Integer , :bar )]
|
args = Register.new_list [ Parfait::Variable.new(:Integer , :bar )]
|
||||||
@method = ::Parfait::Method.new obj , :foo , args
|
@method = ::Parfait::Method.new obj , :foo , args
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ require_relative "../helper"
|
|||||||
class TestSpace < MiniTest::Test
|
class TestSpace < MiniTest::Test
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@machine = Virtual.machine.boot
|
@machine = Register.machine.boot
|
||||||
end
|
end
|
||||||
def classes
|
def classes
|
||||||
[:Kernel,:Word,:List,:Message,:Frame,:Layout,:Object,:Class,:Dictionary,:Method , :Integer]
|
[:Kernel,:Word,:List,:Message,:Frame,:Layout,:Object,:Class,:Dictionary,:Method , :Integer]
|
||||||
|
@ -3,7 +3,7 @@ require_relative "../helper"
|
|||||||
class TestEmptyWord < MiniTest::Test
|
class TestEmptyWord < MiniTest::Test
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
Virtual.machine.boot unless Virtual.machine.booted
|
Register.machine.boot unless Register.machine.booted
|
||||||
@word = ::Parfait::Word.new(0)
|
@word = ::Parfait::Word.new(0)
|
||||||
end
|
end
|
||||||
def test_word_create
|
def test_word_create
|
||||||
|
@ -4,19 +4,19 @@ require_relative "../helper"
|
|||||||
class TestCompat < MiniTest::Test
|
class TestCompat < MiniTest::Test
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
Virtual.machine.boot unless Virtual.machine.booted
|
Register.machine.boot unless Register.machine.booted
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_list_create_from_array
|
def test_list_create_from_array
|
||||||
array = [1,2,3]
|
array = [1,2,3]
|
||||||
list = Virtual.new_list(array)
|
list = Register.new_list(array)
|
||||||
assert_equal array , list.to_a
|
assert_equal array , list.to_a
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_word_create_from_string
|
def test_word_create_from_string
|
||||||
string = "something"
|
string = "something"
|
||||||
word = Virtual.new_word(string)
|
word = Register.new_word(string)
|
||||||
assert_equal word , Virtual.new_word(string)
|
assert_equal word , Register.new_word(string)
|
||||||
assert_equal string , word.to_string
|
assert_equal string , word.to_string
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -2,15 +2,15 @@ require_relative "../helper"
|
|||||||
|
|
||||||
class TestPositioning < MiniTest::Test
|
class TestPositioning < MiniTest::Test
|
||||||
def setup
|
def setup
|
||||||
Virtual.machine.boot unless Virtual.machine.booted
|
Register.machine.boot unless Register.machine.booted
|
||||||
end
|
end
|
||||||
def test_list1
|
def test_list1
|
||||||
list = Virtual.new_list([1])
|
list = Register.new_list([1])
|
||||||
list.set_layout( Parfait::Layout.new Object)
|
list.set_layout( Parfait::Layout.new Object)
|
||||||
assert_equal 32 , list.word_length
|
assert_equal 32 , list.word_length
|
||||||
end
|
end
|
||||||
def test_list5
|
def test_list5
|
||||||
list = Virtual.new_list([1,2,3,4,5])
|
list = Register.new_list([1,2,3,4,5])
|
||||||
list.set_layout( Parfait::Layout.new Object)
|
list.set_layout( Parfait::Layout.new Object)
|
||||||
# TODO check why this is 64 and not 32
|
# TODO check why this is 64 and not 32
|
||||||
assert_equal 32 , list.word_length
|
assert_equal 32 , list.word_length
|
@ -4,6 +4,6 @@ require_relative "elf/test_all"
|
|||||||
|
|
||||||
require_relative "parfait/test_all"
|
require_relative "parfait/test_all"
|
||||||
|
|
||||||
require_relative "virtual/test_all"
|
require_relative "register/test_all"
|
||||||
|
|
||||||
require_relative "interpreter/test_all"
|
require_relative "interpreter/test_all"
|
||||||
|
Loading…
Reference in New Issue
Block a user