diff --git a/stash/test_rubyx/fragments/collector.rb b/stash/fragments/collector.rb similarity index 98% rename from stash/test_rubyx/fragments/collector.rb rename to stash/fragments/collector.rb index c7db0b0b..9c163cc9 100644 --- a/stash/test_rubyx/fragments/collector.rb +++ b/stash/fragments/collector.rb @@ -1,4 +1,3 @@ -require_relative '../helper' require "risc/interpreter" require "parser/ruby22" require "yaml" diff --git a/stash/test_rubyx/fragments/helper.rb b/stash/fragments/helper.rb similarity index 100% rename from stash/test_rubyx/fragments/helper.rb rename to stash/fragments/helper.rb diff --git a/stash/test_rubyx/fragments/test_adds.rb b/stash/fragments/test_adds.rb similarity index 100% rename from stash/test_rubyx/fragments/test_adds.rb rename to stash/fragments/test_adds.rb diff --git a/stash/test_rubyx/fragments/test_calls.rb b/stash/fragments/test_calls.rb similarity index 100% rename from stash/test_rubyx/fragments/test_calls.rb rename to stash/fragments/test_calls.rb diff --git a/stash/test_rubyx/fragments/test_hello.rb b/stash/fragments/test_hello.rb similarity index 100% rename from stash/test_rubyx/fragments/test_hello.rb rename to stash/fragments/test_hello.rb diff --git a/stash/test_rubyx/fragments/test_itos.rb b/stash/fragments/test_itos.rb similarity index 100% rename from stash/test_rubyx/fragments/test_itos.rb rename to stash/fragments/test_itos.rb diff --git a/stash/test_rubyx/fragments/test_loop.rb b/stash/fragments/test_loop.rb similarity index 100% rename from stash/test_rubyx/fragments/test_loop.rb rename to stash/fragments/test_loop.rb diff --git a/stash/test_rubyx/fragments/test_many_adds.rb b/stash/fragments/test_many_adds.rb similarity index 100% rename from stash/test_rubyx/fragments/test_many_adds.rb rename to stash/fragments/test_many_adds.rb diff --git a/stash/test_rubyx/fragments/test_many_calls.rb b/stash/fragments/test_many_calls.rb similarity index 100% rename from stash/test_rubyx/fragments/test_many_calls.rb rename to stash/fragments/test_many_calls.rb diff --git a/stash/test_rubyx/fragments/test_many_hello.rb b/stash/fragments/test_many_hello.rb similarity index 100% rename from stash/test_rubyx/fragments/test_many_hello.rb rename to stash/fragments/test_many_hello.rb diff --git a/stash/test_rubyx/fragments/test_many_itos.rb b/stash/fragments/test_many_itos.rb similarity index 100% rename from stash/test_rubyx/fragments/test_many_itos.rb rename to stash/fragments/test_many_itos.rb diff --git a/stash/list.rb b/stash/list.rb deleted file mode 100644 index e10ab843..00000000 --- a/stash/list.rb +++ /dev/null @@ -1,33 +0,0 @@ -class List - - def initialize - @next = nil - end - def empty? - @next.nil? - end - - def get(key) - @next ? @next.get(key) : nil - end - - def set(key , value) - @next ? @next.set(key,value) : @next = Node.new(key,value) - value - end -end - -class Node < List - def initialize(key,value) - @key = key - @value = value - end - def get(key) - @key == key ? @value : super(key) - end - def set(key,value) - @key == key ? @value = value : super(key,value) - end -end - -# https://www.youtube.com/watch?v=HJ-719EGIts \ No newline at end of file diff --git a/stash/soml/parfait/helper.rb b/stash/parfait/helper.rb similarity index 100% rename from stash/soml/parfait/helper.rb rename to stash/parfait/helper.rb diff --git a/stash/soml/parfait/test_integer.rb b/stash/parfait/test_integer.rb similarity index 100% rename from stash/soml/parfait/test_integer.rb rename to stash/parfait/test_integer.rb diff --git a/stash/soml/parfait/test_type.rb b/stash/parfait/test_type.rb similarity index 100% rename from stash/soml/parfait/test_type.rb rename to stash/parfait/test_type.rb diff --git a/stash/soml/parfait/test_word.rb b/stash/parfait/test_word.rb similarity index 100% rename from stash/soml/parfait/test_word.rb rename to stash/parfait/test_word.rb diff --git a/stash/rubyx/passes/locals_collector.rb b/stash/rubyx/passes/locals_collector.rb deleted file mode 100644 index eea9ba40..00000000 --- a/stash/rubyx/passes/locals_collector.rb +++ /dev/null @@ -1,25 +0,0 @@ -module Rubyx - module Passes - class LocalsCollector < TotalProcessor - - def initialize - @locals = {} - end - - def collect(statement) - process statement - @locals - end - - def on_lvasgn statement - add_local( statement ) - end - - def add_local(statement) - var = statement.children[0] - @locals[var] = :Object #not really used right now - end - - end - end -end diff --git a/stash/rubyx/passes/method_collector.rb b/stash/rubyx/passes/method_collector.rb deleted file mode 100644 index 5854925a..00000000 --- a/stash/rubyx/passes/method_collector.rb +++ /dev/null @@ -1,38 +0,0 @@ -module Rubyx - module Passes - - class MethodCollector < TotalProcessor - - def initialize - @methods = [] - end - - def collect(statement) - process statement - @methods - end - - def on_def(statement) - name , args , body = *statement - args_type = make_type(args) - frame_type = make_locals(body) - @methods << Vool::VoolMethod.new(name , args_type , frame_type , body ) - end - - private - - def make_type( statement ) - type_hash = {} - statement.children.each do |arg| - type_hash[arg.children[0]] = :Object - end - Parfait::NamedList.type_for( type_hash ) - end - - def make_locals(body) - type_hash = LocalsCollector.new.collect(body) - Parfait::NamedList.type_for( type_hash ) - end - end - end -end diff --git a/stash/rubyx/passes/method_compiler.rb b/stash/rubyx/passes/method_compiler.rb deleted file mode 100644 index 750ed1bb..00000000 --- a/stash/rubyx/passes/method_compiler.rb +++ /dev/null @@ -1,61 +0,0 @@ -module Rubyx - module Passes - - class MethodCompiler < AST::Processor - - def initialize( ruby_method ) - @ruby_method = ruby_method - end - - def get_code - process(@ruby_method.source) - end - - def on_ivasgn(statement) - name , value = *statement - w = Vm::Tree::Assignment.new() - w.name = Vm::Tree::InstanceName.new( name[1..-1].to_sym) - w.value = process(value) - w - end - - def on_ivar( var ) - name = var.children.first - w = Vm::Tree::FieldAccess.new() - w.receiver = Vm::Tree::KnownName.new(:self) - w.field = Vm::Tree::InstanceName.new( name[1..-1].to_sym) - w - end - - def on_send( statement ) - receiver , name , args = *statement - w = Vm::Tree::CallSite.new() - w.name = name - w.arguments = process(args) || [] - 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 - - def on_int( expression) - Vm::Tree::IntegerExpression.new(expression.children.first) - end - - def handler_missing(node) - raise "No handler for #{node}" - end - - end - end -end diff --git a/stash/rubyx/passes/normalizer.rb b/stash/rubyx/passes/normalizer.rb deleted file mode 100644 index 543c59c2..00000000 --- a/stash/rubyx/passes/normalizer.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Rubyx - module Passes - - class Normalizer < AST::Processor - - def initialize( ruby_method ) - @ruby_method - end - - end - end -end diff --git a/stash/rubyx/passes/total_processor.rb b/stash/rubyx/passes/total_processor.rb deleted file mode 100644 index 73cf4418..00000000 --- a/stash/rubyx/passes/total_processor.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Rubyx - - module Passes - class TotalProcessor < AST::Processor - - def handler_missing(node) - node.children.each do |kid | - process(kid) if kid.is_a?(AST::Node) - end - end - - end - end -end diff --git a/stash/rubyx/passes/type_collector.rb b/stash/rubyx/passes/type_collector.rb deleted file mode 100644 index ba80c164..00000000 --- a/stash/rubyx/passes/type_collector.rb +++ /dev/null @@ -1,29 +0,0 @@ -module Rubyx - module Passes - class TypeCollector < TotalProcessor - - def initialize - @ivars = {} - end - - def collect(statement) - process statement - @ivars - end - - def on_ivar(statement) - add_ivar(statement) - end - - def on_ivasgn( statement ) - add_ivar(statement) - end - - def add_ivar(statement) - var = statement.children[0].to_s[1..-1].to_sym - @ivars[var] = :Object #guess, can maybe guess better - end - - end - end -end diff --git a/stash/rubyx/ruby_compiler.rb b/stash/rubyx/ruby_compiler.rb deleted file mode 100644 index a3a42f79..00000000 --- a/stash/rubyx/ruby_compiler.rb +++ /dev/null @@ -1,64 +0,0 @@ -require "parser/ruby22" - -require_relative "passes/total_processor" -require_relative "passes/type_collector" -require_relative "passes/method_collector" -require_relative "passes/method_compiler" -require_relative "passes/locals_collector" -require_relative "passes/normalizer" -require "vool/vool_method" - - -module Rubyx - class RubyxCompiler < Passes::TotalProcessor - - def self.compile( input ) - ast = Parser::Ruby22.parse( input ) - self.new.process( ast ) - end - - def on_class statement - name , sup , body = *statement - class_name = get_name(name) - clazz = Parfait.object_space.get_class_by_name(class_name ) - if(clazz) - #FIXME super class check with "sup" - else #existing class, don't overwrite type (parfait only?) - clazz = Parfait.object_space.create_class(class_name , get_name(sup) ) - ivar_hash = Passes::TypeCollector.new.collect(body) - clazz.set_instance_type( Parfait::Type.for_hash( clazz , ivar_hash ) ) - end - methods = create_methods(clazz , body) - compile_methods(clazz,methods) - end - - def create_methods(clazz , body) - methods = Passes::MethodCollector.new.collect(body) - methods.each do |method| - clazz.add_method( method ) - normalizer = Passes::Normalizer.new(method) - method.normalize_source { |sourc| normalizer.process( sourc ) } - end - methods - end - - def compile_methods(clazz , methods) - methods.each do |method| - code = Passes::MethodCompiler.new(method).get_code - typed_method = method.create_parfait_method(clazz.instance_type) - Vm::MethodCompiler.new( typed_method ).init_method.process( code ) - end - end - - private - - def get_name( statement ) - return nil unless statement - raise "Not const #{statement}" unless statement.type == :const - name = statement.children[1] - raise "Not symbol #{name}" unless name.is_a? Symbol - name - end - - end -end diff --git a/stash/slot.rb b/stash/slot.rb deleted file mode 100644 index 936cc4d0..00000000 --- a/stash/slot.rb +++ /dev/null @@ -1,20 +0,0 @@ -module Risc - # A slot is a slot in an object. It is the storage location for a value. - # (Remember, values are typed) - # From a memory perspective a slot is an index into an array (the object) - # The mapping into arrays is a straightforward matter, but happens in the - # next level down, the register machine. - - # Four known objects exist and those correspond to subclasses: - # - the message that has been received: MessageSlot - # - the named_list of the method that is executing (local variables): NamedListSlot - # - self as an object: SelfsSlot - # - a message that will be sent, NewMessageSlot - - # additionally named_list, self and return are slots in Message and NewMessage - - # Slot has a lot of small subclasses - # Names for the slots avoid indexes - - -end diff --git a/stash/soml/fragments/helper.rb b/stash/soml/fragments/helper.rb deleted file mode 100644 index 753a9601..00000000 --- a/stash/soml/fragments/helper.rb +++ /dev/null @@ -1,20 +0,0 @@ -require_relative '../helper' - -# Fragments are small programs that we run through the interpreter and really only check -# - the no. of instructions processed -# - the stdout output - -module Fragments - include RuntimeTests - - # define setup to NOT load parfait. - def setup - @stdout = "" - @machine = Risc.machine.boot - end - - def main() - @string_input - end - -end diff --git a/stash/soml/fragments/test_class.rb b/stash/soml/fragments/test_class.rb deleted file mode 100644 index 4e354b77..00000000 --- a/stash/soml/fragments/test_class.rb +++ /dev/null @@ -1,24 +0,0 @@ -require_relative 'helper' - -module Risc -class TestBasicClass < MiniTest::Test - include Fragments - - def test_class_def - @string_input = < (port || 2222) , :user => (user || "pi")) - end - - def check_r ret_val , dont_run = false - return unless box = connected - load_program - file = write_object_file - r_file = file.sub("./" , "ruby-x/") - box.file_upload file , r_file - print "\nfile #{file} " - return if dont_run - box.ld "-N", r_file - begin #need to rescue here as rye throws if no return 0 - ret = box.aout # and we use return to mean something - rescue Rye::Err => e # so it's basically never 0 - ret = e.rap - end - assert_equal @stdout , ret.stdout.join , "remote std was #{ret.stdout}" if @stdout - assert_equal "" , ret.stderr.join , "remote had error" - if ret_val - ret_val &= 0xFF # don't knwo why exit codes are restricted but there you are - assert_equal ret_val , ret.exit_status.to_i , "remote exit failed for #{@string_input}" - end - end - - def write_object_file - file_name = caller(3).first.split("in ").last.chop.sub("`","") - return if file_name.include?("run") - file_name = "./tmp/" + file_name + ".o" - Risc.machine.translate_arm - writer = Elf::ObjectWriter.new - writer.save file_name - file_name - end - -end diff --git a/stash/test_rubyx/helper.rb b/stash/test_rubyx/helper.rb deleted file mode 100644 index 3f91a123..00000000 --- a/stash/test_rubyx/helper.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../helper' diff --git a/stash/test_rubyx/passes/helper.rb b/stash/test_rubyx/passes/helper.rb deleted file mode 100644 index 3f91a123..00000000 --- a/stash/test_rubyx/passes/helper.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative '../helper' diff --git a/stash/test_rubyx/passes/test_locals_collector.rb b/stash/test_rubyx/passes/test_locals_collector.rb deleted file mode 100644 index ddbfe90e..00000000 --- a/stash/test_rubyx/passes/test_locals_collector.rb +++ /dev/null @@ -1,37 +0,0 @@ -require_relative "helper" - -module Rubyx - module Passes - class TestLocalsCollector #< MiniTest::Test - - def setup - Risc.machine.boot unless Risc.machine.booted - end - - def parse_collect( input ) - ast = Parser::Ruby22.parse input - LocalsCollector.new.collect(ast) - end - - def test_no_locals - locals = parse_collect "def meth; end" - assert locals.empty? - end - - def test_method_is_not_local - locals = parse_collect("def meth2(arg1); foo ;end") - assert locals.empty? - end - - def test_local_assign_one - locals = parse_collect("def meth2(arg1); foo = bar ;end") - assert locals[:foo] , locals.inspect - end - def test_local_assign_two - locals = parse_collect("def meth2(arg1); foo = bar ; groove = 1 + 2 ;end") - assert locals.length == 2 , locals.inspect - end - - end - end -end diff --git a/stash/test_rubyx/passes/test_method_collector.rb b/stash/test_rubyx/passes/test_method_collector.rb deleted file mode 100644 index d3d62f5e..00000000 --- a/stash/test_rubyx/passes/test_method_collector.rb +++ /dev/null @@ -1,39 +0,0 @@ -require_relative "helper" - -module Rubyx - module Passes - class TestMethodCollector #< MiniTest::Test - - def setup - Risc.machine.boot unless Risc.machine.booted - end - - def parse_collect( input ) - ast = Parser::Ruby22.parse input - MethodCollector.new.collect(ast) - end - - def test_no_args - methods = parse_collect "def meth; @ivar;end" - assert methods.find{|m| m.name == :meth } - end - - def test_one_arg - method = parse_collect("def meth2(arg1); 1;end").first - assert method.name == :meth2 - assert_equal 2 , method.args_type.variable_index(:arg1) , method.args_type.inspect - end - - def test_three_args - method = parse_collect("def meth3(yksi,kaksi,kolme); 1;end").first - assert method.args_type.variable_index(:kolme) , method.args_type.inspect - end - - def test_one_local - method = parse_collect("def meth2(arg1); foo = 2 ;end").first - assert method.frame_type.variable_index(:foo) , method.frame_type.inspect - end - - end - end -end diff --git a/stash/test_rubyx/passes/test_normalizer.rb b/stash/test_rubyx/passes/test_normalizer.rb deleted file mode 100644 index f0d89894..00000000 --- a/stash/test_rubyx/passes/test_normalizer.rb +++ /dev/null @@ -1,16 +0,0 @@ -require_relative "helper" - -module Rubyx - module Passes - class TestNormalizer < MiniTest::Test - - def setup - Risc.machine.boot unless Risc.machine.booted - end - - def test_no_thing - assert true - end - end - end -end diff --git a/stash/test_rubyx/passes/test_type_collector.rb b/stash/test_rubyx/passes/test_type_collector.rb deleted file mode 100644 index 1872c4f2..00000000 --- a/stash/test_rubyx/passes/test_type_collector.rb +++ /dev/null @@ -1,40 +0,0 @@ -require_relative "helper" - -module Rubyx - module Passes - class TestTypeCollector #< MiniTest::Test - - def setup - Risc.machine.boot - end - - def parse_collect( input ) - ast = Parser::Ruby22.parse input - TypeCollector.new.collect(ast) - end - - def test_ivar_name - hash = parse_collect "def meth; @ivar;end" - assert hash[:ivar] , hash - end - - def test_ivar_assign - hash = parse_collect "def meth; @ivar = 5;end" - assert hash[:ivar] , hash - end - - def test_ivar_operator_assign - hash = parse_collect "def meth; @ivar += 5;end" - assert hash[:ivar] , hash - end - - def test_compile_class - RubyxCompiler.compile "class TestIvar < Object ; def meth; @ivar;end; end" - itest = Parfait.object_space.get_class_by_name(:TestIvar) - assert itest - assert itest.instance_type.names.include?(:ivar) , itest.instance_type.names.inspect - end - - end - end -end diff --git a/stash/test_rubyx/test_ruby_compiler.rb b/stash/test_rubyx/test_ruby_compiler.rb deleted file mode 100644 index 1c3260a3..00000000 --- a/stash/test_rubyx/test_ruby_compiler.rb +++ /dev/null @@ -1,46 +0,0 @@ -require_relative "helper" - -module Rubyx - class TestCompiler #< MiniTest::Test - - def setup - Risc.machine.boot - end - - def test_doesnt_create_existing_clas - space_class = Parfait.object_space.get_class_by_name(:Space) - RubyxCompiler.compile "class Space ; end" - clazz = Parfait.object_space.get_class_by_name(:Space) - assert_equal clazz , space_class - end - - def test_creates_class_without_deriviation - RubyxCompiler.compile "class Testing ; end" - clazz = Parfait.object_space.get_class_by_name(:Testing) - assert clazz , "No classes created" - assert_equal :Object , clazz.super_class_name - end - - def test_creates_class_with_deriviation - RubyxCompiler.compile "class Test2 < List ;end" - clazz = Parfait.object_space.get_class_by_name(:Test2) - assert clazz, "No classes created" - assert_equal :List , clazz.super_class_name - end - - def test_space_is_unchanged_by_compile - space1 = Parfait.object_space.get_class_by_name(:Space) - RubyxCompiler.compile "class Space ;end" - space2 = Parfait.object_space.get_class_by_name(:Space) - assert_equal space1 , space2 - end - - def test_space_type_is_unchanged_by_compile - space1 = Parfait.object_space.get_class_by_name(:Space).instance_type - RubyxCompiler.compile "class Space ;end" - space2 = Parfait.object_space.get_class_by_name(:Space).instance_type - assert_equal space1 , space2 - end - - end -end diff --git a/stash/test_rubyx/test_ruby_method.rb b/stash/test_rubyx/test_ruby_method.rb deleted file mode 100644 index 4c07e8a6..00000000 --- a/stash/test_rubyx/test_ruby_method.rb +++ /dev/null @@ -1,72 +0,0 @@ -require_relative "helper" - -module Rubyx - class TestRubyMethod < MiniTest::Test - include CompilerHelper - - def setup - Risc.machine.boot - end - - def create_method - Vool::VoolCompiler.compile in_Test("def meth; @ivar ;end") - test = Parfait.object_space.get_class_by_name(:Test) - test.get_method(:meth) - end - - def create_method_arg - Vool::VoolCompiler.compile in_Test("def meth_arg(arg); arg ;end") - test = Parfait.object_space.get_class_by_name(:Test) - test.get_method(:meth_arg) - end - - def create_method_local - Vool::VoolCompiler.compile in_Test("def meth_local(arg); local = 5 ;end") - test = Parfait.object_space.get_class_by_name(:Test) - test.get_method(:meth_local) - end - - def test_creates_method_in_class - method = create_method - assert method , "No method created" - end - - def test_method_has_source - method = create_method - assert_equal Vool::ScopeStatement, method.source.class - assert_equal Vool::InstanceVariable, method.source.first.class - end - - def test_method_has_no_args - method = create_method - assert_equal 1 , method.args_type.instance_length - end - - def test_method_has_no_locals - method = create_method - assert_equal 1 , method.frame_type.instance_length - end - - def test_method_has_args - method = create_method_arg - assert_equal 2 , method.args_type.instance_length - end - - def test_method_has_locals - method = create_method_local - assert_equal 2 , method.frame_type.instance_length - end - - def test_method_create_tmp - name = create_method.create_tmp - assert_equal :tmp_1 , name - end - - def test_method_add_tmp - method = create_method_local - method.create_tmp - assert_equal 3 , method.frame_type.instance_length - end - - end -end diff --git a/stash/test_vm/helper.rb b/stash/test_vm/helper.rb deleted file mode 100644 index 5eea8c93..00000000 --- a/stash/test_vm/helper.rb +++ /dev/null @@ -1,3 +0,0 @@ -require_relative "../helper" - -Risc.machine.boot unless Risc.machine.booted diff --git a/stash/test_vm/method_compiler/helper.rb b/stash/test_vm/method_compiler/helper.rb deleted file mode 100644 index 6fba6006..00000000 --- a/stash/test_vm/method_compiler/helper.rb +++ /dev/null @@ -1,82 +0,0 @@ -require_relative '../helper' - -module Risc - module SpaceHack - # test hack to in place change object type - def add_space_field(name,type) - class_type = Parfait.object_space.get_class_by_name(:Space).instance_type - class_type.send(:private_add_instance_variable, name , type) - end - end - module ExpressionHelper - include SpaceHack - - def check - Risc.machine.boot unless Risc.machine.booted - compiler = Vm::MethodCompiler.new Parfait.object_space.get_main - code = Vm.ast_to_code @input - assert code.to_s , @input - produced = compiler.process( code ) - assert @output , "No output given" - assert_equal produced.class , @output , "Wrong class" - produced - end - - end - - module Statements - include AST::Sexp - include CleanCompile - include SpaceHack - - def setup - Risc.machine.boot # force boot to reset main - end - - def preamble - [Label, SlotToReg , LoadConstant, RegToSlot, LoadConstant,RegToSlot, LoadConstant, SlotToReg, SlotToReg ] - end - def postamble - [ Label, FunctionReturn] - end - def check_nil - assert @expect , "No output given" - compiler = Vm::MethodCompiler.new(:main) - code = Vm.ast_to_code( @input ) - assert code.to_s , @input - produced = compiler.process( code ) - produced = Parfait.object_space.get_main.instructions - compare_instructions produced , @expect - end - def check_return - was = check_nil - raise was if was - Parfait.object_space.get_main.instructions - end - - def compare_instructions( instruction , expect ) - index = 0 - all = instruction.to_arr - full_expect = preamble + expect + postamble - full_expect = expect - begin - should = full_expect[index] - return "No instruction at #{index}" unless should - return "Expected at #{index+1}\n#{should(all)}" unless instruction.class == should - index += 1 - instruction = instruction.next - end while( instruction ) - nil - end - def should( all ) - #preamble.each {all.shift} - #postamble.each {all.pop} - str = all.to_s.gsub("Risc::","") - ret = "" - str.split(",").each_slice(6).each do |line| - ret += " " + line.join(",") + " ,\n" - end - ret - end - end -end diff --git a/stash/test_vm/method_compiler/test_assignment.rb b/stash/test_vm/method_compiler/test_assignment.rb deleted file mode 100644 index 03ec29d1..00000000 --- a/stash/test_vm/method_compiler/test_assignment.rb +++ /dev/null @@ -1,112 +0,0 @@ -require_relative 'helper' - -module Risc - class TestAssignStatement < MiniTest::Test - include Statements - - def test_assign_op - Parfait.object_space.get_main.add_local(:r , :Integer) - - @input = s(:statements, s(:l_assignment, s(:local, :r), s(:operator_value, :+, s(:int, 10), s(:int, 1)))) - - @expect = [Label, LoadConstant, LoadConstant, OperatorInstruction, SlotToReg, RegToSlot , - LoadConstant, SlotToReg, RegToSlot, Label, FunctionReturn] - assert_nil msg = check_nil , msg - end - - def test_assign_ivar_notpresent - @input =s(:statements, s(:i_assignment, s(:ivar, :r), s(:int, 5))) - @expect = [] - assert_raises{ check_nil } - end - - def test_assign_ivar - add_space_field(:r , :Integer) - - @input =s(:statements, s(:i_assignment, s(:ivar, :r), s(:int, 5))) - - @expect = [Label, LoadConstant, SlotToReg, RegToSlot, LoadConstant, SlotToReg , - RegToSlot, Label, FunctionReturn] - assert_nil msg = check_nil , msg - end - - def test_assign_local_assign - Parfait.object_space.get_main.add_local(:r , :Integer) - - @input = s(:statements, s(:l_assignment, s(:local, :r), s(:int, 5))) - - @expect = [Label, LoadConstant, SlotToReg, RegToSlot, LoadConstant, SlotToReg , - RegToSlot, Label, FunctionReturn] - assert_nil msg = check_nil , msg - end - - def test_assign_call - Parfait.object_space.get_main.add_local(:r , :Object) - @input = s(:statements, s(:l_assignment, s(:local, :r), s(:call, :main, s(:arguments)))) - @expect = [Label, SlotToReg, SlotToReg, RegToSlot, LoadConstant, RegToSlot , - LoadConstant, SlotToReg, RegToSlot, LoadConstant, RegToSlot, RiscTransfer , - FunctionCall, Label, RiscTransfer, SlotToReg, SlotToReg, SlotToReg , - RegToSlot, LoadConstant, SlotToReg, RegToSlot, Label, FunctionReturn] - assert_nil msg = check_nil , msg - end - - def test_named_list_get - Parfait.object_space.get_main.add_local(:r , :Integer) - @input = s(:statements, s(:l_assignment, s(:local, :r), s(:int, 5)), s(:return, s(:local, :r))) - @expect = [Label, LoadConstant, SlotToReg, RegToSlot, SlotToReg, SlotToReg , - RegToSlot, LoadConstant, SlotToReg, RegToSlot, Label, FunctionReturn] - was = check_return - get = was.next(5) - assert_equal SlotToReg , get.class - assert_equal 1 + 1, get.index , "Get to named_list index must be offset, not #{get.index}" - end - - def test_assign_local_int - Parfait.object_space.get_main.add_local(:r , :Integer) - @input = s(:statements, s(:l_assignment, s(:local, :r), s(:int, 5)) ) - @expect = [Label, LoadConstant, SlotToReg, RegToSlot, LoadConstant, SlotToReg , - RegToSlot, Label, FunctionReturn] - was = check_return - set = was.next(3) - assert_equal RegToSlot , set.class - assert_equal 1 + 1, set.index , "Set to named_list index must be offset, not #{set.index}" - end - - def test_misassign_local - Parfait.object_space.get_main.add_local(:r , :Integer) - @input = s(:statements, s(:l_assignment, s(:local, :r), s(:string, "5")) ) - @expect = [Label, LoadConstant, SlotToReg, RegToSlot, Label, FunctionReturn] - assert_raises {check } - end - - def test_assign_arg - Parfait.object_space.get_main.add_argument(:blar , :Integer) - @input = s(:statements, s(:a_assignment, s(:arg, :blar), s(:int, 5))) - @expect = [Label, LoadConstant, SlotToReg, RegToSlot, LoadConstant, SlotToReg , - RegToSlot, Label, FunctionReturn] - was = check_return - set = was.next(3) - assert_equal RegToSlot , set.class - assert_equal 1 + 1, set.index , "Set to args index must be offset, not #{set.index}" - end - - def test_misassign_arg - Parfait.object_space.get_main.add_argument(:blar , :Integer) - @input = s(:statements, s(:a_assignment, s(:arg, :blar), s(:string, "5"))) - @expect = [Label, LoadConstant, SlotToReg, RegToSlot, Label, FunctionReturn] - assert_raises {check } - end - - def test_arg_get - # have to define bar externally, just because redefining main. Otherwise that would be automatic - Parfait.object_space.get_main.add_argument(:balr , :Integer) - @input = s(:statements, s(:return, s(:arg, :balr))) - @expect = [Label, SlotToReg, SlotToReg, RegToSlot, LoadConstant, SlotToReg , - RegToSlot, Label, FunctionReturn] - was = check_return - get = was.next(2) - assert_equal SlotToReg , get.class - assert_equal 1 + 1, get.index , "Get to args index must be offset, not #{get.index}" - end - end -end diff --git a/stash/test_vm/method_compiler/test_basic_values.rb b/stash/test_vm/method_compiler/test_basic_values.rb deleted file mode 100644 index 2ed85e8d..00000000 --- a/stash/test_vm/method_compiler/test_basic_values.rb +++ /dev/null @@ -1,41 +0,0 @@ -require_relative "helper" - -module Risc - - class TestBasic < MiniTest::Test - include ExpressionHelper - include AST::Sexp - - def setup - Risc.machine.boot - @output = Risc::RiscValue - end - - def test_number - @input = s(:int , 42) - assert_equal 42 , check.value - end - - def test_true - @input = s(:true) - check - end - def test_false - @input = s(:false) - check - end - def test_nil - @input = s(:nil) - check - end - def test_self - @input = s(:known, :self) - check - end - def test_string - @input = s(:string , "hello") - check - end - - end -end diff --git a/stash/test_vm/method_compiler/test_call_expression.rb b/stash/test_vm/method_compiler/test_call_expression.rb deleted file mode 100644 index 20b943f6..00000000 --- a/stash/test_vm/method_compiler/test_call_expression.rb +++ /dev/null @@ -1,43 +0,0 @@ -require_relative "helper" - -module Risc - class TestCall < MiniTest::Test - include ExpressionHelper - include AST::Sexp - - def setup - Risc.machine.boot - @output = Risc::RiscValue - end - - def test_call_main_plain - @input = s(:call , :main ,s(:arguments)) - check - end - - def test_call_main_int - Parfait.object_space.get_main.add_argument(:blar , :Integer) - @input =s(:call, :main ,s(:arguments , s(:int, 1))) - check - end - - def test_call_main_string - Parfait.object_space.get_main.add_argument(:blar , :Word) - @input =s(:call, :main ,s(:arguments , s(:string, "1") )) - check - end - - def test_call_main_op - Parfait.object_space.get_main.add_local(:bar , :Integer) - Parfait.object_space.get_main.add_argument(:blar , :Integer) - @input =s(:call, :main ,s(:arguments , s(:local, :bar) )) - check - end - - def test_call_string_put - @input = s(:call, :putstring,s(:arguments),s(:receiver,s(:string, "Hello Raisa, I am rubyx"))) - check - end - - end -end diff --git a/stash/test_vm/method_compiler/test_call_site.rb b/stash/test_vm/method_compiler/test_call_site.rb deleted file mode 100644 index 870b4bf2..00000000 --- a/stash/test_vm/method_compiler/test_call_site.rb +++ /dev/null @@ -1,68 +0,0 @@ -require_relative 'helper' -require_relative "test_call_expression" - -module Risc - class TestCallStatement < MiniTest::Test - include Statements - - def test_call_constant_int - clean_compile :Integer, :puti, {}, s(:statements, s(:return, s(:int, 1))) - @input = s(:call, :puti , s(:arguments), s(:receiver, s(:int, 42))) - @expect = [Label, SlotToReg, LoadConstant, RegToSlot, LoadConstant, RegToSlot, LoadConstant , - SlotToReg, RegToSlot, LoadConstant, RegToSlot, RiscTransfer, FunctionCall, Label , - RiscTransfer, SlotToReg, SlotToReg, LoadConstant, SlotToReg, RegToSlot, Label , - FunctionReturn] - assert_nil msg = check_nil , msg - end - - - def test_call_constant_string - clean_compile :Word, :putstr,{}, s(:statements, s(:return, s(:int, 1))) - - @input =s(:call, :putstr, s(:arguments), s(:receiver, s(:string, "Hello"))) - @expect = [Label, SlotToReg, LoadConstant, RegToSlot, LoadConstant, RegToSlot, LoadConstant , - SlotToReg, RegToSlot, LoadConstant, RegToSlot, RiscTransfer, FunctionCall, Label , - RiscTransfer, SlotToReg, SlotToReg, LoadConstant, SlotToReg, RegToSlot, Label , - FunctionReturn] - assert_nil msg = check_nil , msg - end - - def test_call_local_int - Parfait.object_space.get_main.add_local(:testi , :Integer) - clean_compile :Integer, :putint, {}, s(:statements, s(:return, s(:int, 1))) - @input = s(:statements, s(:l_assignment, s(:local, :testi), s(:int, 20)), s(:call, :putint, s(:arguments), s(:receiver, s(:local, :testi)))) - - @expect = [Label, LoadConstant, SlotToReg, RegToSlot, SlotToReg, SlotToReg, SlotToReg , - RegToSlot, LoadConstant, RegToSlot, LoadConstant, SlotToReg, RegToSlot, LoadConstant , - RegToSlot, RiscTransfer, FunctionCall, Label, RiscTransfer, SlotToReg, SlotToReg , - LoadConstant, SlotToReg, RegToSlot, Label, FunctionReturn] - assert_nil msg = check_nil , msg - end - - def test_call_local_class - Parfait.object_space.get_main.add_local(:test_l , :List) - clean_compile :List, :add, {}, s(:statements, s(:return, s(:int, 1))) - - @input =s(:statements, s(:call, :add, s(:arguments), s(:receiver, s(:local, :test_l)))) - @expect = [Label, SlotToReg, SlotToReg, SlotToReg, RegToSlot, LoadConstant, RegToSlot , - LoadConstant, SlotToReg, RegToSlot, LoadConstant, RegToSlot, RiscTransfer, FunctionCall , - Label, RiscTransfer, SlotToReg, SlotToReg, LoadConstant, SlotToReg, RegToSlot , - Label, FunctionReturn] - assert_nil msg = check_nil , msg - end - - def test_call_puts - clean_compile :Space, :putstr, {str: :Word}, s(:statements, s(:return, s(:arg, :str))) - @input =s(:call, :putstr , s(:arguments, s(:string, "Hello") ) ) - @expect = [Label, SlotToReg, SlotToReg, RegToSlot, LoadConstant, RegToSlot , - LoadConstant, SlotToReg, RegToSlot, LoadConstant, SlotToReg, RegToSlot , - LoadConstant, RegToSlot, RiscTransfer, FunctionCall, Label, RiscTransfer , - SlotToReg, SlotToReg, LoadConstant, SlotToReg, RegToSlot, Label , - FunctionReturn] - was = check_return - set = was.next(8) - assert_equal RegToSlot , set.class - assert_equal 1, set.index , "Set to message must be offset, not #{set.index}" - end - end -end diff --git a/stash/test_vm/method_compiler/test_field_access.rb b/stash/test_vm/method_compiler/test_field_access.rb deleted file mode 100644 index 985f1ed6..00000000 --- a/stash/test_vm/method_compiler/test_field_access.rb +++ /dev/null @@ -1,34 +0,0 @@ -require_relative "helper" - -module Risc - class TestFields < MiniTest::Test - include ExpressionHelper - include AST::Sexp - - def setup - Risc.machine.boot - end - - def test_field_not_defined - @root = :field_access - @input = s(:field_access, s(:receiver, s(:known, :self)), s(:field, s(:ivar, :a))) - assert_raises(RuntimeError) { check } - end - - def test_field_not_space - @root = :field_access - @input = s(:field_access, s(:receiver, s(:known, :self)), s(:field, s(:ivar, :space))) - - assert_raises(RuntimeError) { check } - end - - def test_field - add_space_field(:bro,:Object) - @root = :field_access - @input = s(:field_access,s(:receiver, s(:known, :self)),s(:field,s(:ivar, :bro))) - @output = Risc::RiscValue - check - end - - end -end diff --git a/stash/test_vm/method_compiler/test_fields.rb b/stash/test_vm/method_compiler/test_fields.rb deleted file mode 100644 index 15f3eb2b..00000000 --- a/stash/test_vm/method_compiler/test_fields.rb +++ /dev/null @@ -1,42 +0,0 @@ -require_relative 'helper' - - -module Risc - class TestFieldStatement < MiniTest::Test - include Statements - - def test_field_named_list - Parfait.object_space.get_main.add_local( :m , :Message) - @input = s(:statements, s(:return, s(:field_access, - s(:receiver, s(:local, :m)), s(:field, s(:ivar, :name))))) - @expect = [Label, SlotToReg, SlotToReg, SlotToReg, RegToSlot, LoadConstant , - SlotToReg, RegToSlot, Label, FunctionReturn] - assert_nil msg = check_nil , msg - end - - def test_field_arg - Parfait.object_space.get_main.add_local( :m , :Message) - clean_compile :Space, :get_name, { :main => :Message}, - s(:statements, s(:return, s(:field_access, - s(:receiver, s(:arg, :main)), s(:field, s(:ivar, :name))))) - @input =s(:statements, s(:return, s(:call, :get_name, s(:arguments, s(:local, :m))))) - - @expect = [Label, SlotToReg, SlotToReg, RegToSlot, LoadConstant, RegToSlot , - LoadConstant, SlotToReg, RegToSlot, SlotToReg, SlotToReg, SlotToReg , - RegToSlot, LoadConstant, RegToSlot, RiscTransfer, FunctionCall, Label , - RiscTransfer, SlotToReg, SlotToReg, RegToSlot, LoadConstant, SlotToReg , - RegToSlot, Label, FunctionReturn] - assert_nil msg = check_nil , msg - end - - def test_message_field - Parfait.object_space.get_main.add_local(:name , :Word) - @input = s(:statements, s(:l_assignment, s(:local, :name), s(:field_access, s(:receiver, s(:known, :message)), s(:field, s(:ivar, :name)))), s(:return, s(:local, :name))) - - @expect = [Label, RiscTransfer, SlotToReg, SlotToReg, RegToSlot, SlotToReg , - SlotToReg, RegToSlot, LoadConstant, SlotToReg, RegToSlot, Label , - FunctionReturn] - assert_nil msg = check_nil , msg - end - end -end diff --git a/stash/test_vm/method_compiler/test_if_statement.rb b/stash/test_vm/method_compiler/test_if_statement.rb deleted file mode 100644 index e2589b64..00000000 --- a/stash/test_vm/method_compiler/test_if_statement.rb +++ /dev/null @@ -1,36 +0,0 @@ -require_relative 'helper' - -module Risc - class TestIfStatement < MiniTest::Test - include Statements - - def test_if_basicr - @input = s(:statements, s(:if_statement, :plus, s(:condition, s(:operator_value, :-, s(:int, 10), s(:int, 12))), s(:true_statements, s(:return, s(:int, 3))), s(:false_statements, s(:return, s(:int, 4))))) - - @expect = [Label, LoadConstant, LoadConstant, OperatorInstruction, IsPlus, LoadConstant , - RegToSlot, Branch, Label, LoadConstant, RegToSlot, Label , - LoadConstant, SlotToReg, RegToSlot, Label, FunctionReturn] - assert_nil msg = check_nil , msg - end - - - def test_if_small_minus - @input = s(:statements, s(:if_statement, :minus, s(:condition, s(:operator_value, :-, s(:int, 10), s(:int, 12))), s(:true_statements, s(:return, s(:int, 3))), s(:false_statements, nil))) - - @expect = [Label, LoadConstant, LoadConstant, OperatorInstruction, IsMinus, Branch , - Label, LoadConstant, RegToSlot, Label, LoadConstant, SlotToReg , - RegToSlot, Label, FunctionReturn] - assert_nil msg = check_nil , msg - end - - - def test_if_small_zero - @input = s(:statements, s(:if_statement, :zero, s(:condition, s(:operator_value, :-, s(:int, 10), s(:int, 12))), s(:true_statements, s(:return, s(:int, 3))), s(:false_statements, nil))) - - @expect = [Label, LoadConstant, LoadConstant, OperatorInstruction, IsZero, Branch , - Label, LoadConstant, RegToSlot, Label, LoadConstant, SlotToReg , - RegToSlot, Label, FunctionReturn] - assert_nil msg = check_nil , msg - end - end -end diff --git a/stash/test_vm/method_compiler/test_name_expression.rb b/stash/test_vm/method_compiler/test_name_expression.rb deleted file mode 100644 index 1f8c2214..00000000 --- a/stash/test_vm/method_compiler/test_name_expression.rb +++ /dev/null @@ -1,34 +0,0 @@ -require_relative "helper" - -module Risc - class TestFields < MiniTest::Test - include ExpressionHelper - include AST::Sexp - - def setup - Risc.machine.boot - end - - def test_local - Parfait.object_space.get_main.add_local(:bar , :Integer) - @input = s(:local, :bar) - @output = Risc::RiscValue - check - end - - def test_space - @root = :name - @input = s(:known, :space) - @output = Risc::RiscValue - check - end - - def test_args - Parfait.object_space.get_main.add_argument(:bar , :Integer) - @input = s(:arg, :bar) - @output = Risc::RiscValue - check - end - - end -end diff --git a/stash/test_vm/method_compiler/test_operator_expression.rb b/stash/test_vm/method_compiler/test_operator_expression.rb deleted file mode 100644 index f3a2326a..00000000 --- a/stash/test_vm/method_compiler/test_operator_expression.rb +++ /dev/null @@ -1,46 +0,0 @@ -require_relative "helper" - -module Risc - class TestOps < MiniTest::Test - include ExpressionHelper - include AST::Sexp - - def setup - Risc.machine.boot - @root = :operator_value - @output = Risc::RiscValue - end - - def operators - [:+ , :- , :* , :/ , :== ] - end - def test_ints - operators.each do |op| - @input = s(:operator_value, op , s(:int, 2), s(:int, 3)) - check - end - end - def test_local_int - Parfait.object_space.get_main.add_local(:bar , :Integer) - @input = s(:operator_value, :+, s(:local, :bar), s(:int, 3)) - check - end - def test_int_local - Parfait.object_space.get_main.add_local(:bar , :Integer) - @input = s(:operator_value, :+, s(:int, 3), s(:local, :bar)) - check - end - - def test_field_int - add_space_field(:bro,:Integer) - @input = s(:operator_value, :+, s(:field_access,s(:receiver, s(:known, :self)), s(:field, s(:ivar, :bro))), s(:int, 3)) - check - end - - def test_int_field - add_space_field(:bro,:Integer) - @input = s(:operator_value, :+, s(:int, 3), s(:field_access, s(:receiver, s(:known, :self)), s(:field,s(:ivar, :bro)))) - check - end - end -end diff --git a/stash/test_vm/method_compiler/test_return_statement.rb b/stash/test_vm/method_compiler/test_return_statement.rb deleted file mode 100644 index 02e1fdb7..00000000 --- a/stash/test_vm/method_compiler/test_return_statement.rb +++ /dev/null @@ -1,47 +0,0 @@ -require_relative 'helper' - -module Risc - class TestReturnStatement < MiniTest::Test - include Statements - - def test_return_int - @input = s(:statements, s(:return, s(:int, 5))) - @expect = [Label, LoadConstant, RegToSlot, LoadConstant, SlotToReg, RegToSlot , - Label, FunctionReturn] - assert_nil msg = check_nil , msg - end - - def test_return_local - Parfait.object_space.get_main.add_local(:runner , :Integer) - @input = s(:statements, s(:return, s(:local , :runner))) - @expect = [Label, SlotToReg, SlotToReg, RegToSlot, LoadConstant, SlotToReg , - RegToSlot, Label, FunctionReturn] - assert_nil msg = check_nil , msg - end - - def test_return_local_assign - Parfait.object_space.get_main.add_local(:runner , :Integer) - @input = s(:statements, s(:l_assignment, s(:local, :runner), s(:int, 5)), s(:return, s(:local, :runner))) - @expect = [Label, LoadConstant, SlotToReg, RegToSlot, SlotToReg, SlotToReg , - RegToSlot, LoadConstant, SlotToReg, RegToSlot, Label, FunctionReturn] - assert_nil msg = check_nil , msg - end - - def test_return_call - @input =s(:statements, s(:return, s(:call, :main, s(:arguments)))) - @expect = [Label, SlotToReg, SlotToReg, RegToSlot, LoadConstant, RegToSlot , - LoadConstant, SlotToReg, RegToSlot, LoadConstant, RegToSlot, RiscTransfer , - FunctionCall, Label, RiscTransfer, SlotToReg, SlotToReg, RegToSlot , - LoadConstant, SlotToReg, RegToSlot, Label, FunctionReturn] - assert_nil msg = check_nil , msg - end - - def pest_return_space_length # need to add runtime first - Parfait.object_space.get_main.add_local(:l , :Type) - @input = s(:statements, s(:l_assignment, s(:local, :l), s(:call, :get_type, s(:arguments), s(:receiver, s(:known, :space)))), s(:return, s(:field_access, s(:receiver, s(:known, :self)), s(:field, s(:ivar, :runner))))) - @expect = [Label, SlotToReg,SlotToReg ,RegToSlot,Label,FunctionReturn] - assert_nil msg = check_nil , msg - end - - end -end diff --git a/stash/test_vm/method_compiler/test_while_statement.rb b/stash/test_vm/method_compiler/test_while_statement.rb deleted file mode 100644 index 199ec467..00000000 --- a/stash/test_vm/method_compiler/test_while_statement.rb +++ /dev/null @@ -1,49 +0,0 @@ -require_relative 'helper' - -module Risc - class TestWhile < MiniTest::Test - include Statements - - - def test_while_mini - @input = s(:statements, s(:while_statement, :plus, s(:conditional, s(:int, 1)), s(:statements, s(:return, s(:int, 3))))) - - @expect = [Label, Branch, Label, LoadConstant, RegToSlot, Label , - LoadConstant, IsPlus, LoadConstant, SlotToReg, RegToSlot, Label , - FunctionReturn] - assert_nil msg = check_nil , msg - end - - def test_while_assign - Parfait.object_space.get_main.add_local(:n , :Integer) - - @input = s(:statements, s(:l_assignment, s(:local, :n), s(:int, 5)), - s(:while_statement, :plus, s(:conditional, s(:local, :n)), - s(:statements, s(:l_assignment, s(:local, :n), - s(:operator_value, :-, s(:local, :n), s(:int, 1))))), - s(:return, s(:local, :n))) - - @expect = [Label, LoadConstant, SlotToReg, RegToSlot, Branch, Label , - SlotToReg, SlotToReg, LoadConstant, OperatorInstruction, SlotToReg, RegToSlot , - Label, SlotToReg, SlotToReg, IsPlus, SlotToReg, SlotToReg , - RegToSlot, LoadConstant, SlotToReg, RegToSlot, Label, FunctionReturn] - assert_nil msg = check_nil , msg - end - - - def test_while_return - Parfait.object_space.get_main.add_local(:n , :Integer) - - @input = s(:statements, s(:l_assignment, s(:local, :n), s(:int, 10)), s(:while_statement, :plus, s(:conditional, s(:operator_value, :-, s(:local, :n), s(:int, 5))), - s(:statements, s(:l_assignment, s(:local, :n), s(:operator_value, :+, s(:local, :n), s(:int, 1))), - s(:return, s(:local, :n))))) - - @expect = [Label, LoadConstant, SlotToReg, RegToSlot, Branch, Label , - SlotToReg, SlotToReg, LoadConstant, OperatorInstruction, SlotToReg, RegToSlot , - SlotToReg, SlotToReg, RegToSlot, Label, SlotToReg, SlotToReg , - LoadConstant, OperatorInstruction, IsPlus, LoadConstant, SlotToReg, RegToSlot , - Label, FunctionReturn] - assert_nil msg = check_nil , msg - end - end -end diff --git a/stash/test_vm/test_to_code.rb b/stash/test_vm/test_to_code.rb deleted file mode 100644 index 963f0831..00000000 --- a/stash/test_vm/test_to_code.rb +++ /dev/null @@ -1,55 +0,0 @@ -require_relative "helper" - -class ToCodeTest < MiniTest::Test - include AST::Sexp - - def check clazz - tree = Vm.ast_to_code @statement - assert_equal tree.class , Vm::Tree.const_get( clazz ) - end - - def test_field_access - @statement = s(:field_access, s(:receiver, s(:ivar, :m)), s(:field, s(:ivar, :index))) - check "FieldAccess" - end - def test_simple_while - @statement = s(:while_statement, :false, s(:conditional,s(:int, 1)), s(:statements)) - check "WhileStatement" - end - def test_l_assignment - @statement = s(:l_assignment, s(:local, :i), s(:int, 0)) - check "LocalAssignment" - end - def test_a_assignment - @statement = s(:a_assignment, s(:arg, :i), s(:int, 0)) - check "ArgAssignment" - end - def test_i_assignment - @statement = s(:i_assignment, s(:ivar, :i), s(:int, 0)) - check "IvarAssignment" - end - def test_nil - @statement = s(:nil) - check "NilExpression" - end - def test_true - @statement = s(:true) - check "TrueExpression" - end - def test_false - @statement = s(:false) - check "FalseExpression" - end - def test_known - @statement = s(:known, :self) - check "KnownName" - end - def test_ivar - @statement = s(:ivar, :you) - check "InstanceName" - end - def test_class_name - @statement =s(:class_name, :FooBar) - check "ClassExpression" - end -end diff --git a/stash/vm/method_compiler/README.md b/stash/vm/method_compiler/README.md deleted file mode 100644 index 2fe95228..00000000 --- a/stash/vm/method_compiler/README.md +++ /dev/null @@ -1,57 +0,0 @@ -### Compiling - -The typed syntax tree is created by the ruby compiler. - -The code in this directory compiles the typed tree to the register machine code, and -Parfait object structure. - -If this were an interpreter, we would just walk the tree and do what it says. -Since it's not things are a little more difficult, especially in time. - -When compiling we deal with two times, compile-time and run-time. -All the headache comes from mixing those two up.* - -Similarly, the result of compiling is two-fold: a static and a dynamic part. - -- the static part are objects like the constants, but also defined classes and their methods -- the dynamic part is the code, which is stored as streams of instructions in the MethodSource - -Too make things a little simpler, we create a very high level instruction stream at first and then -run transformation and optimization passes on the stream to improve it. - -The compiler has a method for each class of typed tree, named along on_xxx with xxx as the type - -#### Compiler holds scope - -The Compiler instance can hold arbitrary scope needed during the compilation. -A class statement sets the current @type scope , a method definition the @method. -If either are not set when needed compile errors will follow. So easy, so nice. - -All code is encoded as a stream of Instructions in the MethodSource. -Instructions are stored as a list of Blocks, and Blocks are the smallest unit of code, -which is always linear. - -Code is added to the method (using add_code), rather than working with the actual instructions. -This is so each compiling method can just do it's bit and be unaware of the larger structure -that is being created. -The general structure of the instructions is a graph -(with if's and whiles and breaks and what), but we build it to have one start and *one* end (return). - - -#### Messages and frames - -Since the machine is oo we define it in objects. - -Also it is important to define how instructions operate, which is is in a physical machine would -be by changing the contents of registers or some stack. - -Our machine is not a register machine, but an object machine: it operates directly on objects and -also has no separate stack, only objects. There is only one object which is accessible, -basically meaning pinned to a register, the Message. - -One can think of the Message as an oo replacement of the stack. - -When a TypedMethod needs to make a call, it creates a NewMessage object. -Messages contain return addresses (yes, plural) and arguments. - -The important thing here is that Messages and Frames are normal objects. diff --git a/stash/vm/method_compiler/assignment.rb b/stash/vm/method_compiler/assignment.rb deleted file mode 100644 index 33a86b86..00000000 --- a/stash/vm/method_compiler/assignment.rb +++ /dev/null @@ -1,56 +0,0 @@ -module Vm - module Assignment - - def on_IvarAssignment( statement ) - value = assignment_value(statement) - name = check_name(statement.name.name) - index = @method.for_type.variable_index( name) - raise "No such ivar #{name} #{@method.for_type}" unless index - value_type = @method.for_type.type_at( index ) - raise "Argument Type mismatch #{value.type}!=#{value_type}" unless value.type == value_type - value_reg = use_reg(:value_type) - add_slot_to_reg(statement , :message , :receiver , value_reg ) - add_reg_to_slot(statement , value , value_reg , index + 1 ) # one for type - end - - def on_LocalAssignment( statement ) - do_assignment_for( statement , :local ) - end - - def on_ArgAssignment( statement ) - do_assignment_for( statement , :argument ) - end - - private - - def do_assignment_for( statement , type ) - value = assignment_value(statement) - name = check_name(statement.name.name) - index = @method.send( "has_#{type}" , name) - raise "No such #{type} #{name} #{@method.inspect}" unless index - value_type = @method.send("#{type}s_type" , index ) - raise "Argument Type mismatch #{value.type}!=#{value_type}" unless value.type == value_type - move_reg(statement , "#{type}s".to_sym , value , index) - end - - def move_reg(statement , type , value , index) - named_list = use_reg(:NamedList) - add_slot_to_reg(statement , :message , type , named_list ) - add_reg_to_slot(statement , value , named_list , index + 1 ) # one for type - end - - def assignment_value(statement) - reset_regs # statements reset registers, ie have all at their disposal - value = process(statement.value) - raise "Not register #{v}" unless value.is_a?(Risc::RiscValue) - value - end - # ensure the name given is not space and raise exception otherwise - # return the name - def check_name( name ) - raise "space is a reserved name" if name == :space - name - end - - end -end diff --git a/stash/vm/method_compiler/basic_values.rb b/stash/vm/method_compiler/basic_values.rb deleted file mode 100644 index c9592204..00000000 --- a/stash/vm/method_compiler/basic_values.rb +++ /dev/null @@ -1,52 +0,0 @@ -module Vm - # collection of the simple ones, int and strings and such - - module BasicValues - - # Constant expressions can by definition be evaluated at compile time. - # But that does not solve their storage, ie they need to be accessible at runtime from _somewhere_ - # So expressions move the data into a Risc. - # All expressions return registers - - # But in the future (in the one that holds great things) we optimize those unneccesay moves away - - def on_IntegerExpression expression - int = expression.value - reg = use_reg :Integer , int - add_load_constant( expression, int , reg ) - return reg - end - - def on_TrueExpression expression - reg = use_reg :Boolean - add_load_constant( expression, true , reg ) - return reg - end - - def on_FalseExpression expression - reg = use_reg :Boolean - add_load_constant( expression, false , reg ) - return reg - end - - def on_NilExpression expression - reg = use_reg :NilClass - add_load_constant( expression, nil , reg ) - return reg - end - - def on_StringExpression expression - value = Parfait.new_word expression.value.to_sym - reg = use_reg :Word - Risc.machine.constants << value - add_load_constant( expression, value , reg ) - return reg - end - - def on_ClassExpression expression - name = expression.value - raise "No meta class #{name}" - end - - end -end diff --git a/stash/vm/method_compiler/call_site.rb b/stash/vm/method_compiler/call_site.rb deleted file mode 100644 index 075257a2..00000000 --- a/stash/vm/method_compiler/call_site.rb +++ /dev/null @@ -1,99 +0,0 @@ -module Vm - module CallSite - - def on_CallSite( statement ) - raise "not inside method " unless @method - reset_regs - #move the new message (that we need to populate to make a call) to std register - load_new_message(statement) - me = get_me( statement ) - type = get_my_type(me) - - method = type.get_method(statement.name) - raise "Method not implemented for me:#{me} #{type.inspect}.#{statement.name}" unless method - - # move our receiver there - add_reg_to_slot( statement , me , :new_message , :receiver) - - set_message_details(method , statement , statement.arguments) - set_arguments(method , statement.arguments) - ret = use_reg( :Object ) #FIXME real return type - - Risc.issue_call( self , method ) - - # the effect of the method is that the NewMessage Return slot will be filled, return it - # but move it into a register too - add_slot_to_reg(statement, :new_message , :return_value , ret ) - ret - end - - private - - def load_new_message(statement) - new_message = Risc.resolve_to_register(:new_message) - add_slot_to_reg(statement, :message , :next_message , new_message ) - new_message - end - - def get_me( statement ) - if statement.receiver - me = process( statement.receiver ) - else - me = use_reg @method.for_type - add_slot_to_reg(statement, :message , :receiver , me ) - end - me - end - - def get_my_type( me ) - # now we have to resolve the method name (+ receiver) into a callable method - case me.type - when Parfait::Type - type = me.type - when Symbol - type = Parfait.object_space.get_class_by_name(me.type).instance_type - else - raise me.inspect - end - raise "Not type #{type}" unless type.is_a? Parfait::Type - type - end - - # load method name and set to new message (for exceptions/debug) - def set_message_details( method , name_s , arguments ) - name = name_s.name - name_tmp = use_reg(:Word) - add_load_constant("#{name} load method name", name , name_tmp) - add_reg_to_slot( "#{name} store method name" , name_tmp , :new_message , :name) - # next arg type - args_reg = use_reg(:Type , method.arguments ) - list_reg = use_reg(:NamedList , arguments ) - add_load_constant("#{name} load arguments type", method.arguments , args_reg) - add_slot_to_reg( "#{name} get args from method" , :new_message , :arguments , list_reg ) - add_reg_to_slot( "#{name} store args type in args" , args_reg , list_reg , 1 ) - end - - def set_arguments( method , arguments ) - # reset tmp regs for each and load result into new_message - arg_type = method.arguments - message = "Arg number mismatch, method=#{arg_type.instance_length - 1} , call=#{arguments.length}" - raise message if (arg_type.instance_length - 1 ) != arguments.length - arguments.each_with_index do |arg , i | - store_arg_no(arguments , arg_type , arg , i + 1) #+1 for ruby(0 based) - end - end - - def store_arg_no(arguments , arg_type , arg , i ) - reset_regs - i = i + 1 # disregarding type field - val = process( arg) # processing should return the register with the value - raise "Not register #{val}" unless val.is_a?(Risc::RiscValue) - #FIXME definately needs some tests - raise "TypeMismatch calling with #{val.type} , instead of #{arg_type.type_at(i)}" if val.type != arg_type.type_at(i) - list_reg = use_reg(:NamedList , arguments ) - add_slot_to_reg( "Set arg #{i}:#{arg}" , :new_message , :arguments , list_reg ) - # which we load int the new_message at the argument's index - add_reg_to_slot( arg , val , list_reg , i ) #one for type and one for ruby - end - end -end diff --git a/stash/vm/method_compiler/collections.rb b/stash/vm/method_compiler/collections.rb deleted file mode 100644 index 1ea1f33e..00000000 --- a/stash/vm/method_compiler/collections.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Vm - - module Collections - -# attr_reader :values - def on_array statement, context - end -# attr_reader :key , :value - def on_association context - end - def on_hash context - end - end -end diff --git a/stash/vm/method_compiler/field_access.rb b/stash/vm/method_compiler/field_access.rb deleted file mode 100644 index 17e94a9e..00000000 --- a/stash/vm/method_compiler/field_access.rb +++ /dev/null @@ -1,27 +0,0 @@ -module Vm - module FieldAccess - - def on_FieldAccess statement -# receiver_ast , field_ast = *statement - receiver = process(statement.receiver) - - type = receiver.type - if(type.is_a?(Symbol)) - type = Parfait.object_space.get_class_by_name(type).instance_type - end - field_name = statement.field.name - - index = type.variable_index(field_name) - raise "no such field:#{field_name} for class #{type.inspect}" unless index - value = use_reg(type.type_at(index)) - - add_slot_to_reg(statement , receiver , index, value) - - value - end - - def on_receiver expression - process expression.first - end - end -end diff --git a/stash/vm/method_compiler/if_statement.rb b/stash/vm/method_compiler/if_statement.rb deleted file mode 100644 index af7eff98..00000000 --- a/stash/vm/method_compiler/if_statement.rb +++ /dev/null @@ -1,41 +0,0 @@ -module Vm - module IfStatement - - # an if evaluates the condition and jumps to the true block if true - # so the else block is automatically after that. - # But then the else needs to jump over the true block unconditionally. - def on_IfStatement( statement ) -# branch_type , condition , if_true , if_false = *statement - - true_block = compile_if_condition( statement ) - merge = compile_if_false( statement ) - add_code true_block - compile_if_true(statement) - add_code merge - nil # statements don't return anything - end - - private - - def compile_if_condition( statement ) - reset_regs - process(statement.condition) - branch_class = Object.const_get "Risc::Is#{statement.branch_type.capitalize}" - true_block = Risc.label(statement, "if_true") - add_code branch_class.new( statement.condition , true_block ) - return true_block - end - def compile_if_true( statement ) - reset_regs - process(statement.if_true) - end - - def compile_if_false( statement ) - reset_regs - process(statement.if_false) if statement.if_false.statements - merge = Risc.label(statement , "if_merge") - add_code Risc::Branch.new(statement.if_false, merge ) - merge - end - end -end diff --git a/stash/vm/method_compiler/name_expression.rb b/stash/vm/method_compiler/name_expression.rb deleted file mode 100644 index 4d58ce38..00000000 --- a/stash/vm/method_compiler/name_expression.rb +++ /dev/null @@ -1,58 +0,0 @@ -module Vm - module NameExpression - - # attr_reader :name - # 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_KnownName statement - name = statement.name - [:self , :space , :message].each do |special| - return send(:"load_special_#{special}" , statement ) if name == special - end - raise "Unknow 'known' expression #{name}" - end - - 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}" - add_slot_to_reg("#{statement} load args" , :message , :arguments, named_list ) - add_slot_to_reg("#{statement} load #{name}" , named_list , index + 1, ret ) - return ret - end - - def on_LocalName( statement ) - name = statement.name - index = @method.has_local( name ) - raise "must define local '#{name}' before using it" unless index - named_list = use_reg :NamedList - add_slot_to_reg("#{name} load locals" , :message , :frame , named_list ) - ret = use_reg @method.frame_type( index ) - add_slot_to_reg("#{name} load from locals" , named_list , index + 1, ret ) - return ret - end - - def load_special_self(statement) - ret = use_reg @type - add_slot_to_reg("#{statement} load self" , :message , :receiver , ret ) - return ret - end - - def load_special_space(statement) - space = Parfait.object_space - reg = use_reg :Space , space - add_load_constant( "#{statement} load space", space , reg ) - return reg - end - - def load_special_message(statement) - reg = use_reg :Message - add_transfer( "#{statement} load message", Risc.message_reg , reg ) - return reg - end - end #module -end diff --git a/stash/vm/method_compiler/operator_expression.rb b/stash/vm/method_compiler/operator_expression.rb deleted file mode 100644 index 6345e347..00000000 --- a/stash/vm/method_compiler/operator_expression.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Vm - module OperatorExpression - - def on_OperatorExpression statement - # operator , left_e , right_e = *statement - # left and right must be expressions. Expressions return a register when compiled - left_reg = process(statement.left_expression) - right_reg = process(statement.right_expression) - raise "Not register #{left_reg}" unless left_reg.is_a?(Risc::RiscValue) - raise "Not register #{right_reg}" unless right_reg.is_a?(Risc::RiscValue) - add_code Risc::OperatorInstruction.new(statement,statement.operator,left_reg,right_reg) - return left_reg # though this has wrong value attached - end - end -end diff --git a/stash/vm/method_compiler/return_statement.rb b/stash/vm/method_compiler/return_statement.rb deleted file mode 100644 index 5e07b83b..00000000 --- a/stash/vm/method_compiler/return_statement.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Vm - module ReturnStatement - - def on_ReturnStatement statement - reg = process(statement.return_value) - add_reg_to_slot( statement, reg , :message , :return_value) - nil # statements don't return - end - end -end diff --git a/stash/vm/method_compiler/statement_list.rb b/stash/vm/method_compiler/statement_list.rb deleted file mode 100644 index 2ad7f6d8..00000000 --- a/stash/vm/method_compiler/statement_list.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Vm - module StatementList - def on_Statements statement - process_all( statement.statements ) - end - end -end diff --git a/stash/vm/method_compiler/while_statement.rb b/stash/vm/method_compiler/while_statement.rb deleted file mode 100644 index 026b7098..00000000 --- a/stash/vm/method_compiler/while_statement.rb +++ /dev/null @@ -1,42 +0,0 @@ -module Vm - module WhileStatement - - def on_WhileStatement statement - #branch_type , condition , statements = *statement - - condition_label = compile_while_preamble( statement ) #jump there - - start = compile_while_body( statement ) - - # This is where the loop starts, though in subsequent iterations it's in the middle - add_code condition_label - - compile_while_condition( statement ) - - branch_class = Object.const_get "Risc::Is#{statement.branch_type.capitalize}" - # this is where the while ends and both branches meet - add_code branch_class.new( statement.condition , start ) - - nil # statements don't return anything - end - private - - def compile_while_preamble( statement ) - condition_label = Risc.label(statement.condition , "condition_label") - # unconditionally branch to the condition upon entering the loop - add_code Risc::Branch.new(statement.condition , condition_label) - condition_label - end - def compile_while_body( statement ) - start = Risc.label(statement , "while_start" ) - add_code start - reset_regs - process(statement.statements) - start - end - def compile_while_condition( statement ) - reset_regs - process(statement.condition) - end - end -end diff --git a/stash/vm/tree.rb b/stash/vm/tree.rb deleted file mode 100644 index 310d3c1a..00000000 --- a/stash/vm/tree.rb +++ /dev/null @@ -1,48 +0,0 @@ -# Base class for Expresssion and Statement -module Vm - - class Code ; end - class Statement < Code ; end - class Expression < Code ; end - - module ValuePrinter - def to_s - @value.to_s - end - end -end - -require_relative "tree/while_statement" -require_relative "tree/if_statement" -require_relative "tree/return_statement" -require_relative "tree/statements" -require_relative "tree/operator_expression" -require_relative "tree/field_access" -require_relative "tree/call_site" -require_relative "tree/basic_values" -require_relative "tree/assignment" -require_relative "tree/to_code" - -AST::Node.class_eval do - - # def [](name) - # #puts self.inspect - # children.each do |child| - # if child.is_a?(AST::Node) - # #puts child.type - # if (child.type == name) - # return child.children - # end - # else - # #puts child.class - # end - # end - # nil - # end - # - # def first_from( node_name ) - # from = self[node_name] - # return nil unless from - # from.first - # end -end diff --git a/stash/vm/tree/assignment.rb b/stash/vm/tree/assignment.rb deleted file mode 100644 index bbb22843..00000000 --- a/stash/vm/tree/assignment.rb +++ /dev/null @@ -1,30 +0,0 @@ -module Vm - module Tree - - class Assignment < Statement - attr_accessor :name , :value - - def initialize(name , value = nil ) - @name , @value = name , value - end - - def to_s - "#{name} = #{value}\n" - end - - end - - class IvarAssignment < Assignment - def to_s - "@#{name} = #{value}\n" - end - end - - class ArgAssignment < Assignment - end - - class LocalAssignment < Assignment - end - - end -end diff --git a/stash/vm/tree/basic_values.rb b/stash/vm/tree/basic_values.rb deleted file mode 100644 index 9e75f34c..00000000 --- a/stash/vm/tree/basic_values.rb +++ /dev/null @@ -1,66 +0,0 @@ -module Vm - module Tree - class IntegerExpression < Expression - include ValuePrinter - attr_accessor :value - def initialize(value) - @value = value - end - end - class FloatExpression < Expression - include ValuePrinter - attr_accessor :value - def initialize(value) - @value = value - end - end - class TrueExpression < Expression - def to_s - "true" - end - end - class FalseExpression < Expression - def to_s - "false" - end - end - class NilExpression < Expression - def to_s - "nil" - end - end - class StringExpression < Expression - include ValuePrinter - attr_accessor :value - def initialize(value) - @value = value - end - end - - class NameExpression < Expression - include ValuePrinter - attr_accessor :value - alias :name :value - def initialize(value) - @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 - def initialize(value) - @value = value - end - end - end -end diff --git a/stash/vm/tree/call_site.rb b/stash/vm/tree/call_site.rb deleted file mode 100644 index 3f47f3a8..00000000 --- a/stash/vm/tree/call_site.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Vm - module Tree - class CallSite < Expression - attr_accessor :name , :receiver , :arguments - - def to_s - str = receiver ? "#{receiver}.#{name}" : name.to_s - str + arguments.collect{|a| a.to_s }.join(",") - end - end - end -end diff --git a/stash/vm/tree/field_access.rb b/stash/vm/tree/field_access.rb deleted file mode 100644 index cece4a52..00000000 --- a/stash/vm/tree/field_access.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Vm - module Tree - class FieldAccess < Expression - attr_accessor :receiver , :field - def to_s - "#{receiver}.#{field}" - end - end - end -end diff --git a/stash/vm/tree/if_statement.rb b/stash/vm/tree/if_statement.rb deleted file mode 100644 index 1ec794c8..00000000 --- a/stash/vm/tree/if_statement.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Vm - module Tree - class IfStatement < Statement - attr_accessor :branch_type , :condition , :if_true , :if_false - def to_s - str = "if_#{branch_type}(#{condition}) \n #{if_true}\n" - str += "else\n #{if_false}\n" if if_false - str + "end\n" - end - end - end -end diff --git a/stash/vm/tree/operator_expression.rb b/stash/vm/tree/operator_expression.rb deleted file mode 100644 index ad173e16..00000000 --- a/stash/vm/tree/operator_expression.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Vm - module Tree - class OperatorExpression < Expression - attr_accessor :operator , :left_expression , :right_expression - def to_s - "#{left_expression} #{operator} #{right_expression}" - end - end - end -end diff --git a/stash/vm/tree/return_statement.rb b/stash/vm/tree/return_statement.rb deleted file mode 100644 index ea43bf75..00000000 --- a/stash/vm/tree/return_statement.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Vm - module Tree - class ReturnStatement < Statement - attr_accessor :return_value - - def to_s - "return #{return_value}" - end - end - end -end diff --git a/stash/vm/tree/statements.rb b/stash/vm/tree/statements.rb deleted file mode 100644 index 0fa4182b..00000000 --- a/stash/vm/tree/statements.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Vm - class Statements < Statement - attr_accessor :statements - def to_s - return "" unless statements - statements.collect() { |s| s.to_s }.join - end - end -end diff --git a/stash/vm/tree/to_code.rb b/stash/vm/tree/to_code.rb deleted file mode 100644 index 1e5e2adf..00000000 --- a/stash/vm/tree/to_code.rb +++ /dev/null @@ -1,162 +0,0 @@ -module Vm - - def self.ast_to_code statement - compiler = ToCode.new - compiler.process statement - end - - # ToCode converts an ast (from the ast gem) into the vm code expressions - # Code is the base class of the tree that is transformed to and - # Expression and Statement the next two subclasses. - # While it is an ast, it is NOT a ruby parser generated ast. Instead the ast is generated - # with s-expressions (also from the ast gem), mostly in tests, but also a little in - # the generation of functions (Builtin) - # - class ToCode < AST::Processor - - def handler_missing node - raise "No handler on_#{node.type}(node)" - end - - def on_parameters statement - params = {} - statement.children.each do |param , type , name| - type , name = *param - params[name] = type - end - params - end - - def on_while_statement statement - branch_type , condition , statements = *statement - whil = Tree::WhileStatement.new() - whil.branch_type = branch_type - whil.condition = process(condition) - whil.statements = process(statements) - whil - end - - def on_if_statement statement - branch_type , condition , if_true , if_false = *statement - iff = Tree::IfStatement.new() - iff.branch_type = branch_type - iff.condition = process(condition) - iff.if_true = process(if_true) - iff.if_false = process(if_false) - iff - end - - def process_first code - raise "Too many children #{code.inspect}" if code.children.length != 1 - process code.children.first - end - alias :on_conditional :process_first - alias :on_condition :process_first - alias :on_field :process_first - - def on_statements( statement ) - list = Statements.new() - kids = statement.children - return list unless kids - return list unless kids.first - list.statements = process_all(kids) - list - end - - alias :on_true_statements :on_statements - alias :on_false_statements :on_statements - - def on_return statement - ret = Tree::ReturnStatement.new() - ret.return_value = process(statement.children.first) - ret - end - - def on_operator_value statement - operator , left_e , right_e = *statement - op = Tree::OperatorExpression.new() - op.operator = operator - op.left_expression = process(left_e) - op.right_expression = process(right_e) - op - end - - def on_field_access statement - receiver_ast , field_ast = *statement - field = Tree::FieldAccess.new() - field.receiver = process(receiver_ast) - field.field = process(field_ast) - field - end - - def on_receiver expression - process expression.children.first - end - - def on_call statement - name , arguments , receiver = *statement - call = Tree::CallSite.new() - call.name = name - call.arguments = process_all(arguments) - call.receiver = process(receiver) - call - end - - def on_int expression - Tree::IntegerExpression.new(expression.children.first) - end - - def on_true _expression - Tree::TrueExpression.new - end - - def on_false _expression - Tree::FalseExpression.new - end - - def on_nil _expression - Tree::NilExpression.new - end - - 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 expressions - Tree::StringExpression.new(expressions.children.first) - end - - def on_class_name expression - Tree::ClassExpression.new(expression.children.first) - end - - def on_i_assignment statement - assignment_for( statement, Vm::Tree::IvarAssignment) - end - - def on_a_assignment statement - assignment_for( statement, Vm::Tree::ArgAssignment) - end - - def on_l_assignment( statement ) - assignment_for( statement, Vm::Tree::LocalAssignment) - end - - def assignment_for( statement , clazz) - name , value = *statement - p_name = process name - p_value = process(value) - clazz.new(p_name , p_value) - end - - end -end diff --git a/stash/vm/tree/while_statement.rb b/stash/vm/tree/while_statement.rb deleted file mode 100644 index 84edcca2..00000000 --- a/stash/vm/tree/while_statement.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Vm - module Tree - class WhileStatement < Statement - attr_accessor :branch_type , :condition , :statements - def to_s - str = "while_#{branch_type}(#{condition}) do\n" - str + statements.to_s + "\nend\n" - end - end - end -end