renamed the kernel dir/ module to Builtin (so to not confuse with ruby kernel module)

This commit is contained in:
Torsten Ruger
2014-08-28 18:27:04 +03:00
parent 8c1c72f1c3
commit b8a74f4a77
7 changed files with 22 additions and 24 deletions

17
lib/builtin/README.md Normal file
View File

@ -0,0 +1,17 @@
### Builtin module
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.
The functions are organized by their respective class and get loaded in boot_classes! , right at the start.
These functions return their code, ie a Virtual::CompiledMethod object, 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 be written in ruby,
one of those chicken and egg things. C uses Assembler in this situation, we use Kernel function.
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.

19
lib/builtin/array.rb Normal file
View File

@ -0,0 +1,19 @@
module Builtin
class Array
module ClassMethods
def get context , index = Virtual::Integer
get_function = Virtual::CompiledMethod.new(:get , [ Virtual::Integer] , Virtual::Integer , Virtual::Integer )
return get_function
end
def set context , index = Virtual::Integer , object = Virtual::Reference
set_function = Virtual::CompiledMethod.new(:set , [Virtual::Integer, Virtual::Reference] )
return set_function
end
def push context , object = Virtual::Reference
push_function = Virtual::CompiledMethod.new(:push , [Virtual::Reference] )
return push_function
end
end
extend ClassMethods
end
end

89
lib/builtin/integer.rb Normal file
View File

@ -0,0 +1,89 @@
#integer related kernel functions
module Builtin
module Kernel
# The conversion to base10 is quite a bit more complicated than i thought. The bulk of it is in div10
# We set up variables, do the devision and write the result to the string
# then check if were done and recurse if neccessary
# As we write before we recurse (save a push) we write the number backwards
# arguments: string address , integer
def self.utoa context
utoa_function = Virtual::CompiledMethod.new(:utoa , [ Virtual::Integer ] , Virtual::Integer ,Virtual::Integer )
return utoa_function
str_addr = utoa_function.receiver
number = utoa_function.args.first
remainder = utoa_function.new_local
Virtual::RegisterMachine.instance.div10( utoa_function , number , remainder )
# make char out of digit (by using ascii encoding) 48 == "0"
utoa_function.instance_eval do
add( remainder , remainder , 48)
strb( remainder, str_addr )
sub( str_addr, str_addr , 1 )
cmp( number , 0 )
callne( utoa_function )
end
return utoa_function
end
def self.putint context
putint_function = Virtual::CompiledMethod.new(:putint , [] , Virtual::Integer ,Virtual::Integer )
return putint_function
buffer = Virtual::StringConstant.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_or_create_class(:Object).resolve_function(: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 self.fibo context
fibo_function = Virtual::CompiledMethod.new(:fibo , [] , Virtual::Integer ,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
end

81
lib/builtin/object.rb Normal file
View File

@ -0,0 +1,81 @@
module Builtin
class Object
module ClassMethods
# return the index of the variable. Now "normal" code can't really do anything with that, but
# set/get instance variable use it.
# This is just a placeholder, as we code this in ruby, but the instance methods need the definition before.
def index_of context , name = Virtual::Integer
index_function = Virtual::CompiledMethod.new(:index_of , Virtual::Reference , [Virtual::Reference] , Virtual::Integer )
return index_function
end
def self.layout
layout_function = Virtual::Function.new(:layout , [ ] , Virtual::Reference , Virtual::Reference )
layout_function.at_index 2
layout_function
end
# in ruby, how this goes is
# def _get_instance_variable var
# i = self.index_of(var)
# return at_index(i)
# end
# 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
def _get_instance_variable context , name = Virtual::Integer
get_function = Virtual::CompiledMethod.new(:_get_instance_variable , [ Virtual::Reference ] , Virtual::Reference ,Virtual::Mystery )
return get_function
me = get_function.receiver
var_name = get_function.args.first
return_to = get_function.return_type
index_function = context.object_space.get_or_create_class(:Object).resolve_function(:index_of)
get_function.push( [me] )
index = get_function.call( index_function )
after_body = get_function.new_block("after_index")
get_function.current after_body
get_function.pop([me])
return_to.at_index( get_function , me , return_to )
get_function.set_return return_to
return get_function
end
def _set_instance_variable(context , name = Virtual::Integer , value = Virtual::Integer )
set_function = Virtual::CompiledMethod.new(:_set_instance_variable ,[Virtual::Reference ,Virtual::Reference], Virtual::Reference ,Virtual::Mystery )
return set_function
receiver set_function
me = set_function.receiver
var_name = set_function.args.first
return_to = set_function.return_type
index_function = context.object_space.get_or_create_class(:Object).resolve_function(:index_of)
set_function.push( [me] )
set_function.call( index_function )
after_body = set_function.new_block("after_index")
set_function.current after_body
set_function.pop([me])
return_to.at_index( set_function , me , return_to )
set_function.set_return return_to
return set_function
end
def _get_singleton_method(context , name )
raise name
end
def _add_singleton_method(context, method)
raise "4"
end
def initialize(context)
raise "4"
end
end
extend ClassMethods
end
end
require_relative "integer"
require_relative "string"
require_relative "array"
require_relative "system"

28
lib/builtin/string.rb Normal file
View File

@ -0,0 +1,28 @@
module Builtin
module Kernel
def self.putstring context
function = Virtual::CompiledMethod.new(:putstring , [] )
return function
ret = Virtual::RegisterMachine.instance.write_stdout(function)
function.set_return ret
function
end
end
class String
module ClassMethods
def get context , index = Virtual::Integer
get_function = Virtual::CompiledMethod.new(:get , [ Virtual::Integer] , Virtual::Integer , Virtual::Integer )
return get_function
end
def set context , index = Virtual::Integer , char = Virtual::Integer
set_function = Virtual::CompiledMethod.new(:set , [Virtual::Integer, Virtual::Integer] , Virtual::Integer ,Virtual::Integer )
return set_function
end
def puts context
puts_function = Virtual::CompiledMethod.new(:puts , [] )
return puts_function
end
end
extend ClassMethods
end
end

11
lib/builtin/system.rb Normal file
View File

@ -0,0 +1,11 @@
module Builtin
module Kernel
def self.exit context
function = Virtual::CompiledMethod.new(:exit , [] , Virtual::Integer)
return function
ret = Virtual::RegisterMachine.instance.exit(function)
function.set_return ret
function
end
end
end