coming together, more and more each day

This commit is contained in:
Torsten Ruger 2014-05-13 21:06:12 +03:00
parent f6711ea49c
commit 04af367bc0
8 changed files with 45 additions and 28 deletions

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -29,6 +29,7 @@ module Vm
branch_body
end
attr_reader :args , :entry , :exit , :body , :name
attr_accessor :return_type
def arity
@args.length

View File

@ -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

View File

@ -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

View File

@ -5,7 +5,7 @@ def fibonaccit(n)
tmp = a
a = b
b = tmp + b
puts(b)
putstring(b)
n = n - 1
end
end