rggen 0.4.4 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +3 -2
  4. data/c/rggen.h +17 -0
  5. data/lib/rggen.rb +7 -16
  6. data/lib/rggen/base/item_factory.rb +2 -0
  7. data/lib/rggen/builtins.rb +15 -13
  8. data/lib/rggen/builtins/bit_field/{reserved.rb → types/reserved.rb} +0 -0
  9. data/lib/rggen/builtins/bit_field/{ro.erb → types/ro.erb} +0 -0
  10. data/lib/rggen/builtins/bit_field/{ro.rb → types/ro.rb} +0 -0
  11. data/lib/rggen/builtins/bit_field/{rw.erb → types/rw.erb} +0 -0
  12. data/lib/rggen/builtins/bit_field/{rw.rb → types/rw.rb} +0 -0
  13. data/lib/rggen/builtins/bit_field/{rwl_rwe.erb → types/rwl_rwe.erb} +0 -0
  14. data/lib/rggen/builtins/bit_field/{rwl_rwe.rb → types/rwl_rwe.rb} +0 -0
  15. data/lib/rggen/builtins/bit_field/{w0c_w1c.erb → types/w0c_w1c.erb} +0 -0
  16. data/lib/rggen/builtins/bit_field/{w0c_w1c.rb → types/w0c_w1c.rb} +0 -0
  17. data/lib/rggen/builtins/bit_field/{w0s_w1s.erb → types/w0s_w1s.erb} +0 -0
  18. data/lib/rggen/builtins/bit_field/{w0s_w1s.rb → types/w0s_w1s.rb} +0 -0
  19. data/lib/rggen/builtins/bit_field/{wo.rb → types/wo.rb} +0 -0
  20. data/lib/rggen/builtins/register/address_decoder.erb +9 -9
  21. data/lib/rggen/builtins/register/address_decoder.rb +24 -24
  22. data/lib/rggen/builtins/register/array.rb +0 -22
  23. data/lib/rggen/builtins/register/bus_exporter.rb +10 -2
  24. data/lib/rggen/builtins/register/indirect_index_configurator.rb +54 -0
  25. data/lib/rggen/builtins/register/offset_address.rb +21 -15
  26. data/lib/rggen/builtins/register/read_data.rb +1 -1
  27. data/lib/rggen/builtins/register/reg_model.rb +5 -5
  28. data/lib/rggen/builtins/register/sub_block_model.rb +1 -1
  29. data/lib/rggen/builtins/register/type.rb +207 -0
  30. data/lib/rggen/builtins/register/types/external.rb +15 -0
  31. data/lib/rggen/builtins/register/types/indirect.rb +134 -0
  32. data/lib/rggen/builtins/register/uniqueness_validator.rb +10 -7
  33. data/lib/rggen/builtins/register_block/address_struct.rb +56 -0
  34. data/lib/rggen/builtins/register_block/c_header_file.rb +15 -0
  35. data/lib/rggen/builtins/register_block/{apb.erb → host_ifs/apb.erb} +0 -0
  36. data/lib/rggen/builtins/register_block/{apb.rb → host_ifs/apb.rb} +0 -0
  37. data/lib/rggen/builtins/register_block/{axi4lite.erb → host_ifs/axi4lite.erb} +0 -0
  38. data/lib/rggen/builtins/register_block/{axi4lite.rb → host_ifs/axi4lite.rb} +0 -0
  39. data/lib/rggen/builtins/register_block/ral_package.rb +6 -1
  40. data/lib/rggen/builtins/register_block/response_mux.rb +2 -2
  41. data/lib/rggen/builtins/register_block/top_module.rb +5 -1
  42. data/lib/rggen/core_components.rb +25 -0
  43. data/lib/rggen/core_components/c_header/item.rb +8 -0
  44. data/lib/rggen/core_components/c_header/setup.rb +19 -0
  45. data/lib/rggen/core_components/c_utility.rb +19 -0
  46. data/lib/rggen/core_components/c_utility/data_structure_definition.rb +62 -0
  47. data/lib/rggen/core_components/c_utility/source_file.rb +10 -0
  48. data/lib/rggen/core_components/c_utility/variable_declaration.rb +35 -0
  49. data/lib/rggen/core_components/code_utility.rb +56 -0
  50. data/lib/rggen/{output_base → core_components/code_utility}/code_block.rb +1 -1
  51. data/lib/rggen/{output_base → core_components/code_utility}/line.rb +1 -1
  52. data/lib/rggen/core_components/code_utility/source_file.rb +97 -0
  53. data/lib/rggen/core_components/erb_engine.rb +15 -0
  54. data/lib/rggen/core_components/ral/item.rb +2 -1
  55. data/lib/rggen/core_components/register_map/generic_map.rb +3 -1
  56. data/lib/rggen/core_components/rtl/item.rb +2 -1
  57. data/lib/rggen/core_components/verilog_utility.rb +69 -0
  58. data/lib/rggen/core_components/verilog_utility/class_definition.rb +56 -0
  59. data/lib/rggen/core_components/verilog_utility/declaration.rb +66 -0
  60. data/lib/rggen/core_components/verilog_utility/identifier.rb +27 -0
  61. data/lib/rggen/core_components/verilog_utility/module_definition.rb +71 -0
  62. data/lib/rggen/core_components/verilog_utility/package_definition.rb +65 -0
  63. data/lib/rggen/core_components/verilog_utility/source_file.rb +10 -0
  64. data/lib/rggen/core_components/verilog_utility/structure_definition.rb +50 -0
  65. data/lib/rggen/core_components/verilog_utility/subroutine_definition.rb +41 -0
  66. data/lib/rggen/core_extensions/facets.rb +5 -0
  67. data/lib/rggen/generator.rb +19 -5
  68. data/lib/rggen/input_base/item.rb +6 -6
  69. data/lib/rggen/output_base/code_generator.rb +36 -0
  70. data/lib/rggen/output_base/component.rb +27 -41
  71. data/lib/rggen/output_base/file_writer.rb +36 -0
  72. data/lib/rggen/output_base/item.rb +34 -100
  73. data/lib/rggen/output_base/template_engine.rb +24 -0
  74. data/lib/rggen/rggen_home.rb +3 -0
  75. data/lib/rggen/version.rb +2 -2
  76. data/ral/rggen_ral_block.svh +1 -1
  77. data/ral/rggen_ral_indirect_reg.svh +193 -0
  78. data/ral/rggen_ral_map.svh +20 -20
  79. data/ral/rggen_ral_pkg.sv +1 -1
  80. data/rtl/register/rggen_address_decoder.sv +14 -14
  81. data/sample/sample.csv +21 -22
  82. data/sample/sample.xls +0 -0
  83. data/sample/sample.xlsx +0 -0
  84. data/sample/sample_0.h +17 -0
  85. data/sample/sample_0.sv +92 -92
  86. data/sample/sample_0_ral_pkg.sv +8 -5
  87. data/sample/sample_1.h +9 -0
  88. data/sample/sample_1.sv +27 -27
  89. data/sample/sample_1_ral_pkg.sv +3 -0
  90. data/sample/sample_setup.rb +4 -2
  91. data/setup/default.rb +4 -2
  92. metadata +53 -36
  93. data/lib/rggen/builtins/register/accessibility.rb +0 -23
  94. data/lib/rggen/builtins/register/external.rb +0 -42
  95. data/lib/rggen/builtins/register/shadow.rb +0 -130
  96. data/lib/rggen/builtins/register/shadow_index_configurator.rb +0 -56
  97. data/lib/rggen/output_base/code_utility.rb +0 -50
  98. data/lib/rggen/output_base/template_utility.rb +0 -29
  99. data/lib/rggen/output_base/verilog_utility.rb +0 -69
  100. data/lib/rggen/output_base/verilog_utility/class_definition.rb +0 -58
  101. data/lib/rggen/output_base/verilog_utility/declaration.rb +0 -68
  102. data/lib/rggen/output_base/verilog_utility/identifier.rb +0 -29
  103. data/lib/rggen/output_base/verilog_utility/module_definition.rb +0 -73
  104. data/lib/rggen/output_base/verilog_utility/package_definition.rb +0 -67
  105. data/lib/rggen/output_base/verilog_utility/structure_definition.rb +0 -52
  106. data/lib/rggen/output_base/verilog_utility/subroutine_definition.rb +0 -43
  107. data/ral/rggen_ral_shadow_reg.svh +0 -193
