rubyx/lib/mom/builtin/word.rb
Torsten Rüger fa0aa30386 Move builtin wholesale to Mom
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)
2019-08-12 12:38:29 +03:00

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