fixed and tightened transformation tests, also by implementing node ==
This commit is contained in:
@ -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
|
||||
|
Reference in New Issue
Block a user