delete some files i had kept for reference
This commit is contained in:
parent
8718ebf476
commit
da9a57b3cf
@ -54,7 +54,9 @@ The important thing here is that Messages and Frames are normal objects.
|
|||||||
And interestingly we can partly use ruby to find the method, so in a way it is not just a top down transformation. but
|
And interestingly we can partly use ruby to find the method, so in a way it is not just a top down transformation. but
|
||||||
the sending goes back up and then down again.
|
the sending goes back up and then down again.
|
||||||
|
|
||||||
The Message object is the second parameter to the compile method, the run-time part as it were.
|
The Message object is the second parameter to the compile method, the run-time part as it were. Why? Since it only
|
||||||
|
exists at runtime: to make compile time analysis possible. Especially for those times when we can resolve the method
|
||||||
|
at compile time. (Which is for all vm code)
|
||||||
|
|
||||||
|
|
||||||
*
|
*
|
||||||
|
@ -22,31 +22,5 @@ module Ast
|
|||||||
method.current = merge
|
method.current = merge
|
||||||
last
|
last
|
||||||
end
|
end
|
||||||
def old
|
|
||||||
into = context.function
|
|
||||||
ret = into.new_block "while_end"
|
|
||||||
while_block = into.new_block "while_start"
|
|
||||||
into.insert_at while_block
|
|
||||||
|
|
||||||
puts "compiling while condition #{condition}"
|
|
||||||
cond_val = condition.compile(context)
|
|
||||||
into.b ret , condition_code: cond_val.not_operator
|
|
||||||
into.insertion_point.branch = ret
|
|
||||||
|
|
||||||
last = nil
|
|
||||||
|
|
||||||
body.each do |part|
|
|
||||||
puts "compiling in while #{part}"
|
|
||||||
last = part.compile(context)
|
|
||||||
end
|
|
||||||
into.b while_block
|
|
||||||
into.insertion_point.branch = while_block
|
|
||||||
|
|
||||||
puts "compile while end"
|
|
||||||
into.insert_at ret
|
|
||||||
return last
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
@ -1,10 +0,0 @@
|
|||||||
require "ast/expression"
|
|
||||||
require_relative "basic_expressions"
|
|
||||||
require_relative "call_site_expression"
|
|
||||||
require_relative "compound_expressions"
|
|
||||||
require_relative "if_expression"
|
|
||||||
require_relative "function_expression"
|
|
||||||
require_relative "module_expression"
|
|
||||||
require_relative "operator_expressions"
|
|
||||||
require_relative "return_expression"
|
|
||||||
require_relative "while_expression"
|
|
@ -1,42 +0,0 @@
|
|||||||
# collection of the simple ones, int and strings and such
|
|
||||||
|
|
||||||
module Ast
|
|
||||||
|
|
||||||
class IntegerExpression < Expression
|
|
||||||
# attr_reader :value
|
|
||||||
def compile context
|
|
||||||
Vm::IntegerConstant.new value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class NameExpression < Expression
|
|
||||||
# attr_reader :name
|
|
||||||
|
|
||||||
# compiling a variable resolves it. if it wasn't defined, raise an exception
|
|
||||||
def compile context
|
|
||||||
raise "Undefined variable #{name}, defined locals #{context.locals.keys.join('-')}" unless context.locals.has_key?(name)
|
|
||||||
context.locals[name]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class ModuleName < NameExpression
|
|
||||||
|
|
||||||
def compile context
|
|
||||||
clazz = context.object_space.get_or_create_class name
|
|
||||||
raise "uups #{clazz}.#{name}" unless clazz
|
|
||||||
#class qualifier, means call from metaclass
|
|
||||||
clazz = clazz.meta_class
|
|
||||||
puts "CLAZZ #{clazz}"
|
|
||||||
clazz
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class StringExpression < Expression
|
|
||||||
# attr_reader :string
|
|
||||||
def compile context
|
|
||||||
value = Vm::StringConstant.new(string)
|
|
||||||
context.object_space.add_object value
|
|
||||||
value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,59 +0,0 @@
|
|||||||
module Ast
|
|
||||||
# assignment, like operators are really function calls
|
|
||||||
|
|
||||||
class CallSiteExpression < Expression
|
|
||||||
# attr_reader :name, :args , :receiver
|
|
||||||
@@counter = 0
|
|
||||||
def compile context
|
|
||||||
into = context.function
|
|
||||||
params = args.collect{ |a| a.compile(context) }
|
|
||||||
puts "compiling receiver #{receiver} (call #{name})"
|
|
||||||
if receiver.is_a? ModuleName
|
|
||||||
clazz = context.object_space.get_or_create_class receiver.name
|
|
||||||
value_receiver = clazz.meta_class
|
|
||||||
function = value_receiver.resolve_function name
|
|
||||||
elsif receiver.is_a?(StringExpression) or receiver.is_a?(IntegerExpression)
|
|
||||||
#TODO obviously the class is wrong, but you gotta start somewhere
|
|
||||||
clazz = context.object_space.get_or_create_class :Object
|
|
||||||
function = clazz.resolve_function name
|
|
||||||
value_receiver = receiver.compile(context)
|
|
||||||
elsif receiver.is_a?(NameExpression)
|
|
||||||
if(receiver.name == :self)
|
|
||||||
function = context.current_class.resolve_function(name)
|
|
||||||
value_receiver = Vm::Integer.new(Vm::RegisterMachine.instance.receiver_register)
|
|
||||||
else
|
|
||||||
value_receiver = receiver.compile(context)
|
|
||||||
# TODO HACK warning: should determine class dynamically
|
|
||||||
function = context.current_class.resolve_function(name)
|
|
||||||
end
|
|
||||||
elsif receiver.is_a? VariableExpression
|
|
||||||
value_receiver = receiver.compile(context)
|
|
||||||
function = context.current_class.resolve_function(name)
|
|
||||||
else
|
|
||||||
#This , how does one say nowadays, smells. Smells of unused polymorphism actually
|
|
||||||
raise "Not sure this is possible, but never good to leave elses open #{receiver} #{receiver.class}"
|
|
||||||
end
|
|
||||||
raise "No such method error #{inspect}" if (function.nil?)
|
|
||||||
raise "No receiver error #{inspect}:#{receiver}" if (value_receiver.nil?)
|
|
||||||
call = Vm::CallSite.new( name , value_receiver , params , function)
|
|
||||||
current_function = context.function
|
|
||||||
into.push([]) unless current_function.nil?
|
|
||||||
call.load_args into
|
|
||||||
call.do_call into
|
|
||||||
|
|
||||||
after = into.new_block("#{name}#{@@counter+=1}")
|
|
||||||
into.insert_at after
|
|
||||||
into.pop([]) unless current_function.nil?
|
|
||||||
function.return_type
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class VariableExpression < CallSiteExpression
|
|
||||||
# super( :_get_instance_variable , [StringExpression.new(name)] )
|
|
||||||
def make_setter
|
|
||||||
@name = :_set_instance_variable
|
|
||||||
@args << StringExpression.new("value")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,20 +0,0 @@
|
|||||||
module Ast
|
|
||||||
|
|
||||||
class ArrayExpression < Expression
|
|
||||||
# attr_reader :values
|
|
||||||
def compile context
|
|
||||||
to.do
|
|
||||||
end
|
|
||||||
end
|
|
||||||
class AssociationExpression < Expression
|
|
||||||
# attr_reader :key , :value
|
|
||||||
def compile context
|
|
||||||
to.do
|
|
||||||
end
|
|
||||||
end
|
|
||||||
class HashExpression < ArrayExpression
|
|
||||||
def compile context
|
|
||||||
to.do
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,51 +0,0 @@
|
|||||||
module Ast
|
|
||||||
class FunctionExpression < Expression
|
|
||||||
# attr_reader :name, :params, :body , :receiver
|
|
||||||
def compile context
|
|
||||||
args = []
|
|
||||||
locals = {}
|
|
||||||
params.each_with_index do |param , index|
|
|
||||||
arg = param.name
|
|
||||||
register = Vm::RegisterReference.new(Vm::RegisterMachine.instance.receiver_register).next_reg_use(index + 1)
|
|
||||||
arg_value = Vm::Integer.new(register)
|
|
||||||
locals[arg] = arg_value
|
|
||||||
args << arg_value
|
|
||||||
end
|
|
||||||
# class depends on receiver
|
|
||||||
me = Vm::Integer.new( Vm::RegisterMachine.instance.receiver_register )
|
|
||||||
if receiver.nil?
|
|
||||||
clazz = context.current_class
|
|
||||||
else
|
|
||||||
c = context.object_space.get_or_create_class receiver.name.to_sym
|
|
||||||
clazz = c.meta_class
|
|
||||||
end
|
|
||||||
|
|
||||||
function = Vm::Function.new(name , me , args )
|
|
||||||
clazz.add_function function
|
|
||||||
|
|
||||||
parent_locals = context.locals
|
|
||||||
parent_function = context.function
|
|
||||||
context.locals = locals
|
|
||||||
context.function = function
|
|
||||||
|
|
||||||
last_compiled = nil
|
|
||||||
body.each do |b|
|
|
||||||
puts "compiling in function #{b}"
|
|
||||||
last_compiled = b.compile(context)
|
|
||||||
raise "alarm #{last_compiled} \n #{b}" unless last_compiled.is_a? Vm::Word
|
|
||||||
end
|
|
||||||
|
|
||||||
return_reg = Vm::Integer.new(Vm::RegisterMachine.instance.return_register)
|
|
||||||
if last_compiled.is_a?(Vm::IntegerConstant) or last_compiled.is_a?(Vm::ObjectConstant)
|
|
||||||
return_reg.load function , last_compiled if last_compiled.register_symbol != return_reg.register_symbol
|
|
||||||
else
|
|
||||||
return_reg.move( function, last_compiled ) if last_compiled.register_symbol != return_reg.register_symbol
|
|
||||||
end
|
|
||||||
function.set_return return_reg
|
|
||||||
|
|
||||||
context.locals = parent_locals
|
|
||||||
context.function = parent_function
|
|
||||||
function
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,41 +0,0 @@
|
|||||||
module Ast
|
|
||||||
class IfExpression < Expression
|
|
||||||
# attr_reader :cond, :if_true, :if_false
|
|
||||||
def compile context
|
|
||||||
f = context.function
|
|
||||||
# to execute the logic as the if states it, the blocks are the other way around
|
|
||||||
# so we can the jump over the else if true ,and the else joins unconditionally after the true_block
|
|
||||||
merge_block = f.new_block "if_merge"
|
|
||||||
true_block = f.new_block "if_true"
|
|
||||||
false_block = f.new_block "if_false"
|
|
||||||
|
|
||||||
puts "compiling if condition #{cond}"
|
|
||||||
cond_val = cond.compile(context)
|
|
||||||
unless cond_val.is_a? Vm::BranchCondition
|
|
||||||
cond_val = cond_val.is_true? f
|
|
||||||
end
|
|
||||||
f.b true_block , condition_code: cond_val.operator
|
|
||||||
f.insertion_point.branch = true_block
|
|
||||||
|
|
||||||
f.insert_at false_block
|
|
||||||
if_false.each do |part|
|
|
||||||
puts "compiling in if false #{part}"
|
|
||||||
last = part.compile(context )
|
|
||||||
end
|
|
||||||
f.b merge_block
|
|
||||||
f.insertion_point.branch = false_block
|
|
||||||
|
|
||||||
f.insert_at true_block
|
|
||||||
last = nil
|
|
||||||
if_true.each do |part|
|
|
||||||
puts "compiling in if true #{part}"
|
|
||||||
last = part.compile(context )
|
|
||||||
end
|
|
||||||
|
|
||||||
puts "compiled if: end"
|
|
||||||
f.insert_at merge_block
|
|
||||||
|
|
||||||
return last
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,24 +0,0 @@
|
|||||||
module Ast
|
|
||||||
class ModuleExpression < Expression
|
|
||||||
# attr_reader :name ,:expressions
|
|
||||||
def compile context
|
|
||||||
clazz = context.object_space.get_or_create_class name
|
|
||||||
puts "Created class #{clazz.name.inspect}"
|
|
||||||
context.current_class = clazz
|
|
||||||
expressions.each do |expression|
|
|
||||||
# check if it's a function definition and add
|
|
||||||
# if not, execute it, but that does means we should be in kide (executable), not ruby. ie throw an error for now
|
|
||||||
raise "only functions for now #{expression.inspect}" unless expression.is_a? Ast::FunctionExpression
|
|
||||||
puts "compiling expression #{expression}"
|
|
||||||
expression_value = expression.compile(context )
|
|
||||||
#puts "compiled expression #{expression_value.inspect}"
|
|
||||||
end
|
|
||||||
|
|
||||||
return clazz
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class ClassExpression < ModuleExpression
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,56 +0,0 @@
|
|||||||
module Ast
|
|
||||||
class OperatorExpression < Expression
|
|
||||||
# attr_reader :operator, :left, :right
|
|
||||||
def compile context
|
|
||||||
into = context.function
|
|
||||||
puts "compiling operator #{to_s}"
|
|
||||||
r_val = right.compile(context)
|
|
||||||
#puts "compiled right #{r_val.inspect}"
|
|
||||||
if operator == "=" # assignment, value based
|
|
||||||
if(left.is_a? VariableExpression)
|
|
||||||
left.make_setter
|
|
||||||
l_val = left.compile(context)
|
|
||||||
elsif left.is_a?(NameExpression)
|
|
||||||
puts context.inspect unless context.locals
|
|
||||||
l_val = context.locals[left.name]
|
|
||||||
if( l_val ) #variable existed, move data there
|
|
||||||
l_val = l_val.move( into , r_val)
|
|
||||||
else
|
|
||||||
l_val = context.function.new_local.move( into , r_val )
|
|
||||||
end
|
|
||||||
context.locals[left.name] = l_val
|
|
||||||
else
|
|
||||||
raise "Can only assign variables, not #{left}"
|
|
||||||
end
|
|
||||||
return l_val
|
|
||||||
end
|
|
||||||
|
|
||||||
l_val = left.compile(context)
|
|
||||||
case operator
|
|
||||||
when ">"
|
|
||||||
code = l_val.greater_than into , r_val
|
|
||||||
when "<"
|
|
||||||
code = l_val.less_than into , r_val
|
|
||||||
when ">="
|
|
||||||
code = l_val.greater_or_equal into , r_val
|
|
||||||
when "<="
|
|
||||||
code = l_val.less_or_equal into , r_val
|
|
||||||
when "=="
|
|
||||||
code = l_val.equals into , r_val
|
|
||||||
when "+"
|
|
||||||
res = context.function.new_local
|
|
||||||
into.add res , l_val , r_val
|
|
||||||
code = res
|
|
||||||
when "-"
|
|
||||||
res = context.function.new_local
|
|
||||||
code = res.minus into , l_val , r_val
|
|
||||||
when "<<"
|
|
||||||
res = context.function.new_local
|
|
||||||
code = res.left_shift into , l_val , r_val
|
|
||||||
else
|
|
||||||
raise "unimplemented operator #{operator} #{self}"
|
|
||||||
end
|
|
||||||
code
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,22 +0,0 @@
|
|||||||
module Ast
|
|
||||||
class ReturnExpression < Expression
|
|
||||||
# attr_reader :expression
|
|
||||||
def compile context
|
|
||||||
into = context.function
|
|
||||||
puts "compiling return expression #{expression}, now return in return_regsiter"
|
|
||||||
expression_value = expression.compile(context)
|
|
||||||
# copied from function expression: TODO make function
|
|
||||||
|
|
||||||
return_reg = Vm::Integer.new(Vm::RegisterMachine.instance.return_register)
|
|
||||||
if expression_value.is_a?(Vm::IntegerConstant) or expression_value.is_a?(Vm::ObjectConstant)
|
|
||||||
return_reg.load into , expression_value
|
|
||||||
else
|
|
||||||
return_reg.move( into, expression_value ) if expression_value.register_symbol != return_reg.register_symbol
|
|
||||||
end
|
|
||||||
#function.set_return return_reg
|
|
||||||
return return_reg
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
@ -1,31 +0,0 @@
|
|||||||
module Ast
|
|
||||||
class WhileExpression < Expression
|
|
||||||
# attr_reader :condition, :body
|
|
||||||
def compile context
|
|
||||||
into = context.function
|
|
||||||
ret = into.new_block "while_end"
|
|
||||||
while_block = into.new_block "while_start"
|
|
||||||
into.insert_at while_block
|
|
||||||
|
|
||||||
puts "compiling while condition #{condition}"
|
|
||||||
cond_val = condition.compile(context)
|
|
||||||
into.b ret , condition_code: cond_val.not_operator
|
|
||||||
into.insertion_point.branch = ret
|
|
||||||
|
|
||||||
last = nil
|
|
||||||
|
|
||||||
body.each do |part|
|
|
||||||
puts "compiling in while #{part}"
|
|
||||||
last = part.compile(context)
|
|
||||||
end
|
|
||||||
into.b while_block
|
|
||||||
into.insertion_point.branch = while_block
|
|
||||||
|
|
||||||
puts "compile while end"
|
|
||||||
into.insert_at ret
|
|
||||||
return last
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
Loading…
Reference in New Issue
Block a user