diff --git a/Gemfile b/Gemfile index 255fa318..172a8ade 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,8 @@ source "http://rubygems.org" -gem "parslet" -gem "salama-reader" , "0.0.2" , :require => "parser" , :git => "https://github.com/salama/salama-reader.git" +gem "parslet" +gem "salama-reader" , "0.0.2" , :require => "parser" , :git => "https://github.com/salama/salama-reader.git" +gem "salama-object-file" , "0.1" , :git => "https://github.com/salama/salama-object-file.git" group :development do gem "minitest" diff --git a/Gemfile.lock b/Gemfile.lock index 9e67bd98..8e5db958 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,9 @@ +GIT + remote: https://github.com/salama/salama-object-file.git + revision: c8d35adef4858b14d75f14f0c2de1883762ef4ad + specs: + salama-object-file (0.1) + GIT remote: https://github.com/salama/salama-reader.git revision: 1272af6c660efe0af93d7f5ad87d98bd04ce5d22 @@ -19,4 +25,5 @@ PLATFORMS DEPENDENCIES minitest parslet + salama-object-file (= 0.1)! salama-reader (= 0.0.2)! diff --git a/Rakefile b/Rakefile index fcb8c7f8..955d3402 100644 --- a/Rakefile +++ b/Rakefile @@ -11,20 +11,6 @@ rescue Bundler::BundlerError => e end require 'rake' -require 'jeweler' -Jeweler::Tasks.new do |gem| - # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options - gem.name = "salama" - gem.homepage = "http://github.com/salama-ruby/salama" - gem.license = "MIT" - gem.summary = %Q{Create fast code} - gem.description = %Q{A long way to china and back} - gem.email = "torsten@villataika.fi" - gem.authors = ["Torsten Ruger"] - # dependencies defined in Gemfile -end -Jeweler::RubygemsDotOrgTasks.new - require 'rake/testtask' Rake::TestTask.new(:test) do |test| test.libs << 'lib' << 'test' diff --git a/lib/sof/README.md b/lib/sof/README.md deleted file mode 100644 index 5baa6392..00000000 --- a/lib/sof/README.md +++ /dev/null @@ -1,59 +0,0 @@ -### Reading the code - -Knowing what's going on while coding salama is not so easy: Hence the need to look at code dumps - -Hence the need for a code/object file format -(remember an oo program is just objects, some data, some code, all objects) - -I started with yaml, which is nice in that it has a solid implementation, reads and writes, -handles arbitrary objects, handles graphs and is a sort of readable text format. - -But the "sort of" started to get to me, because - -- 1) it's way to verbose (long files, object groups over many pages) and -- 2) does not allow for (easy) ordering. - -To fix this i started on Sof, with an eye to expand it. - -The main starting goal was quite like yaml, but with - -- more text per line, specifically objects with simple attributes to have a constructor like syntax -- also short versions of arrays and hashes -- Shorter class names (no ruby/object or even ruby/struct stuff) -- references at the most shallow level -- an easy way to order attributes and specify attributes that should not be serialized - -### Salama Object File - -Ok, so we all heard about object files, it's the things compilers create so we don't have to have -huge compiles and can link them later. - -Much fewer know what they include, and that is not because they are not very useful, -but rather very complicated. - -An object machine must off course have it's own object files, because: - -- otherwise we'd have to express the object machine in c (nischt gut) -- we would be forced to read the source every time (slow) -- we would have no language independant format - -And i was going to get there, juust not now. I mean i think it's a great idea to have many languages -compile and run on the same object machine. -Not neccessarily my idea, but i haven't seen it pulled off. Not that i will. - -I just want to be able to read my compiled code!! - -And so this is a little start, just some outputter. - -#### Direction - -The way this is meant to go (planned for 2020+) was a salama core with only a sof parser -(as that is soo much simpler). - -Then to_ruby for all the ast classes to be able to roundtrip ruby code. - -Then go to storing sof in git, rather than ruby. - -Then write a python/java parser and respective runtime conversion. Extracting common features. -With the respective to_python on the ast's to roundtrip that too. -Have to since by now we work on sof's. Etc . .. diff --git a/lib/sof/all.rb b/lib/sof/all.rb deleted file mode 100644 index 178bb0fd..00000000 --- a/lib/sof/all.rb +++ /dev/null @@ -1,39 +0,0 @@ -require_relative "util" -require_relative "node" -require_relative "members" -require_relative "volotile" -require_relative "writer" -require_relative "array" -require_relative "hash" -require_relative "occurence" - -Symbol.class_eval do - def to_sof() - ":#{to_s}" - end -end -TrueClass.class_eval do - def to_sof() - "true" - end -end -NilClass.class_eval do - def to_sof() - "nil" - end -end -FalseClass.class_eval do - def to_sof() - "false" - end -end -String.class_eval do - def to_sof() - "'" + self + "'" - end -end -Fixnum.class_eval do - def to_sof() - to_s - end -end diff --git a/lib/sof/array.rb b/lib/sof/array.rb deleted file mode 100644 index 1ee03944..00000000 --- a/lib/sof/array.rb +++ /dev/null @@ -1,51 +0,0 @@ -module Sof - class ArrayNode < Node - def initialize ref - super(ref) - @children = [] - end - attr_reader :children - def add c - @children << c - end - def out io , level = 0 - super - short = true - children.each do |c| - short = false unless c.is_a?(SimpleNode) - end - if(short and children.length < 7 ) - short_out(io,level) - else - long_out(io , level) - end - end - - private - def short_out(io,level) - io.write("[") - @children.each_with_index do |child , i| - child.out(io , level + 1) - io.write ", " unless (i+1) == children.length - end - io.write("]") - end - def long_out io , level - indent = " " * level - @children.each_with_index do |child , i| - io.write "\n#{indent}" unless i == 0 - io.write "-" - child.out(io , level + 1) - end - end - end -end -Array.class_eval do - def to_sof_node(writer , level , ref ) - node = Sof::ArrayNode.new(ref) - each do |object| - node.add writer.to_sof_node( object , level + 1) - end - node - end -end diff --git a/lib/sof/hash.rb b/lib/sof/hash.rb deleted file mode 100644 index ad3c4aa9..00000000 --- a/lib/sof/hash.rb +++ /dev/null @@ -1,60 +0,0 @@ -module Sof - class HashNode < Node - def initialize ref - super(ref) - @children = [] - end - attr_reader :children - def add key , val - @children << [key,val] - end - def out io , level = 0 - super - short = true - children.each do |k,v| - short = false unless k.is_a?(SimpleNode) - short = false unless v.is_a?(SimpleNode) - end - if(short and children.length < 7 ) - short_out(io,level) - else - long_out(io , level) - end - end - def short_out(io,level) - io.write("{") - children.each_with_index do |child , i| - key , val = child - key.out(io , level + 1) - io.write " => " - val.out(io , level + 1) - io.write ", " unless (i+1) == children.length - end - io.write("}") - end - def long_out io , level - indent = " " * level - children.each_with_index do |child , i| - key , val = child - io.write "\n#{indent}" unless i == 0 - io.write "-" - key.out(io , level + 1) - io.write " => " - val.out(io , level + 1) - end - end - end -end - -Hash.class_eval do - def to_sof_node(writer , level , ref) - node = Sof::HashNode.new(ref) - each do |key , object| - k = writer.to_sof_node( key ,level + 1) - v = writer.to_sof_node( object ,level +1) - node.add(k , v) - end - node - end -end - diff --git a/lib/sof/members.rb b/lib/sof/members.rb deleted file mode 100644 index 13e5c30f..00000000 --- a/lib/sof/members.rb +++ /dev/null @@ -1,49 +0,0 @@ -module Sof - - class Members - include Util - - def initialize root - @root = root - @counter = 1 - @objects = {} - @referenced = false - add(root , 0) - end - attr_reader :objects , :root , :referenced - - def add object , level - return if is_value?(object) - if( occurence = @objects[object.object_id] ) - #puts "reset level #{level} at #{occurence.level}" - if occurence.level > level - occurence.level = level - end - unless occurence.referenced - #puts "referencing #{@counter} , at level #{level}/#{occurence.level} " - occurence.set_reference(@counter) - @counter = @counter + 1 - end - return - end - o = Occurence.new( object , level ) - @objects[object.object_id] = o - attributes = attributes_for(object) - attributes.each do |a| - val = get_value( object , a) - add(val , level + 1) - end - if( object.is_a? Array ) - object.each do |a| - add(a , level + 1) - end - end - if( object.is_a? Hash ) - object.each do |a,b| - add(a , level + 1) - add(b , level + 1) - end - end - end - end -end diff --git a/lib/sof/node.rb b/lib/sof/node.rb deleted file mode 100644 index 713d0df9..00000000 --- a/lib/sof/node.rb +++ /dev/null @@ -1,58 +0,0 @@ -# We transform objects into a tree of nodes - -module Sof - #abstract base class for nodes in the tree - # may be referenced (should be a simple name or number) - class Node - include Util - def initialize ref - @referenced = ref - end - # must be able to output to a stream - def out io ,level - io.write "&#{@referenced} " if @referenced - end - def as_string(level) - io = StringIO.new - out(io,level) - io.string - end - attr_reader :referenced - end - - class SimpleNode < Node - def initialize data , ref = nil - super(ref) - @data = data - end - attr_reader :data - def out io , level - super(io,level) - io.write(data) - end - end - - class ObjectNode < Node - def initialize data , ref - super(ref) - @data = data - @children = [] - end - attr_reader :children , :data - def add k , v - @children << [k,v] - end - def out io , level = 0 - super - io.write(@data) - indent = " " * (level + 1) - @children.each_with_index do |child , i| - k , v = child - io.write "\n#{indent}" - k.out(io , level + 2) - io.write " " - v.out(io , level + 2) - end - end - end -end diff --git a/lib/sof/occurence.rb b/lib/sof/occurence.rb deleted file mode 100644 index 79b4f306..00000000 --- a/lib/sof/occurence.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Sof - - class Occurence - def initialize object , level - @object = object - @level = level - @referenced = nil - end - def set_reference r - @referenced = r - end - attr_reader :object , :referenced - attr_accessor :level - end - -end diff --git a/lib/sof/util.rb b/lib/sof/util.rb deleted file mode 100644 index 99b391aa..00000000 --- a/lib/sof/util.rb +++ /dev/null @@ -1,25 +0,0 @@ -module Sof - module Util - def is_value? o - return true if o == true - return true if o == false - return true if o == nil - return true if o.class == Fixnum - return true if o.class == Symbol - return true if o.class == String - return false - end - - def get_value(object,name) - object.instance_variable_get "@#{name}".to_sym - end - - def attributes_for object - Sof::Util.attributes(object) - end - def self.attributes( object ) - atts = object.instance_variables.collect{|i| i.to_s[1..-1].to_sym } # chop of @ - atts - Volotile.attributes(object.class) - end - end -end diff --git a/lib/sof/volotile.rb b/lib/sof/volotile.rb deleted file mode 100644 index 704a9f88..00000000 --- a/lib/sof/volotile.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Sof - class Volotile - @@mapping = { } - def self.attributes clazz - @@mapping[clazz] || [] - end - def self.add clazz , attributes - @@mapping[clazz] = attributes - end - end -end diff --git a/lib/sof/writer.rb b/lib/sof/writer.rb deleted file mode 100644 index 6b205071..00000000 --- a/lib/sof/writer.rb +++ /dev/null @@ -1,60 +0,0 @@ -module Sof - class Writer - include Util - def initialize members - @members = members - end - - def write - node = to_sof_node(@members.root , 0) - io = StringIO.new - node.out( io , 0 ) - io.string - end - - def to_sof_node(object , level) - if is_value?(object) - return SimpleNode.new(object.to_sof()) - end - occurence = @members.objects[object.object_id] - raise "no object #{object}" unless occurence - if(level > occurence.level ) - #puts "ref #{occurence.referenced} level #{level} at #{occurence.level}" - return SimpleNode.new("*#{occurence.referenced}") - end - ref = occurence.referenced - if(object.respond_to? :to_sof_node) #mainly meant for arrays and hashes - object.to_sof_node(self , level , ref ) - else - object_sof_node(object , level , ref ) - end - end - - def object_sof_node( object , level , ref) - if( object.is_a? Class ) - return SimpleNode.new( object.name , ref ) - end - head = object.class.name + "(" - atts = {} - attributes_for(object).each() do |a| - val = get_value(object , a) - next if val.nil? - atts[a] = to_sof_node(val , level + 1) - end - immediate , extended = atts.partition {|a,val| val.is_a?(SimpleNode) } - head += immediate.collect {|a,val| "#{a.to_sof()} => #{val.as_string(level)}"}.join(", ") + ")" - return SimpleNode.new(head) if( ref.nil? and extended.empty? and head.length < 30 ) - node = ObjectNode.new(head , ref) - extended.each do |a , val| - node.add( to_sof_node(a,level + 1) , val ) - end - node - end - - def self.write object - writer = Writer.new(Members.new(object) ) - writer.write - end - - end -end diff --git a/test/README.md b/test/README.md index aca94758..a7cedc45 100644 --- a/test/README.md +++ b/test/README.md @@ -15,16 +15,9 @@ time comes to move to salama, less work. ruby test/test_all.rb '''' -### sof - -'''' - ruby test/test_sof.rb -'''' - ### vm As this is all quite new, i tend to test only when i know that the functionality will stay that way. Otherwise it's just too much effort to rewrite and rewrite the tests. -There used to be better tests, but rewrites bring fluctuation, so poke around and make suggestion :-) - +There used to be better tests, but rewrites bring fluctuation, so poke around and make suggestion :-) diff --git a/test/sof.rb b/test/sof.rb deleted file mode 100644 index b1fa2647..00000000 --- a/test/sof.rb +++ /dev/null @@ -1,106 +0,0 @@ -require_relative "helper" -require "yaml" - -class ObjectWithAttributes - def initialize - @name = "some name" - @number = 1234 - end - attr_accessor :extra -end -OBJECT_STRING = "ObjectWithAttributes(:name => 'some name', :number => 1234)" - -class BasicSof < MiniTest::Test - def check should - same = (should == @out) - puts "Shouldda\n#{@out}" unless same - assert_equal should , @out - end - def test_true - @out = Sof::Writer.write(true) - check "true" - end - def test_num - @out = Sof::Writer.write(124) - check "124" - end - def test_simple_object - @out = Sof::Writer.write(ObjectWithAttributes.new) - check "#{OBJECT_STRING}" - end - def test_object_extra_array - object = ObjectWithAttributes.new - object.extra = [:sym , 123] - @out = Sof::Writer.write(object) - check "#{OBJECT_STRING}\n :extra [:sym, 123]" - end - def test_simple_array - @out = Sof::Writer.write([true, 1234]) - check "[true, 1234]" - end - def test_array_object - @out = Sof::Writer.write([true, 1234 , ObjectWithAttributes.new]) - check "-true\n-1234\n-#{OBJECT_STRING}" - end - def test_array_array - @out = Sof::Writer.write([true, 1 , [true , 12 ]]) - check "-true\n-1\n-[true, 12]" - end - def test_array_array_reverse - @out = Sof::Writer.write([ [true , 12 ], true, 1]) - check "-[true, 12]\n-true\n-1" - end - def test_array_array_array - @out = Sof::Writer.write([true, 1 , [true , 12 , [true , 123 ]]]) - check "-true\n-1\n--true\n -12\n -[true, 123]" - end - def test_array_array_object - @out = Sof::Writer.write([true, 1 , [true , 12 , ObjectWithAttributes.new]]) - check "-true\n-1\n--true\n -12\n -#{OBJECT_STRING}" - end - def test_simple_hash - @out = Sof::Writer.write({ one: 1 , tru: true }) - check "{:one => 1, :tru => true}" - end - def test_hash_object - @out = Sof::Writer.write({ one: 1 , two: ObjectWithAttributes.new }) - check "-:one => 1\n-:two => #{OBJECT_STRING}" - end - def test_array_hash - @out = Sof::Writer.write([true, 1 , { one: 1 , tru: true }]) - check "-true\n-1\n-{:one => 1, :tru => true}" - end - def test_hash_array - @out = Sof::Writer.write({ one: [1 , ObjectWithAttributes.new] , two: true }) - check "-:one => -1\n -#{OBJECT_STRING}\n-:two => true" - end - def test_array_recursive - ar = [true, 1 ] - ar << ar - @out = Sof::Writer.write(ar) - check "&1 [true, 1, *1]" - end - def test_object_recursive - object = ObjectWithAttributes.new - object.extra = object - @out = Sof::Writer.write(object) - check "&1 ObjectWithAttributes(:name => 'some name', :number => 1234, :extra => *1)" - end - def test_object_inline - object = ObjectWithAttributes.new - object.extra = Object.new - @out = Sof::Writer.write(object) - check "ObjectWithAttributes(:name => 'some name', :number => 1234, :extra => Object())" - end - def test_class - @out = Sof::Writer.write(ObjectWithAttributes) - check "ObjectWithAttributes" - end - def test_class_ref - object = ObjectWithAttributes.new - object.extra = ObjectWithAttributes - ar = [object , ObjectWithAttributes] - @out = Sof::Writer.write(ar) - check "-ObjectWithAttributes(:name => 'some name', :number => 1234, :extra => *1)\n-&1 ObjectWithAttributes" - end -end \ No newline at end of file diff --git a/test/test_all.rb b/test/test_all.rb index 2d1636b9..c9558b3a 100644 --- a/test/test_all.rb +++ b/test/test_all.rb @@ -1,6 +1,5 @@ # All working tests (ahm), still working on the others, so no use to be constantly reminded require_relative "arm/test_all" -require_relative "sof" require "parfait/hash_test" #require_relative "virtual/test_all"