@@ -0,0 +1,41 @@
1
+ module RgGen
2
+ module VerilogUtility
3
+ class SubroutineDefinition < StructureDefinition
4
+ def initialize(type, name, &body)
5
+ @type = type
6
+ super(name, &body)
7
+ end
8
+
9
+ def return_type(data_type_and_width)
10
+ if [Symbol, String].any?(&data_type_and_width.method(:is_a?))
11
+ @return_type = data_type_and_width
12
+ else
13
+ data_type = data_type_and_width[:data_type]
14
+ width = data_type_and_width[:width ] || 1
15
+ @return_type =
16
+ ((width > 1) && "#{data_type} [#{width - 1}:0]") || data_type
17
+ end
18
+ end
19
+
20
+ attr_setter :arguments
21
+
22
+ private
23
+
24
+ def function?
25
+ @type == :function
26
+ end
27
+
28
+ def header_code
29
+ [
30
+ (function? && :function ) || :task,
31
+ (function? && @return_type) || nil,
32
+ "#{@name}(#{Array(@arguments).join(', ')});"
33
+ ].compact.join(' ')
34
+ end
35
+
36
+ def footer_code
37
+ (function? && :endfunction) || :endtask
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,4 +1,5 @@
1
1
  require 'facets/enumerable/exclude'
