Skip to content

Commit

Permalink
Generator: Simplify
Browse files Browse the repository at this point in the history
  • Loading branch information
judofyr committed Oct 18, 2010
1 parent 5a9a39d commit 6518e6b
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 46 deletions.
14 changes: 7 additions & 7 deletions lib/temple/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@ def preamble; buffer " = []" end
def postamble; buffer ".join" end

def on_static(text)
to_ruby(text)
concat(to_ruby(text))
end

def on_dynamic(code)
code
concat(code)
end

def on_block(code)
Expand All @@ -98,6 +98,7 @@ def on_block(code)
# Just like ArrayBuffer, but doesn't call #join on the array.
class Array < ArrayBuffer
def postamble; buffer; end
def capture_postamble; end
end

# Implements a string buffer.
Expand All @@ -110,15 +111,14 @@ def postamble; buffer; end
# end
# _buf
class StringBuffer < ArrayBuffer
Generator::DEFAULT_OPTIONS[:capture_generator] = self

def preamble; buffer " = ''" end
def postamble; buffer end
def capture_postamble; end

def on_dynamic(code)
if @options[:check_literal] && Utils.literal_string?(code)
code
else
"(#{code}).to_s"
end
concat(code) + '.to_s'
end
end
end
Expand Down
69 changes: 30 additions & 39 deletions lib/temple/generator.rb
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
module Temple
class Generator
DEFAULT_OPTIONS = {
:buffer => "_buf"
:buffer => "_buf",
# :capture_generator => Temple::Core::StringBuffer
#
# The capture generator is set in the definition of StringBuffer
# in order to avoid circular dependencies.
}

CONCATABLE = [:static, :dynamic]

def initialize(options = {})
@options = DEFAULT_OPTIONS.merge(options)
@in_multi = false
end

def compile(exp)
res = send("on_#{exp.first}", *exp[1..-1])
if @in_multi && CONCATABLE.include?(exp.first)
concat(res)
else
res
end
[preamble, compile_part(exp), postamble].join(' ; ')
end

def compile_part(exp)
type, *args = exp
recv = @in_capture || self
recv.send("on_#{type}", *args)
end

def buffer(str = '')
@options[:buffer] + str
end


def concat(str)
buffer " << (#{str})"
end

def self.to_ruby(str)
str.inspect
end
Expand All @@ -37,42 +42,28 @@ def to_ruby(str)

def preamble; '' end
def postamble; '' end
def concat(s) buffer " << (#{s})" end
def capture_postamble; buffer " = #{postamble}"; end

def on_multi(*exp)
if @in_multi
exp.map { |e| compile(e) }
else
@in_multi = true
content = exp.map { |e| compile(e) }
content = [preamble, content, postamble].flatten
@in_multi = false
content
end.join(" ; ")
exp.map { |e| compile_part(e) }.join(" ; ")
end

def on_newline
"\n"
end

def on_capture(name, block)
unless @in_multi
# We always need the preamble/postamble in capture.
return compile([:multi, [:capture, name, block]])
end

@in_multi = false
prev_buffer, @options[:buffer] = @options[:buffer], name.to_s
content = compile(block)
@in_multi = true

if CONCATABLE.include?(block.first)
"#{name} = #{content}"
else
content
end
before = @capture
@capture = @options[:capture_generator].new(:buffer => name)

[
@capture.preamble,
@capture.compile_part(block),
@capture.capture_postamble
].join(' ; ')
ensure
@options[:buffer] = prev_buffer
@capture = before
end
end
end

0 comments on commit 6518e6b

Please sign in to comment.