diff --git a/lib/sof/all.rb b/lib/sof/all.rb index 873ea2c3..49ce053e 100644 --- a/lib/sof/all.rb +++ b/lib/sof/all.rb @@ -1,4 +1,5 @@ require_relative "members" +require_relative "writer" require_relative "array" require_relative "occurence" diff --git a/lib/sof/array.rb b/lib/sof/array.rb index 4ea037cc..02b2177e 100644 --- a/lib/sof/array.rb +++ b/lib/sof/array.rb @@ -1,9 +1,4 @@ Array.class_eval do - def add_sof(members , level) - each do |o| - members.add(o , level + 1) - end - end def to_sof(io , members) each do |object| io.write("\n") diff --git a/lib/sof/known.rb b/lib/sof/known.rb new file mode 100644 index 00000000..216296b0 --- /dev/null +++ b/lib/sof/known.rb @@ -0,0 +1,13 @@ +module Sof + class Known + @@mapping = { + MethodDefinition => [:name , :args , :receiver , :return_type , :blocks] + } + def self.is clazz + @@mapping.has_key? clazz + end + def self.attributes clazz + @@mapping[clazz] + end + end +end diff --git a/lib/sof/members.rb b/lib/sof/members.rb index cd0ba3ee..5ef8098d 100644 --- a/lib/sof/members.rb +++ b/lib/sof/members.rb @@ -7,29 +7,31 @@ module Sof @objects = {} add(root ,0 ) end - attr_reader :objects + attr_reader :objects , :root def add object , level + return if Members.is_value?(object) if( @objects.has_key?(object) ) occurence = @objects[object] occurence.level = level if occurence.level > level - else - o = Occurence.new( object , @counter , level ) - @objects[object] = o - c = @counter - @counter = @counter + 1 - if( object.respond_to?(:attributes)) - object.attributes.each do |a| - val = object.send a - add(val , level + 1) - end - elsif not value?(object) - object.add_sof(self , level) + return + end + o = Occurence.new( object , @counter , level ) + @objects[object] = o + @counter = @counter + 1 + attributes = attributes_for(object) + attributes.each do |a| + val = object.instance_variable_get "@#{a}".to_sym + add(val , level + 1) + end + if( object.is_a? Array ) + object.each do |a| + add(a , level + 1) end end end - def value? o + def self.is_value? o return true if o == true return true if o == false return true if o == nil @@ -38,38 +40,13 @@ module Sof return true if o.class == String return false end - def write - io = StringIO.new - output io , @root - io.string - end - def output io , object - occurence = @objects[object] - raise "no object #{object}" unless occurence - indent = " " * occurence.level - io.write indent - if(object.respond_to? :to_sof) - object.to_sof(io , self) + def attributes_for object + if( Known.is( object.class )) + Known.attributes(object.class) else - io.write object.class.name - if( object.respond_to?(:attributes)) - object.attributes.each do |a| - val = object.send a - io.write( a ) - io.write( " " ) - output( io , val) - end - io.puts "" - else - raise "General object not supported (yet), need attribute method #{object}" - end + object.instance_variables.collect{|i| i.to_s[1..-1].to_sym } # chop of @ end end - - def self.write object - members = Members.new object - members.write - end end end diff --git a/lib/sof/writer.rb b/lib/sof/writer.rb new file mode 100644 index 00000000..fc29c911 --- /dev/null +++ b/lib/sof/writer.rb @@ -0,0 +1,46 @@ +module Sof + class Writer + def initialize members + @members = members + end + + def write + io = StringIO.new + output io , @members.root + io.string + end + + def output io , object + if Members.is_value?(object) + object.to_sof(io , self) + return + end + occurence = @members.objects[object] + raise "no object #{object}" unless occurence + indent = " " * occurence.level + io.write indent + if(object.respond_to? :to_sof) + object.to_sof(io , self) + else + io.write object.class.name + if( object.respond_to?(:attributes)) + object.attributes.each do |a| + val = object.send a + io.write( a ) + io.write( " " ) + output( io , val) + end + io.puts "" + else + raise "General object not supported (yet), need attribute method #{object}" + end + end + end + + def self.write object + writer = Writer.new(Members.new(object) ) + writer.write + end + + end +end diff --git a/lib/virtual/method_definition.rb b/lib/virtual/method_definition.rb index 9ebc5ff3..2340e16d 100644 --- a/lib/virtual/method_definition.rb +++ b/lib/virtual/method_definition.rb @@ -34,9 +34,6 @@ module Virtual def MethodDefinition.main MethodDefinition.new(:main , [] , Virtual::SelfReference ) end - def attributes - [:name , :args , :receiver , :return_type , :blocks] - end def initialize name , args , receiver = Virtual::SelfReference.new , return_type = Virtual::Mystery , start = MethodEnter.new() @name = name.to_sym @args = args diff --git a/test/sof.rb b/test/sof.rb index 3b12cf44..0ff33fdd 100644 --- a/test/sof.rb +++ b/test/sof.rb @@ -6,12 +6,12 @@ end class BasicSof < MiniTest::Test def test_true - out = Sof::Members.write(true) - assert_equal " true\n" , out + out = Sof::Writer.write(true) + assert_equal "true" , out end def test_num - out = Sof::Members.write(124) - assert_equal " 124\n" , out + out = Sof::Writer.write(124) + assert_equal "124" , out end end \ No newline at end of file