fibinacci actually compiles, doesnt mean it works though

This commit is contained in:
Torsten Ruger 2014-05-19 11:29:18 +03:00
parent c56b7cdf09
commit 8ba79d8de8
5 changed files with 34 additions and 17 deletions

View File

@ -11,10 +11,24 @@ module Ast
function = context.program.get_or_create_function(name)
raise "Forward declaration not implemented (#{name}) #{inspect}" if function == nil
call = Vm::CallSite.new( name , params , function)
save_locals context , into
call.load_args into
call.do_call into
resore_locals context , into
end
def save_locals context , into
into.instance_eval do
push [:r0, :r1 , :r2]
end
end
def resore_locals context , into
into.instance_eval do
pop [:r0, :r1 , :r2]
end
end
def inspect
self.class.name + ".new(" + name.inspect + ", ["+
args.collect{|m| m.inspect }.join( ",") +"] )"

View File

@ -18,6 +18,7 @@ module Ast
def compile context , into
puts "compile operator #{to_s}"
r_val = right.compile(context , into)
puts "compiled right #{r_val.inspect}"
if operator == "=" # assignment, value based
raise "Can only assign variables, not #{left}" unless left.is_a?(NameExpression)
l_val = context.locals[left.name]
@ -38,7 +39,9 @@ module Ast
code = l_val.less_or_equal into , r_val
when "+"
res = Vm::Integer.new(context.function.next_register)
code = res.plus into , l_val , r_val
into.add_code res.is l_val + r_val
# code = res.plus into , l_val , r_val
code = res
when "-"
res = Vm::Integer.new(context.function.next_register)
code = res.minus into , l_val , r_val

View File

@ -23,8 +23,8 @@ module Core
#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 context
function = Vm::Function.new(:putstring , [Vm::Integer , Vm::Integer ] )
def putstring context , string = Vm::Integer , length = Vm::Integer
function = Vm::Function.new(:putstring , [string , length ] , string)
block = function.body
# should be another level of indirection, ie write(io,str)
ret = Vm::CMachine.instance.write_stdout(block)
@ -32,16 +32,16 @@ module Core
function
end
def putint context
function = Vm::Function.new(:putint , [Vm::Integer , Vm::Integer ] )
block = function.body
def putint context , arg = Vm::Integer
arg = Vm::Integer.new( 0 )
function = Vm::Function.new(:putint , [arg ] , arg )
buffer = Vm::StringConstant.new(" ")
context.program.add_object buffer
str_addr = Vm::Integer.new(0) # address of the
str_addr = Vm::Integer.new(1)
context.str_addr = str_addr
reg1 = Vm::Integer.new(1)
reg1 = Vm::Integer.new(2)
itos_fun = context.program.get_or_create_function(:utoa)
block.instance_eval do
function.body.instance_eval do
mov( reg1 , str_addr ) #move arg up
add( str_addr , buffer ,nil ) # string to write to
add( str_addr , str_addr , (buffer.length-3))
@ -50,7 +50,7 @@ module Core
add( str_addr , buffer , nil ) # string to write to
mov( reg1 , buffer.length )
end
ret = Vm::CMachine.instance.write_stdout(block)
ret = Vm::CMachine.instance.write_stdout(function.body)
function
end

View File

@ -5,10 +5,9 @@ def fibonaccit(n) # n == r0
tmp = a # r3 <- r1
a = b # r1 <- r2
b = tmp + b # r4 = r2 + r3 (r4 transient) r2 <- r4
tmp = putint(b)
putstring(tmp)
n = n - 1 # r2 <- 0 ???? #call ok
end #r5 <- r0 - 1 # r0 <- r5
end
putint(b)
n = n - 1 # r0 <- r2 for call, #call ok
end #r5 <- r0 - 1 n=n-1 through r5 tmp
end # r0 <- r5
fibonaccit( 10 )

View File

@ -22,6 +22,7 @@ class TestRunner < MiniTest::Test
parser = Parser::Crystal.new
program = Vm::Program.new "Arm"
syntax = parser.parse_with_debug(string)
assert syntax
parts = Parser::Transform.new.apply(syntax)
# file is a list of expressions, all but the last must be a function
# and the last is wrapped as a main
@ -37,7 +38,7 @@ class TestRunner < MiniTest::Test
program.link_at( 0 , program.context )
binary = program.assemble(StringIO.new )
assert binary
writer = Elf::ObjectWriter.new(Elf::Constants::TARGET_ARM)
blocks = program.functions.collect{ |f| [f.entry , f.exit , f.body] }
blocks += [program.entry , program.exit , program.main]