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) def on_ivasgn(statement)
name , value = *statement name , value = *statement
w = Vm::Tree::Assignment.new() 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.value = process(value)
w w
end end
@ -22,8 +22,8 @@ module Melon
def on_ivar( var ) def on_ivar( var )
name = var.children.first name = var.children.first
w = Vm::Tree::FieldAccess.new() w = Vm::Tree::FieldAccess.new()
w.receiver = Vm::Tree::NameExpression.new(:self) w.receiver = Vm::Tree::KnownName.new(:self)
w.field = Vm::Tree::NameExpression.new( name[1..-1].to_sym) w.field = Vm::Tree::InstanceName.new( name[1..-1].to_sym)
w w
end end
@ -31,12 +31,20 @@ module Melon
receiver , name , args = *statement receiver , name , args = *statement
w = Vm::Tree::CallSite.new() w = Vm::Tree::CallSite.new()
puts "receiver #{statement}" puts "receiver #{statement}"
w.name = process(receiver) w.name = name
w.arguments = process(args) w.arguments = process(args)
w.receiver = nil w.receiver = process(receiver)
w w
end 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 ) def on_str( string )
Vm::Tree::StringExpression.new(string.children.first) Vm::Tree::StringExpression.new(string.children.first)
end end

View File

@ -4,7 +4,7 @@ module Register
module CompileHelper module CompileHelper
def self_and_int_arg(compiler , source) 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 ) int_arg = load_int_arg_at(compiler , source , 1 )
return me , int_arg return me , int_arg
end end

View File

@ -18,9 +18,9 @@ module Register
def div10 context def div10 context
s = "div_10" s = "div_10"
compiler = Vm::MethodCompiler.new.create_method(:Integer,:div10 ).init_method compiler = Vm::MethodCompiler.new.create_method(:Integer,:div10 ).init_method
me = compiler.process( Vm::Tree::NameExpression.new( :self) ) me = compiler.process( Vm::Tree::KnownName.new( :self) )
tmp = compiler.process( Vm::Tree::NameExpression.new( :self) ) tmp = compiler.process( Vm::Tree::KnownName.new( :self) )
q = compiler.process( Vm::Tree::NameExpression.new( :self) ) q = compiler.process( Vm::Tree::KnownName.new( :self) )
const = compiler.process( Vm::Tree::IntegerExpression.new(1) ) const = compiler.process( Vm::Tree::IntegerExpression.new(1) )
# int tmp = self >> 1 # int tmp = self >> 1
compiler.add_code Register.op( s , ">>" , tmp , const) 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 # compiling name needs to check if it's a local variable
# or an argument # or an argument
# whichever way this goes the result is stored in the return slot (as all compiles) # 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 name = statement.name
[:self , :space , :message].each do |special| [:self , :space , :message].each do |special|
return send(:"load_special_#{special}" , statement ) if name == special return send(:"load_special_#{special}" , statement ) if name == special
end end
return load_argument(statement) if( @method.has_argument(name)) raise "Unknow 'known' expression #{name}"
load_local(statement)
end end
private def on_ArgumentName(statement)
def load_argument(statement)
name = statement.name name = statement.name
index = @method.has_argument(name) index = @method.has_argument(name)
raise "no arg #{name}" unless index
named_list = use_reg :NamedList named_list = use_reg :NamedList
ret = use_reg @method.arguments_type(index) ret = use_reg @method.arguments_type(index)
#puts "For #{name} at #{index} got #{@method.arguments.inspect}" #puts "For #{name} at #{index} got #{@method.arguments.inspect}"
@ -27,10 +25,10 @@ module Vm
return ret return ret
end end
def load_local( statement ) def on_LocalName( statement )
name = statement.name name = statement.name
index = @method.has_local( 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 named_list = use_reg :NamedList
add_slot_to_reg("#{name} load locals" , :message , :locals , named_list ) add_slot_to_reg("#{name} load locals" , :message , :locals , named_list )
ret = use_reg @method.locals_type( index ) ret = use_reg @method.locals_type( index )

View File

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

View File

@ -85,9 +85,9 @@ module Vm
end end
def on_call statement def on_call statement
name_s , arguments , receiver = *statement name , arguments , receiver = *statement
w = Tree::CallSite.new() w = Tree::CallSite.new()
w.name = name_s.children.first w.name = name
w.arguments = process_all(arguments) w.arguments = process_all(arguments)
w.receiver = process(receiver) w.receiver = process(receiver)
w w
@ -109,8 +109,17 @@ module Vm
Tree::NilExpression.new Tree::NilExpression.new
end end
def on_name statement def on_arg statement
Tree::NameExpression.new(statement.children.first) 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 end
def on_string expression def on_string expression