finally scoping builtin to register
had put this off because it breaks history but now the references to register stuff which builtin is off course full of, become much shorter
This commit is contained in:
parent
a03dcecbbd
commit
0f2c8e4201
@ -1,17 +1,18 @@
|
|||||||
### Builtin module
|
### Builtin module
|
||||||
|
|
||||||
The Builtin module contains functions that can not be coded in ruby.
|
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! , right at the start.
|
The functions are organized by their respective class and get loaded in boot_classes! ,
|
||||||
|
right at the start. (see virtual/boot.rb)
|
||||||
|
|
||||||
These functions return their code, ie a Virtual::CompiledMethod object, which can then be called by ruby code
|
These functions return their code, ie a Virtual::CompiledMethod object, which can then be called by
|
||||||
as if it were a "normal" function.
|
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 be written in ruby,
|
A normal ruby function is one that is parsed and transformed to code. But not all functionality can
|
||||||
one of those chicken and egg things. C uses Assembler in this situation, we use Builtin functions.
|
be written in ruby, one of those chicken and egg things.
|
||||||
|
C uses Assembler in this situation, we use Builtin functions.
|
||||||
|
|
||||||
Slightly more here : http://salama.github.io/2014/06/10/more-clarity.html (then still called Kernel)
|
Slightly more here : http://salama.github.io/2014/06/10/more-clarity.html (then still called Kernel)
|
||||||
|
|
||||||
The Builtin module is scattered into several files, but that is just so the file doesn't get too long.
|
The Builtin module is scattered into several files, but that is just so the file doesn't get too long.
|
||||||
|
|
@ -1,19 +1,21 @@
|
|||||||
module Builtin
|
module Register
|
||||||
class Array
|
module Builtin
|
||||||
module ClassMethods
|
class Array
|
||||||
def get context , index = Virtual::Integer
|
module ClassMethods
|
||||||
get_function = Virtual::CompiledMethodInfo.create_method(:get , [ Virtual::Integer] , Virtual::Integer , Virtual::Integer )
|
def get context , index = Virtual::Integer
|
||||||
return get_function
|
get_function = Virtual::CompiledMethodInfo.create_method(:get , [ Virtual::Integer] , Virtual::Integer , Virtual::Integer )
|
||||||
end
|
return get_function
|
||||||
def set context , index = Virtual::Integer , object = Virtual::Reference
|
end
|
||||||
set_function = Virtual::CompiledMethodInfo.create_method(:set , [Virtual::Integer, Virtual::Reference] )
|
def set context , index = Virtual::Integer , object = Virtual::Reference
|
||||||
return set_function
|
set_function = Virtual::CompiledMethodInfo.create_method(:set , [Virtual::Integer, Virtual::Reference] )
|
||||||
end
|
return set_function
|
||||||
def push context , object = Virtual::Reference
|
end
|
||||||
push_function = Virtual::CompiledMethodInfo.create_method(:push , [Virtual::Reference] )
|
def push context , object = Virtual::Reference
|
||||||
return push_function
|
push_function = Virtual::CompiledMethodInfo.create_method(:push , [Virtual::Reference] )
|
||||||
|
return push_function
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
extend ClassMethods
|
||||||
end
|
end
|
||||||
extend ClassMethods
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,98 +1,100 @@
|
|||||||
#integer related kernel functions
|
#integer related kernel functions
|
||||||
module Builtin
|
module Register
|
||||||
module Integer
|
module Builtin
|
||||||
module ClassMethods
|
module Integer
|
||||||
# The conversion to base10 is quite a bit more complicated than i thought.
|
module ClassMethods
|
||||||
# The bulk of it is in div10
|
# The conversion to base10 is quite a bit more complicated than i thought.
|
||||||
# We set up variables, do the devision and write the result to the string
|
# The bulk of it is in div10
|
||||||
# then check if were done and recurse if neccessary
|
# We set up variables, do the devision and write the result to the string
|
||||||
# As we write before we recurse (save a push) we write the number backwards
|
# then check if were done and recurse if neccessary
|
||||||
# arguments: string address , integer
|
# As we write before we recurse (save a push) we write the number backwards
|
||||||
def utoa context
|
# arguments: string address , integer
|
||||||
utoa_function = Virtual::CompiledMethodInfo.create_method(:Integer ,:utoa , [ Virtual::Integer ] )
|
def utoa context
|
||||||
function.info.return_type = Virtual::Integer
|
utoa_function = Virtual::CompiledMethodInfo.create_method(:Integer ,:utoa , [ Virtual::Integer ] )
|
||||||
function.info.receiver = Virtual::Integer
|
function.info.return_type = Virtual::Integer
|
||||||
return utoa_function
|
function.info.receiver = Virtual::Integer
|
||||||
str_addr = utoa_function.receiver
|
return utoa_function
|
||||||
number = utoa_function.args.first
|
str_addr = utoa_function.receiver
|
||||||
remainder = utoa_function.new_local
|
number = utoa_function.args.first
|
||||||
Virtual::RegisterMachine.instance.div10( utoa_function , number , remainder )
|
remainder = utoa_function.new_local
|
||||||
# make char out of digit (by using ascii encoding) 48 == "0"
|
Virtual::RegisterMachine.instance.div10( utoa_function , number , remainder )
|
||||||
utoa_function.instance_eval do
|
# make char out of digit (by using ascii encoding) 48 == "0"
|
||||||
add( remainder , remainder , 48)
|
utoa_function.instance_eval do
|
||||||
strb( remainder, str_addr )
|
add( remainder , remainder , 48)
|
||||||
sub( str_addr, str_addr , 1 )
|
strb( remainder, str_addr )
|
||||||
cmp( number , 0 )
|
sub( str_addr, str_addr , 1 )
|
||||||
callne( utoa_function )
|
cmp( number , 0 )
|
||||||
end
|
callne( utoa_function )
|
||||||
return utoa_function
|
end
|
||||||
end
|
return utoa_function
|
||||||
|
|
||||||
def putint context
|
|
||||||
putint_function = Virtual::CompiledMethodInfo.create_method(:Integer,:putint , [] )
|
|
||||||
putint_function.info.return_type = Virtual::Integer
|
|
||||||
putint_function.info.receiver = Virtual::Integer
|
|
||||||
return putint_function
|
|
||||||
buffer = Parfait::Word.new(" ") # create a buffer
|
|
||||||
context.object_space.add_object buffer # and save it (function local variable: a no no)
|
|
||||||
int = putint_function.receiver
|
|
||||||
moved_int = putint_function.new_local
|
|
||||||
utoa = context.object_space.get_class_by_name(:Object).resolve_method(:utoa)
|
|
||||||
putint_function.instance_eval do
|
|
||||||
mov( moved_int , int ) # move arg up
|
|
||||||
add( int , buffer ,nil ) # string to write to (add string address to pc)
|
|
||||||
add( int , int , buffer.length - 3) # 3 for good measure , ahem.
|
|
||||||
call( utoa )
|
|
||||||
after = new_block("after_call")
|
|
||||||
insert_at after
|
|
||||||
# And now we "just" have to print it, using the write_stdout
|
|
||||||
add( int , buffer , nil ) # string to write to
|
|
||||||
mov( moved_int , buffer.length )
|
|
||||||
end
|
|
||||||
Virtual::RegisterMachine.instance.write_stdout(putint_function)
|
|
||||||
putint_function
|
|
||||||
end
|
|
||||||
|
|
||||||
# testing method, hand coded fibo, expects arg in receiver_register
|
|
||||||
# result comes in return_register
|
|
||||||
# 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
|
|
||||||
def fibo context
|
|
||||||
fibo_function = Virtual::CompiledMethodInfo.create_method(:Integer,:fibo , [] )
|
|
||||||
fibo_function.info.return_type = Virtual::Integer
|
|
||||||
fibo_function.info.receiver = Virtual::Integer
|
|
||||||
return fibo_function
|
|
||||||
result = fibo_function.return_type
|
|
||||||
int = fibo_function.receiver
|
|
||||||
|
|
||||||
last = fibo_function.new_block("return")
|
|
||||||
|
|
||||||
f1 = fibo_function.new_local
|
|
||||||
f2 = fibo_function.new_local
|
|
||||||
|
|
||||||
fibo_function.instance_eval do
|
|
||||||
cmp int , 1
|
|
||||||
mov( result, int , condition_code: :le)
|
|
||||||
ble( last ) #branch to return, rather than return (as the original)
|
|
||||||
mov f1 , 1 #set up initial values
|
|
||||||
mov f2 , 0
|
|
||||||
end
|
end
|
||||||
|
|
||||||
loop = fibo_function.new_block("loop")
|
def putint context
|
||||||
fibo_function.insert_at loop
|
putint_function = Virtual::CompiledMethodInfo.create_method(:Integer,:putint , [] )
|
||||||
|
putint_function.info.return_type = Virtual::Integer
|
||||||
fibo_function.instance_eval do #loop through
|
putint_function.info.receiver = Virtual::Integer
|
||||||
add f1 , f1 , f2 # f1 = f1 + f2
|
return putint_function
|
||||||
sub f2 , f1 , f2 # f2 = f1 -f2
|
buffer = Parfait::Word.new(" ") # create a buffer
|
||||||
sub int , int , 1 # todo: set.. should do below cmp, but doesn't , set_update_status: 1
|
context.object_space.add_object buffer # and save it (function local variable: a no no)
|
||||||
cmp int , 1
|
int = putint_function.receiver
|
||||||
bne( loop )
|
moved_int = putint_function.new_local
|
||||||
mov( result , f1 )
|
utoa = context.object_space.get_class_by_name(:Object).resolve_method(:utoa)
|
||||||
|
putint_function.instance_eval do
|
||||||
|
mov( moved_int , int ) # move arg up
|
||||||
|
add( int , buffer ,nil ) # string to write to (add string address to pc)
|
||||||
|
add( int , int , buffer.length - 3) # 3 for good measure , ahem.
|
||||||
|
call( utoa )
|
||||||
|
after = new_block("after_call")
|
||||||
|
insert_at after
|
||||||
|
# And now we "just" have to print it, using the write_stdout
|
||||||
|
add( int , buffer , nil ) # string to write to
|
||||||
|
mov( moved_int , buffer.length )
|
||||||
|
end
|
||||||
|
Virtual::RegisterMachine.instance.write_stdout(putint_function)
|
||||||
|
putint_function
|
||||||
end
|
end
|
||||||
|
|
||||||
fibo_function
|
# testing method, hand coded fibo, expects arg in receiver_register
|
||||||
|
# result comes in return_register
|
||||||
|
# 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
|
||||||
|
def fibo context
|
||||||
|
fibo_function = Virtual::CompiledMethodInfo.create_method(:Integer,:fibo , [] )
|
||||||
|
fibo_function.info.return_type = Virtual::Integer
|
||||||
|
fibo_function.info.receiver = Virtual::Integer
|
||||||
|
return fibo_function
|
||||||
|
result = fibo_function.return_type
|
||||||
|
int = fibo_function.receiver
|
||||||
|
|
||||||
|
last = fibo_function.new_block("return")
|
||||||
|
|
||||||
|
f1 = fibo_function.new_local
|
||||||
|
f2 = fibo_function.new_local
|
||||||
|
|
||||||
|
fibo_function.instance_eval do
|
||||||
|
cmp int , 1
|
||||||
|
mov( result, int , condition_code: :le)
|
||||||
|
ble( last ) #branch to return, rather than return (as the original)
|
||||||
|
mov f1 , 1 #set up initial values
|
||||||
|
mov f2 , 0
|
||||||
|
end
|
||||||
|
|
||||||
|
loop = fibo_function.new_block("loop")
|
||||||
|
fibo_function.insert_at loop
|
||||||
|
|
||||||
|
fibo_function.instance_eval do #loop through
|
||||||
|
add f1 , f1 , f2 # f1 = f1 + f2
|
||||||
|
sub f2 , f1 , f2 # f2 = f1 -f2
|
||||||
|
sub int , int , 1 # todo: set.. should do below cmp, but doesn't , set_update_status: 1
|
||||||
|
cmp int , 1
|
||||||
|
bne( loop )
|
||||||
|
mov( result , f1 )
|
||||||
|
end
|
||||||
|
|
||||||
|
fibo_function
|
||||||
|
end
|
||||||
|
end
|
||||||
|
extend ClassMethods
|
||||||
end
|
end
|
||||||
end
|
|
||||||
extend ClassMethods
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,81 +1,82 @@
|
|||||||
module Builtin
|
module Register
|
||||||
module Kernel
|
module Builtin
|
||||||
module ClassMethods
|
module Kernel
|
||||||
# this is the really really first place the machine starts (apart from the jump here)
|
module ClassMethods
|
||||||
# it isn't really a function, ie it is jumped to (not called), exits and may not return
|
# this is the really really first place the machine starts (apart from the jump here)
|
||||||
# so it is responsible for initial setup
|
# it isn't really a function, ie it is jumped to (not called), exits and may not return
|
||||||
def __init__ context
|
# so it is responsible for initial setup
|
||||||
function = Virtual::CompiledMethodInfo.create_method(:Kernel,:__init__ , [])
|
def __init__ context
|
||||||
function.info.return_type = Virtual::Integer
|
function = Virtual::CompiledMethodInfo.create_method(:Kernel,:__init__ , [])
|
||||||
# no method enter or return (automatically added), remove
|
function.info.return_type = Virtual::Integer
|
||||||
function.info.blocks.first.codes.pop # no Method enter
|
# no method enter or return (automatically added), remove
|
||||||
function.info.blocks.last.codes.pop # no Method return
|
function.info.blocks.first.codes.pop # no Method enter
|
||||||
#Set up the Space as self upon init
|
function.info.blocks.last.codes.pop # no Method return
|
||||||
space = Parfait::Space.object_space
|
#Set up the Space as self upon init
|
||||||
function.info.add_code Register::LoadConstant.new( space , Register::RegisterReference.self_reg)
|
space = Parfait::Space.object_space
|
||||||
message_ind = space.get_layout().index_of( :next_message )
|
function.info.add_code LoadConstant.new( space , Register.self_reg)
|
||||||
# Load the message to message register (0)
|
message_ind = space.get_layout().index_of( :next_message )
|
||||||
function.info.add_code Register::GetSlot.new( Register::RegisterReference.self_reg , message_ind , Register::RegisterReference.new_message_reg)
|
# Load the message to message register (0)
|
||||||
# And store the space as the new self (so the call can move it back as self)
|
function.info.add_code Register.get_slot( :self , message_ind , :message)
|
||||||
function.info.add_code Register::SetSlot.new( Register::RegisterReference.self_reg , Register::RegisterReference.new_message_reg , Virtual::SELF_INDEX)
|
# And store the space as the new self (so the call can move it back as self)
|
||||||
# now we are set up to issue a call to the main
|
function.info.add_code Register.set_slot( :self , :message , :receiver)
|
||||||
function.info.add_code Virtual::MethodCall.new(Virtual.machine.space.get_main)
|
# now we are set up to issue a call to the main
|
||||||
emit_syscall( function , :exit )
|
function.info.add_code Virtual::MethodCall.new(Virtual.machine.space.get_main)
|
||||||
return function
|
emit_syscall( function , :exit )
|
||||||
end
|
return function
|
||||||
def putstring context
|
end
|
||||||
function = Virtual::CompiledMethodInfo.create_method(:Kernel , :putstring , [] )
|
def putstring context
|
||||||
emit_syscall( function , :putstring )
|
function = Virtual::CompiledMethodInfo.create_method(:Kernel , :putstring , [] )
|
||||||
function
|
emit_syscall( function , :putstring )
|
||||||
end
|
function
|
||||||
def exit context
|
end
|
||||||
function = Virtual::CompiledMethodInfo.create_method(:Kernel,:exit , [])
|
def exit context
|
||||||
function.info.return_type = Virtual::Integer
|
function = Virtual::CompiledMethodInfo.create_method(:Kernel,:exit , [])
|
||||||
return function
|
function.info.return_type = Virtual::Integer
|
||||||
ret = Virtual::RegisterMachine.instance.exit(function)
|
return function
|
||||||
function.set_return ret
|
ret = Virtual::RegisterMachine.instance.exit(function)
|
||||||
function
|
function.set_return ret
|
||||||
end
|
function
|
||||||
def __send context
|
end
|
||||||
function = Virtual::CompiledMethodInfo.create_method(:Kernel ,:__send , [] )
|
def __send context
|
||||||
function.info.return_type = Virtual::Integer
|
function = Virtual::CompiledMethodInfo.create_method(:Kernel ,:__send , [] )
|
||||||
return function
|
function.info.return_type = Virtual::Integer
|
||||||
end
|
return function
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def emit_syscall function , name
|
def emit_syscall function , name
|
||||||
save_message( function )
|
save_message( function )
|
||||||
function.info.add_code Register::Syscall.new( name )
|
function.info.add_code Syscall.new( name )
|
||||||
restore_message(function)
|
restore_message(function)
|
||||||
end
|
end
|
||||||
# save the current message, as the syscall destroys all context
|
# save the current message, as the syscall destroys all context
|
||||||
#
|
#
|
||||||
# currently HACKED into the space as a temporary varaible. As the space is a globally
|
# currently HACKED into the space as a temporary varaible. As the space is a globally
|
||||||
# unique object we can retrieve it from there
|
# unique object we can retrieve it from there
|
||||||
# TODO : fix this to use global (later per thread) variable
|
# TODO : fix this to use global (later per thread) variable
|
||||||
def save_message(function)
|
def save_message(function)
|
||||||
space_tmp = Register::RegisterReference.tmp_reg
|
space_tmp = Register.tmp_reg
|
||||||
ind = Parfait::Space.object_space.get_layout().index_of( :syscall_message )
|
ind = Parfait::Space.object_space.get_layout().index_of( :syscall_message )
|
||||||
raise "index not found for :syscall_message" unless ind
|
raise "index not found for :syscall_message" unless ind
|
||||||
function.info.add_code Register::LoadConstant.new( Parfait::Space.object_space , space_tmp)
|
function.info.add_code LoadConstant.new( Parfait::Space.object_space , space_tmp)
|
||||||
function.info.add_code Register::SetSlot.new( Register::RegisterReference.message_reg , space_tmp , ind)
|
function.info.add_code SetSlot.new( Register.message_reg , space_tmp , ind)
|
||||||
end
|
end
|
||||||
def restore_message(function)
|
def restore_message(function)
|
||||||
# get the sys return out of the way
|
# get the sys return out of the way
|
||||||
return_tmp = Register::RegisterReference.tmp_reg
|
return_tmp = Register.tmp_reg
|
||||||
# load the space into the base register
|
# load the space into the base register
|
||||||
function.info.add_code Register::RegisterTransfer.new( return_tmp , Register::RegisterReference.message_reg )
|
function.info.add_code RegisterTransfer.new( return_tmp , Register.message_reg )
|
||||||
slot = Virtual::Slot
|
# find the stored message
|
||||||
# find the stored message
|
ind = Parfait::Space.object_space.get_layout().index_of( :syscall_message )
|
||||||
ind = Parfait::Space.object_space.get_layout().index_of( :syscall_message )
|
raise "index not found for #{kind}.#{kind.class}" unless ind
|
||||||
raise "index not found for #{kind}.#{kind.class}" unless ind
|
# and load it into the base RegisterMachine
|
||||||
# and load it into the base RegisterMachine
|
function.info.add_code Register.get_slot :message , ind , :message
|
||||||
function.info.add_code Register::GetSlot.new( Register::RegisterReference.message_reg , ind , Register::RegisterReference.message_reg )
|
# and "unroll" self and frame
|
||||||
# and "unroll" self and frame
|
function.info.add_code Register.get_slot(:message , :receiver, :self )
|
||||||
function.info.add_code Register::GetSlot.new( Register::RegisterReference.message_reg , Virtual::SELF_INDEX, Register::RegisterReference.self_reg )
|
function.info.add_code Register.get_slot(:message , :frame , :frame)
|
||||||
function.info.add_code Register::GetSlot.new( Register::RegisterReference.message_reg , Virtual::FRAME_INDEX, Register::RegisterReference.frame_reg )
|
end
|
||||||
end
|
end
|
||||||
|
extend ClassMethods
|
||||||
end
|
end
|
||||||
extend ClassMethods
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,75 +1,77 @@
|
|||||||
module Builtin
|
module Register
|
||||||
class Object
|
module Builtin
|
||||||
module ClassMethods
|
class Object
|
||||||
|
module ClassMethods
|
||||||
|
|
||||||
# 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::CompiledMethodInfo.create_method(:Object,:main , [])
|
function = Virtual::CompiledMethodInfo.create_method(:Object,:main , [])
|
||||||
return function
|
return function
|
||||||
end
|
end
|
||||||
|
|
||||||
# in ruby, how this goes is
|
# in ruby, how this goes is
|
||||||
# def _get_instance_variable var
|
# def _get_instance_variable var
|
||||||
# i = self.index_of(var)
|
# i = self.index_of(var)
|
||||||
# return at_index(i)
|
# return at_index(i)
|
||||||
# end
|
# end
|
||||||
# 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 = Virtual::Integer
|
def _get_instance_variable context , name = Virtual::Integer
|
||||||
get_function = Virtual::CompiledMethodInfo.create_method(:Object,:_get_instance_variable , [ Virtual::Reference ] )
|
get_function = Virtual::CompiledMethodInfo.create_method(:Object,:_get_instance_variable , [ Virtual::Reference ] )
|
||||||
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 = ::Virtual.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 )
|
||||||
|
|
||||||
after_body = get_function.new_block("after_index")
|
after_body = get_function.new_block("after_index")
|
||||||
get_function.current after_body
|
get_function.current after_body
|
||||||
|
|
||||||
# get_function.pop([me])
|
# get_function.pop([me])
|
||||||
# return_to.at_index( get_function , me , return_to )
|
# return_to.at_index( get_function , me , return_to )
|
||||||
|
|
||||||
# get_function.set_return return_to
|
# get_function.set_return return_to
|
||||||
return get_function
|
return get_function
|
||||||
end
|
end
|
||||||
|
|
||||||
def _set_instance_variable(context , name = Virtual::Integer , value = Virtual::Integer )
|
def _set_instance_variable(context , name = Virtual::Integer , value = Virtual::Integer )
|
||||||
set_function = Virtual::CompiledMethodInfo.create_method(:Object,:_set_instance_variable ,[Virtual::Reference ,Virtual::Reference] )
|
set_function = Virtual::CompiledMethodInfo.create_method(:Object,:_set_instance_variable ,[Virtual::Reference ,Virtual::Reference] )
|
||||||
return set_function
|
return set_function
|
||||||
receiver set_function
|
receiver set_function
|
||||||
me = set_function.receiver
|
me = set_function.receiver
|
||||||
var_name = set_function.args.first
|
var_name = set_function.args.first
|
||||||
return_to = set_function.return_type
|
return_to = set_function.return_type
|
||||||
index_function = context.object_space.get_class_by_name(:Object).resolve_method(:index_of)
|
index_function = context.object_space.get_class_by_name(:Object).resolve_method(:index_of)
|
||||||
set_function.push( [me] )
|
set_function.push( [me] )
|
||||||
set_function.call( index_function )
|
set_function.call( index_function )
|
||||||
after_body = set_function.new_block("after_index")
|
after_body = set_function.new_block("after_index")
|
||||||
|
|
||||||
set_function.current after_body
|
set_function.current after_body
|
||||||
set_function.pop([me])
|
set_function.pop([me])
|
||||||
return_to.at_index( set_function , me , return_to )
|
return_to.at_index( set_function , me , return_to )
|
||||||
set_function.set_return return_to
|
set_function.set_return return_to
|
||||||
return set_function
|
return set_function
|
||||||
end
|
end
|
||||||
|
|
||||||
def _get_singleton_method(context , name )
|
def _get_singleton_method(context , name )
|
||||||
raise name
|
raise name
|
||||||
end
|
end
|
||||||
def _add_singleton_method(context, method)
|
def _add_singleton_method(context, method)
|
||||||
raise "4"
|
raise "4"
|
||||||
end
|
end
|
||||||
def initialize(context)
|
def initialize(context)
|
||||||
raise "4"
|
raise "4"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
extend ClassMethods
|
||||||
end
|
end
|
||||||
extend ClassMethods
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
require_relative "integer"
|
require_relative "integer"
|
||||||
require_relative "word"
|
|
||||||
require_relative "array"
|
require_relative "array"
|
||||||
require_relative "kernel"
|
require_relative "kernel"
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
module Builtin
|
|
||||||
class Word
|
|
||||||
module ClassMethods
|
|
||||||
end
|
|
||||||
extend ClassMethods
|
|
||||||
end
|
|
||||||
end
|
|
@ -25,7 +25,8 @@ module Virtual
|
|||||||
value_classes = values.collect { |cl| @space.create_class(cl,nil) }
|
value_classes = values.collect { |cl| @space.create_class(cl,nil) }
|
||||||
layouts = { :Word => [] ,
|
layouts = { :Word => [] ,
|
||||||
:List => [] ,
|
:List => [] ,
|
||||||
:Message => [:next_message],
|
# Assumtion is that name is the last of message
|
||||||
|
:Message => [:next_message , :receiver , :frame , :return_address , :caller , :name ],
|
||||||
:MetaClass => [],
|
:MetaClass => [],
|
||||||
:BinaryCode => [],
|
:BinaryCode => [],
|
||||||
:Space => [:classes ,:next_message ,:next_frame, :syscall_message],
|
:Space => [:classes ,:next_message ,:next_frame, :syscall_message],
|
||||||
@ -99,17 +100,17 @@ 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 = @class_mappings[:Object ]
|
obj = @class_mappings[: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 Builtin::Object.send(f , nil)
|
obj.add_instance_method Register::Builtin::Object.send(f , nil)
|
||||||
end
|
end
|
||||||
obj = @class_mappings[:Kernel ]
|
obj = @class_mappings[:Kernel ]
|
||||||
# create dummy main first, __init__ calls it
|
# create dummy main first, __init__ calls it
|
||||||
[:putstring,:exit,:__send , :__init__ ].each do |f|
|
[:putstring,:exit,:__send , :__init__ ].each do |f|
|
||||||
obj.add_instance_method Builtin::Kernel.send(f , nil)
|
obj.add_instance_method Register::Builtin::Kernel.send(f , nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
obj = @class_mappings[:Integer ]
|
obj = @class_mappings[:Integer ]
|
||||||
[:putint,:fibo].each do |f|
|
[:putint,:fibo].each do |f|
|
||||||
obj.add_instance_method Builtin::Integer.send(f , nil)
|
obj.add_instance_method Register::Builtin::Integer.send(f , nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user