Splitting NameExpression into three, Known,Local,Argument

The decision which to use can be made higher up, in ruby, and so it
should.
This commit is contained in:
Torsten Ruger 2017-01-16 09:33:49 +02:00
parent 96f19d18c0
commit 5f7ea08a43
6 changed files with 47 additions and 21 deletions

View File

@ -14,7 +14,7 @@ module Melon
def on_ivasgn(statement)
name , value = *statement
w = Vm::Tree::Assignment.new()
w.name = Vm::Tree::NameExpression.new( name[1..-1].to_sym)
w.name = Vm::Tree::InstanceName.new( name[1..-1].to_sym)
w.value = process(value)
w
end
@ -22,8 +22,8 @@ module Melon
def on_ivar( var )
name = var.children.first
w = Vm::Tree::FieldAccess.new()
w.receiver = Vm::Tree::NameExpression.new(:self)
w.field = Vm::Tree::NameExpression.new( name[1..-1].to_sym)
w.receiver = Vm::Tree::KnownName.new(:self)
w.field = Vm::Tree::InstanceName.new( name[1..-1].to_sym)
w
end
@ -31,12 +31,20 @@ module Melon
receiver , name , args = *statement
w = Vm::Tree::CallSite.new()
puts "receiver #{statement}"
w.name = process(receiver)
w.name = name
w.arguments = process(args)
w.receiver = nil
w.receiver = process(receiver)
w
end
def on_lvar(statement)
name = statement.children.first.to_sym
if(@ruby_method.args_type.variable_index(name))
return Vm::Tree::ArgumentName.new(name)
end
raise "Not found #{name}"
end
def on_str( string )
Vm::Tree::StringExpression.new(string.children.first)
end

View File

@ -4,7 +4,7 @@ module Register
module CompileHelper
def self_and_int_arg(compiler , source)
me = compiler.process( Vm::Tree::NameExpression.new( :self) )
me = compiler.process( Vm::Tree::KnownName.new( :self) )
int_arg = load_int_arg_at(compiler , source , 1 )
return me , int_arg
end

View File

@ -18,9 +18,9 @@ module Register
def div10 context
s = "div_10"
compiler = Vm::MethodCompiler.new.create_method(:Integer,:div10 ).init_method
me = compiler.process( Vm::Tree::NameExpression.new( :self) )
tmp = compiler.process( Vm::Tree::NameExpression.new( :self) )
q = compiler.process( Vm::Tree::NameExpression.new( :self) )
me = compiler.process( Vm::Tree::KnownName.new( :self) )
tmp = compiler.process( Vm::Tree::KnownName.new( :self) )
q = compiler.process( Vm::Tree::KnownName.new( :self) )
const = compiler.process( Vm::Tree::IntegerExpression.new(1) )
# int tmp = self >> 1
compiler.add_code Register.op( s , ">>" , tmp , const)

View File

@ -5,20 +5,18 @@ module Vm
# compiling name needs to check if it's a local variable
# or an argument
# whichever way this goes the result is stored in the return slot (as all compiles)
def on_NameExpression statement
def on_KnownName statement
name = statement.name
[:self , :space , :message].each do |special|
return send(:"load_special_#{special}" , statement ) if name == special
end
return load_argument(statement) if( @method.has_argument(name))
load_local(statement)
raise "Unknow 'known' expression #{name}"
end
private
def load_argument(statement)
def on_ArgumentName(statement)
name = statement.name
index = @method.has_argument(name)
raise "no arg #{name}" unless index
named_list = use_reg :NamedList
ret = use_reg @method.arguments_type(index)
#puts "For #{name} at #{index} got #{@method.arguments.inspect}"
@ -27,10 +25,10 @@ module Vm
return ret
end
def load_local( statement )
def on_LocalName( statement )
name = statement.name
index = @method.has_local( name )
raise "must define variable '#{name}' before using it" unless index
raise "must define local '#{name}' before using it" unless index
named_list = use_reg :NamedList
add_slot_to_reg("#{name} load locals" , :message , :locals , named_list )
ret = use_reg @method.locals_type( index )

View File

@ -36,6 +36,7 @@ module Vm
@value = value
end
end
class NameExpression < Expression
include ValuePrinter
attr_accessor :value
@ -44,6 +45,16 @@ module Vm
@value = value
end
end
class LocalName < NameExpression
end
class ArgumentName < NameExpression
end
class InstanceName < NameExpression
end
class KnownName < NameExpression
end
class ClassExpression < Expression
include ValuePrinter
attr_accessor :value

View File

@ -85,9 +85,9 @@ module Vm
end
def on_call statement
name_s , arguments , receiver = *statement
name , arguments , receiver = *statement
w = Tree::CallSite.new()
w.name = name_s.children.first
w.name = name
w.arguments = process_all(arguments)
w.receiver = process(receiver)
w
@ -109,8 +109,17 @@ module Vm
Tree::NilExpression.new
end
def on_name statement
Tree::NameExpression.new(statement.children.first)
def on_arg statement
Tree::ArgumentName.new(statement.children.first)
end
def on_local statement
Tree::LocalName.new(statement.children.first)
end
def on_ivar statement
Tree::InstanceName.new(statement.children.first)
end
def on_known statement
Tree::KnownName.new(statement.children.first)
end
def on_string expression