From 5f7ea08a4342a7bd322387513b16a4ae93063c6c Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Mon, 16 Jan 2017 09:33:49 +0200 Subject: [PATCH] Splitting NameExpression into three, Known,Local,Argument The decision which to use can be made higher up, in ruby, and so it should. --- lib/melon/compilers/method_compiler.rb | 18 +++++++++++++----- lib/register/builtin/compile_helper.rb | 2 +- lib/register/builtin/integer.rb | 6 +++--- lib/vm/method_compiler/name_expression.rb | 14 ++++++-------- lib/vm/tree/basic_values.rb | 11 +++++++++++ lib/vm/tree/to_code.rb | 17 +++++++++++++---- 6 files changed, 47 insertions(+), 21 deletions(-) diff --git a/lib/melon/compilers/method_compiler.rb b/lib/melon/compilers/method_compiler.rb index e44b6e1b..8c4b26ec 100644 --- a/lib/melon/compilers/method_compiler.rb +++ b/lib/melon/compilers/method_compiler.rb @@ -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 diff --git a/lib/register/builtin/compile_helper.rb b/lib/register/builtin/compile_helper.rb index feab0893..fc50f5e6 100644 --- a/lib/register/builtin/compile_helper.rb +++ b/lib/register/builtin/compile_helper.rb @@ -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 diff --git a/lib/register/builtin/integer.rb b/lib/register/builtin/integer.rb index e457428d..186373d0 100644 --- a/lib/register/builtin/integer.rb +++ b/lib/register/builtin/integer.rb @@ -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) diff --git a/lib/vm/method_compiler/name_expression.rb b/lib/vm/method_compiler/name_expression.rb index 3be9d5c1..667dcaf5 100644 --- a/lib/vm/method_compiler/name_expression.rb +++ b/lib/vm/method_compiler/name_expression.rb @@ -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 ) diff --git a/lib/vm/tree/basic_values.rb b/lib/vm/tree/basic_values.rb index bb0730d9..9e75f34c 100644 --- a/lib/vm/tree/basic_values.rb +++ b/lib/vm/tree/basic_values.rb @@ -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 diff --git a/lib/vm/tree/to_code.rb b/lib/vm/tree/to_code.rb index a2dc8183..eb120b59 100644 --- a/lib/vm/tree/to_code.rb +++ b/lib/vm/tree/to_code.rb @@ -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