2
+ require 'facets/enumerable/find_yield'
2
3
  require 'facets/enumerable/sum'
3
4
  require 'facets/file/ext'
4
5
  require 'facets/hash/symbolize_keys'
@@ -6,9 +7,13 @@ require 'facets/integer/multiple'
6
7
  require 'facets/kernel/attr_singleton'
7
8
  require 'facets/kernel/not'
8
9
  require 'facets/kernel/not_nil'
10
+ require 'facets/method/curry' unless Method.public_method_defined?(:curry)
11
+ require 'facets/module/attr_class_accessor'
9
12
  require 'facets/module/attr_setter'
10
13
  require 'facets/numeric/positive'
11
14
  require 'facets/object/itself' unless Object.public_method_defined?(:itself)
15
+ require 'facets/pathname/to_path'
16
+ require 'facets/pathname/to_str'
12
17
  require 'facets/range/overlap'
13
18
  require 'facets/regexp/op_add'
14
19
  require 'facets/regexp/op_or'
@@ -20,7 +20,7 @@ module RgGen
20
20
  attr_writer :body
21
21
 
22
22
  def on(parser, options)
23
- options[@kind] = @default if @default
23
+ options[@kind] = default_value if default_value
24
24
  parser.on(*args) do |value|
25
25
  parser.instance_exec(value, options, @kind, &body)
26
26
  end
@@ -31,10 +31,10 @@ module RgGen
31
31
  end
32
32
 
33
33
  def description
34
- return nil unless @description || @default
34
+ return nil unless @description || default_value
35
35
  d = ''
36
36
  d << @description.to_s
37
- d << "(default: #{@default})" if @default
37
+ d << "(default: #{default_value})" if default_value
38
38
  d
39
39
  end
40
40
 
@@ -47,6 +47,16 @@ module RgGen
47
47
  options[kind] = value
48
48
  end
49
49
  end
50
+
51
+ def default_value
52
+ return unless @default
53
+ case @default
54
+ when Proc
55
+ @default.call
56
+ else
57
+ @default
58
+ end
59
+ end
50
60
  end
51
61
 
52
62
  class << self
@@ -64,13 +74,17 @@ module RgGen
64
74
 
65
75
  add_option :setup do |option|
66
76
  option.long = '--setup FILE'
67
- option.default = File.join(RGGEN_HOME, 'setup', 'default.rb')
77
+ option.default = proc do
78
+ ENV['RGGEN_DEFAULT_SETUP_FILE'] ||
79
+ File.join(RGGEN_HOME, 'setup', 'default.rb')
80
+ end
68
81
  option.description = 'Specify a setup file to set up RgGen tool'
69
82
  end
70
83
 
71
84
  add_option :configuration do |option|
72
85
  option.short = '-c'
73
86
  option.long = '--configuration FILE'
87
+ option.default = proc { ENV['RGGEN_DEFAULT_CONFIGURATION_FILE'] }
74
88
  option.description = 'Specify a configuration file ' \
75
89
  'for generated source code'
76
90
  end
@@ -78,7 +92,7 @@ module RgGen
78
92
  add_option :output do |option|
79
93
  option.short = '-o'
80
94
  option.long = '--output DIR'
