bit more cleanup after compiler

This commit is contained in:
Torsten Ruger 2015-05-05 15:11:09 +03:00
parent 001af3f8b6
commit cdea4915f9
8 changed files with 31 additions and 29 deletions

View File

@ -73,8 +73,8 @@ module Compiler
#attr_reader :left, :right #attr_reader :left, :right
def self.compile_assignment expession , method , message def self.compile_assignment expession , method , message
raise "must assign to NameExpression , not #{expession.left}" unless expession.left.instance_of? NameExpression raise "must assign to NameExpression , not #{expession.left}" unless expession.left.instance_of? Ast::NameExpression
r = right.compile(method,message) r = Compiler.compile(expession.right , method,message)
raise "oh noo, nil from where #{expession.right.inspect}" unless r raise "oh noo, nil from where #{expession.right.inspect}" unless r
message.compile_set( method , expession.left.name , r ) message.compile_set( method , expession.left.name , r )
end end

View File

@ -3,15 +3,15 @@ module Compiler
# call_site - attr_reader :name, :args , :receiver # call_site - attr_reader :name, :args , :receiver
def self.compile_call_site expession , method , message def self.compile_callsite expession , method , message
me = expession.receiver.compile( method, message ) me = Compiler.compile( expession.receiver , method, message )
method.add_code Virtual::NewMessage.new 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::NewSelf.new(me.type), me)
method.add_code Virtual::Set.new(Virtual::NewName.new(), Virtual::StringConstant.new(expession.name)) method.add_code Virtual::Set.new(Virtual::NewName.new(), Virtual::StringConstant.new(expession.name))
compiled_args = [] compiled_args = []
expession.args.each_with_index do |arg , i| expession.args.each_with_index do |arg , i|
#compile in the running method, ie before passing control #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 # move the compiled value to it's slot in the new message
to = Virtual::NewMessageSlot.new(i ,val.type , val) 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) # (doing this immediately, not after the loop, so if it's a return it won't get overwritten)

View File

@ -1,20 +1,20 @@
module Compiler module Compiler
# function attr_reader :name, :params, :body , :receiver # function attr_reader :name, :params, :body , :receiver
def self.compile_function expression, method , message def self.compile_function expression, method , message
args = expession.params.collect do |p| args = expression.params.collect do |p|
raise "error, argument must be a identifier, not #{p}" unless p.is_a? NameExpression raise "error, argument must be a identifier, not #{p}" unless p.is_a? Ast::NameExpression
p.name p.name
end end
r = expession.receiver ? expession.receiver.compile(method,message) : Virtual::Self.new() r = expression.receiver ? expression.receiver.compile(method,message) : Virtual::Self.new()
new_method = Virtual::CompiledMethod.new(expession.name , args , r ) new_method = Virtual::CompiledMethod.new(expression.name , args , r )
new_method.class_name = r.is_a?(Virtual::BootClass) ? r.name : method.class_name 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 = Virtual::BootSpace.space.get_or_create_class(new_method.class_name)
clazz.add_instance_method new_method clazz.add_instance_method new_method
#frame = frame.new_frame #frame = frame.new_frame
return_type = nil return_type = nil
expession.body.each do |ex| expression.body.each do |ex|
return_type = ex.compile(new_method,message ) return_type = Compiler.compile(ex,new_method,message )
raise return_type.inspect if return_type.is_a? Virtual::Instruction raise return_type.inspect if return_type.is_a? Virtual::Instruction
end end
new_method.return_type = return_type new_method.return_type = return_type
@ -23,7 +23,7 @@ module Compiler
def scratch def scratch
args = [] args = []
locals = {} locals = {}
expession.params.each_with_index do |param , index| expression.params.each_with_index do |param , index|
arg = param.name arg = param.name
register = Virtual::RegisterReference.new(Virtual::RegisterMachine.instance.receiver_register).next_reg_use(index + 1) register = Virtual::RegisterReference.new(Virtual::RegisterMachine.instance.receiver_register).next_reg_use(index + 1)
arg_value = Virtual::Integer.new(register) arg_value = Virtual::Integer.new(register)
@ -32,10 +32,10 @@ module Compiler
end end
# class depends on receiver # class depends on receiver
me = Virtual::Integer.new( Virtual::RegisterMachine.instance.receiver_register ) me = Virtual::Integer.new( Virtual::RegisterMachine.instance.receiver_register )
if expession.receiver.nil? if expression.receiver.nil?
clazz = context.current_class clazz = context.current_class
else 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 clazz = c.meta_class
end end
@ -48,7 +48,7 @@ module Compiler
context.function = function context.function = function
last_compiled = nil last_compiled = nil
expession.body.each do |b| expression.body.each do |b|
puts "compiling in function #{b}" puts "compiling in function #{b}"
last_compiled = b.compile(context) last_compiled = b.compile(context)
raise "alarm #{last_compiled} \n #{b}" unless last_compiled.is_a? Virtual::Word raise "alarm #{last_compiled} \n #{b}" unless last_compiled.is_a? Virtual::Word

View File

@ -5,14 +5,14 @@ module Compiler
end end
def self.compile_class expression , method , message 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}" puts "Created class #{clazz.name.inspect}"
expression.expressions.each do |expr| expression.expressions.each do |expr|
# check if it's a function definition and add # 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 # 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 raise "only functions for now #{expr.inspect}" unless expr.is_a? Ast::FunctionExpression
#puts "compiling expression #{expression}" #puts "compiling expression #{expression}"
expression_value = expr.compile(method,message ) expression_value = Compiler.compile(expr,method,message )
clazz.add_instance_method(expression_value) clazz.add_instance_method(expression_value)
#puts "compiled expression #{expression_value.inspect}" #puts "compiled expression #{expression_value.inspect}"
end end

View File

@ -112,16 +112,16 @@ module Virtual
# used to determine if a send must be issued # used to determine if a send must be issued
def has_var name def has_var name
name = name.to_sym name = name.to_sym
var = @arg_names.find {|a| a.name == name } var = @arg_names.find {|a| a == name }
var = @locals.find {|a| a.name == name } unless var var = @locals.find {|a| a == name } unless var
var = @tmps.find {|a| a.name == name } unless var var = @tmps.find {|a| a == name } unless var
var var
end end
# determine whether this method has an argument by the name # determine whether this method has an argument by the name
def has_arg name def has_arg name
name = name.to_sym name = name.to_sym
var = @arg_names.find {|a| a.name == name } var = @arg_names.find {|a| a == name }
var var
end end

View File

@ -11,7 +11,7 @@ class Object
end end
end end
HERE 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 check
end end

View File

@ -11,7 +11,9 @@ module VirtualHelper
def check def check
machine = Virtual::Machine.boot machine = Virtual::Machine.boot
expressions = machine.compile_main @string_input 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 assert_equal is , @output
end end