Class: Linguify::Reduction
- Inherits:
-
Object
- Object
- Linguify::Reduction
- Defined in:
- lib/linguify/reduction.rb
Constant Summary collapse
- @@reductions =
[]
Instance Attribute Summary collapse
-
#args ⇒ Object
Returns the value of attribute args.
-
#from ⇒ Object
Returns the value of attribute from.
-
#inline ⇒ Object
Returns the value of attribute inline.
-
#lang ⇒ Object
Returns the value of attribute lang.
-
#line ⇒ Object
Returns the value of attribute line.
-
#location ⇒ Object
Returns the value of attribute location.
-
#named_args ⇒ Object
Returns the value of attribute named_args.
-
#reduction_id ⇒ Object
Returns the value of attribute reduction_id.
-
#regexp ⇒ Object
Returns the value of attribute regexp.
-
#returns ⇒ Object
Returns the value of attribute returns.
-
#rule_args ⇒ Object
Returns the value of attribute rule_args.
-
#sexp ⇒ Object
Returns the value of attribute sexp.
Class Method Summary collapse
-
.parse(str) ⇒ Object
Parse the string and return its reduction rule.
Instance Method Summary collapse
- #allocate_variable(name, not_in) ⇒ Object
- #compile ⇒ Object
-
#compile_with_return_to_var(params = {}) ⇒ Object
Compile self.
-
#determine_arguments ⇒ Object
Extract the arguments from the code block of this Reduction.
-
#initialize(params) ⇒ Reduction
constructor
A new instance of Reduction.
-
#to_rexp ⇒ Object
Get the reduction reference for this Reduction.
Constructor Details
#initialize(params) ⇒ Reduction
Returns a new instance of Reduction.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/linguify/reduction.rb', line 45 def initialize params @returns = params[:returns] @lang = params[:lang] @inline = params[:inline] @location = params[:location] @line = params[:line] @regexp = params[:regexp] @rule_args= @regexp.split(')').map{ |sub| sub.split('(')[1] }.select{ |v| v } @args = params[:args] @sexp = params[:sexp] @reduction_id = @@reductions.size determine_arguments @@reductions << self end |
Instance Attribute Details
#args ⇒ Object
Returns the value of attribute args.
41 42 43 |
# File 'lib/linguify/reduction.rb', line 41 def args @args end |
#from ⇒ Object
Returns the value of attribute from.
41 42 43 |
# File 'lib/linguify/reduction.rb', line 41 def from @from end |
#inline ⇒ Object
Returns the value of attribute inline.
41 42 43 |
# File 'lib/linguify/reduction.rb', line 41 def inline @inline end |
#lang ⇒ Object
Returns the value of attribute lang.
41 42 43 |
# File 'lib/linguify/reduction.rb', line 41 def lang @lang end |
#line ⇒ Object
Returns the value of attribute line.
41 42 43 |
# File 'lib/linguify/reduction.rb', line 41 def line @line end |
#location ⇒ Object
Returns the value of attribute location.
41 42 43 |
# File 'lib/linguify/reduction.rb', line 41 def location @location end |
#named_args ⇒ Object
Returns the value of attribute named_args.
41 42 43 |
# File 'lib/linguify/reduction.rb', line 41 def named_args @named_args end |
#reduction_id ⇒ Object
Returns the value of attribute reduction_id.
41 42 43 |
# File 'lib/linguify/reduction.rb', line 41 def reduction_id @reduction_id end |
#regexp ⇒ Object
Returns the value of attribute regexp.
41 42 43 |
# File 'lib/linguify/reduction.rb', line 41 def regexp @regexp end |
#returns ⇒ Object
Returns the value of attribute returns.
41 42 43 |
# File 'lib/linguify/reduction.rb', line 41 def returns @returns end |
#rule_args ⇒ Object
Returns the value of attribute rule_args.
41 42 43 |
# File 'lib/linguify/reduction.rb', line 41 def rule_args @rule_args end |
#sexp ⇒ Object
Returns the value of attribute sexp.
41 42 43 |
# File 'lib/linguify/reduction.rb', line 41 def sexp @sexp end |
Class Method Details
.parse(str) ⇒ Object
Parse the string and return its reduction rule.
97 98 99 100 101 102 103 104 105 |
# File 'lib/linguify/reduction.rb', line 97 def self.parse str if /^{(?<return>[^:]*):(?<rid>[0-9]+)}$/ =~ str @@reductions[rid.to_i] elsif /^(?<return>[^:]*):(?<rid>[0-9]+)$/ =~ str @@reductions[rid.to_i] else raise "hell #{str}" end end |
Instance Method Details
#allocate_variable(name, not_in) ⇒ Object
111 112 113 114 115 116 117 118 |
# File 'lib/linguify/reduction.rb', line 111 def allocate_variable name,not_in n = 0 begin var = "#{name}_#{n}".to_sym n += 1 end while not_in.select{ |sexp| sexp.variable_exists?(var) }.size > 0 var end |
#compile ⇒ Object
107 108 109 |
# File 'lib/linguify/reduction.rb', line 107 def compile compile_with_return_to_var end |
#compile_with_return_to_var(params = {}) ⇒ Object
Compile self
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/linguify/reduction.rb', line 126 def compile_with_return_to_var params={} replace = params[:replace] || {} s = Marshal.load(Marshal.dump(self)) # sexp handling is not clean cut args = @named_args.keys # args[] now has the symbolized argument names of the code block args_code = [] s.args.each_with_index do |arg,i| if /^{(?<ret>[^:]*):(?<n>[0-9]+)}$/ =~ arg # got a argument that referes to a reduction # pseudo allocate a return variable name and compile the reduction red = Reduction::parse(arg) if red.lang != lang && red.lang == :js && lang == :ruby # paste javascript code into a ruby variable code = red.compile_with_return_to_var :replace => replace clone = Marshal.load(Marshal.dump(code)) # code is not cleanly duplicated code = Sexp.new(:iter,Sexp.new(:call, nil, :lambda, Sexp.new(:arglist)), nil, Sexp.new(:block, *clone ) ) code = Ruby2Js.new.process(code) code = [Sexp.new(:lasgn, args[i], Sexp.new(:lit, code))] args_code += code else raise "trying to reference #{red.lang} code in #{lang} code" if red.lang != lang if red.inline code = red.compile_with_return_to_var :replace => replace replace[args[i]] = Replacement.new(:sexp => Sexp.new(:block,*code), :inline => true) else var = allocate_variable(ret,[*args_code,sexp]) code = red.compile_with_return_to_var :return_variable => var, :replace => replace args_code += code replace[args[i]] = Replacement.new(:sexp => var) end end elsif /^[0-9]+$/ =~ arg # got a number argument, stuff it in a integer variable args_code << Sexp.new(:lasgn, args[i], Sexp.new(:lit, arg.to_i)) else # got a string replace[args[i]] = Replacement.new(:sexp => Sexp.new(:str, arg)) if args[i] end end if params[:return_variable] if s.sexp[3][0] == :block code = Sexp.new(:lasgn, params[:return_variable], Sexp.new(:block, *(s.sexp[3][1..-1].map{ |s| s.dup }) ) ) else code = Sexp.new(:lasgn, params[:return_variable], s.sexp[3].dup) end else code = s.sexp[3].dup end replace.each do |k,v| code.replace_variable_references! :replacement => v, :needle => k, :named_args => @named_args end return *args_code + [code] end |
#determine_arguments ⇒ Object
Extract the arguments from the code block of this Reduction.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/linguify/reduction.rb', line 64 def determine_arguments s = Marshal.load(Marshal.dump(self)) # sexp handling is not clean cut raise "what is this?" unless s.sexp.sexp_type == :iter && s.sexp[1].sexp_type == :call && s.sexp[1][1] == nil && s.sexp[1][2] == :proc && s.sexp[1][3].sexp_type == :arglist block_args = s.sexp[2] if block_args if block_args[0]==:lasgn # single argument args = [block_args[1]] elsif block_args[0]==:masgn # multiple arguments args = block_args[1] raise "unsupported argument type #{args}" unless args[0]==:array args = args[1..-1].map{ |arg| raise "unsupported argument type #{arg}" unless arg[0]==:lasgn arg[1] } else raise "unsupported argument type #{args}" end end # maybe we can fix the input so we don't have to repair it here? @args = @args[-args.size..-1] if args and args.size != @args.size @named_args = Hash[*args.zip(@args[-args.size..-1]).flatten] if args @named_args ||= {} end |
#to_rexp ⇒ Object
Get the reduction reference for this Reduction.
197 198 199 200 |
# File 'lib/linguify/reduction.rb', line 197 def to_rexp raise "hell" if returns.kind_of?(Array) "{#{returns}:#{reduction_id}}" end |