81
- option.default = './'
95
+ option.default = '.'
82
96
  option.description = 'Specify output directory'
83
97
  end
84
98
 
@@ -53,8 +53,8 @@ module RgGen
53
53
  def field(field_name, options = {}, &body)
54
54
  return if fields.include?(field_name)
55
55
 
56
- define_method(field_name) do
57
- field_method(field_name, options, body)
56
+ define_method(field_name) do |*args, &block|
57
+ field_method(field_name, options, body, args, block)
58
58
  end
59
59
 
60
60
  fields << field_name
@@ -139,14 +139,14 @@ module RgGen
139
139
  input_matcher && input_matcher.match_automatically?
140
140
  end
141
141
 
142
- def field_method(field_name, options, body)
142
+ def field_method(field_name, options, body, args, block)
143
143
  validate if options[:need_validation]
144
144
  if body
145
- instance_exec(&body)
145
+ instance_exec(*args, &body)
146
146
  elsif options[:forward_to_helper]
147
- self.class.__send__(field_name)
147
+ self.class.__send__(field_name, *args, &block)
148
148
  elsif options.key?(:forward_to)
149
- __send__(options[:forward_to])
149
+ __send__(options[:forward_to], *args, &block)
150
150
  else
151
151
  default_field_method(field_name, options[:default])
152
152
  end
@@ -0,0 +1,36 @@
1
+ module RgGen
2
+ module OutputBase
3
+ class CodeGenerator
4
+ def []=(kind, body)
5
+ (@bodies ||= {})[kind] = body
6
+ end
7
+
8
+ def generate_code(context, kind, code)
9
+ return code unless body?(kind)
10
+ (code || context.create_blank_code).tap do |c|
11
+ execute_body(context, kind, c)
12
+ end
13
+ end
14
+
15
+ def copy
16
+ CodeGenerator.new.tap do |g|
17
+ g.instance_variable_set(:@bodies, Hash[@bodies]) if @bodies
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def body?(kind)
24
+ @bodies && @bodies.key?(kind)
25
+ end
26
+
27
+ def execute_body(context, kind, code)
28
+ if @bodies[kind].arity.zero?
29
+ code << context.instance_exec(&@bodies[kind])
30
+ else
31
+ context.instance_exec(code, &@bodies[kind])
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -26,64 +26,50 @@ module RgGen
26
26
  children.each(&:build)
27
27
  end
28
28
 
29
- def generate_code(kind, mode, buffer = nil)
30
- buffer ||= CodeBlock.new
31
- generate_pre_code(kind, buffer)
32
- generate_main_code(kind, mode, buffer)
33
- generate_post_code(kind, buffer)
34
- buffer
29
+ def generate_code(kind, mode, code = nil)
30
+ [
31
+ pre_code_generator, *main_code_generator(mode), post_code_generator
32
+ ].inject(code) { |c, g| g.call(kind, mode, c) }
35
33
  end
36
34
 
37
- def write_file(root_directory)
38
- directory = output_directory(root_directory)
39
- FileUtils.mkpath(directory) unless Dir.exist?(directory)
40
- items.each do |item|
41
- item.write_file(directory)
42
- end
43
- children.each do |child|
44
- child.write_file(directory)
35
+ def write_file(output_directory)
36
+ directoris = [*Array(output_directory), @output_directory].compact
37
+ [*items, *children].each do |item_or_child|
38
+ item_or_child.write_file(directoris)
45
39
  end
46
40
  end
47
41
 
48
42
  private
49
43
 
50
- def generate_pre_code(kind, buffer)
51
- items.each do |item|
52
- item.generate_pre_code(kind, buffer)
53
- end
54
- end
55
-
56
- def generate_main_code(kind, mode, buffer)
57
- case mode
58
- when :top_down
59
- generate_item_code(kind, buffer)
60
- generate_child_code(kind, mode, buffer)
61
- when :bottom_up
62
- generate_child_code(kind, mode, buffer)
63
- generate_item_code(kind, buffer)
44
+ def generate_item_code(method_name, kind, _, code)
45
+ items.inject(code) do |c, item|
46
+ item.send(method_name, kind, c)
64
47
  end
65
48
  end
66
49
 
67
- def generate_child_code(kind, mode, buffer)
68
- children.each do |child|
69
- child.generate_code(kind, mode, buffer)
50
+ def generate_child_code(kind, mode, code)
51
+ children.inject(code) do |c, child|
52
+ child.generate_code(kind, mode, code)
70
53
  end
