Created
January 3, 2009 21:03
-
-
Save collin/42929 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Working through some ideas from the subtext language project | |
| # http://www.subtextual.org/ | |
| # http://alarmingdevelopment.org/?p=160 <= Subtext Source | |
| require 'rubygems' | |
| require 'extlib' | |
| class Node | |
| attr_accessor :input, :parent, :children, :assertion, :root, :table | |
| def initialize input, assertion | |
| raise "Assertion can only be true/false!" unless [true, false].include? assertion | |
| @input = input | |
| @assertion = assertion | |
| @children = [] | |
| end | |
| def unflattened_all_nodes | |
| children + map{|child| child.all_nodes} | |
| end | |
| def all_nodes | |
| unflattened_all_nodes.flatten | |
| end | |
| def all_ids | |
| all_nodes.map{|node| node.id } | |
| end | |
| def id | |
| "#{parent_id}#{self_id}" | |
| end | |
| def self_id | |
| return "/" if root? | |
| "#{input.name}/#{assertion}" | |
| end | |
| def root? | |
| root.object_id == self.object_id | |
| end | |
| def table | |
| return @table if root? | |
| root.table | |
| end | |
| def parent_id | |
| return "" if parent.nil? | |
| "#{parent.id}" | |
| end | |
| def == other | |
| self.id == other.id | |
| end | |
| def empty? | |
| children.empty? | |
| end | |
| def gaps | |
| (instance_gaps + children.map{|child| child.gaps }).flatten.uniq | |
| end | |
| def instance_gaps | |
| NodeSet.new(table.inputs.map { |input| | |
| [Node.new(input.last, true), Node.new(input.last, false)] | |
| }.flatten) - (parent_ids << id) | |
| # [] | |
| end | |
| def parent_ids | |
| ids = [parent_id] | |
| ids += parent.parent_ids unless parent.nil? | |
| ids | |
| end | |
| def overlaps | |
| [] | |
| end | |
| def inspect | |
| "#<Node #{id}>" | |
| end | |
| alias to_s inspect | |
| def map &block | |
| children.map &block | |
| end | |
| def append input, assertion | |
| node = Node.new input, assertion | |
| node.parent = self | |
| node.root = self if self.root? | |
| children << node | |
| node | |
| end | |
| end | |
| class Input | |
| attr_accessor :name | |
| def initialize name | |
| @name = name | |
| end | |
| end | |
| class Inputs | |
| def initialize | |
| @inputs = {} | |
| end | |
| def [] name | |
| @inputs[name] | |
| end | |
| def names | |
| @inputs.keys | |
| end | |
| def map &block | |
| @inputs.map &block | |
| end | |
| def << name | |
| raise "Cannot have two inputs with the same name, fool!" if names.include? name | |
| input = Input.new(name) | |
| @inputs[name] = input | |
| input | |
| end | |
| end | |
| class Table | |
| @@input_names = [] | |
| attr_accessor :inputs, :root | |
| def initialize | |
| @inputs = Inputs.new | |
| @root = Node.new Input.new(:root), true | |
| @root.root = @root | |
| @root.table = self | |
| end | |
| def inspect | |
| "#<Table #{root.all_ids}>" | |
| end | |
| def append *args | |
| root.append *args | |
| end | |
| def gaps | |
| set = if root.empty? | |
| [] | |
| else | |
| root.gaps | |
| end | |
| GapSet.new set | |
| end | |
| def overlaps | |
| set = if root.empty? | |
| [] | |
| else | |
| root.overlaps | |
| end | |
| OverlapSet.new set | |
| end | |
| def [] *args | |
| inputs.[] *args | |
| end | |
| alias to_s inspect | |
| end | |
| class NodeSet | |
| def initialize nodes | |
| @nodes = nodes | |
| end | |
| def inspect | |
| "#<#{self.class.name} [#{@nodes.map{|node| node.inspect }.join(', ')}]>" | |
| end | |
| def + nodeset | |
| @nodes += nodeset.instance_variable_get :@nodes | |
| end | |
| def - nodes | |
| @nodes = @nodes.reject do |node| | |
| nodes.include? node.id | |
| end | |
| end | |
| alias to_s inspect | |
| end | |
| class GapSet < NodeSet | |
| end | |
| class OverlapSet < NodeSet | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment