add the ! syntax to create variables in builder, fix #8
now a variable has to be created before being used thus it is save to develop contracts where a certain name must exist in the scope Maybe the syntax starts getting a bit weird, but at least the ! is a common symbol in ruby
This commit is contained in:
parent
0bf008b351
commit
37461a1727
@ -36,16 +36,16 @@ module Mom
|
||||
def build_with(builder)
|
||||
case from = method_source
|
||||
when Parfait::CallableMethod
|
||||
builder.build { callable << from }
|
||||
builder.build { callable! << from }
|
||||
when Parfait::CacheEntry
|
||||
builder.build do
|
||||
cache_entry << from
|
||||
callable << cache_entry[:cached_method]
|
||||
cache_entry! << from
|
||||
callable! << cache_entry[:cached_method]
|
||||
end
|
||||
when Integer
|
||||
builder.build do
|
||||
arguments << message[:arguments]
|
||||
callable << arguments[ from ]
|
||||
arguments! << message[:arguments]
|
||||
callable! << arguments[ from ]
|
||||
end
|
||||
else
|
||||
raise "unknown source #{method_source.class}:#{method_source}"
|
||||
@ -64,11 +64,11 @@ module Mom
|
||||
# set the method into the message
|
||||
def build_message_data( builder )
|
||||
builder.build do
|
||||
space << Parfait.object_space
|
||||
next_message << space[:next_message]
|
||||
space! << Parfait.object_space
|
||||
next_message! << space[:next_message]
|
||||
|
||||
#FIXME in a multithreaded future this should be done using lock free compare and swap.
|
||||
next_message_reg << next_message[:next_message]
|
||||
next_message_reg! << next_message[:next_message]
|
||||
space[:next_message] << next_message_reg
|
||||
|
||||
message[:next_message] << next_message
|
||||
|
@ -37,20 +37,20 @@ module Mom
|
||||
cache_entry_ = @cache_entry
|
||||
builder = compiler.code_builder(self)
|
||||
builder.build do
|
||||
word << name_
|
||||
cache_entry << cache_entry_
|
||||
word! << name_
|
||||
cache_entry! << cache_entry_
|
||||
|
||||
type << cache_entry[:cached_type]
|
||||
callable_method << type[:methods]
|
||||
type! << cache_entry[:cached_type]
|
||||
callable_method! << type[:methods]
|
||||
|
||||
add_code while_start_label
|
||||
|
||||
space << Parfait.object_space
|
||||
space! << Parfait.object_space
|
||||
space << space[:nil_object]
|
||||
space - callable_method
|
||||
if_zero exit_label
|
||||
|
||||
name << callable_method[:name]
|
||||
name! << callable_method[:name]
|
||||
name - word
|
||||
|
||||
if_zero ok_label
|
||||
|
@ -23,17 +23,17 @@ module Mom
|
||||
compiler.reset_regs
|
||||
builder = compiler.code_builder(self)
|
||||
builder.build do
|
||||
object << message[:return_value]
|
||||
caller_reg << message[:caller]
|
||||
object! << message[:return_value]
|
||||
caller_reg! << message[:caller]
|
||||
caller_reg[:return_value] << object
|
||||
space << Parfait.object_space
|
||||
next_message << space[:next_message]
|
||||
space! << Parfait.object_space
|
||||
next_message! << space[:next_message]
|
||||
message[:next_message] << next_message
|
||||
space[:next_message] << message
|
||||
end
|
||||
compiler.reset_regs
|
||||
builder.build do
|
||||
return_address << message[:return_address]
|
||||
return_address! << message[:return_address]
|
||||
return_address << return_address[ Parfait::Integer.integer_index]
|
||||
message << message[:caller]
|
||||
return_address.function_return
|
||||
|
@ -28,17 +28,21 @@ module Risc
|
||||
# make the magic: convert incoming names into registers that have the
|
||||
# type set according to the name (using resolve_type)
|
||||
# anmes are stored, so subsequent calls use the same register
|
||||
def method_missing(*args)
|
||||
super if args.length != 1
|
||||
name = args[0]
|
||||
def method_missing(name , *args)
|
||||
super if args.length != 0
|
||||
name = name.to_s
|
||||
return @names[name] if @names.has_key?(name)
|
||||
if name == :message
|
||||
if name == "message"
|
||||
reg = Risc.message_reg
|
||||
reg.builder = self
|
||||
elsif name.to_s.index("label")
|
||||
return reg
|
||||
end
|
||||
if name.index("label")
|
||||
reg = Risc.label( @source , "#{name}_#{object_id}")
|
||||
@source_used = true
|
||||
else
|
||||
raise "Must create (with !) before using #{name}" unless name[-1] == "!"
|
||||
name = name[0 ... -1]
|
||||
type = infer_type(name )
|
||||
reg = @compiler.use_reg( type.object_class.name )
|
||||
reg.builder = self
|
||||
@ -90,6 +94,7 @@ module Risc
|
||||
# but since the names in the builder are not variables, we need this method
|
||||
# as it says, swap the two names around. Names must exist
|
||||
def swap_names(left , right)
|
||||
left , right = left.to_s , right.to_s
|
||||
l = @names[left]
|
||||
r = @names[right]
|
||||
raise "No such name #{left}" unless l
|
||||
@ -127,9 +132,9 @@ module Risc
|
||||
to.builder = self # esecially div10 comes in without having used builder
|
||||
from.builder = self # not named regs, different regs ==> silent errors
|
||||
build do
|
||||
space << Parfait.object_space
|
||||
space! << Parfait.object_space
|
||||
to << space[:next_integer]
|
||||
integer_tmp << to[:next_integer]
|
||||
integer_tmp! << to[:next_integer]
|
||||
space[:next_integer] << integer_tmp
|
||||
to[Parfait::Integer.integer_index] << from
|
||||
end
|
||||
|
@ -14,9 +14,9 @@ module Risc
|
||||
def div4(context)
|
||||
compiler = compiler_for(:Integer,:div4 ,{})
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
integer << message[:receiver]
|
||||
integer! << message[:receiver]
|
||||
integer.reduce_int
|
||||
integer_reg << 2
|
||||
integer_reg! << 2
|
||||
integer.op :>> , integer_reg
|
||||
add_new_int("div4", integer , integer_reg)
|
||||
message[:return_value] << integer_reg
|
||||
@ -52,8 +52,8 @@ module Risc
|
||||
compiler = compiler_for(:Integer, operator ,{other: :Integer})
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
builder.build do
|
||||
integer << message[:receiver]
|
||||
integer_reg << message[:arguments]
|
||||
integer! << message[:receiver]
|
||||
integer_reg! << message[:arguments]
|
||||
integer_reg << integer_reg[ 1]
|
||||
integer.reduce_int
|
||||
integer_reg.reduce_int
|
||||
@ -61,7 +61,7 @@ module Risc
|
||||
integer.op :- , integer_reg
|
||||
if_minus false_label
|
||||
if_zero( false_label ) if operator.to_s.length == 1
|
||||
object << Parfait.object_space.true_object
|
||||
object! << Parfait.object_space.true_object
|
||||
branch merge_label
|
||||
add_code false_label
|
||||
object << Parfait.object_space.false_object
|
||||
@ -89,8 +89,8 @@ module Risc
|
||||
compiler = compiler_for(:Integer, op_sym ,{other: :Integer})
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
builder.build do
|
||||
integer << message[:receiver]
|
||||
integer_reg << message[:arguments]
|
||||
integer! << message[:receiver]
|
||||
integer_reg! << message[:arguments]
|
||||
integer_reg << integer_reg[ 1]
|
||||
integer.reduce_int
|
||||
integer_reg.reduce_int
|
||||
|
@ -9,9 +9,9 @@ module Risc
|
||||
def get_internal_word( context )
|
||||
compiler = compiler_for(:Object , :get_internal_word ,{at: :Integer})
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
object << message[:receiver]
|
||||
integer << message[:arguments]
|
||||
integer << integer_reg[1]
|
||||
object! << message[:receiver]
|
||||
integer! << message[:arguments]
|
||||
integer << integer[1]
|
||||
integer.reduce_int
|
||||
object << object[integer]
|
||||
message[:return_value] << object
|
||||
@ -25,10 +25,10 @@ module Risc
|
||||
def set_internal_word( context )
|
||||
compiler = compiler_for(:Object , :set_internal_word , {at: :Integer, :value => :Object} )
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
object << message[:receiver]
|
||||
integer << message[:arguments]
|
||||
object_reg << integer[ 2]
|
||||
integer << integer[ 1]
|
||||
object! << message[:receiver]
|
||||
integer! << message[:arguments]
|
||||
object_reg! << integer[ 2]
|
||||
integer << integer[1]
|
||||
integer.reduce_int
|
||||
object[integer] << object_reg
|
||||
message[:return_value] << object_reg
|
||||
@ -56,9 +56,9 @@ module Risc
|
||||
Parfait::NamedList.type_for({}) , Parfait::NamedList.type_for({}))
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
builder.build do
|
||||
space << Parfait.object_space
|
||||
space! << Parfait.object_space
|
||||
message << space[:next_message]
|
||||
next_message << message[:next_message]
|
||||
next_message! << message[:next_message]
|
||||
space[:next_message] << next_message
|
||||
end
|
||||
|
||||
@ -128,7 +128,7 @@ module Risc
|
||||
r8 = RegisterValue.new( :r8 , :Message)
|
||||
int = builder.compiler.use_reg(:Integer)
|
||||
builder.build do
|
||||
integer_reg << message
|
||||
integer_reg! << message
|
||||
message << r8
|
||||
add_new_int( "_restore_message", integer_reg , int )
|
||||
message[:return_value] << int
|
||||
|
@ -28,8 +28,8 @@ module Risc
|
||||
def get_internal_byte( context)
|
||||
compiler = compiler_for(:Word , :get_internal_byte , {at: :Integer})
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
object << message[:receiver]
|
||||
integer << message[:arguments]
|
||||
object! << message[:receiver]
|
||||
integer! << message[:arguments]
|
||||
integer << integer[1]
|
||||
integer.reduce_int
|
||||
object <= object[integer]
|
||||
@ -46,11 +46,11 @@ module Risc
|
||||
def set_internal_byte( context )
|
||||
compiler = compiler_for(:Word, :set_internal_byte , {at: :Integer , :value => :Integer} )
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
word << message[:receiver]
|
||||
integer << message[:arguments]
|
||||
word! << message[:receiver]
|
||||
integer! << message[:arguments]
|
||||
integer << integer[1]
|
||||
integer_reg << message[:arguments]
|
||||
integer_obj << integer_reg[2]
|
||||
integer_reg! << message[:arguments]
|
||||
integer_obj! << integer_reg[2]
|
||||
integer_reg << integer_reg[2]
|
||||
integer.reduce_int
|
||||
integer_reg.reduce_int
|
||||
|
@ -17,12 +17,15 @@ module Risc
|
||||
assert_nil @builder.built
|
||||
end
|
||||
def test_alloc_space
|
||||
reg = @builder.space
|
||||
reg = @builder.space!
|
||||
assert_equal RegisterValue , reg.class
|
||||
assert_equal :Space , reg.type.class_name
|
||||
end
|
||||
def test_not_alloc_space
|
||||
assert_raises {@builder.space}
|
||||
end
|
||||
def test_next_message
|
||||
reg = @builder.next_message
|
||||
reg = @builder.next_message!
|
||||
assert_equal :r1 , reg.symbol
|
||||
assert_equal :Message , reg.type.class_name
|
||||
end
|
||||
@ -33,31 +36,31 @@ module Risc
|
||||
end
|
||||
def test_returns_built
|
||||
r1 = RegisterValue.new(:r1 , :Space)
|
||||
built = @builder.build{ space << r1 }
|
||||
built = @builder.build{ space! << r1 }
|
||||
assert_equal Transfer , built.class
|
||||
end
|
||||
def test_returns_two
|
||||
r1 = RegisterValue.new(:r1 , :Space)
|
||||
built = @builder.build{ space << r1 ; space << r1}
|
||||
built = @builder.build{ space! << r1 ; space << r1}
|
||||
assert_equal Transfer , built.next.class
|
||||
end
|
||||
def test_returns_slot
|
||||
r2 = RegisterValue.new(:r2 , :Message)
|
||||
r2.builder = @builder
|
||||
built = @builder.build{ r2 << space[:next_message] }
|
||||
built = @builder.build{ r2 << space![:next_message] }
|
||||
assert_equal SlotToReg , built.class
|
||||
assert_equal :r1 , built.array.symbol
|
||||
end
|
||||
def test_returns_slot_reverse
|
||||
r2 = RegisterValue.new(:r2 , :Message)
|
||||
r2.builder = @builder
|
||||
built = @builder.build{ r2 << space[:next_message] }
|
||||
built = @builder.build{ r2 << space![:next_message] }
|
||||
assert_equal SlotToReg , built.class
|
||||
assert_equal :r1 , built.array.symbol
|
||||
end
|
||||
def test_reuses_names
|
||||
r1 = RegisterValue.new(:r1 , :Space)
|
||||
built = @builder.build{ space << r1 ; space << r1}
|
||||
built = @builder.build{ space! << r1 ; space << r1}
|
||||
assert_equal built.to.symbol , built.next.to.symbol
|
||||
end
|
||||
def test_uses_message_as_message
|
||||
@ -92,7 +95,7 @@ module Risc
|
||||
assert_equal @label , ret.label
|
||||
end
|
||||
def test_minus
|
||||
op = @builder.build {space - callable_method}
|
||||
op = @builder.build {space! - callable_method!}
|
||||
assert_equal OperatorInstruction , op.class
|
||||
assert_equal :- , op.operator
|
||||
assert_equal :Space , op.left.type.class_name
|
||||
|
@ -12,17 +12,17 @@ module Risc
|
||||
end
|
||||
def test_inserts_built
|
||||
r1 = RegisterValue.new(:r1 , :Space)
|
||||
@builder.build{ space << r1 }
|
||||
@builder.build{ space! << r1 }
|
||||
assert_equal Transfer , @compiler.risc_instructions.next.class
|
||||
assert_equal RegisterValue , @builder.space.class
|
||||
end
|
||||
def test_loads
|
||||
@builder.build{ space << Parfait.object_space }
|
||||
@builder.build{ space! << Parfait.object_space }
|
||||
assert_equal LoadConstant , @compiler.risc_instructions.next.class
|
||||
assert_equal RegisterValue , @builder.space.class
|
||||
end
|
||||
def test_two
|
||||
@builder.build{ space << Parfait.object_space ; integer << 1}
|
||||
@builder.build{ space! << Parfait.object_space ; integer! << 1}
|
||||
assert_equal LoadConstant , @compiler.risc_instructions.next.class
|
||||
assert_equal LoadData , @compiler.risc_instructions.next(2).class
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user