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
This commit is contained in:
@ -17,9 +17,9 @@ what we may loosely call type here, ie the kind of statement.
|
||||
The ruby layer is really all about defining classes for every kind of statement,
|
||||
thus "typing" the syntax tree, and making it concrete.
|
||||
|
||||
## to Vool
|
||||
## to Sol
|
||||
|
||||
In our nice layers, we are on the way down to Vool, a simplified version of oo.
|
||||
In our nice layers, we are on the way down to Sol, a simplified version of oo.
|
||||
|
||||
It has proven handy to have this layer, so the code for transforming each object
|
||||
is in the class representing that object. (As one does in oo, again imho).
|
||||
@ -35,4 +35,4 @@ will surely follow.
|
||||
|
||||
The compilation process ends up creating (parfait) objects to represent
|
||||
things like classes, types and constants. This is not done here yet, but in
|
||||
the vool layer.
|
||||
the sol layer.
|
||||
|
@ -6,11 +6,11 @@ module Ruby
|
||||
@name , @value = name , value
|
||||
end
|
||||
|
||||
def to_vool()
|
||||
def to_sol()
|
||||
raise "not named left #{name.class}" unless name.is_a?(Symbol)
|
||||
case value
|
||||
when Variable , Constant
|
||||
return self.vool_brother.new(name,@value.to_vool)
|
||||
return self.sol_brother.new(name,@value.to_sol)
|
||||
when SendStatement , YieldStatement , RubyBlockStatement
|
||||
return normalize_send
|
||||
else
|
||||
@ -18,12 +18,12 @@ module Ruby
|
||||
end
|
||||
end
|
||||
|
||||
# sends may have complex args that get hoisted in vool:ing them
|
||||
# sends may have complex args that get hoisted in sol:ing them
|
||||
# in which case we have to assign the simplified, otherwise the
|
||||
# plain send
|
||||
def normalize_send
|
||||
statements = value.to_vool
|
||||
return assignment( statements ) if statements.is_a?(Vool::CallStatement)
|
||||
statements = value.to_sol
|
||||
return assignment( statements ) if statements.is_a?(Sol::CallStatement)
|
||||
# send has hoisted assigns, so we make an assign out of the "pure" send
|
||||
statements << assignment(statements.statements.pop)
|
||||
statements
|
||||
@ -32,7 +32,7 @@ module Ruby
|
||||
# create same type assignment with the value (a send)
|
||||
def assignment(value)
|
||||
value ||= @value
|
||||
self.vool_brother.new(name,value)
|
||||
self.sol_brother.new(name,value)
|
||||
end
|
||||
|
||||
def to_s(depth = 0)
|
||||
|
@ -1,7 +1,7 @@
|
||||
module Ruby
|
||||
class Constant < Statement
|
||||
def to_vool
|
||||
vool_brother.new
|
||||
def to_sol
|
||||
sol_brother.new
|
||||
end
|
||||
end
|
||||
class ValueConstant < Constant
|
||||
@ -9,8 +9,8 @@ module Ruby
|
||||
def initialize(value)
|
||||
@value = value
|
||||
end
|
||||
def to_vool
|
||||
vool_brother.new(@value)
|
||||
def to_sol
|
||||
sol_brother.new(@value)
|
||||
end
|
||||
end
|
||||
class IntegerConstant < ValueConstant
|
||||
|
@ -5,8 +5,8 @@ module Ruby
|
||||
#
|
||||
# A CallStatement has a name, receiver and arguments
|
||||
#
|
||||
# Using the "vool_brother" we can create the right Vool class for it.
|
||||
# Arguments in vool must be simple, so any complex expressions get
|
||||
# Using the "sol_brother" we can create the right Sol class for it.
|
||||
# Arguments in sol must be simple, so any complex expressions get
|
||||
# hoisted and assigned to temporary variables.
|
||||
#
|
||||
class CallStatement < Statement
|
||||
@ -18,17 +18,17 @@ module Ruby
|
||||
end
|
||||
|
||||
# we "normalize" or flatten any complex argument expressions into a list
|
||||
def to_vool
|
||||
statements = Vool::Statements.new([])
|
||||
def to_sol
|
||||
statements = Sol::Statements.new([])
|
||||
receiver = normalize_arg(@receiver , statements)
|
||||
arguments = []
|
||||
@arguments.each_with_index do |arg , index |
|
||||
arguments << normalize_arg(arg , statements)
|
||||
end
|
||||
if statements.empty?
|
||||
return vool_brother.new(@name, receiver , arguments)
|
||||
return sol_brother.new(@name, receiver , arguments)
|
||||
else
|
||||
statements << vool_brother.new(@name, receiver , arguments)
|
||||
statements << sol_brother.new(@name, receiver , arguments)
|
||||
return statements
|
||||
end
|
||||
end
|
||||
@ -38,17 +38,17 @@ module Ruby
|
||||
# the effect is of walking the call tree now,
|
||||
# rather than using a stack to do that at runtime
|
||||
def normalize_arg(arg , statements)
|
||||
vool_arg = arg.to_vool
|
||||
return vool_arg if vool_arg.is_a?(Vool::Expression)
|
||||
if( vool_arg.is_a?(Vool::Statements))
|
||||
while(vool_arg.length > 1)
|
||||
statements << vool_arg.shift
|
||||
sol_arg = arg.to_sol
|
||||
return sol_arg if sol_arg.is_a?(Sol::Expression)
|
||||
if( sol_arg.is_a?(Sol::Statements))
|
||||
while(sol_arg.length > 1)
|
||||
statements << sol_arg.shift
|
||||
end
|
||||
vool_arg = vool_arg.shift
|
||||
sol_arg = sol_arg.shift
|
||||
end
|
||||
assign = Vool::LocalAssignment.new( "tmp_#{arg.object_id}".to_sym, vool_arg)
|
||||
assign = Sol::LocalAssignment.new( "tmp_#{arg.object_id}".to_sym, sol_arg)
|
||||
statements << assign
|
||||
return Vool::LocalVariable.new(assign.name)
|
||||
return Sol::LocalVariable.new(assign.name)
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,9 +1,9 @@
|
||||
module Ruby
|
||||
class ClassMethodStatement < MethodStatement
|
||||
|
||||
def to_vool
|
||||
def to_sol
|
||||
body = normalized_body
|
||||
Vool::ClassMethodExpression.new( @name , @args.dup , body.to_vool)
|
||||
Sol::ClassMethodExpression.new( @name , @args.dup , body.to_sol)
|
||||
end
|
||||
|
||||
def to_s(depth = 0)
|
||||
|
@ -3,7 +3,7 @@ module Ruby
|
||||
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)
|
||||
# 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
|
||||
@ -18,23 +18,23 @@ module Ruby
|
||||
end
|
||||
end
|
||||
|
||||
# Create equivalent vool objects. Mostly for method statements
|
||||
# Create equivalent sol objects. Mostly for method statements
|
||||
# For calls, call transform_statement, see there
|
||||
def to_vool
|
||||
def to_sol
|
||||
meths = []
|
||||
body.statements.each do |meth|
|
||||
if( meth.is_a?(MethodStatement))
|
||||
meths << meth.to_vool
|
||||
meths << meth.to_sol
|
||||
else
|
||||
meths += transform_statement(meth)
|
||||
end
|
||||
end
|
||||
Vool::ClassExpression.new(@name , @super_class_name, Vool::Statements.new(meths) )
|
||||
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 vool
|
||||
# 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}"
|
||||
@ -53,21 +53,21 @@ module Ruby
|
||||
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 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_vool
|
||||
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_vool is called to transform to Vool
|
||||
# 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_vool
|
||||
MethodStatement.new("#{instance_name}=".to_sym , [:val] , statements).to_sol
|
||||
end
|
||||
|
||||
def to_s(depth = 0)
|
||||
|
@ -3,11 +3,11 @@ require_relative "normalizer"
|
||||
module Ruby
|
||||
# The if must have condition and a true branch, the false is optional
|
||||
#
|
||||
# It maps pretty much one to one to a Vool, except for "hoisting"
|
||||
# It maps pretty much one to one to a Sol, except for "hoisting"
|
||||
#
|
||||
# Ruby may have super complex expressions as the condition, whereas
|
||||
# Vool may not. Ie of a Statement list all but the last are hoisted to before
|
||||
# the vool if. This is equivalent, just easier to compile later
|
||||
# Sol may not. Ie of a Statement list all but the last are hoisted to before
|
||||
# the sol if. This is equivalent, just easier to compile later
|
||||
#
|
||||
# The hoisintg code is in Normalizer, as it is also useed in return and while
|
||||
class IfStatement < Statement
|
||||
@ -21,11 +21,11 @@ module Ruby
|
||||
@if_false = if_false
|
||||
end
|
||||
|
||||
def to_vool
|
||||
cond , hoisted = *normalized_vool(@condition)
|
||||
me = Vool::IfStatement.new(cond , @if_true&.to_vool, @if_false&.to_vool)
|
||||
def to_sol
|
||||
cond , hoisted = *normalized_sol(@condition)
|
||||
me = Sol::IfStatement.new(cond , @if_true&.to_sol, @if_false&.to_sol)
|
||||
return me unless hoisted
|
||||
Vool::Statements.new( hoisted ) << me
|
||||
Sol::Statements.new( hoisted ) << me
|
||||
end
|
||||
|
||||
def has_false?
|
||||
|
@ -7,7 +7,7 @@ module Ruby
|
||||
# ie: false && non_existant_method
|
||||
# will never call the non_existant_method , but instead evaluate to false
|
||||
#
|
||||
# Vool has no concept of this, so the Statement is expanded into the if
|
||||
# Sol has no concept of this, so the Statement is expanded into the if
|
||||
# that it really is
|
||||
class LogicalStatement < Statement
|
||||
attr_reader :name , :left , :right
|
||||
|
@ -15,9 +15,9 @@ module Ruby
|
||||
body << replace_return( body.pop )
|
||||
end
|
||||
|
||||
def to_vool
|
||||
def to_sol
|
||||
body = normalized_body
|
||||
Vool::MethodExpression.new( @name , @args.dup , body.to_vool)
|
||||
Sol::MethodExpression.new( @name , @args.dup , body.to_sol)
|
||||
end
|
||||
|
||||
def replace_return(statement)
|
||||
|
@ -1,9 +1,9 @@
|
||||
module Ruby
|
||||
module Normalizer
|
||||
# Normalize ruby to vool by "flattening" structure
|
||||
# Normalize ruby to sol by "flattening" structure
|
||||
#
|
||||
# This is a common issue for return, if and while , which all need to operate on the
|
||||
# last value. In ruby the last value is always implicit, in vool not.
|
||||
# last value. In ruby the last value is always implicit, in sol not.
|
||||
#
|
||||
# A "normalized" structure is first of all not recursive, a list not a tree,
|
||||
# The last expression of the list may be one of three things
|
||||
@ -13,11 +13,11 @@ module Ruby
|
||||
#
|
||||
# We return the last expression, the one that is returned or tested on, seperately
|
||||
#
|
||||
def normalized_vool( condition )
|
||||
vool_condition = condition.to_vool
|
||||
return vool_condition unless( vool_condition.is_a?(Vool::Statements) )
|
||||
return vool_condition.first if( vool_condition.single?)
|
||||
return [vool_condition.pop , vool_condition ]
|
||||
def normalized_sol( condition )
|
||||
sol_condition = condition.to_sol
|
||||
return sol_condition unless( sol_condition.is_a?(Sol::Statements) )
|
||||
return sol_condition.first if( sol_condition.single?)
|
||||
return [sol_condition.pop , sol_condition ]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -8,11 +8,11 @@ module Ruby
|
||||
@return_value = value || NilConstant.new
|
||||
end
|
||||
|
||||
def to_vool
|
||||
val , hoisted = *normalized_vool(@return_value)
|
||||
me = Vool::ReturnStatement.new(val)
|
||||
def to_sol
|
||||
val , hoisted = *normalized_sol(@return_value)
|
||||
me = Sol::ReturnStatement.new(val)
|
||||
return me unless hoisted
|
||||
Vool::Statements.new( hoisted ) << me
|
||||
Sol::Statements.new( hoisted ) << me
|
||||
end
|
||||
|
||||
def to_s(depth = 0)
|
||||
|
@ -13,16 +13,16 @@ module Ruby
|
||||
raise "no bod" unless @body
|
||||
end
|
||||
|
||||
# This resolves to a Vool SendStatement, in fact that is mostly what it is.
|
||||
# This resolves to a Sol SendStatement, in fact that is mostly what it is.
|
||||
#
|
||||
# The implicitly passed block (in ruby) gets converted to the constant it is, and
|
||||
# is passed as the last argument.
|
||||
#
|
||||
def to_vool
|
||||
def to_sol
|
||||
#block_name = "implicit_block_#{object_id}".to_sym
|
||||
lambda = Vool::LambdaExpression.new( @args.dup , @body.to_vool)
|
||||
ret = @send.to_vool
|
||||
sendd = ret.is_a?(Vool::Statements) ? ret.last : ret
|
||||
lambda = Sol::LambdaExpression.new( @args.dup , @body.to_sol)
|
||||
ret = @send.to_sol
|
||||
sendd = ret.is_a?(Sol::Statements) ? ret.last : ret
|
||||
sendd.arguments << lambda
|
||||
ret
|
||||
end
|
||||
|
@ -22,7 +22,7 @@ module Ruby
|
||||
#
|
||||
# As a second step, it extracts classes, methods, ivars and locals.
|
||||
#
|
||||
# The next step is then to go to the vool level, which is
|
||||
# The next step is then to go to the sol level, which is
|
||||
# simpler, and then finally to compile
|
||||
# to the next level down, SlotMachine (Minimal Object Machine)
|
||||
class RubyCompiler < AST::Processor
|
||||
|
@ -5,10 +5,10 @@ module Ruby
|
||||
#
|
||||
class SendStatement < CallStatement
|
||||
|
||||
def to_vool
|
||||
def to_sol
|
||||
if @receiver.is_a?(ModuleName) and @receiver.name == :X
|
||||
args = @arguments.collect { |arg| arg.to_vool }
|
||||
return Vool::MacroExpression.new(name , args)
|
||||
args = @arguments.collect { |arg| arg.to_sol }
|
||||
return Sol::MacroExpression.new(name , args)
|
||||
end
|
||||
return require_file if( @name == :require_relative )
|
||||
return super
|
||||
@ -25,7 +25,7 @@ module Ruby
|
||||
end
|
||||
path = File.expand_path( "../../../#{file}" , __FILE__)
|
||||
source = File.read(path)
|
||||
RubyCompiler.compile( source ).to_vool
|
||||
RubyCompiler.compile( source ).to_sol
|
||||
end
|
||||
end
|
||||
class SuperStatement < SendStatement
|
||||
|
@ -7,16 +7,16 @@ module Ruby
|
||||
#
|
||||
class Statement
|
||||
|
||||
# Many statements exist in the vool layer in quite a similar arrangement
|
||||
# Many statements exist in the sol layer in quite a similar arrangement
|
||||
# Especially for different types of assignment we can abstract the creation
|
||||
# of the vool, by using the right class to instantiate, the "vool_brother"
|
||||
# Ie same class_name, but in the Vool module
|
||||
def vool_brother
|
||||
eval "Vool::#{class_name}"
|
||||
# of the sol, by using the right class to instantiate, the "sol_brother"
|
||||
# Ie same class_name, but in the Sol module
|
||||
def sol_brother
|
||||
eval "Sol::#{class_name}"
|
||||
end
|
||||
|
||||
# return the class name without the module
|
||||
# used to evaluate the vool_brother
|
||||
# used to evaluate the sol_brother
|
||||
def class_name
|
||||
self.class.name.split("::").last
|
||||
end
|
||||
|
@ -35,11 +35,11 @@ module Ruby
|
||||
@statements << o
|
||||
self
|
||||
end
|
||||
def to_vool
|
||||
return first.to_vool if( single? )
|
||||
brother = vool_brother.new(nil)
|
||||
def to_sol
|
||||
return first.to_sol if( single? )
|
||||
brother = sol_brother.new(nil)
|
||||
@statements.each do |s|
|
||||
brother << s.to_vool
|
||||
brother << s.to_sol
|
||||
end
|
||||
brother
|
||||
end
|
||||
|
@ -6,8 +6,8 @@ module Ruby
|
||||
@name = name
|
||||
end
|
||||
|
||||
def to_vool
|
||||
vool_brother.new(@name)
|
||||
def to_sol
|
||||
sol_brother.new(@name)
|
||||
end
|
||||
def to_s(depth=0)
|
||||
name.to_s
|
||||
|
@ -11,9 +11,9 @@ module Ruby
|
||||
@body = body
|
||||
end
|
||||
|
||||
def to_vool
|
||||
cond , hoisted = *normalized_vool(@condition)
|
||||
Vool::WhileStatement.new(cond , @body.to_vool , hoisted)
|
||||
def to_sol
|
||||
cond , hoisted = *normalized_sol(@condition)
|
||||
Sol::WhileStatement.new(cond , @body.to_sol , hoisted)
|
||||
end
|
||||
|
||||
def to_s(depth = 0)
|
||||
|
Reference in New Issue
Block a user