71
54
  end
72
55
 
73
- def generate_item_code(kind, buffer)
74
- items.each do |item|
75
- item.generate_code(kind, buffer)
76
- end
56
+ def pre_code_generator
57
+ method(:generate_item_code).curry[:generate_pre_code]
77
58
  end
78
59
 
79
- def generate_post_code(kind, buffer)
80
- items.reverse_each do |item|
81
- item.generate_post_code(kind, buffer)
82
- end
60
+ def main_code_generator(mode)
61
+ return [
62
+ method(:generate_item_code ).curry[:generate_code],
63
+ method(:generate_child_code)
64
+ ] if mode == :top_down
65
+ return [
66
+ method(:generate_child_code),
67
+ method(:generate_item_code ).curry[:generate_code]
68
+ ] if mode == :bottom_up
83
69
  end
84
70
 
85
- def output_directory(root_directory)
86
- File.join([root_directory, @output_directory.to_s].reject(&:empty?))
71
+ def post_code_generator
72
+ method(:generate_item_code).curry[:generate_post_code]
87
73
  end
88
74
  end
89
75
  end
@@ -0,0 +1,36 @@
1
+ module RgGen
2
+ module OutputBase
3
+ class FileWriter
4
+ def initialize(pattern, body)
5
+ @pattern = BabyErubis::Text.new.from_str(pattern)
6
+ @body = body
7
+ end
8
+
9
+ def write_file(context, output_directory = nil)
10
+ path = generate_path(context, output_directory)
11
+ code = generate_code(context, path)
12
+ create_output_directory(path)
13
+ File.binwrite(path, code)
14
+ end
15
+
16
+ private
17
+
18
+ def generate_path(context, output_directory)
19
+ [
20
+ *Array(output_directory), @pattern.render(context)
21
+ ].map(&:to_s).reject(&:empty?).to_path
22
+ end
23
+
24
+ def generate_code(context, path)
25
+ context.create_blank_file(path).tap do |file|
26
+ context.instance_exec(file, &@body)
27
+ end
28
+ end
29
+
30
+ def create_output_directory(path)
31
+ dirname = path.dirname
32
+ dirname.directory? || dirname.mkpath
33
+ end
34
+ end
35
+ end
36
+ end
@@ -2,100 +2,41 @@ module RgGen
2
2
  module OutputBase
3
3
  class Item < Base::Item
4
4
  include Base::HierarchicalItemAccessors
5
- include CodeUtility
6
- include TemplateUtility
7
5
 
8
- class CodeGenerator
9
- def []=(kind, body)
10
- @bodies ||= {}
11
- @bodies[kind] = body
12
- end
13
-
14
- def generate_code(item, kind, buffer)
15
- return unless @bodies && @bodies.key?(kind)
16
- if @bodies[kind].arity.zero?
17
- buffer << item.instance_exec(&@bodies[kind])
18
- else
19
- item.instance_exec(buffer, &@bodies[kind])
20
- end
21
- end
22
-
23
- def copy
24
- CodeGenerator.new.tap do |g|
25
- g.instance_variable_set(:@bodies, Hash[@bodies]) if @bodies
26
- end
27
- end
28
- end
29
-
30
- class FileWriter
31
- def initialize(name_pattern, body)
32
- @name_pattern = BabyErubis::Text.new.from_str(name_pattern)
33
- @body = body
34
- end
35
-
36
- def write_file(item, outptu_directory)
37
- code = generate_code(item)
38
- path = file_path(item, outptu_directory)
39
- File.write(path, code, nil, binmode: true)
40
- end
41
-
42
- private
43
-
44
- def generate_code(item)
45
- code = CodeBlock.new.tap do |c|
46
- if @body.arity.zero?
47
- c << item.instance_exec(&@body)
48
- else
49
- item.instance_exec(c, &@body)
50
- end
51
- end
52
- code.to_s
53
- end
54
-
55
- def file_path(item, outptu_directory)
56
- path = [outptu_directory, file_name(item)].reject(&:empty?)
57
- File.join(*path)
58
- end
59
-
60
- def file_name(item)
61
- @name_pattern.render(item)
62
- end
63
- end
6
+ CODE_GENERATION_METHODS = {
7
+ pre: :generate_pre_code,
8
+ main: :generate_code,
9
+ post: :generate_post_code
10
+ }
64
11
 
