Torsten Rüger
f87526f86f
Class, Method and Lambda (was block) are expressions. Just making things clearer, especially for the blocks (ahem, lambdas) is matters. wip
78 lines
2.8 KiB
Ruby
78 lines
2.8 KiB
Ruby
module Ruby
|
|
class ClassStatement < Statement
|
|
attr_reader :name, :super_class_name , :body
|
|
|
|
# init with the class name, super class name and statement body
|
|
# body must be Method or Send (See to_vool) or empty/nil (possibly not handled right)
|
|
def initialize( name , supe , body)
|
|
@name , @super_class_name = name , supe
|
|
case body
|
|
when MethodStatement , SendStatement
|
|
@body = Statements.new([body])
|
|
when Statements
|
|
@body = body
|
|
when nil
|
|
@body = Statements.new([])
|
|
else
|
|
raise "what body #{body.class}:#{body}"
|
|
end
|
|
end
|
|
|
|
# Create equivalent vool objects. Mostly for method statements
|
|
# For calls, call transform_statement, see there
|
|
def to_vool
|
|
meths = []
|
|
body.statements.each do |meth|
|
|
if( meth.is_a?(MethodStatement))
|
|
meths << meth.to_vool
|
|
else
|
|
meths += transform_statement(meth)
|
|
end
|
|
end
|
|
Vool::ClassExpression.new(@name , @super_class_name, Vool::Statements.new(meths) )
|
|
end
|
|
|
|
# We rewrite certain send statements (so raise error for all else)
|
|
# Currently only attributes (ie attr :name) supported, for which the standard getter
|
|
# and setter is created and returned as vool
|
|
def transform_statement( class_send )
|
|
unless class_send.is_a?(SendStatement)
|
|
raise "Other than methods, only class methods allowed, not #{class_send.class}"
|
|
end
|
|
allowed = [:attr , :attr_reader]
|
|
attr_name = class_send.name
|
|
unless allowed.include?(attr_name)
|
|
raise "Only remapping #{allowed}, not #{attr_name}"
|
|
end
|
|
methods = []
|
|
class_send.arguments.each do |attr|
|
|
methods << getter_for(attr.value)
|
|
methods << setter_for(attr.value) if attr_name == :attr
|
|
end
|
|
methods
|
|
end
|
|
|
|
# creates a getter method for the given instance name (sym)
|
|
# The Method is created in Ruby, and to_vool is called to transform to Vool
|
|
# The standard getter obviously only returns the ivar
|
|
def getter_for(instance_name)
|
|
return_statement = ReturnStatement.new(InstanceVariable.new(instance_name))
|
|
MethodStatement.new(instance_name , [] , return_statement).to_vool
|
|
end
|
|
|
|
# creates a setter method (name=) for the given instance name (sym)
|
|
# The Method is created in Ruby, and to_vool is called to transform to Vool
|
|
# The setter method assigns the incoming value and returns the ivar
|
|
def setter_for(instance_name)
|
|
assign = IvarAssignment.new(instance_name , LocalVariable.new(:val))
|
|
return_statement = ReturnStatement.new(InstanceVariable.new(instance_name))
|
|
statements = Statements.new([assign, return_statement])
|
|
MethodStatement.new("#{instance_name}=".to_sym , [:val] , statements).to_vool
|
|
end
|
|
|
|
def to_s(depth = 0)
|
|
at_depth(depth , "class #{name}" , @body.to_s(depth + 1) , "end")
|
|
end
|
|
end
|
|
end
|