fixed and tightened transformation tests, also by implementing node ==
This commit is contained in:
parent
e04973fc3c
commit
cfcb9ded2f
@ -20,8 +20,10 @@ module Parser
|
||||
end
|
||||
|
||||
rule(:conditional => simple(:conditional),
|
||||
:if_true => {:block => simple(:if_true)},
|
||||
:if_false => {:block => simple(:if_false)}) { Vm::ConditionalExpression.new(conditional, if_true, if_false) }
|
||||
:if_true => {:expressions => sequence(:if_true)},
|
||||
:if_false => {:expressions => sequence(:if_false)}) do
|
||||
Vm::ConditionalExpression.new(conditional, if_true, if_false)
|
||||
end
|
||||
|
||||
rule(:parmeter => simple(:parmeter)) { parmeter }
|
||||
rule(:parmeter_list => sequence(:parmeter_list)) { parmeter_list }
|
||||
@ -29,14 +31,14 @@ module Parser
|
||||
# need TWO transform rules, for one/many arguments (see the[] wrapping in the first)
|
||||
rule(:function_definition => simple(:function_definition),
|
||||
:parmeter_list => simple(:parmeter),
|
||||
:block => simple(:block)) do
|
||||
Vm::FunctionExpression.new(function_definition.name, [parmeter], block)
|
||||
:expressions => sequence(:expressions)) do
|
||||
Vm::FunctionExpression.new(function_definition.name, [parmeter], expressions)
|
||||
end
|
||||
|
||||
rule(:function_definition => simple(:function_definition),
|
||||
:parmeter_list => sequence(:parmeter_list),
|
||||
:block => simple(:block)) do
|
||||
Vm::FunctionExpression.new(function_definition.name, parmeter_list, block)
|
||||
:expressions => sequence(:expressions)) do
|
||||
Vm::FunctionExpression.new(function_definition.name, parmeter_list, expressions)
|
||||
end
|
||||
|
||||
#shortcut to get the ast tree for a given string
|
||||
|
@ -5,6 +5,15 @@ module Vm
|
||||
def eval
|
||||
raise "abstract"
|
||||
end
|
||||
def compare other , attributes
|
||||
attributes.each do |a|
|
||||
left = send(a)
|
||||
right = other.send( a)
|
||||
return false unless left.class == right.class
|
||||
return false unless left == right
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
class IntegerExpression < Expression
|
||||
@ -12,6 +21,9 @@ module Vm
|
||||
def initialize val
|
||||
@value = val
|
||||
end
|
||||
def == other
|
||||
compare other , [:value]
|
||||
end
|
||||
def eval(context, builder)
|
||||
builder.mov "r0" , value
|
||||
end
|
||||
@ -22,11 +34,13 @@ module Vm
|
||||
def initialize name
|
||||
@name = name
|
||||
end
|
||||
def == other
|
||||
compare other , [:name]
|
||||
end
|
||||
def eval(context, builder)
|
||||
param_names = context[:params] || []
|
||||
position = param_names.index(name)
|
||||
raise "Unknown parameter #{name}" unless position
|
||||
|
||||
builder.iload position
|
||||
end
|
||||
end
|
||||
@ -36,6 +50,9 @@ module Vm
|
||||
def initialize name, args
|
||||
@name , @args = name , args
|
||||
end
|
||||
def == other
|
||||
compare other , [:name , :args]
|
||||
end
|
||||
def eval(context, builder)
|
||||
args.each { |a| a.eval(context, builder) }
|
||||
types = [builder.int] * (args.length + 1)
|
||||
@ -48,6 +65,9 @@ module Vm
|
||||
def initialize cond, if_true, if_false
|
||||
@cond, @if_true, @if_false = cond, if_true, if_false
|
||||
end
|
||||
def == other
|
||||
compare other , [:cond, :if_true, :if_false]
|
||||
end
|
||||
def eval(context, builder)
|
||||
cond.eval context, builder
|
||||
|
||||
@ -68,6 +88,9 @@ module Vm
|
||||
def initialize name, params, block
|
||||
@name, @params, @block = name, params, block
|
||||
end
|
||||
def == other
|
||||
compare other , [:name, :params, :block]
|
||||
end
|
||||
def eval(context, builder)
|
||||
param_names = [params].flatten.map(&:name)
|
||||
context[:params] = param_names
|
||||
|
@ -10,7 +10,7 @@ class TransformTest < MiniTest::Test
|
||||
|
||||
def check_equals
|
||||
is = @transform.apply @input
|
||||
assert_equal @expected.class , is.class
|
||||
assert_equal @expected , is
|
||||
end
|
||||
def test_number
|
||||
@input = {:integer => '42'}
|
||||
@ -52,13 +52,15 @@ class TransformTest < MiniTest::Test
|
||||
end
|
||||
|
||||
def test_conditional
|
||||
@input = {:conditional => {:integer => '0'},
|
||||
:if_true => {:block => {:integer => '42'}},
|
||||
:if_false => {:block => {:integer => '667'}}}
|
||||
@expected = Vm::ConditionalExpression.new \
|
||||
Vm::IntegerExpression.new(0),
|
||||
Vm::IntegerExpression.new(42),
|
||||
Vm::IntegerExpression.new(667)
|
||||
@input = { :conditional => { :integer => "0"},
|
||||
:if_true => { :expressions => [ { :integer => "42" } ] } ,
|
||||
:if_false => { :expressions => [ { :integer => "667" } ] } }
|
||||
# = {:conditional => {:integer => '0'},
|
||||
# :if_true => {:block => {:integer => '42'}},
|
||||
# :if_false => {:block => {:integer => '667'}}}
|
||||
@expected = Vm::ConditionalExpression.new( Vm::IntegerExpression.new(0),
|
||||
[Vm::IntegerExpression.new(42)],
|
||||
[Vm::IntegerExpression.new(667)])
|
||||
check_equals
|
||||
end
|
||||
|
||||
@ -74,10 +76,12 @@ class TransformTest < MiniTest::Test
|
||||
end
|
||||
|
||||
def test_function_definition
|
||||
@input = {:function_definition => { :name => "foo"},
|
||||
:parmeter_list => { :parmeter => { :name => "x" }} ,
|
||||
:block => { :integer => "5" }}
|
||||
@expected = Vm::FunctionExpression.new('foo', [Vm::NameExpression.new('x')], Vm::IntegerExpression.new(5))
|
||||
@input = {:function_definition => {:name => 'foo'},
|
||||
:parmeter_list => {:parmeter => {:name => 'x'}},
|
||||
:expressions => [{:integer => '5'}]}
|
||||
@expected = Vm::FunctionExpression.new('foo',
|
||||
[Vm::NameExpression.new('x')],
|
||||
[Vm::IntegerExpression.new(5)])
|
||||
check_equals
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user