bit more cleanup after compiler
This commit is contained in:
parent
001af3f8b6
commit
cdea4915f9
@ -73,8 +73,8 @@ module Compiler
|
||||
|
||||
#attr_reader :left, :right
|
||||
def self.compile_assignment expession , method , message
|
||||
raise "must assign to NameExpression , not #{expession.left}" unless expession.left.instance_of? NameExpression
|
||||
r = right.compile(method,message)
|
||||
raise "must assign to NameExpression , not #{expession.left}" unless expession.left.instance_of? Ast::NameExpression
|
||||
r = Compiler.compile(expession.right , method,message)
|
||||
raise "oh noo, nil from where #{expession.right.inspect}" unless r
|
||||
message.compile_set( method , expession.left.name , r )
|
||||
end
|
||||
|
@ -3,15 +3,15 @@ module Compiler
|
||||
|
||||
# call_site - attr_reader :name, :args , :receiver
|
||||
|
||||
def self.compile_call_site expession , method , message
|
||||
me = expession.receiver.compile( method, message )
|
||||
def self.compile_callsite expession , method , message
|
||||
me = Compiler.compile( expession.receiver , method, message )
|
||||
method.add_code Virtual::NewMessage.new
|
||||
method.add_code Virtual::Set.new(Virtual::NewSelf.new(me.type), me)
|
||||
method.add_code Virtual::Set.new(Virtual::NewName.new(), Virtual::StringConstant.new(expession.name))
|
||||
compiled_args = []
|
||||
expession.args.each_with_index do |arg , i|
|
||||
#compile in the running method, ie before passing control
|
||||
val = arg.compile( method, message)
|
||||
val = Compiler.compile( arg , method, message)
|
||||
# move the compiled value to it's slot in the new message
|
||||
to = Virtual::NewMessageSlot.new(i ,val.type , val)
|
||||
# (doing this immediately, not after the loop, so if it's a return it won't get overwritten)
|
||||
|
@ -1,20 +1,20 @@
|
||||
module Compiler
|
||||
# function attr_reader :name, :params, :body , :receiver
|
||||
def self.compile_function expression, method , message
|
||||
args = expession.params.collect do |p|
|
||||
raise "error, argument must be a identifier, not #{p}" unless p.is_a? NameExpression
|
||||
args = expression.params.collect do |p|
|
||||
raise "error, argument must be a identifier, not #{p}" unless p.is_a? Ast::NameExpression
|
||||
p.name
|
||||
end
|
||||
r = expession.receiver ? expession.receiver.compile(method,message) : Virtual::Self.new()
|
||||
new_method = Virtual::CompiledMethod.new(expession.name , args , r )
|
||||
r = expression.receiver ? expression.receiver.compile(method,message) : Virtual::Self.new()
|
||||
new_method = Virtual::CompiledMethod.new(expression.name , args , r )
|
||||
new_method.class_name = r.is_a?(Virtual::BootClass) ? r.name : method.class_name
|
||||
clazz = Virtual::BootSpace.space.get_or_create_class(new_method.class_name)
|
||||
clazz.add_instance_method new_method
|
||||
|
||||
#frame = frame.new_frame
|
||||
return_type = nil
|
||||
expession.body.each do |ex|
|
||||
return_type = ex.compile(new_method,message )
|
||||
expression.body.each do |ex|
|
||||
return_type = Compiler.compile(ex,new_method,message )
|
||||
raise return_type.inspect if return_type.is_a? Virtual::Instruction
|
||||
end
|
||||
new_method.return_type = return_type
|
||||
@ -23,7 +23,7 @@ module Compiler
|
||||
def scratch
|
||||
args = []
|
||||
locals = {}
|
||||
expession.params.each_with_index do |param , index|
|
||||
expression.params.each_with_index do |param , index|
|
||||
arg = param.name
|
||||
register = Virtual::RegisterReference.new(Virtual::RegisterMachine.instance.receiver_register).next_reg_use(index + 1)
|
||||
arg_value = Virtual::Integer.new(register)
|
||||
@ -32,10 +32,10 @@ module Compiler
|
||||
end
|
||||
# class depends on receiver
|
||||
me = Virtual::Integer.new( Virtual::RegisterMachine.instance.receiver_register )
|
||||
if expession.receiver.nil?
|
||||
if expression.receiver.nil?
|
||||
clazz = context.current_class
|
||||
else
|
||||
c = context.object_space.get_or_create_class expession.receiver.name.to_sym
|
||||
c = context.object_space.get_or_create_class expression.receiver.name.to_sym
|
||||
clazz = c.meta_class
|
||||
end
|
||||
|
||||
@ -48,7 +48,7 @@ module Compiler
|
||||
context.function = function
|
||||
|
||||
last_compiled = nil
|
||||
expession.body.each do |b|
|
||||
expression.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? Virtual::Word
|
||||
|
@ -5,14 +5,14 @@ module Compiler
|
||||
end
|
||||
|
||||
def self.compile_class expression , method , message
|
||||
clazz = ::Virtual::BootSpace.space.get_or_create_class name
|
||||
clazz = ::Virtual::BootSpace.space.get_or_create_class expression.name
|
||||
puts "Created class #{clazz.name.inspect}"
|
||||
expression.expressions.each do |expr|
|
||||
# check if it's a function definition and add
|
||||
# if not, execute it, but that does means we should be in salama (executable), not ruby. ie throw an error for now
|
||||
raise "only functions for now #{expr.inspect}" unless expr.is_a? Ast::FunctionExpression
|
||||
#puts "compiling expression #{expression}"
|
||||
expression_value = expr.compile(method,message )
|
||||
expression_value = Compiler.compile(expr,method,message )
|
||||
clazz.add_instance_method(expression_value)
|
||||
#puts "compiled expression #{expression_value.inspect}"
|
||||
end
|
||||
|
@ -112,16 +112,16 @@ module Virtual
|
||||
# used to determine if a send must be issued
|
||||
def has_var name
|
||||
name = name.to_sym
|
||||
var = @arg_names.find {|a| a.name == name }
|
||||
var = @locals.find {|a| a.name == name } unless var
|
||||
var = @tmps.find {|a| a.name == name } unless var
|
||||
var = @arg_names.find {|a| a == name }
|
||||
var = @locals.find {|a| a == name } unless var
|
||||
var = @tmps.find {|a| a == name } unless var
|
||||
var
|
||||
end
|
||||
|
||||
# determine whether this method has an argument by the name
|
||||
def has_arg name
|
||||
name = name.to_sym
|
||||
var = @arg_names.find {|a| a.name == name }
|
||||
var = @arg_names.find {|a| a == name }
|
||||
var
|
||||
end
|
||||
|
||||
|
@ -8,13 +8,13 @@ module Virtual
|
||||
|
||||
# The methods that are there, are nevertheless meant to be called at compile time and generate code, rather than
|
||||
# executing it.
|
||||
|
||||
|
||||
# The caller creates the Message and passes control to the receiver's method
|
||||
|
||||
# The receiver create a new Frame to hold local and temporary variables and (later) creates default values for
|
||||
# arguments that were not passed
|
||||
|
||||
# How the actual finding of the method takes place (acording to the ruby rules) is not simple, but as there is a
|
||||
# How the actual finding of the method takes place (acording to the ruby rules) is not simple, but as there is a
|
||||
# guaranteed result (be it method_missing) it does not matter to the passing mechanism described
|
||||
|
||||
# During compilation Message and frame objects are created to do type analysis
|
||||
@ -27,7 +27,7 @@ module Virtual
|
||||
NEW_MESSAGE_REG = :r3
|
||||
|
||||
TMP_REG = :r4
|
||||
|
||||
|
||||
def initialize me , normal , exceptional
|
||||
@me = me
|
||||
@next_normal = normal
|
||||
@ -42,7 +42,7 @@ module Virtual
|
||||
def new_frame
|
||||
raise self.inspect
|
||||
end
|
||||
#
|
||||
#
|
||||
def compile_get method , name
|
||||
raise "CALLED"
|
||||
if method.has_arg(name)
|
||||
|
@ -2,7 +2,7 @@ require_relative "virtual_helper"
|
||||
|
||||
class TestMethods < MiniTest::Test
|
||||
include VirtualHelper
|
||||
|
||||
|
||||
def test_object
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
@ -11,7 +11,7 @@ class Object
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@output = ""
|
||||
@output = "-&5 Virtual::BootClass(:length => -1, :name => :Object, :super_class_name => :Object)*^* :instance_methods -Virtual::CompiledMethod(:name => :index_of, :class_name => :Object, :arg_names => &1 Virtual::Reference, :return_type => Virtual::Integer)*^* :locals []*^* :tmps []*^* :receiver [*1]*^* :blocks -Virtual::Block(:length => -1, :name => :enter)*^* :codes -Virtual::MethodEnter(:length => -1)*^* -Virtual::Block(:length => -1, :name => :return)*^* :codes -Virtual::MethodReturn(:length => -1)*^* -Virtual::CompiledMethod(:name => :_get_instance_variable, :class_name => :Object, :receiver => &1 Virtual::Reference, :return_type => &2 Virtual::Mystery)*^* :arg_names [*1]*^* :locals []*^* :tmps []*^* :blocks -Virtual::Block(:length => -1, :name => :enter)*^* :codes -Virtual::MethodEnter(:length => -1)*^* -Virtual::Block(:length => -1, :name => :return)*^* :codes -Virtual::MethodReturn(:length => -1)*^* -Virtual::CompiledMethod(:name => :_set_instance_variable, :class_name => :Object, :receiver => &1 Virtual::Reference, :return_type => &2 Virtual::Mystery)*^* :arg_names [*1, *1]*^* :locals []*^* :tmps []*^* :blocks -Virtual::Block(:length => -1, :name => :enter)*^* :codes -Virtual::MethodEnter(:length => -1)*^* -Virtual::Block(:length => -1, :name => :return)*^* :codes -Virtual::MethodReturn(:length => -1)*^* -&4 Virtual::CompiledMethod(:name => :get_class, :class_name => :Object)*^* :arg_names []*^* :locals []*^* :tmps []*^* :receiver Virtual::Self(:index => 3, :type => *2)*^* :return_type Virtual::NewReturn(:index => 5, :type => *2)*^* :blocks -Virtual::Block(:length => -1, :name => :enter)*^* :codes -Virtual::MethodEnter(:length => -1)*^* -Virtual::InstanceGet(:name => :layout)*^* -Virtual::NewMessage(:length => -1)*^* -Virtual::Set()*^* :to Virtual::NewSelf(:index => 3, :type => *2)*^* :from &3 Virtual::NewReturn(:index => 5, :type => *2)*^* -Virtual::Set()*^* :to Virtual::NewName(:index => 4, :type => *2)*^* :from Virtual::StringConstant(:string => :get_class)*^* -Virtual::MessageSend(:name => :get_class)*^* :me &3 Virtual::NewReturn(:index => 5, :type => *2)*^* :args []*^* -Virtual::Block(:length => -1, :name => :return)*^* :codes -Virtual::MethodReturn(:length => -1)*^* -&4 Virtual::CompiledMethod(:name => :get_class, :class_name => :Object)*^* :arg_names []*^* :locals []*^* :tmps []*^* :receiver Virtual::Self(:index => 3, :type => *2)*^* :return_type Virtual::NewReturn(:index => 5, :type => *2)*^* :blocks -Virtual::Block(:length => -1, :name => :enter)*^* :codes -Virtual::MethodEnter(:length => -1)*^* -Virtual::InstanceGet(:name => :layout)*^* -Virtual::NewMessage(:length => -1)*^* -Virtual::Set()*^* :to Virtual::NewSelf(:index => 3, :type => *2)*^* :from &3 Virtual::NewReturn(:index => 5, :type => *2)*^* -Virtual::Set()*^* :to Virtual::NewName(:index => 4, :type => *2)*^* :from Virtual::StringConstant(:string => :get_class)*^* -Virtual::MessageSend(:name => :get_class)*^* :me &3 Virtual::NewReturn(:index => 5, :type => *2)*^* :args []*^* -Virtual::Block(:length => -1, :name => :return)*^* :codes -Virtual::MethodReturn(:length => -1)*^* :meta_class Virtual::MetaClass(:length => -1, :me_self => *5)*^* :functions []"
|
||||
check
|
||||
end
|
||||
|
||||
@ -28,4 +28,4 @@ HERE
|
||||
check
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
@ -11,7 +11,9 @@ module VirtualHelper
|
||||
def check
|
||||
machine = Virtual::Machine.boot
|
||||
expressions = machine.compile_main @string_input
|
||||
is = Sof::Writer.write(expressions).gsub("\n" , "*^*")
|
||||
is = Sof::Writer.write(expressions)
|
||||
# puts is
|
||||
is.gsub!("\n" , "*^*")
|
||||
assert_equal is , @output
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user