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