diff --git a/lib/parfait.rb b/lib/parfait.rb index ea25a880..4ab70e9e 100644 --- a/lib/parfait.rb +++ b/lib/parfait.rb @@ -2,6 +2,7 @@ require "parfait/value" require "parfait/object" require "parfait/module" require "parfait/class" +require "parfait/method" require "parfait/dictionary" require "parfait/list" require "parfait/layout" diff --git a/lib/parfait/method.rb b/lib/parfait/method.rb index 6618334f..4515d006 100644 --- a/lib/parfait/method.rb +++ b/lib/parfait/method.rb @@ -34,7 +34,7 @@ module Parfait # used to determine if a send must be issued # return index of the name into the message if so def has_var name - name = name.to_sym + raise "uups #{name}.#{name.class}" unless name.is_a? Word index = has_arg(name) return index if index has_local(name) diff --git a/lib/parfait/module.rb b/lib/parfait/module.rb index 34e4b752..279a55f7 100644 --- a/lib/parfait/module.rb +++ b/lib/parfait/module.rb @@ -14,15 +14,20 @@ module Parfait class Module < Object def initialize name , superclass + @name = name @instance_methods = [] @name = name @super_class = superclass @meta_class = Virtual::MetaClass.new(self) end + def name + @name + end + def add_instance_method method raise "not a method #{method.class} #{method.inspect}" unless method.is_a? Method - raise "syserr " unless method.name.is_a? Symbol + raise "syserr #{method.name.class}" unless method.name.is_a? Word method.for_class = self @instance_methods << method method diff --git a/lib/parfait/space.rb b/lib/parfait/space.rb index 2689d7c9..c9c67b5d 100644 --- a/lib/parfait/space.rb +++ b/lib/parfait/space.rb @@ -64,13 +64,16 @@ module Parfait # this is the way to instantiate classes (not Parfait::Class.new) # so we get and keep exactly one per name def get_class_by_name name - raise "uups #{name}.#{name.class}" unless name.is_a? String or name.is_a? Word + raise "uups #{name}.#{name.class}" unless name.is_a? Word c = @classes[name] + raise "uups " if name.is_a? String + puts "MISS, no class #{name} #{name.class}" # " #{@classes}" c end def create_class name c = Class.new_object(name) + raise "uups " if name.is_a? String @classes[name] = c end diff --git a/lib/virtual/boot.rb b/lib/virtual/boot.rb index 633a3c86..f0d54e1d 100644 --- a/lib/virtual/boot.rb +++ b/lib/virtual/boot.rb @@ -16,9 +16,9 @@ module Virtual # (not use the normal initialize way) def boot_parfait! @space = Parfait::Space.new_object - object_class = Parfait::Class.new_object "Parfait::Object" - space_class = Parfait::Class.new_object "Parfait::Space" , object_class - space_layout = Parfait::Layout.new_object space_class + boot_classes! + #space_layout = +# Parfait::Layout.new_object space_class puts "Space #{space.get_layout}" end @@ -27,13 +27,13 @@ module Virtual puts "BOOT" values = [ "Integer" , "Object" , "Value" , "Kernel"] rest = ["Word" , "Class" , "Dictionary" , "Space" , "List", "Layout"] - (values + rest).each { |cl| @space.create_class(cl) } - value_class = @space.get_class_by_name "Value" - @space.get_class_by_name("Integer").set_super_class( value_class ) - object_class = @space.get_class_by_name("Object") + (values + rest).each { |cl| @space.create_class(Virtual.new_word(cl)) } + value_class = @space.get_class_by_name Virtual.new_word("Value") + @space.get_class_by_name(Virtual.new_word("Integer")).set_super_class( value_class ) + object_class = @space.get_class_by_name(Virtual.new_word("Object")) object_class.set_super_class( value_class ) rest.each do |name| - cl = @space.get_class_by_name( name ) + cl = @space.get_class_by_name( Virtual.new_word( name )) cl.set_super_class(object_class) end boot_layouts! @@ -73,7 +73,7 @@ module Virtual [:putint,:fibo].each do |f| obj.add_instance_method Builtin::Integer.send(f , nil) end - obj = @space.get_class_by_name "Word" + obj = @space.get_class_by_name Virtual.new_word "Word" [:get , :set , :puts].each do |f| obj.add_instance_method Builtin::Word.send(f , nil) end diff --git a/lib/virtual/compiled_method_info.rb b/lib/virtual/compiled_method_info.rb index 8a0720d0..b222666d 100644 --- a/lib/virtual/compiled_method_info.rb +++ b/lib/virtual/compiled_method_info.rb @@ -31,7 +31,7 @@ module Virtual # return the main function (the top level) into which code is compiled # this just create a "main" with create_method , see there def self.main - self.create_method( "Object" , :main , [] ) + self.create_method( "Object" , "main" , [] ) end # create method does two things @@ -40,6 +40,8 @@ module Virtual # # compile code then works with the method, but adds code tot the info def self.create_method( class_name , method_name , args) + raise "uups #{class_name}.#{class_name.class}" if class_name.is_a? Symbol + raise "uups #{method_name}.#{method_name.class}" if class_name.is_a? Symbol class_name = Virtual.new_word(class_name) if class_name.is_a? String method_name = Virtual.new_word(method_name) if method_name.is_a? String clazz = Machine.instance.space.get_class_by_name class_name @@ -48,15 +50,16 @@ module Virtual method.info = CompiledMethodInfo.new method end - def initialize receiver = Virtual::Self.new , return_type = Virtual::Mystery + def initialize return_type = Virtual::Mystery # first block we have to create with .new , as new_block assumes a current enter = Block.new( "enter" , self ).add_code(MethodEnter.new()) + @return_type = return_type @blocks = [enter] @current = enter new_block("return").add_code(MethodReturn.new) end - attr_reader :receiver , :blocks - attr_accessor :return_type , :current + attr_reader :blocks + attr_accessor :return_type , :current , :receiver # add an instruction after the current (insertion point) # the added instruction will become the new insertion point diff --git a/lib/virtual/compiler/function_expression.rb b/lib/virtual/compiler/function_expression.rb index a87840d1..d231a689 100644 --- a/lib/virtual/compiler/function_expression.rb +++ b/lib/virtual/compiler/function_expression.rb @@ -6,11 +6,20 @@ module Virtual raise "error, argument must be a identifier, not #{p}" unless p.is_a? Ast::NameExpression p.name end - r = expression.receiver ? Compiler.compile(expression.receiver, method ) : Self.new() - new_method = CompiledMethodInfo.create_method(expression.name , args , r ) - new_method.class_name = r.is_a?(Parfait::Class) ? r.name : method.class_name - clazz = Machine.instance.space.get_class_by_name(new_method.class_name) - clazz.add_instance_method new_method + if expression.receiver + #Do something clever instead of + r = Compiler.compile(expression.receiver, method ) + if( r.is_a? Parfait::Class ) + class_name = r.name + else + raise "unimplemented #{r}" + end + else + r = Self.new() + class_name = method.for_class.name + end + new_method = CompiledMethodInfo.create_method(class_name, expression.name.to_s , args ) + new_method.info.receiver = r #frame = frame.new_frame return_type = nil @@ -18,7 +27,7 @@ module Virtual return_type = Compiler.compile(ex,new_method ) raise return_type.inspect if return_type.is_a? Instruction end - new_method.return_type = return_type + new_method.info.return_type = return_type new_method end def scratch diff --git a/lib/virtual/machine.rb b/lib/virtual/machine.rb index 82c28b64..895dc388 100644 --- a/lib/virtual/machine.rb +++ b/lib/virtual/machine.rb @@ -93,7 +93,7 @@ module Virtual def compile_main bytes syntax = @parser.parse_with_debug(bytes) parts = Parser::Transform.new.apply(syntax) - main = Virtual::CompiledMethod.main + main = Virtual::CompiledMethodInfo.main Compiler.compile( parts , main ) end end