From b7d0ee8f99065484d0060b6206fa055f494c9cc7 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Sun, 25 Oct 2015 15:40:12 +0200 Subject: [PATCH] wit metaclass and class functions needs to go back to arrays first --- lib/parfait/meta_class.rb | 26 +++++----- lib/soml/compiler/function_definition.rb | 33 ++++++------ test/compiler/statements/test_class.rb | 2 +- test/parfait/test_all.rb | 1 + test/parfait/test_meta.rb | 66 ++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 31 deletions(-) create mode 100644 test/parfait/test_meta.rb diff --git a/lib/parfait/meta_class.rb b/lib/parfait/meta_class.rb index b5db999f..264cb48f 100644 --- a/lib/parfait/meta_class.rb +++ b/lib/parfait/meta_class.rb @@ -1,7 +1,5 @@ module Parfait - # TODO : rethink - possibly needs to be a module to be mixed into Object - # # class that acts like a class, but is really the object # described in the ruby language book as the eigenclass, what you get with @@ -9,19 +7,23 @@ module Parfait # class << self <--- this is called the eigenclass, or metaclass, and really is just # .... the class object but gives us the ability to use the # syntax as if it were a class - # PS: can't say i fancy the << self syntax and am considerernig adding a - # keyword for it, like meta - # In effect it is a very similar construct to def self.function(...) - # So one could write def meta.function(...) and thus define on the meta-class + # + class MetaClass < Object - # no name, nor nothing. as this is just the object really + attribute :me - # def initialize(object) - # super() - # self.functions = [] - # self.me_self = object - # end + def initialize(object) + super() + self.me = object + end + def super_class + Space.object_space.get_class_by_name(self.me.super_class_name).meta + end + + def name + "Meta#{me.name}".to_sym + end # in a non-booting version this should map to _add_singleton_method # def add_function function # raise "not a function #{function}" unless function.is_a? Register::Function diff --git a/lib/soml/compiler/function_definition.rb b/lib/soml/compiler/function_definition.rb index a01e199e..f707ea90 100644 --- a/lib/soml/compiler/function_definition.rb +++ b/lib/soml/compiler/function_definition.rb @@ -5,44 +5,41 @@ module Soml #puts statement.inspect return_type , name , parameters, kids , receiver = *statement name = name.to_a.first + raise "Already in method #{@method}" if @method + args = parameters.to_a.collect do |p| raise "error, argument must be a identifier, not #{p}" unless p.type == :parameter Parfait::Variable.new( *p) end - if receiver - # compiler will always return slot. with known value or not - r = receiver.first - if( r.is_a? Parfait::Class ) - class_name = r.value.name + class_method = nil + if(receiver ) + if( receiver.first == :self) #class method + class_method = @clazz + @clazz = @clazz.meta_class else - if( r != :self) - raise "unimplemented case in function #{r}" - else - r = Register::Self.new() - class_name = method.for_class.name - end + raise "Not covered #{receiver}" end - else - r = @clazz - class_name = @clazz.name end - raise "Already in method #{@method}" if @method + r = @clazz + class_name = @clazz.name + @method = @clazz.get_instance_method( name ) if(@method) #puts "Warning, redefining method #{name}" unless name == :main #TODO check args / type compatibility @method.source.init @method else - @method = Register::MethodSource.create_method(class_name, return_type, name , args ) - @method.for_class.add_instance_method @method + @method = Register::MethodSource.create_method_for(@clazz, return_type, name , args ) + @clazz.add_instance_method @method end @method.source.receiver = r #puts "compile method #{@method.name}" kids.to_a.each do |ex| - ret = process(ex) + process(ex) end + @clazz = class_method if class_method @method = nil # function definition is a statement, does not return any value return nil diff --git a/test/compiler/statements/test_class.rb b/test/compiler/statements/test_class.rb index 27df8869..4b992040 100644 --- a/test/compiler/statements/test_class.rb +++ b/test/compiler/statements/test_class.rb @@ -7,7 +7,7 @@ class TestBasicClass < MiniTest::Test def test_class_def @string_input = <