From cd211f970f78e791efa11022f8895c4a19bc82d2 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Tue, 17 Jan 2017 21:23:58 +0200 Subject: [PATCH] make method creation class methods in MethodCompiler and pass the wish to use main explicitly, which is really a test feature --- lib/register/builtin/compile_helper.rb | 2 +- lib/register/builtin/integer.rb | 6 +++--- lib/register/builtin/kernel.rb | 4 ++-- lib/register/builtin/space.rb | 2 +- lib/register/builtin/word.rb | 2 +- lib/vm/method_compiler.rb | 21 ++++++++++----------- test/helper.rb | 2 +- test/vm/method_compiler/helper.rb | 4 ++-- 8 files changed, 21 insertions(+), 22 deletions(-) diff --git a/lib/register/builtin/compile_helper.rb b/lib/register/builtin/compile_helper.rb index fc50f5e6..0ae017a1 100644 --- a/lib/register/builtin/compile_helper.rb +++ b/lib/register/builtin/compile_helper.rb @@ -11,7 +11,7 @@ module Register def compiler_for( type , method_name , extra_args = {}) args = {:index => :Integer}.merge( extra_args ) - Vm::MethodCompiler.new.create_method(type , method_name , args ).init_method + Vm::MethodCompiler.create_method(type , method_name , args ).init_method end # Load the value diff --git a/lib/register/builtin/integer.rb b/lib/register/builtin/integer.rb index 186373d0..83be2340 100644 --- a/lib/register/builtin/integer.rb +++ b/lib/register/builtin/integer.rb @@ -6,18 +6,18 @@ module Register include AST::Sexp def mod4 context - compiler = Vm::MethodCompiler.new.create_method(:Integer,:mod4 ).init_method + compiler = Vm::MethodCompiler.create_method(:Integer,:mod4 ).init_method return compiler.method end def putint context - compiler = Vm::MethodCompiler.new.create_method(:Integer,:putint ).init_method + compiler = Vm::MethodCompiler.create_method(:Integer,:putint ).init_method return compiler.method end def div10 context s = "div_10" - compiler = Vm::MethodCompiler.new.create_method(:Integer,:div10 ).init_method + compiler = Vm::MethodCompiler.create_method(:Integer,:div10 ).init_method me = compiler.process( Vm::Tree::KnownName.new( :self) ) tmp = compiler.process( Vm::Tree::KnownName.new( :self) ) q = compiler.process( Vm::Tree::KnownName.new( :self) ) diff --git a/lib/register/builtin/kernel.rb b/lib/register/builtin/kernel.rb index 0ee7669e..23655dab 100644 --- a/lib/register/builtin/kernel.rb +++ b/lib/register/builtin/kernel.rb @@ -6,7 +6,7 @@ module Register # it isn't really a function, ie it is jumped to (not called), exits and may not return # so it is responsible for initial setup def __init__ context - compiler = Vm::MethodCompiler.new.create_method(:Kernel,:__init__ ) + compiler = Vm::MethodCompiler.create_method(:Kernel,:__init__ ) new_start = Register.label("__init__ start" , "__init__" ) compiler.method.set_instructions( new_start) compiler.set_current new_start @@ -29,7 +29,7 @@ module Register end def exit context - compiler = Vm::MethodCompiler.new.create_method(:Kernel,:exit ).init_method + compiler = Vm::MethodCompiler.create_method(:Kernel,:exit ).init_method emit_syscall( compiler , :exit ) return compiler.method end diff --git a/lib/register/builtin/space.rb b/lib/register/builtin/space.rb index 0cb315cb..308cf72a 100644 --- a/lib/register/builtin/space.rb +++ b/lib/register/builtin/space.rb @@ -9,7 +9,7 @@ module Register # main entry point, ie __init__ calls this # defined here as empty, to be redefined def main context - compiler = Vm::MethodCompiler.new.create_method(:Space , :main ).init_method + compiler = Vm::MethodCompiler.create_method(:Space , :main ).init_method return compiler.method end diff --git a/lib/register/builtin/word.rb b/lib/register/builtin/word.rb index b5f3ad00..f52fcdbf 100644 --- a/lib/register/builtin/word.rb +++ b/lib/register/builtin/word.rb @@ -7,7 +7,7 @@ module Register include CompileHelper def putstring context - compiler = Vm::MethodCompiler.new.create_method(:Word , :putstring ).init_method + compiler = Vm::MethodCompiler.create_method(:Word , :putstring ).init_method compiler.add_slot_to_reg( "putstring" , :message , :receiver , :new_message ) index = Parfait::Word.get_length_index reg = RegisterValue.new(:r2 , :Integer) diff --git a/lib/vm/method_compiler.rb b/lib/vm/method_compiler.rb index 42843be5..1dbcbf22 100644 --- a/lib/vm/method_compiler.rb +++ b/lib/vm/method_compiler.rb @@ -56,7 +56,7 @@ module Vm # Helper function to create a new compiler and compie the statement(s) # Statement must be and AST::Node as generated by s expressions def self.compile_ast( statement ) - compiler = MethodCompiler.new + compiler = MethodCompiler.new(:main) code = Vm.ast_to_code statement compiler.process code end @@ -66,15 +66,15 @@ module Vm include Vm.const_get( mod.camelize ) end - def initialize( method = nil ) + def initialize( method ) @regs = [] - if method - @method = method - @type = method.for_type - else + if method == :main @type = Parfait.object_space.get_type() @method = @type.get_method( :main ) @method = @type.create_method( :main ,{}) unless @method + else + @method = method + @type = method.for_type end @current = @method.instructions end @@ -107,7 +107,7 @@ module Vm # create the method, do some checks and set it as the current method to be added to # class_name and method_name are pretty clear, args are given as a ruby array - def create_method( class_name , method_name , args = {}) + def self.create_method( class_name , method_name , args = {}) raise "create_method #{class_name}.#{class_name.class}" unless class_name.is_a? Symbol clazz = Parfait.object_space.get_class_by_name! class_name create_method_for( clazz.instance_type , method_name , args) @@ -118,13 +118,12 @@ module Vm # args a hash that will be converted to a type # the created method is set as the current and the given type too # return the compiler (for chaining) - def create_method_for( type , method_name , args ) - @type = type + def self.create_method_for( type , method_name , args ) raise "create_method #{type.inspect} is not a Type" unless type.is_a? Parfait::Type raise "Args must be Hash #{args}" unless args.is_a?(Hash) raise "create_method #{method_name}.#{method_name.class}" unless method_name.is_a? Symbol - @method = type.create_method( method_name , args) - self + method = type.create_method( method_name , args) + self.new(method) end # add method entry and exit code. Mainly save_return for the enter and diff --git a/test/helper.rb b/test/helper.rb index a5454733..186bad02 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -22,7 +22,7 @@ require 'rubyx' module Compiling def clean_compile(clazz_name , method_name , args , statements) - compiler = Vm::MethodCompiler.new.create_method(clazz_name,method_name,args ).init_method + compiler = Vm::MethodCompiler.create_method(clazz_name,method_name,args ).init_method compiler.process( Vm.ast_to_code( statements ) ) end diff --git a/test/vm/method_compiler/helper.rb b/test/vm/method_compiler/helper.rb index 251e8db6..a1b04d77 100644 --- a/test/vm/method_compiler/helper.rb +++ b/test/vm/method_compiler/helper.rb @@ -28,7 +28,7 @@ module Register include AST::Sexp include Compiling include SpaceHack - + def setup Register.machine.boot # force boot to reset main end @@ -41,7 +41,7 @@ module Register end def check_nil assert @expect , "No output given" - compiler = Vm::MethodCompiler.new + compiler = Vm::MethodCompiler.new(:main) code = Vm.ast_to_code( @input ) assert code.to_s , @input produced = compiler.process( code )