Skip to content
This repository has been archived by the owner on Aug 31, 2021. It is now read-only.

Commit

Permalink
remove WIP code to compile to ruby or javascript
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonhutchens committed Mar 20, 2014
1 parent a930530 commit be5f8ea
Show file tree
Hide file tree
Showing 12 changed files with 6 additions and 230 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ doc
pkg
*.swp
.rvmrc
.ruby-version
.ruby-gemset
.ditz-config
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ group :development do
gem "rubyXL", "~> 1.2.7"
gem "nokogiri", ">= 1.4.4"
gem "rubyzip", ">= 0.9.4"
gem "awesome_print"
end

group :test do
Expand Down
2 changes: 0 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
GEM
remote: http://rubygems.org/
specs:
awesome_print (1.1.0)
diff-lcs (1.1.3)
git (1.2.5)
jeweler (1.8.4)
Expand Down Expand Up @@ -35,7 +34,6 @@ PLATFORMS
ruby

DEPENDENCIES
awesome_print
jeweler (~> 1.8.3)
nokogiri (>= 1.4.4)
rake
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2013 Agworld Pty. Ltd.
Copyright (c) 2014 Agworld Pty. Ltd.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
Expand Down
9 changes: 1 addition & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,6 @@ s.g = "=FOO(10, 20)"
puts s.g # => 17
```

Compilation
-----------

Rather than interact with a `Soroban::Sheet` object at runtime, you can compile
the sheet into a Ruby or JavaScript class which you can then either save out to
a file or evaluate directly. This is slightly less flexible, but more efficient.

Contributing to Soroban
-----------------------

Expand All @@ -168,4 +161,4 @@ Contributing to Soroban
Copyright
---------

Copyright (c) 2013 Agworld Pty. Ltd. See LICENSE.txt for further details.
Copyright (c) 2014 Agworld Pty. Ltd. See LICENSE.txt for further details.
19 changes: 2 additions & 17 deletions lib/soroban/cell.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module Soroban
# representation of its contents, and the executable Ruby version of same, as
# generated via a rewrite grammar. Cells also store their dependencies.
class Cell
attr_reader :excel, :javascript, :dependencies
attr_reader :excel, :dependencies

# Cells are initialised with a binding to allow formulas to be executed
# within the context of the sheet which owns the cell.
Expand All @@ -18,10 +18,6 @@ def initialize(context)
@value = nil
end

def to_compiled_ruby
@tree.to_compiled_ruby
end

# Set the contents of a cell, and store the executable Ruby version.
def set(contents)
contents = contents.to_s
Expand All @@ -30,7 +26,7 @@ def set(contents)
@excel = contents
@tree = Soroban::parser.parse(@excel)
raise Soroban::ParseError, Soroban::parser.failure_reason if @tree.nil?
@ruby = _to_ruby
@ruby = @tree.to_ruby(@dependencies.clear)
end

# Clear the cached value of a cell to force it to be recalculated
Expand All @@ -49,17 +45,6 @@ def get
ensure
@touched = false
end

private

def _to_ruby
@tree.to_ruby(@dependencies.clear)
end

def _to_javascript
@tree.to_javascript(@dependencies.clear)
end

end

end
36 changes: 0 additions & 36 deletions lib/soroban/parser/nodes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,12 @@ class Formula < Treetop::Runtime::SyntaxNode
def rewrite_ruby(value)
value.gsub(/^= */, '')
end
alias :compile_ruby :rewrite_ruby
end

class Identifier < Treetop::Runtime::SyntaxNode
def rewrite_ruby(value)
"@#{value}.get"
end
def compile_ruby(value)
"@cells[:#{value}].call"
end
def extract(value)
value.to_sym
end
Expand All @@ -23,81 +19,49 @@ class IntegerValue < Treetop::Runtime::SyntaxNode
def rewrite_ruby(value)
"#{value.to_f}"
end
alias :compile_ruby :rewrite_ruby
end

class FloatValue < Treetop::Runtime::SyntaxNode
def rewrite_ruby(value)
"#{value.to_f}"
end
alias :compile_ruby :rewrite_ruby
end

class Function < Treetop::Runtime::SyntaxNode
def rewrite_ruby(value)
match = /^([^(]*)(.*)$/.match(value)
"func_#{match[1].downcase}#{match[2]}"
end
def compile_ruby(value)
match = /^([A-Z]+)\((.*)\)$/.match(value)
name, args = match[1], match[2].split(',')
case name
when 'VLOOKUP'
find, table, column, _ = args
table = table[1...-1]
column = column.to_i
table_key = "'#{table}_#{column}'"
code = []
code << "begin"
code << " @cache[#{table_key}] ||= {"
cols = Tabulator.new(table).get
lookup = Hash[cols[0].zip(cols[column-1])]
code << lookup.map do |key, val|
" @cells[:#{key}].call => @cells[:#{val}].call"
end.join(",\n")
code << " }"
code << " @cache[#{table_key}][#{find}] || 0.0"
code << " end"
code.join("\n")
else
value
end
end
end

class Pow < Treetop::Runtime::SyntaxNode
def rewrite_ruby(value)
"**"
end
alias :compile_ruby :rewrite_ruby
end

class Equal < Treetop::Runtime::SyntaxNode
def rewrite_ruby(value)
"=="
end
alias :compile_ruby :rewrite_ruby
end

class NotEqual < Treetop::Runtime::SyntaxNode
def rewrite_ruby(value)
"!="
end
alias :compile_ruby :rewrite_ruby
end

class Label < Treetop::Runtime::SyntaxNode
def rewrite_ruby(value)
value.gsub('$', '')
end
alias :compile_ruby :rewrite_ruby
end

class Range < Treetop::Runtime::SyntaxNode
def rewrite_ruby(value)
"'#{value}'"
end
alias :compile_ruby :rewrite_ruby
def extract(value)
LabelWalker.new(value).map { |label| "#{label}".to_sym }
end
Expand Down
30 changes: 0 additions & 30 deletions lib/soroban/parser/rewrite.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,10 @@ def to_ruby(dependencies)
end
end

def to_compiled_ruby
if nonterminal?
value = ""
elements.each { |element| value << element.to_compiled_ruby }
compile_ruby(value)
else
compile_ruby(text_value)
end
end

def to_javascript(dependencies)
if nonterminal?
value = ""
elements.each { |element| value << element.to_javascript(dependencies) }
_add_dependency(dependencies, extract(value))
rewrite_javascript(value)
else
_add_dependency(dependencies, extract(text_value))
rewrite_javascript(text_value)
end
end

def compile_ruby(value)
value
end

def rewrite_ruby(value)
value
end

def rewrite_javascript(value)
value
end

def extract(value)
end

Expand Down
54 changes: 0 additions & 54 deletions lib/soroban/sheet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
require 'soroban/functions'
require 'soroban/label_walker'
require 'soroban/value_walker'
require 'soroban/tabulator'
require 'soroban/cell'

require 'set'
Expand All @@ -17,62 +16,10 @@ class Sheet
def initialize(logger=nil)
@logger = logger
@cells = {}
@compiled = {}
@changes = Hash.new{ |h, k| h[k] = Set.new }
@bindings = {}
end

def factory(name)
eval(self.to_ruby(name), TOPLEVEL_BINDING)
Object::const_get('Soroban').const_get('Model').const_get(name).new
end

# Return a string containing a ruby class that implements the sheet. You can
# call eval() on this string to create the class, which you can then
# instantiate. Set inputs on the instance and read outputs off.
def to_ruby(class_name)
data = []
data << "module Soroban"
data << "module Model"
data << "class #{class_name}"
data << " def initialize"
data << " @binds = {"
data << bindings.map do |name, cell|
" '#{name}' => :#{cell}"
end.join(",\n")
data << " }"
data << " @cache = {}"
data << " @cells = {"
data << @compiled.map do |label, cell|
" :#{label} => lambda { @cache[:#{label}] ||= #{cell.to_compiled_ruby} }"
end.join(",\n")
data << " }"
data << " end"
data << " def clear"
data << " @cache.clear"
data << " end"
data << " def get(name)"
data << " @cells[@binds[name]].call"
data << " end"
data << " def set(name, value)"
data << " self.clear"
data << " @cells[@binds[name]] = lambda { @cache[@binds[name]] ||= value }"
data << " end"
bindings.each do |name, cell|
data << " def #{name}"
data << " get('#{name}')"
data << " end"
data << " def #{name}=(value)"
data << " set('#{name}', value)"
data << " end"
end
data << "end"
data << "end"
data << "end"
puts data.join("\n")
data.join("\n")
end

# Used for calling dynamically defined functions, and for creating new
# cells (via `label=`).
def method_missing(method, *args, &block)
Expand Down Expand Up @@ -180,7 +127,6 @@ def _add(label, contents)
internal = "@#{label}"
_expose(internal, label)
cell = Cell.new(binding)
@compiled[label] = cell
_set(label, cell, contents)
instance_variable_set(internal, cell)
end
Expand Down
34 changes: 0 additions & 34 deletions lib/soroban/tabulator.rb

This file was deleted.

Loading

0 comments on commit be5f8ea

Please sign in to comment.