bit of documentation
This commit is contained in:
@ -1,10 +1,16 @@
|
||||
#integer related kernel functions
|
||||
module Risc
|
||||
module Builtin
|
||||
# integer related kernel functions
|
||||
# all these functions (return the functione they implement) assume interger input
|
||||
#
|
||||
# This means they will have to be renamed at some point and wrapped
|
||||
module Integer
|
||||
module ClassMethods
|
||||
include CompileHelper
|
||||
|
||||
# div by 4, ie shift two left
|
||||
# Mostly created for testing at this point, as it is short
|
||||
# return new int with result
|
||||
def div4(context)
|
||||
compiler = compiler_for(:Integer,:div4 ,{})
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
@ -18,18 +24,30 @@ module Risc
|
||||
compiler.add_mom( Mom::ReturnSequence.new)
|
||||
return compiler
|
||||
end
|
||||
# implemented by the comparison
|
||||
def >( context )
|
||||
comparison( :> )
|
||||
end
|
||||
# implemented by the comparison
|
||||
def <( context )
|
||||
comparison( :< )
|
||||
end
|
||||
# implemented by the comparison
|
||||
def <=( context )
|
||||
comparison( :<= )
|
||||
end
|
||||
# implemented by the comparison
|
||||
def >=( context )
|
||||
comparison( :>= )
|
||||
end
|
||||
|
||||
# all (four) comparison operation are quite similar and implemented here
|
||||
# - reduce the ints (assume int as input)
|
||||
# - subtract the fixnums
|
||||
# - check for minus ( < and > )
|
||||
# - also check for zero (<= and >=)
|
||||
# - load true or false object into return, depending on check
|
||||
# - return
|
||||
def comparison( operator )
|
||||
compiler = compiler_for(:Integer, operator ,{other: :Integer})
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
@ -54,11 +72,19 @@ module Risc
|
||||
return compiler
|
||||
end
|
||||
|
||||
# not implemented, would need a itos and that needs "new" (wip)
|
||||
def putint(context)
|
||||
compiler = compiler_for(:Integer,:putint ,{})
|
||||
compiler.add_mom( Mom::ReturnSequence.new)
|
||||
return compiler
|
||||
end
|
||||
|
||||
# implemented all known binary operators that map straight to machine codes
|
||||
# this function (similar to comparison):
|
||||
# - unpacks the intergers to fixnum
|
||||
# - applies the operator (at a risc level)
|
||||
# - gets a new integer and stores the result
|
||||
# - returns the new int
|
||||
def operator_method( op_sym )
|
||||
compiler = compiler_for(:Integer, op_sym ,{other: :Integer})
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
@ -76,6 +102,7 @@ module Risc
|
||||
return compiler
|
||||
end
|
||||
|
||||
# old helper function for div10 (which doesn't use builder yet)
|
||||
def add_receiver(builder)
|
||||
message = Risc.message_reg
|
||||
ret_type = builder.compiler.receiver_type
|
||||
|
@ -6,7 +6,6 @@ module Risc
|
||||
|
||||
# self[index] basically. Index is the first arg
|
||||
# return is stored in return_value
|
||||
# (this method returns a new method off course, like all builtin)
|
||||
def get_internal_word( context )
|
||||
compiler = compiler_for(:Object , :get_internal_word ,{at: :Integer})
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
@ -22,7 +21,7 @@ module Risc
|
||||
end
|
||||
|
||||
# self[index] = val basically. Index is the first arg , value the second
|
||||
# no return
|
||||
# return the value passed in
|
||||
def set_internal_word( context )
|
||||
compiler = compiler_for(:Object , :set_internal_word , {at: :Integer, :value => :Object} )
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
@ -48,8 +47,11 @@ module Risc
|
||||
|
||||
# this is the really really first place the machine starts (apart from the jump here)
|
||||
# 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
|
||||
def __init__ context
|
||||
# so it is responsible for initial setup:
|
||||
# - load fist message, set up Space as receiver
|
||||
# - call main, ie set up message for that etc
|
||||
# - exit (exit_sequence) which passes a machine int out to c
|
||||
def __init__( context )
|
||||
compiler = MethodCompiler.compiler_for_class(:Object,:__init__ ,
|
||||
Parfait::NamedList.type_for({}) , Parfait::NamedList.type_for({}))
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
@ -82,6 +84,7 @@ module Risc
|
||||
|
||||
# a sort of inline version of exit method.
|
||||
# Used by exit and __init__ (so it doesn't have to call it)
|
||||
# Assumes int return value and extracts the fixnum for process exit code
|
||||
def exit_sequence(builder)
|
||||
save_message( builder )
|
||||
message = Risc.message_reg
|
||||
@ -90,6 +93,8 @@ module Risc
|
||||
builder.add_code Syscall.new("emit_syscall(exit)", :exit )
|
||||
end
|
||||
|
||||
# the exit function
|
||||
# mainly calls exit_sequence
|
||||
def exit( context )
|
||||
compiler = compiler_for(:Object,:exit ,{})
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
@ -97,6 +102,8 @@ module Risc
|
||||
return compiler
|
||||
end
|
||||
|
||||
# emit the syscall with given name
|
||||
# there is a Syscall instruction, but the message has to be saved and restored
|
||||
def emit_syscall( builder , name )
|
||||
save_message( builder )
|
||||
builder.add_code Syscall.new("emit_syscall(#{name})", name )
|
||||
@ -114,6 +121,9 @@ module Risc
|
||||
builder.add_transfer("save_message", Risc.message_reg , r8 )
|
||||
end
|
||||
|
||||
# restore the message that we save in r8
|
||||
# get a new int and save the c return into it
|
||||
# tht int gets retured, ie is the return_value of the message
|
||||
def restore_message(builder)
|
||||
r8 = RegisterValue.new( :r8 , :Message)
|
||||
int = builder.compiler.use_reg(:Integer)
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
module Risc
|
||||
module Builtin
|
||||
class Space
|
||||
|
@ -4,6 +4,12 @@ module Risc
|
||||
module ClassMethods
|
||||
include CompileHelper
|
||||
|
||||
# wrapper for the syscall
|
||||
# io/file currently hardcoded to stdout
|
||||
# set up registers for syscall, ie
|
||||
# - pointer in r1
|
||||
# - length in r2
|
||||
# - emit_syscall (which does the return of an integer, see there)
|
||||
def putstring( context)
|
||||
compiler = compiler_for(:Word , :putstring ,{})
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
@ -18,7 +24,7 @@ module Risc
|
||||
end
|
||||
|
||||
# self[index] basically. Index is the first arg > 0
|
||||
# return (and word sized int) is stored in return_value
|
||||
# return a word sized new int, in return_value
|
||||
def get_internal_byte( context)
|
||||
compiler = compiler_for(:Word , :get_internal_byte , {at: :Integer})
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
@ -30,14 +36,13 @@ module Risc
|
||||
add_new_int("get_internal_byte", object , integer)
|
||||
message[:return_value] << integer
|
||||
end
|
||||
|
||||
compiler.add_mom( Mom::ReturnSequence.new)
|
||||
return compiler
|
||||
end
|
||||
|
||||
# self[index] = val basically. Index is the first arg ( >0),
|
||||
# value the second
|
||||
# return self
|
||||
# return value
|
||||
def set_internal_byte( context )
|
||||
compiler = compiler_for(:Word, :set_internal_byte , {at: :Integer , :value => :Integer} )
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
|
Reference in New Issue
Block a user