diff --git a/lib/ast/basic_expressions.rb b/lib/ast/basic_expressions.rb index 84e980f0..45d792c7 100644 --- a/lib/ast/basic_expressions.rb +++ b/lib/ast/basic_expressions.rb @@ -34,6 +34,7 @@ module Ast # otherwise it's a method without args and a send is ussued. # this makes the namespace static, ie when eval and co are implemented method needs recompilation def compile frame , method + return Virtual::SelfReference.new() if name == :self if method.has_var(name) frame.compile_get(method , name ) else diff --git a/lib/ast/function_expression.rb b/lib/ast/function_expression.rb index 4d2fcd01..f4ab6d55 100644 --- a/lib/ast/function_expression.rb +++ b/lib/ast/function_expression.rb @@ -5,6 +5,13 @@ module Ast args = params.collect{ |p| p.compile(frame , method )} r = receiver ? receiver.compile(frame,method) : Virtual::SelfReference.new method = Virtual::Method.new(name , params , r ) + frame = frame.new_frame + return_type = nil + body.each do |ex| + return_type = ex.compile(frame , method ) + end + method.return_type = return_type + method end def scratch args = [] diff --git a/lib/boot/meta_class.rb b/lib/boot/meta_class.rb index a7ddb381..88bca2f5 100644 --- a/lib/boot/meta_class.rb +++ b/lib/boot/meta_class.rb @@ -49,9 +49,6 @@ module Boot fun end - def inspect - "MetaClass.new(:#{@me_self.name})" - end def to_s "#{inspect} on #{@me_self}, #{@functions.length} functions" end diff --git a/lib/virtual/frame.rb b/lib/virtual/frame.rb index 6d94e6da..f10a1885 100644 --- a/lib/virtual/frame.rb +++ b/lib/virtual/frame.rb @@ -23,6 +23,10 @@ module Virtual end attr_reader :next_normal, :next_exception, :me, :binding + # dummy for the eventual + def new_frame + self + end # def compile_get method , name method.add FrameGet.new(name) diff --git a/lib/virtual/instruction.rb b/lib/virtual/instruction.rb index a62bff75..4b9f0ab1 100644 --- a/lib/virtual/instruction.rb +++ b/lib/virtual/instruction.rb @@ -1,3 +1,5 @@ +require_relative "object" + module Virtual # Instruction is an abstract for all the code of the object-machine. Derived classe make up the actual functionality @@ -8,11 +10,10 @@ module Virtual # defining a minimal set of instructions needed to implement oo. # This is partly because jumping over this layer and doing in straight in assember was too big a step - class Instruction + class Instruction < Virtual::Object attr_accessor :next - - def inspect - self.class.name + ".new()" + def attributes + [:next] end end diff --git a/lib/virtual/method.rb b/lib/virtual/method.rb index cddabb1c..bbb30394 100644 --- a/lib/virtual/method.rb +++ b/lib/virtual/method.rb @@ -15,7 +15,7 @@ module Virtual Method.new(:main , [] , Virtual::SelfReference ) end def attributes - [:name , :args , :receiver] + [:name , :args , :receiver , :start , :return_type] end def initialize name , args , receiver = Virtual::SelfReference.new , return_type = Virtual::Reference @name = name.to_sym @@ -26,7 +26,8 @@ module Virtual @start = MethodEnter.new @current = @start end - attr_reader :name , :args , :receiver + attr_reader :name , :args , :receiver , :start + attr_accessor :return_type def add instruction @current.next = instruction diff --git a/test/virtual/test_basic.rb b/test/virtual/test_basic.rb index 2e2a239d..43815340 100644 --- a/test/virtual/test_basic.rb +++ b/test/virtual/test_basic.rb @@ -31,6 +31,12 @@ class TestBasic < MiniTest::Test check end + def test_self + @string_input = 'self ' + @output = [Virtual::SelfReference.new()] + check + end + def test_instance_variable @string_input = '@foo_bar ' @output = [Virtual::FrameSend.new(:_get_instance_variable , [ Virtual::StringConstant.new('foo_bar')])] @@ -39,7 +45,7 @@ class TestBasic < MiniTest::Test def test_module_name @string_input = 'FooBar ' - @output = [Boot::MetaClass.new(:FooBar)] + @output = [Boot::BootClass.new(:FooBar,:Object)] check end