65
12
  define_helpers do
66
13
  attr_reader :builders
67
- attr_reader :pre_code_generator
68
- attr_reader :code_generator
69
- attr_reader :post_code_generator
70
14
  attr_reader :file_writer
71
15
 
72
- def use_verilog_utility
73
- include VerilogUtility
74
- end
75
-
76
16
  def build(&body)
77
17
  @builders ||= []
78
18
  @builders << body
79
19
  end
80
20
 
81
- def generate_pre_code(kind, &body)
82
- @pre_code_generator ||= CodeGenerator.new
83
- @pre_code_generator[kind] = body
21
+ def template_engine(engine)
22
+ define_method(:template_engine) { engine.instance }
84
23
  end
85
24
 
86
- def generate_code(kind, &body)
87
- @code_generator ||= CodeGenerator.new
88
- @code_generator[kind] = body
25
+ def code_generators
26
+ @code_generators ||= {}
89
27
  end
90
28
 
91
- def generate_code_from_template(kind, path = nil)
92
- path ||= File.ext(caller.first[/^(.+?):\d/, 1], 'erb')
93
- generate_code(kind) { process_template(path) }
29
+ CODE_GENERATION_METHODS.each do |type, method_name|
30
+ define_method(method_name) do |kind, &body|
31
+ (code_generators[type] ||= CodeGenerator.new)[kind] = body
32
+ end
94
33
  end
95
34
 
96
- def generate_post_code(kind, &body)
97
- @post_code_generator ||= CodeGenerator.new
98
- @post_code_generator[kind] = body
35
+ def generate_code_from_template(kind, path = nil)
36
+ call_info = caller.first
37
+ generate_code(kind) do
38
+ template_engine.process_template(self, path, call_info)
39
+ end
99
40
  end
100
41
 
101
42
  def write_file(name_pattern, &body)
@@ -118,12 +59,11 @@ module RgGen
118
59
  [:@builders, :@exported_methods].each do |v|
119
60
  subclass.inherit_class_instance_variable(v, self, &:dup)
120
61
  end
121
- [
122
- :@pre_code_generator,
123
- :@code_generator,
124
- :@post_code_generator
125
- ].each do |v|
126
- subclass.inherit_class_instance_variable(v, self, &:copy)
62
+ if @code_generators && @code_generators.size > 0
63
+ subclass.instance_variable_set(
64
+ :@code_generators,
65
+ Hash[*@code_generators.flat_map { |k, g| [k, g.copy] }]
66
+ )
127
67
  end
128
68
  end
129
69
 
@@ -133,10 +73,8 @@ module RgGen
133
73
  end
134
74
 
135
75
  class_delegator :builders
136
- class_delegator :pre_code_generator
137
- class_delegator :code_generator
76
+ class_delegator :code_generators
138
77
  class_delegator :file_writer
139
- class_delegator :post_code_generator
140
78
  class_delegator :exported_methods
141
79
 
142
80
  def build
@@ -146,28 +84,24 @@ module RgGen
146
84
  end
147
85
  end
148
86
 
149
- def generate_pre_code(kind, buffer)
150
- return if pre_code_generator.nil?
151
- pre_code_generator.generate_code(self, kind, buffer)
152
- end
153
-
154
- def generate_code(kind, buffer)
155
- return if code_generator.nil?
156
- code_generator.generate_code(self, kind, buffer)
157
- end
158
-
159
- def generate_post_code(kind, buffer)
160
- return if post_code_generator.nil?
161
- post_code_generator.generate_code(self, kind, buffer)
87
+ CODE_GENERATION_METHODS.each do |type, method_name|
88
+ define_method(method_name) do |kind, code|
89
+ return code unless code_generators.key?(type)
90
+ code_generators[type].generate_code(self, kind, code)
91
+ end
162
92
  end
163
93
 
164
- def write_file(output_directory = '')
94
+ def write_file(output_directory = nil)
165
95
  return if file_writer.nil?
166
96
  file_writer.write_file(self, output_directory)
167
97
  end
168
98
 
169
99
  private
170
100
 
101
+ def process_template(path = nil)
102
+ template_engine.process_template(self, path, caller.first)
103
+ end
104
+
171
105
  def configuration
172
106
  @owner.configuration
173
107
  end