first step of assignment magic
This commit is contained in:
parent
e8660d92db
commit
7056f6f05c
@ -63,8 +63,15 @@ module Vm
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def at where
|
# to use the assignment syntax (see method_missing) the scope must be set, so variables can be resolved
|
||||||
@current = where
|
# The scope you set should be a binding (literally, the kernel.binding)
|
||||||
|
# The function return the block, so it can be chained into an assignment
|
||||||
|
# Example (coding a function ) and having variable int defined
|
||||||
|
# b = function.body.scope(binding)
|
||||||
|
# b.int = 5 will create a mov instruction to set the register that int points to
|
||||||
|
def scope where
|
||||||
|
@scope = where
|
||||||
|
self
|
||||||
end
|
end
|
||||||
# set the next executed block after self.
|
# set the next executed block after self.
|
||||||
# why is this useful? if it's unconditional, why not merge them:
|
# why is this useful? if it's unconditional, why not merge them:
|
||||||
@ -74,12 +81,27 @@ module Vm
|
|||||||
@next = block
|
@next = block
|
||||||
end
|
end
|
||||||
|
|
||||||
# sugar to create instructions easily. Any method with one arg is sent to the machine and the result
|
# sugar to create instructions easily. Actually just got double sweet with two versions:
|
||||||
# (hopefully an instruction) added as code
|
# 1 for any method that ends in = we evaluate the method name in the current scope (see scope())
|
||||||
|
# for the result we call assign with the right value. The resulting instruction is added to
|
||||||
|
# the block.
|
||||||
|
# Thus we emulate assignment,
|
||||||
|
# Example: block b
|
||||||
|
# b.variable = value looks like what it does, but actually generates
|
||||||
|
# an instruction for the block (mov or add)
|
||||||
|
#
|
||||||
|
# 2- any other method will be passed on to the CMachine and the result added to the block
|
||||||
|
# With this trick we can write what looks like assembler,
|
||||||
|
# Example b.instance_eval
|
||||||
|
# mov( r1 , r2 )
|
||||||
|
# add( r1 , r2 , 4)
|
||||||
|
# end
|
||||||
|
# mov and add will be called on Machine and generate Inststuction that are then added
|
||||||
|
# to the block
|
||||||
def method_missing(meth, *args, &block)
|
def method_missing(meth, *args, &block)
|
||||||
if( meth.to_s[-1] == "=")
|
if( meth.to_s[-1] == "=" && args.length == 1)
|
||||||
val = @current.eval meth.to_s[0 ... -1]
|
l_val = @scope.eval meth.to_s[0 ... -1]
|
||||||
raise "hallo #{val}"
|
add_code l_val.asign(args[0])
|
||||||
end
|
end
|
||||||
add_code CMachine.instance.send(meth , *args)
|
add_code CMachine.instance.send(meth , *args)
|
||||||
end
|
end
|
||||||
|
@ -48,7 +48,10 @@ module Vm
|
|||||||
attr_accessor :register
|
attr_accessor :register
|
||||||
|
|
||||||
def inspect
|
def inspect
|
||||||
self.class.name + ":reg:#{register}:"
|
self.class.name + "(r#{register})"
|
||||||
|
end
|
||||||
|
def to_s
|
||||||
|
inspect
|
||||||
end
|
end
|
||||||
def initialize reg
|
def initialize reg
|
||||||
@register = reg
|
@register = reg
|
||||||
|
@ -13,17 +13,17 @@ class TestSmallProg < MiniTest::Test
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_loop
|
def test_loop
|
||||||
@program.main.instance_eval do
|
|
||||||
mov :r0, 5 #1
|
|
||||||
start = Vm::Block.new("start")
|
start = Vm::Block.new("start")
|
||||||
add_code start
|
m = @program.main.scope binding
|
||||||
|
r0 = Vm::Integer.new(0)
|
||||||
|
m.r0 = 5 #1
|
||||||
|
m.add_code start
|
||||||
start.instance_eval do
|
start.instance_eval do
|
||||||
sub :r0, :r0, 1 , :update_status => 1 #2
|
sub :r0, :r0, 1 , :update_status => 1 #2
|
||||||
bne start ,{} #3
|
bne start #3
|
||||||
end
|
|
||||||
end
|
end
|
||||||
@should = [0,176,160,227,5,0,160,227,1,0,80,226,253,255,255,26,1,112,160,227,0,0,0,239]
|
@should = [0,176,160,227,5,0,160,227,1,0,80,226,253,255,255,26,1,112,160,227,0,0,0,239]
|
||||||
write( 6 , "loop" )
|
write "loop"
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_hello
|
def test_hello
|
||||||
@ -60,7 +60,7 @@ class TestSmallProg < MiniTest::Test
|
|||||||
def write name
|
def write name
|
||||||
writer = Elf::ObjectWriter.new(@program , Elf::Constants::TARGET_ARM)
|
writer = Elf::ObjectWriter.new(@program , Elf::Constants::TARGET_ARM)
|
||||||
assembly = writer.text
|
assembly = writer.text
|
||||||
puts assembly
|
# use this for getting the bytes to compare to : puts assembly
|
||||||
assembly.text.bytes.each_with_index do |byte , index|
|
assembly.text.bytes.each_with_index do |byte , index|
|
||||||
assert_equal byte , @should[index] , "byte #{index}"
|
assert_equal byte , @should[index] , "byte #{index}"
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user