1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 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
|
# frozen_string_literal: true
module Temple
# Abstract generator base class
# Generators should inherit this class and
# compile the Core Abstraction to ruby code.
#
# @api public
class Generator
include Utils
include Mixins::CompiledDispatcher
include Mixins::Options
define_options :save_buffer,
capture_generator: 'StringBuffer',
buffer: '_buf',
freeze_static: true
def call(exp)
[preamble, compile(exp), postamble].flatten.compact.join('; ')
end
def preamble
[save_buffer, create_buffer]
end
def postamble
[return_buffer, restore_buffer]
end
def save_buffer
"begin; #{@original_buffer = unique_name} = #{buffer} if defined?(#{buffer})" if options[:save_buffer]
end
def restore_buffer
"ensure; #{buffer} = #{@original_buffer}; end" if options[:save_buffer]
end
def create_buffer
end
def return_buffer
'nil'
end
def on(*exp)
raise InvalidExpression, "Generator supports only core expressions - found #{exp.inspect}"
end
def on_multi(*exp)
exp.map {|e| compile(e) }.join('; '.freeze)
end
def on_newline
"\n"
end
def on_capture(name, exp)
capture_generator.new(capture_generator: options[:capture_generator],
freeze_static: options[:freeze_static],
buffer: name).call(exp)
end
def on_static(text)
concat(options[:freeze_static] ? "#{text.inspect}.freeze" : text.inspect)
end
def on_dynamic(code)
concat(code)
end
def on_code(code)
code
end
protected
def buffer
options[:buffer]
end
def capture_generator
@capture_generator ||= Class === options[:capture_generator] ?
options[:capture_generator] :
Generators.const_get(options[:capture_generator])
end
def concat(str)
"#{buffer} << (#{str})"
end
end
end
|