revert to symbols

Parfait::Words were nice, but endless problems with the fact that when
you write “String” you get a string.
Symbols take care of uniqueness at the same time
This commit is contained in:
Torsten Ruger
2015-05-31 18:34:18 +03:00
parent 5d870ef154
commit bee73801eb
18 changed files with 101 additions and 85 deletions

View File

@ -21,23 +21,23 @@ module Virtual
# map from the vm - class_name to the Parfait class (which carries parfait name)
class_mappings = {} #will later become instance variable
values = [ "Value" , "Integer" , "Kernel" , "Object"].collect {|cl| Virtual.new_word(cl) }
values = [ :Value , :Integer , :Kernel , :Object]
value_classes = values.collect { |cl| @space.create_class(cl,nil) }
layouts = { "Word" => [] ,
"List" => [] ,
"Message" => [],
"MetaClass" => [],
"BinaryCode" => [],
"Space" => ["classes","frames","messages","next_message","next_frame"],
"Frame" => ["locals" , "tmps" ],
"Layout" => ["object_class"] ,
"Class" => ["object_layout"],
"Dictionary" => ["keys" , "values"] ,
"Method" => ["name" , "code" ,"arg_names" , "locals" , "tmps"] ,
"Module" => ["name" , "instance_methods", "super_class", "meta_class"]
layouts = { :Word => [] ,
:List => [] ,
:Message => [],
:MetaClass => [],
:BinaryCode => [],
:Space => [:classes ,:frames ,:messages ,:next_message ,:next_frame],
:Frame => [:locals , :tmps ],
:Layout => [:object_class] ,
:Class => [:object_layout ],
:Dictionary => [:keys , :values ] ,
:Method => [:name , :code ,:arg_names , :locals , :tmps ] ,
:Module => [:name , :instance_methods , :super_class , :meta_class ]
}
layouts.each do |name , layout|
class_mappings[name] = @space.create_class(Virtual.new_word(name) , nil)
class_mappings[name] = @space.create_class(name , nil)
end
value_classes[1].set_super_class( value_classes[0] ) # #set superclass (value) for integer
value_classes[2].set_super_class( value_classes[0] ) # and kernel (TODO is module)
@ -49,11 +49,11 @@ module Virtual
class_mappings.each do |name , clazz|
variables = layouts[name]
variables.each do |var_name|
clazz.object_layout.add_instance_variable Virtual.new_word(var_name)
clazz.object_layout.add_instance_variable var_name
end
end
# superclass and layout corrections
supers = { "BinaryCode" => "Word", "Layout" => "List", "Class" => "Module"}
supers = { :BinaryCode => :Word , :Layout => :List , :Class => :Module }
supers.each do |classname , superclass_name|
clazz = class_mappings[classname]
super_class = class_mappings[superclass_name]
@ -70,9 +70,9 @@ module Virtual
# lookup half created class info
# but it must be done before going through the objects (next step)
@class_mappings = class_mappings
class_mappings["Integer"] = value_classes[1] #need for further booting
class_mappings["Kernel"] = value_classes[2] #need for further booting
class_mappings["Object"] = value_classes[3] #need for further booting
class_mappings[:Integer ] = value_classes[1] #need for further booting
class_mappings[:Kernel ] = value_classes[2] #need for further booting
class_mappings[:Object ] = value_classes[3] #need for further booting
@space.late_init
@ -96,25 +96,25 @@ module Virtual
def boot_functions!
# very fiddly chicken 'n egg problem. Functions need to be in the right order, and in fact we
# have to define some dummies, just for the other to compile
# TODO: go through the virtual parfait layer and adjust function names to what they really are
obj = @class_mappings["Object"]
# TODO go through the virtual parfait layer and adjust function names to what they really are
obj = @class_mappings[:Object ]
[:main , :_get_instance_variable , :_set_instance_variable].each do |f|
obj.add_instance_method Builtin::Object.send(f , nil)
end
obj = @class_mappings["Kernel"]
obj = @class_mappings[:Kernel ]
# create dummy main first, __init__ calls it
[:putstring,:exit,:__send ].each do |f|
obj.add_instance_method Builtin::Kernel.send(f , nil)
end
underscore_init = obj.add_instance_method Builtin::Kernel.send(:__init__, nil)
obj = @class_mappings["Integer"]
obj = @class_mappings[:Integer ]
[:putint,:fibo].each do |f|
obj.add_instance_method Builtin::Integer.send(f , nil)
end
# and the @init block in turn _jumps_ to __init__
# the point of which is that by the time main executes, all is "normal"
# the point of which is that by the time main executes, all is :normal:
@init = Block.new(:_init_ , nil )
@init.add_code(Register::RegisterMain.new(underscore_init))
end

View File

@ -35,10 +35,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
raise "uups #{class_name}.#{class_name.class}" unless class_name.is_a? Symbol
raise "uups #{method_name}.#{method_name.class}" unless class_name.is_a? Symbol
clazz = Machine.instance.space.get_class_by_name class_name
raise "No such class #{class_name}" unless clazz
method = clazz.create_instance_method( method_name , Virtual.new_list(args))

View File

@ -46,7 +46,7 @@ module Virtual
# whichever way this goes the result is stored in the return slot (as all compiles)
def self.compile_name expression , method
return Self.new( Reference.new(method.for_class)) if expression.name == :self
name = Virtual.new_word expression.name.to_s
name = expression.name.to_sym
if method.has_var(name)
# either an argument, so it's stored in message
if( index = method.has_arg(name))
@ -71,7 +71,7 @@ module Virtual
# attr_reader :string
def self.compile_string expression , method
value = Virtual.new_word(expression.string)
value = expression.string.to_sym
to = Return.new(Reference , value)
method.info.add_code Set.new( to , value )
to
@ -84,11 +84,11 @@ module Virtual
end
r = Compiler.compile(expression.right , method )
raise "oh noo, nil from where #{expression.right.inspect}" unless r
index = method.has_arg(Virtual.new_word name)
index = method.has_arg(name)
if index
method.info.add_code Set.new(Return.new , MessageSlot.new(index , r,type , r ))
else
index = method.ensure_local(Virtual.new_word expression.left.name)
index = method.ensure_local(expression.left.name.to_sym)
method.info.add_code Set.new(Return.new , FrameSlot.new(index , r.type , r ))
end
r

View File

@ -8,7 +8,7 @@ module Virtual
me = Compiler.compile( expession.receiver , method )
method.info.add_code NewMessage.new
method.info.add_code Set.new(NewSelf.new(me.type), me)
method.info.add_code Set.new(NewName.new(), Virtual.new_word(expession.name))
method.info.add_code Set.new(NewName.new(), expession.name.to_sym)
compiled_args = []
expession.args.each_with_index do |arg , i|
#compile in the running method, ie before passing control

View File

@ -1,4 +1,3 @@
require_relative "positioned"
module Virtual

View File

@ -7,8 +7,6 @@ module Virtual
class Set < Instruction
def initialize to , from
@to = to
# hard to find afterwards where it came from, so ensure it doesn't happen
raise "From must be slot or constant, not symbol #{from}" if from.is_a? Symbol
@from = from
end
attr_reader :from , :to

View File

@ -16,7 +16,7 @@ module FakeMem
end
end
def init_layout
vm_name = self.class.name.split("::").last
vm_name = self.class.name.split("::").last.to_sym
clazz = Virtual::Machine.instance.class_mappings[vm_name]
raise "Class not found #{vm_name}" unless clazz
raise "Layout not set #{vm_name}" unless clazz.object_layout
@ -52,6 +52,28 @@ module FakeMem
padded(words*4) # 4 == word length, a constant waiting for a home
end
end
module Virtual
def self.new_list array
list = Parfait::List.new_object
list.set_length array.length
index = 1
while index <= array.length do
list.set(index , array[index - 1])
index = index + 1
end
list
end
end
class Symbol
include Positioned
def init_layout; end
def has_layout?
true
end
def get_layout
Virtual::Machine.instance.class_mappings[:Word].object_layout
end
end
module Parfait
# Objects memory functions. Object memory is 1 based
@ -158,26 +180,3 @@ module Parfait
end
end
end
module Virtual
# Functions to generate parfait objects
def self.new_word( string )
string = string.to_s if string.is_a? Symbol
word = Parfait::Word.new_object( string.length )
string.codepoints.each_with_index do |code , index |
word.set_char(index + 1 , code)
end
word
end
def self.new_list array
list = Parfait::List.new_object
list.set_length array.length
index = 1
while index <= array.length do
list.set(index , array[index - 1])
index = index + 1
end
list
end
end

View File

@ -11,7 +11,7 @@ module Virtual
@gonners << f
end
end
init= Parfait::Space.object_space.get_class_by_name("Kernel").get_instance_method "__init__"
init= Parfait::Space.object_space.get_class_by_name(:Kernel).get_instance_method :__init__
remove init
dump_remaining
end

View File

@ -39,8 +39,11 @@ module Virtual
if ref.type.is_a?(Reference) and ref.type.of_class
#find method and call
clazz = ref.type.of_class
method = clazz.resolve_method code.name.to_s
raise "No method found #{code.name}" unless method
begin
method = clazz.resolve_method code.name
rescue
raise "No method found #{code.name} for #{clazz.name} in #{clazz.method_names}" unless method
end
new_codes << MethodCall.new( method )
else
# must defer send to run-time