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:
2019-10-04 00:36:49 +03:00
parent aa9fc8bc81
commit d1f8733623
135 changed files with 636 additions and 636 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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?

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)