rubyx/lib/ruby/class_statement.rb
Torsten Rüger d1f8733623 Rename Vool to Sol
Simple is really the descriptive name for the layer
Sure, it is "virtual" but that is not as important as the fact that it is simple (or simplified)
Also objct (based really) is better, since orientated implies it is a little like that, but only orientated, not really it. Sol only has objects, nothing else
Just cause i was renaming anyway
2019-10-04 00:38:47 +03:00

82 lines
3.0 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_sol) 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 sol objects. Mostly for method statements
# For calls, call transform_statement, see there
def to_sol
meths = []
body.statements.each do |meth|
if( meth.is_a?(MethodStatement))
meths << meth.to_sol
else
meths += transform_statement(meth)
end
end
Sol::ClassExpression.new(@name , @super_class_name, Sol::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 sol
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_sol is called to transform to Sol
# 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_sol
end
# creates a setter method (name=) for the given instance name (sym)
# The Method is created in Ruby, and to_sol is called to transform to Sol
# 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_sol
end
def to_s(depth = 0)
at_depth(depth , "class #{name} #{super_s}\n#{@body.to_s(depth + 1)}\nend")
end
# deriviation if apropriate
def super_s
@super_class_name ? " < #{@super_class_name}" : ""
end
end
end