fibinacci actually compiles, doesnt mean it works though
This commit is contained in:
parent
c56b7cdf09
commit
8ba79d8de8
@ -11,8 +11,22 @@ module Ast
|
|||||||
function = context.program.get_or_create_function(name)
|
function = context.program.get_or_create_function(name)
|
||||||
raise "Forward declaration not implemented (#{name}) #{inspect}" if function == nil
|
raise "Forward declaration not implemented (#{name}) #{inspect}" if function == nil
|
||||||
call = Vm::CallSite.new( name , params , function)
|
call = Vm::CallSite.new( name , params , function)
|
||||||
|
save_locals context , into
|
||||||
call.load_args into
|
call.load_args into
|
||||||
call.do_call 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
|
end
|
||||||
|
|
||||||
def inspect
|
def inspect
|
||||||
|
@ -18,6 +18,7 @@ module Ast
|
|||||||
def compile context , into
|
def compile context , into
|
||||||
puts "compile operator #{to_s}"
|
puts "compile operator #{to_s}"
|
||||||
r_val = right.compile(context , into)
|
r_val = right.compile(context , into)
|
||||||
|
puts "compiled right #{r_val.inspect}"
|
||||||
if operator == "=" # assignment, value based
|
if operator == "=" # assignment, value based
|
||||||
raise "Can only assign variables, not #{left}" unless left.is_a?(NameExpression)
|
raise "Can only assign variables, not #{left}" unless left.is_a?(NameExpression)
|
||||||
l_val = context.locals[left.name]
|
l_val = context.locals[left.name]
|
||||||
@ -38,7 +39,9 @@ module Ast
|
|||||||
code = l_val.less_or_equal into , r_val
|
code = l_val.less_or_equal into , r_val
|
||||||
when "+"
|
when "+"
|
||||||
res = Vm::Integer.new(context.function.next_register)
|
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 "-"
|
when "-"
|
||||||
res = Vm::Integer.new(context.function.next_register)
|
res = Vm::Integer.new(context.function.next_register)
|
||||||
code = res.minus into , l_val , r_val
|
code = res.minus into , l_val , r_val
|
||||||
|
@ -23,8 +23,8 @@ module Core
|
|||||||
|
|
||||||
#TODO this is in the wrong place. It is a function that returns a function object
|
#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
|
# while all other methods add their code into some block. --> kernel
|
||||||
def putstring context
|
def putstring context , string = Vm::Integer , length = Vm::Integer
|
||||||
function = Vm::Function.new(:putstring , [Vm::Integer , Vm::Integer ] )
|
function = Vm::Function.new(:putstring , [string , length ] , string)
|
||||||
block = function.body
|
block = function.body
|
||||||
# should be another level of indirection, ie write(io,str)
|
# should be another level of indirection, ie write(io,str)
|
||||||
ret = Vm::CMachine.instance.write_stdout(block)
|
ret = Vm::CMachine.instance.write_stdout(block)
|
||||||
@ -32,16 +32,16 @@ module Core
|
|||||||
function
|
function
|
||||||
end
|
end
|
||||||
|
|
||||||
def putint context
|
def putint context , arg = Vm::Integer
|
||||||
function = Vm::Function.new(:putint , [Vm::Integer , Vm::Integer ] )
|
arg = Vm::Integer.new( 0 )
|
||||||
block = function.body
|
function = Vm::Function.new(:putint , [arg ] , arg )
|
||||||
buffer = Vm::StringConstant.new(" ")
|
buffer = Vm::StringConstant.new(" ")
|
||||||
context.program.add_object buffer
|
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
|
context.str_addr = str_addr
|
||||||
reg1 = Vm::Integer.new(1)
|
reg1 = Vm::Integer.new(2)
|
||||||
itos_fun = context.program.get_or_create_function(:utoa)
|
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
|
mov( reg1 , str_addr ) #move arg up
|
||||||
add( str_addr , buffer ,nil ) # string to write to
|
add( str_addr , buffer ,nil ) # string to write to
|
||||||
add( str_addr , str_addr , (buffer.length-3))
|
add( str_addr , str_addr , (buffer.length-3))
|
||||||
@ -50,7 +50,7 @@ module Core
|
|||||||
add( str_addr , buffer , nil ) # string to write to
|
add( str_addr , buffer , nil ) # string to write to
|
||||||
mov( reg1 , buffer.length )
|
mov( reg1 , buffer.length )
|
||||||
end
|
end
|
||||||
ret = Vm::CMachine.instance.write_stdout(block)
|
ret = Vm::CMachine.instance.write_stdout(function.body)
|
||||||
function
|
function
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -5,10 +5,9 @@ def fibonaccit(n) # n == r0
|
|||||||
tmp = a # r3 <- r1
|
tmp = a # r3 <- r1
|
||||||
a = b # r1 <- r2
|
a = b # r1 <- r2
|
||||||
b = tmp + b # r4 = r2 + r3 (r4 transient) r2 <- r4
|
b = tmp + b # r4 = r2 + r3 (r4 transient) r2 <- r4
|
||||||
tmp = putint(b)
|
putint(b)
|
||||||
putstring(tmp)
|
n = n - 1 # r0 <- r2 for call, #call ok
|
||||||
n = n - 1 # r2 <- 0 ???? #call ok
|
end #r5 <- r0 - 1 n=n-1 through r5 tmp
|
||||||
end #r5 <- r0 - 1 # r0 <- r5
|
end # r0 <- r5
|
||||||
end
|
|
||||||
|
|
||||||
fibonaccit( 10 )
|
fibonaccit( 10 )
|
||||||
|
@ -22,6 +22,7 @@ class TestRunner < MiniTest::Test
|
|||||||
parser = Parser::Crystal.new
|
parser = Parser::Crystal.new
|
||||||
program = Vm::Program.new "Arm"
|
program = Vm::Program.new "Arm"
|
||||||
syntax = parser.parse_with_debug(string)
|
syntax = parser.parse_with_debug(string)
|
||||||
|
assert syntax
|
||||||
parts = Parser::Transform.new.apply(syntax)
|
parts = Parser::Transform.new.apply(syntax)
|
||||||
# file is a list of expressions, all but the last must be a function
|
# file is a list of expressions, all but the last must be a function
|
||||||
# and the last is wrapped as a main
|
# and the last is wrapped as a main
|
||||||
@ -37,7 +38,7 @@ class TestRunner < MiniTest::Test
|
|||||||
program.link_at( 0 , program.context )
|
program.link_at( 0 , program.context )
|
||||||
|
|
||||||
binary = program.assemble(StringIO.new )
|
binary = program.assemble(StringIO.new )
|
||||||
|
assert binary
|
||||||
writer = Elf::ObjectWriter.new(Elf::Constants::TARGET_ARM)
|
writer = Elf::ObjectWriter.new(Elf::Constants::TARGET_ARM)
|
||||||
blocks = program.functions.collect{ |f| [f.entry , f.exit , f.body] }
|
blocks = program.functions.collect{ |f| [f.entry , f.exit , f.body] }
|
||||||
blocks += [program.entry , program.exit , program.main]
|
blocks += [program.entry , program.exit , program.main]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user