coming together, more and more each day
This commit is contained in:
parent
f6711ea49c
commit
04af367bc0
@ -53,17 +53,18 @@ module Arm
|
||||
str_lit
|
||||
end
|
||||
|
||||
def function_call call
|
||||
def function_call into , call
|
||||
raise "Not FunctionCall #{call.inspect}" unless call.is_a? Vm::FunctionCall
|
||||
block.add_code bl( :left => call.function )
|
||||
call.function.return_value
|
||||
raise "Not linked #{call.inspect}" unless call.function
|
||||
into.add_code bl( :left => call.function )
|
||||
call.function.return_type
|
||||
end
|
||||
|
||||
def main_start entry
|
||||
entry.add_code mov( :left => :fp , :right => 0 )
|
||||
end
|
||||
def main_exit exit
|
||||
exit.add_code syscall(1)
|
||||
syscall(exit , 1)
|
||||
end
|
||||
def function_entry block, f_name
|
||||
# entry.add_code push( :regs => [:lr] )
|
||||
@ -72,17 +73,21 @@ module Arm
|
||||
def function_exit entry , f_name
|
||||
entry.add_code mov( :left => :pc , :right => :lr )
|
||||
end
|
||||
def putstring
|
||||
put = Vm::Block.new("putstring_code")
|
||||
# should be another level of indirection, ie write(io,str)
|
||||
put.add_code mov( :left => :r2 , :right => :r1 )
|
||||
put.add_code mov( :left => :r1 , :right => :r0 )
|
||||
put.add_code mov( :left => :r0 , :right => 1 ) #stdout
|
||||
put.add_code syscall(4)
|
||||
|
||||
# assumes string in r0 and r1 and moves them along for the syscall
|
||||
def write_stdout block
|
||||
block.add_code mov( :left => :r2 , :right => :r1 )
|
||||
block.add_code mov( :left => :r1 , :right => :r0 )
|
||||
block.add_code mov( :left => :r0 , :right => 1 ) # 1 == stdout
|
||||
syscall( block , 4 )
|
||||
end
|
||||
|
||||
private
|
||||
def syscall num
|
||||
[mov( :left => :r7 , :right => num ) , swi( :left => 0 )]
|
||||
|
||||
def syscall block , num
|
||||
block.add_code mov( :left => :r7 , :right => num )
|
||||
block.add_code swi( :left => 0 )
|
||||
Vm::Integer.new(0) #small todo, is this actually correct for all (that they return int)
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -27,12 +27,13 @@ module Ast
|
||||
args << arg_value
|
||||
end
|
||||
function = Vm::Function.new(name , args )
|
||||
context.program.add_function function
|
||||
|
||||
parent_locals = context.locals
|
||||
parent_function = context.function
|
||||
context.locals = locals
|
||||
context.function = function
|
||||
|
||||
context.program.add_function function
|
||||
into = function.entry
|
||||
block.each do |b|
|
||||
compiled = b.compile(context , into)
|
||||
|
@ -5,14 +5,16 @@ module Ast
|
||||
class FuncallExpression < Expression
|
||||
attr_reader :name, :args
|
||||
def initialize name, args
|
||||
@name , @args = name , args
|
||||
@name , @args = name.to_sym , args
|
||||
end
|
||||
def compile context , into
|
||||
params = args.collect{ |a| a.compile(context, into) }
|
||||
fun = Vm::FunctionCall.new( name , params )
|
||||
fun.load_args into
|
||||
fun.do_call into
|
||||
fun
|
||||
function = context.program.get_or_create_function(name)
|
||||
raise "Forward declaration not implemented (#{name}) #{inspect}" if function == nil
|
||||
call = Vm::FunctionCall.new( name , params , function)
|
||||
call.load_args into
|
||||
call.do_call into
|
||||
call
|
||||
end
|
||||
|
||||
def inspect
|
||||
|
@ -18,9 +18,16 @@ module Core
|
||||
def function_exit block , f_name
|
||||
Vm::CMachine.instance.function_exit block , f_name
|
||||
end
|
||||
|
||||
#TODO this is in the wrong place. It is a function that returns a function object
|
||||
# while all other methods add their code into some block. --> kernel
|
||||
def putstring
|
||||
# should unwrap from string to char*
|
||||
Vm::CMachine.instance.putstring
|
||||
function = Vm::Function.new(:putstring , [Vm::Integer , Vm::Integer ] )
|
||||
block = function.body
|
||||
# should be another level of indirection, ie write(io,str)
|
||||
ret = Vm::CMachine.instance.write_stdout(block)
|
||||
function.return_type = ret
|
||||
function
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -29,6 +29,7 @@ module Vm
|
||||
branch_body
|
||||
end
|
||||
attr_reader :args , :entry , :exit , :body , :name
|
||||
attr_accessor :return_type
|
||||
|
||||
def arity
|
||||
@args.length
|
||||
|
@ -4,22 +4,22 @@ module Vm
|
||||
|
||||
class FunctionCall < Value
|
||||
|
||||
def initialize(name , args)
|
||||
def initialize(name , args , function )
|
||||
@name = name
|
||||
@args = args
|
||||
@function = nil
|
||||
@function = function
|
||||
end
|
||||
attr_reader :function , :args , :name
|
||||
|
||||
def load_args into
|
||||
args.each_with_index do |arg , index|
|
||||
puts "load " + arg.inspect
|
||||
into.add_code arg.move("r#{index}".to_sym)
|
||||
arg.load( into , index )
|
||||
end
|
||||
end
|
||||
|
||||
def do_call into
|
||||
into.add_code Machine.instance.function_call self
|
||||
into.add_code CMachine.instance.function_call into , self
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -45,20 +45,21 @@ module Vm
|
||||
|
||||
def add_function function
|
||||
raise "not a function #{function}" unless function.is_a? Function
|
||||
raise "syserr " unless function.name.is_a? Symbol
|
||||
@functions << function
|
||||
end
|
||||
|
||||
def get_function name
|
||||
name = name.to_sym
|
||||
@functions.detect{ |f| (f.name == name) }
|
||||
@functions.detect{ |f| f.name == name }
|
||||
end
|
||||
|
||||
# preferred way of creating new functions (also forward declarations, will flag unresolved later)
|
||||
def get_or_create_function name
|
||||
fun = get_function name
|
||||
unless fun
|
||||
puts @functions.inspect
|
||||
fun = Core::Kernel.send(name)
|
||||
raise "no such function '#{name}'" if fun == nil
|
||||
@functions << fun
|
||||
end
|
||||
fun
|
||||
|
@ -5,7 +5,7 @@ def fibonaccit(n)
|
||||
tmp = a
|
||||
a = b
|
||||
b = tmp + b
|
||||
puts(b)
|
||||
putstring(b)
|
||||
n = n - 1
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user