Torsten Rüger
fa0aa30386
Since Builtin generates risc, just like mom instructions, it was a design mistake to put builtin into risc in the first place. Now that borders are coming more into focus, it make much more sense to have the builtin in mom. In fact the instructions should be moved out and a seperate invocation mechanism used , so functions can be parsed, not generated (wip)
83 lines
3.2 KiB
Ruby
83 lines
3.2 KiB
Ruby
module Mom
|
|
module Builtin
|
|
module Word
|
|
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 ,{})
|
|
compiler.add_code Putstring.new("putstring")
|
|
return compiler
|
|
end
|
|
class Putstring < ::Mom::Instruction
|
|
def to_risc(compiler)
|
|
builder = compiler.builder(compiler.source)
|
|
builder.prepare_int_return # makes integer_tmp variable as return
|
|
builder.build do
|
|
word! << message[:receiver]
|
|
integer! << word[Parfait::Word.get_length_index]
|
|
end
|
|
Mom::Builtin.emit_syscall( builder , :putstring )
|
|
compiler
|
|
end
|
|
end
|
|
# self[index] basically. Index is the first arg > 0
|
|
# return a word sized new int, in return_value
|
|
#
|
|
# Note: no index (or type) checking. Method should be internal and check before.
|
|
# Which means the returned integer could be passed in, instead of allocated.
|
|
def get_internal_byte( context)
|
|
compiler = compiler_for(:Word , :get_internal_byte , {at: :Integer})
|
|
compiler.add_code GetInternalByte.new("get_internal_byte")
|
|
return compiler
|
|
end
|
|
class GetInternalByte < ::Mom::Instruction
|
|
def to_risc(compiler)
|
|
builder = compiler.builder(compiler.source)
|
|
integer_tmp = builder.allocate_int
|
|
builder.build do
|
|
object! << message[:receiver]
|
|
integer! << message[:arguments]
|
|
integer << integer[Parfait::NamedList.type_length + 0] #"at" is at index 0
|
|
integer.reduce_int
|
|
object <= object[integer]
|
|
integer_tmp[Parfait::Integer.integer_index] << object
|
|
message[:return_value] << integer_tmp
|
|
end
|
|
return compiler
|
|
end
|
|
end
|
|
# self[index] = val basically. Index is the first arg ( >0 , unchecked),
|
|
# value the second, which is also returned
|
|
def set_internal_byte( context )
|
|
compiler = compiler_for(:Word, :set_internal_byte , {at: :Integer , value: :Integer} )
|
|
compiler.add_code SetInternalByte.new("set_internal_byte")
|
|
return compiler
|
|
end
|
|
class SetInternalByte < ::Mom::Instruction
|
|
def to_risc(compiler)
|
|
compiler.builder(compiler.source).build do
|
|
word! << message[:receiver]
|
|
integer! << message[:arguments]
|
|
integer_reg! << integer[Parfait::NamedList.type_length + 1] #"value" is at index 1
|
|
message[:return_value] << integer_reg
|
|
integer << integer[Parfait::NamedList.type_length + 0] #"at" is at index 0
|
|
integer.reduce_int
|
|
integer_reg.reduce_int
|
|
word[integer] <= integer_reg
|
|
end
|
|
return compiler
|
|
end
|
|
end
|
|
end
|
|
extend ClassMethods
|
|
end
|
|
end
|
|
end
|