class Eggshell::Bundles::Basics::ControlMacros
Public Class Methods
new()
click to toggle source
# File lib/eggshell/bundles/basics-old.rb, line 638 def initialize @stack = [] @state = [] @macstack = [] end
Public Instance Methods
process(buffer, macname, args, lines, depth)
click to toggle source
# File lib/eggshell/bundles/basics-old.rb, line 649 def process(buffer, macname, args, lines, depth) p0 = args.is_a?(Array) ? args[0] : nil lines ? lines.delete('') : '' macname = macname.to_sym st = @state[depth] if !@state[depth] st = {:type => macname} @state[depth] = st # erase nested state @state[depth+1] = nil end if macname == :for || macname == :loop p0 = p0 || {} st[:var] = p0['var'] st[:start] = p0['start'] st[:stop] = p0['stop'] st[:step] = p0['step'] || 1 st[:iter] = p0['items'] || 'items' st[:item] = p0['item'] || 'item' st[:counter] = p0['counter'] || 'counter' st[:raw] = p0['raw'] # @todo inherit if not set? st[:collect] = p0['collect'] st[:agg_block] = p0['aggregate_block'] mbuff = [] looper = nil loop_is_map = false # in for, construct range that can be looped over # in loop, detect 'each' method if macname == :for st[:item] = st[:var] looper = Range.new(st[:start], st[:stop]).step(st[:step]).to_a elsif macname == :loop begin looper = st[:iter].is_a?(Array) && st[:iter][0].is_a?(Symbol) ? @proc.expr_eval(st[:iter]) : st[:iter] looper = nil if !looper.respond_to?(:each) loop_is_map = looper.is_a?(Hash) rescue end end collector = [] if looper counter = 0 looper.each do |i1, i2| # for maps, use key as the counter val = nil if loop_is_map @proc.vars[st[:counter]] = i1 val = i2 else val = i1 @proc.vars[st[:counter]] = counter end # inject value into :item -- if it's an expression, evaluate first @proc.vars[st[:item]] = val.is_a?(Array) && val[0].is_a?(Symbol) ? @proc.expr_eval(val) : val # divert lines to collector if st[:collect] lines.each do |_line| if _line.is_a?(String) collector << @proc.expand_expr(_line) elsif _line.is_a?(Eggshell::Block) _line.process(collector) end end else process_lines(lines, buffer, depth + 1, st[:raw]) end break if st[:break] counter += 1 end end # since there are lines here, process collected as an aggregated set of blocks if collector.length > 0 if st[:collect] == 'aggregate' if st[:agg_block] collector.unshift(st[:agg_block]) end process_lines(collector, buffer, depth + 1, false) else buffer << collector.join("\n") end end # clear state @state[depth] = nil elsif macname == :while raw = args[1] while @proc.expr_eval(p0) process_lines(lines, buffer, depth + 1, raw) break if st[:break] end elsif macname == :if || macname == :elsif || macname == :else cond = p0 st[:if] = true if macname == :if if st[:cond_count] == nil || macname == :if st[:cond_count] = 0 st[:cond_eval] = false st[:cond_met] = false end last_action = st[:last_action] st[:last_action] = macname.to_sym # @todo more checks (e.g. no elsif after else, no multiple else, etc.) if !st[:if] || (macname != :else && !cond) # @todo exception? return end if macname != :else if !st[:cond_eval] cond_struct = Eggshell::ExpressionEvaluator.struct(cond) st[:cond_eval] = @proc.expr_eval(cond_struct)[0] end else st[:cond_eval] = true end if st[:cond_eval] && !st[:cond_met] st[:cond_met] = true process_lines(lines, buffer, depth + 1) end elsif macname == :break lvl = p0 || 1 i = depth - 1 # set breaks at each found loop until # of levels reached while i >= 0 st = @state[i] i -= 1 next if !st if st[:type] == :for || st[:type] == :while || st[:type] == :loop lvl -= 1 st[:break] = true break if lvl <= 0 end end elsif macname == :next lvl = p0 || 1 i = depth - 1 # set breaks at each found loop until # of levels reached while i >= 0 st = @state[i] i -= 1 next if !st if st[:type] == :for || st[:type] == :while || st[:type] == :loop lvl -= 1 st[:next] = true break if lvl <= 0 end end end end
set_processor(eggshell)
click to toggle source
# File lib/eggshell/bundles/basics-old.rb, line 644 def set_processor(eggshell) @proc = eggshell @proc.register_macro(self, *%w(if elsif else loop for while break next)) end
Protected Instance Methods
process_lines(lines, buffer, depth, raw = false)
click to toggle source
# File lib/eggshell/bundles/basics-old.rb, line 812 def process_lines(lines, buffer, depth, raw = false) return if !lines ln = [] lines.each do |line| if line.is_a?(Eggshell::Block) if ln.length > 0 buffer << (raw ? @proc.expand_expr(ln.join("\n")) : @proc.process(ln, depth)) ln = [] end line.process(buffer, depth) if @state[depth-1][:next] @state[depth-1][:next] = false break end else ln << line end end if ln.length > 0 buffer << (raw ? @proc.expand_expr(ln.join("\n")) : @proc.process(ln, depth)) end end