linked list of methods instead of list of methods
api changes slightly, especially for each, but mostly sama sama
This commit is contained in:
parent
ad497b34f1
commit
fb29fb6431
@ -24,7 +24,7 @@ module Elf
|
||||
|
||||
# for debug add labels for labels
|
||||
Parfait.object_space.each_type do |type|
|
||||
type.methods.each do |f|
|
||||
type.each_method do |f|
|
||||
f.cpu_instructions.each do |label|
|
||||
next unless label.is_a?(Risc::Label)
|
||||
add_symbol "#{type.name}::#{f.name}:#{label.name}" , Positioned.position(label)
|
||||
|
@ -75,7 +75,7 @@ module Parfait
|
||||
def collect_methods
|
||||
methods = []
|
||||
each_type do | type |
|
||||
type.methods.each do |meth|
|
||||
type.each_method do |meth|
|
||||
methods << meth
|
||||
end
|
||||
end
|
||||
|
@ -52,7 +52,7 @@ module Parfait
|
||||
# this part of the init is seperate because at boot time we can not use normal new
|
||||
# new is overloaded to grab the type from space, and before boot, that is not set up
|
||||
def init_lists(hash)
|
||||
@methods = List.new
|
||||
@methods = nil
|
||||
@names = List.new
|
||||
@types = List.new
|
||||
raise "No type Type in #{hash}" unless hash[:type]
|
||||
@ -68,7 +68,8 @@ module Parfait
|
||||
|
||||
def method_names
|
||||
names = List.new
|
||||
@methods.each do |method|
|
||||
return names unless @methods
|
||||
@methods.each_method do |method|
|
||||
names.push method.name
|
||||
end
|
||||
names
|
||||
@ -95,25 +96,39 @@ module Parfait
|
||||
if self.is_a?(Class) and (method.for_type != self)
|
||||
raise "Adding to wrong class, should be #{method.for_class}"
|
||||
end
|
||||
found = get_method( method.name )
|
||||
if found
|
||||
@methods.delete(found)
|
||||
if get_method( method.name )
|
||||
remove_method(method.name)
|
||||
end
|
||||
@methods.push method
|
||||
method.set_next( @methods )
|
||||
@methods = method
|
||||
#puts "#{self.name} add #{method.name}"
|
||||
method
|
||||
end
|
||||
|
||||
def remove_method( method_name )
|
||||
found = get_method( method_name )
|
||||
raise "No such method #{method_name} in #{self.name}" unless found
|
||||
@methods.delete(found)
|
||||
raise "May not remove method_missing" if method_name == :method_missing
|
||||
raise "No such method #{method_name} in #{self.name}" unless @methods
|
||||
if( @methods.name == method_name)
|
||||
@methods = @methods.next_method
|
||||
return true
|
||||
end
|
||||
method = @methods
|
||||
while(method && method.next_method)
|
||||
if( method.next_method.name == method_name)
|
||||
method.set_next( method.next_method.next_method )
|
||||
return true
|
||||
else
|
||||
method = method.next_method
|
||||
end
|
||||
end
|
||||
raise "No such method #{method_name} in #{self.name}"
|
||||
end
|
||||
|
||||
def get_method( fname )
|
||||
raise "get_method #{fname}.#{fname.class}" unless fname.is_a?(Symbol)
|
||||
#if we had a hash this would be easier. Detect or find would help too
|
||||
@methods.each do |m|
|
||||
return nil unless @methods
|
||||
@methods.each_method do |m|
|
||||
return m if(m.name == fname )
|
||||
end
|
||||
nil
|
||||
@ -133,6 +148,13 @@ module Parfait
|
||||
sup.instance_type.resolve_method(fname)
|
||||
end
|
||||
|
||||
def methods_length
|
||||
return 0 unless @methods
|
||||
len = 0
|
||||
@methods.each_method { len += 1}
|
||||
return len
|
||||
end
|
||||
|
||||
def == other
|
||||
self.object_id == other.object_id
|
||||
end
|
||||
@ -195,6 +217,10 @@ module Parfait
|
||||
end
|
||||
end
|
||||
|
||||
def each_method(&block)
|
||||
return unless @methods
|
||||
@methods.each_method(&block)
|
||||
end
|
||||
def to_hash
|
||||
hash = {}
|
||||
each do |name , type|
|
||||
|
@ -22,7 +22,7 @@ module Parfait
|
||||
class TypedMethod < Object
|
||||
|
||||
attr_reader :name , :risc_instructions , :for_type , :cpu_instructions
|
||||
attr_reader :arguments , :frame , :binary
|
||||
attr_reader :arguments , :frame , :binary , :next_method
|
||||
|
||||
# not part of the parfait model, hence ruby accessor
|
||||
attr_accessor :source
|
||||
@ -118,5 +118,12 @@ module Parfait
|
||||
"#{@for_type.object_class.name}:#{name}(#{arguments.inspect})"
|
||||
end
|
||||
|
||||
def each_method( &block )
|
||||
block.call( self )
|
||||
next_method.each_method( &block ) if next_method
|
||||
end
|
||||
def set_next( method )
|
||||
@next_method = method
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -145,14 +145,15 @@ module Risc
|
||||
false_object: :FalseClass , nil_object: :NilClass},
|
||||
NamedList: {},
|
||||
Type: {names: :List , types: :List ,
|
||||
object_class: :Class, methods: :List } ,
|
||||
object_class: :Class, methods: :TypedMethod } ,
|
||||
Class: {instance_methods: :List, instance_type: :Type, name: :Word,
|
||||
super_class_name: :Word , instance_names: :List },
|
||||
Dictionary: {keys: :List , values: :List } ,
|
||||
CacheEntry: {cached_type: :Type , cached_method: :TypedMethod } ,
|
||||
TypedMethod: {name: :Word, source: :Object, risc_instructions: :Object,
|
||||
cpu_instructions: :Object, binary: :BinaryCode,
|
||||
arguments: :Type , for_type: :Type, frame: :Type } ,
|
||||
arguments: :Type , for_type: :Type, frame: :Type ,
|
||||
next_method: :TypedMethod} ,
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -55,10 +55,8 @@ module Risc
|
||||
# This method is just a placeholder until boot is over and the real method is
|
||||
# parsed.
|
||||
def resolve_method( context)
|
||||
compiler = compiler_for(:Word, :resolve_method , {:value => :Object} )
|
||||
args = compiler.method.arguments
|
||||
len = args.instance_length
|
||||
raise "Compiler arg number mismatch, method=#{args} " if len != 2
|
||||
compiler = compiler_for(:Word, :resolve_method , {:value => :Type} )
|
||||
|
||||
compiler.add_mom( Mom::ReturnSequence.new)
|
||||
return compiler.method
|
||||
end
|
||||
|
@ -99,6 +99,11 @@ module Risc
|
||||
true
|
||||
end
|
||||
# Instruction interpretation starts here
|
||||
def execute_DynamicJump
|
||||
label = get_register(@instruction.register)
|
||||
puts "Jump to :#{label}:"
|
||||
set_instruction label
|
||||
end
|
||||
def execute_Branch
|
||||
label = @instruction.label
|
||||
set_instruction label
|
||||
|
@ -149,13 +149,13 @@ class TestSpace < MiniTest::Test
|
||||
def test_no_methods_in_types
|
||||
test_remove_methods
|
||||
@space.each_type do |type|
|
||||
assert_equal 0 , type.methods.get_length , "name #{type.name}"
|
||||
assert_equal 0 , type.methods_length , "name #{type.name}"
|
||||
end
|
||||
end
|
||||
def test_no_methods_in_classes
|
||||
test_remove_methods
|
||||
@space.classes.each do |name , cl|
|
||||
assert_equal 0 , cl.instance_type.methods.get_length , "name #{cl.name}"
|
||||
assert_equal 0 , cl.instance_type.methods_length , "name #{cl.name}"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -25,24 +25,30 @@ class TestMethodApi < MiniTest::Test
|
||||
@space.get_class_by_name(:Object).instance_type
|
||||
end
|
||||
def test_new_methods
|
||||
assert_equal @try_type.method_names.class, @try_type.methods.class
|
||||
assert_equal @try_type.method_names.get_length , @try_type.methods.get_length
|
||||
assert_equal Parfait::List , @try_type.method_names.class
|
||||
assert_equal @try_type.method_names.get_length , @try_type.methods_length
|
||||
end
|
||||
def test_add_method
|
||||
before = @try_type.methods.get_length
|
||||
before = @try_type.methods_length
|
||||
add_foo_to
|
||||
assert_equal 1 , @try_type.methods.get_length - before
|
||||
assert_equal 1 , @try_type.methods_length - before
|
||||
assert @try_type.method_names.inspect.include?(":foo")
|
||||
end
|
||||
def test_remove_method
|
||||
add_foo_to
|
||||
assert_equal true , @try_type.remove_method(:foo)
|
||||
assert @try_type.remove_method(:foo)
|
||||
end
|
||||
def test_remove_not_there
|
||||
assert_raises RuntimeError do
|
||||
@try_type.remove_method(:foo)
|
||||
end
|
||||
end
|
||||
def test_remove_method_missing
|
||||
# assert @try_type.get_method( :method_missing)
|
||||
assert_raises RuntimeError do
|
||||
@try_type.remove_method(:method_missing)
|
||||
end
|
||||
end
|
||||
def test_create_method
|
||||
args = Parfait::Type.for_hash( @try_class , { bar: :Integer})
|
||||
@try_type.create_method :bar, args , empty_frame
|
||||
|
@ -50,6 +50,10 @@ module Risc
|
||||
assert_equal Label , call_ins.class
|
||||
assert_equal "Word_Type.resolve_method" , call_ins.name
|
||||
end
|
||||
def est_dyn
|
||||
cal = ticks(102)
|
||||
assert_equal DynamicJump , cal.class
|
||||
end
|
||||
#should end in exit, but doesn't, becasue resolve never returns
|
||||
def ttest_sys
|
||||
sys = ticks(20)
|
||||
|
Loading…
Reference in New Issue
Block a user