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 str_lit
end end
def function_call call def function_call into , call
raise "Not FunctionCall #{call.inspect}" unless call.is_a? Vm::FunctionCall raise "Not FunctionCall #{call.inspect}" unless call.is_a? Vm::FunctionCall
block.add_code bl( :left => call.function ) raise "Not linked #{call.inspect}" unless call.function
call.function.return_value into.add_code bl( :left => call.function )
call.function.return_type
end end
def main_start entry def main_start entry
entry.add_code mov( :left => :fp , :right => 0 ) entry.add_code mov( :left => :fp , :right => 0 )
end end
def main_exit exit def main_exit exit
exit.add_code syscall(1) syscall(exit , 1)
end end
def function_entry block, f_name def function_entry block, f_name
# entry.add_code push( :regs => [:lr] ) # entry.add_code push( :regs => [:lr] )
@ -72,17 +73,21 @@ module Arm
def function_exit entry , f_name def function_exit entry , f_name
entry.add_code mov( :left => :pc , :right => :lr ) entry.add_code mov( :left => :pc , :right => :lr )
end end
def putstring
put = Vm::Block.new("putstring_code") # assumes string in r0 and r1 and moves them along for the syscall
# should be another level of indirection, ie write(io,str) def write_stdout block
put.add_code mov( :left => :r2 , :right => :r1 ) block.add_code mov( :left => :r2 , :right => :r1 )
put.add_code mov( :left => :r1 , :right => :r0 ) block.add_code mov( :left => :r1 , :right => :r0 )
put.add_code mov( :left => :r0 , :right => 1 ) #stdout block.add_code mov( :left => :r0 , :right => 1 ) # 1 == stdout
put.add_code syscall(4) syscall( block , 4 )
end end
private 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
end end

View File

@ -27,12 +27,13 @@ module Ast
args << arg_value args << arg_value
end end
function = Vm::Function.new(name , args ) function = Vm::Function.new(name , args )
context.program.add_function function
parent_locals = context.locals parent_locals = context.locals
parent_function = context.function parent_function = context.function
context.locals = locals context.locals = locals
context.function = function context.function = function
context.program.add_function function
into = function.entry into = function.entry
block.each do |b| block.each do |b|
compiled = b.compile(context , into) compiled = b.compile(context , into)

View File

@ -5,14 +5,16 @@ module Ast
class FuncallExpression < Expression class FuncallExpression < Expression
attr_reader :name, :args attr_reader :name, :args
def initialize name, args def initialize name, args
@name , @args = name , args @name , @args = name.to_sym , args
end end
def compile context , into def compile context , into
params = args.collect{ |a| a.compile(context, into) } params = args.collect{ |a| a.compile(context, into) }
fun = Vm::FunctionCall.new( name , params ) function = context.program.get_or_create_function(name)
fun.load_args into raise "Forward declaration not implemented (#{name}) #{inspect}" if function == nil
fun.do_call into call = Vm::FunctionCall.new( name , params , function)
fun call.load_args into
call.do_call into
call
end end
def inspect def inspect

View File

@ -18,9 +18,16 @@ module Core
def function_exit block , f_name def function_exit block , f_name
Vm::CMachine.instance.function_exit block , f_name Vm::CMachine.instance.function_exit block , f_name
end 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 def putstring
# should unwrap from string to char* function = Vm::Function.new(:putstring , [Vm::Integer , Vm::Integer ] )
Vm::CMachine.instance.putstring 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
end end

View File

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

View File

@ -4,22 +4,22 @@ module Vm
class FunctionCall < Value class FunctionCall < Value
def initialize(name , args) def initialize(name , args , function )
@name = name @name = name
@args = args @args = args
@function = nil @function = function
end end
attr_reader :function , :args , :name attr_reader :function , :args , :name
def load_args into def load_args into
args.each_with_index do |arg , index| args.each_with_index do |arg , index|
puts "load " + arg.inspect puts "load " + arg.inspect
into.add_code arg.move("r#{index}".to_sym) arg.load( into , index )
end end
end end
def do_call into def do_call into
into.add_code Machine.instance.function_call self into.add_code CMachine.instance.function_call into , self
end end
end end
end end

View File

@ -45,20 +45,21 @@ module Vm
def add_function function def add_function function
raise "not a function #{function}" unless function.is_a? Function raise "not a function #{function}" unless function.is_a? Function
raise "syserr " unless function.name.is_a? Symbol
@functions << function @functions << function
end end
def get_function name def get_function name
name = name.to_sym name = name.to_sym
@functions.detect{ |f| (f.name == name) } @functions.detect{ |f| f.name == name }
end end
# preferred way of creating new functions (also forward declarations, will flag unresolved later) # preferred way of creating new functions (also forward declarations, will flag unresolved later)
def get_or_create_function name def get_or_create_function name
fun = get_function name fun = get_function name
unless fun unless fun
puts @functions.inspect
fun = Core::Kernel.send(name) fun = Core::Kernel.send(name)
raise "no such function '#{name}'" if fun == nil
@functions << fun @functions << fun
end end
fun fun

View File

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