rggen 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +7 -0
  3. data/.rubocop_todo.yml +91 -0
  4. data/CODE_OF_CONDUCT.md +49 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +31 -0
  7. data/bin/rggen +6 -0
  8. data/lib/rggen/base/component.rb +27 -0
  9. data/lib/rggen/base/component_factory.rb +46 -0
  10. data/lib/rggen/base/hierarchical_accessors.rb +87 -0
  11. data/lib/rggen/base/hierarchical_item_accessors.rb +79 -0
  12. data/lib/rggen/base/item.rb +24 -0
  13. data/lib/rggen/base/item_factory.rb +20 -0
  14. data/lib/rggen/builder/builder.rb +69 -0
  15. data/lib/rggen/builder/category.rb +52 -0
  16. data/lib/rggen/builder/component_entry.rb +50 -0
  17. data/lib/rggen/builder/component_store.rb +42 -0
  18. data/lib/rggen/builder/input_component_store.rb +25 -0
  19. data/lib/rggen/builder/item_store.rb +89 -0
  20. data/lib/rggen/builder/list_item_entry.rb +81 -0
  21. data/lib/rggen/builder/output_component_store.rb +13 -0
  22. data/lib/rggen/builder/simple_item_entry.rb +33 -0
  23. data/lib/rggen/builtins/bit_field/bit_assignment.rb +39 -0
  24. data/lib/rggen/builtins/bit_field/field_model_creation.rb +25 -0
  25. data/lib/rggen/builtins/bit_field/field_model_declaration.rb +9 -0
  26. data/lib/rggen/builtins/bit_field/initial_value.rb +36 -0
  27. data/lib/rggen/builtins/bit_field/name.rb +26 -0
  28. data/lib/rggen/builtins/bit_field/reference.rb +42 -0
  29. data/lib/rggen/builtins/bit_field/reserved.rb +9 -0
  30. data/lib/rggen/builtins/bit_field/ro.rb +19 -0
  31. data/lib/rggen/builtins/bit_field/rw.erb +13 -0
  32. data/lib/rggen/builtins/bit_field/rw.rb +25 -0
  33. data/lib/rggen/builtins/bit_field/type.rb +205 -0
  34. data/lib/rggen/builtins/bit_field/wo.rb +5 -0
  35. data/lib/rggen/builtins/global/address_width.rb +17 -0
  36. data/lib/rggen/builtins/global/data_width.rb +20 -0
  37. data/lib/rggen/builtins/loaders/configuration/json_loader.rb +7 -0
  38. data/lib/rggen/builtins/loaders/configuration/yaml_loader.rb +7 -0
  39. data/lib/rggen/builtins/loaders/register_map/csv_loader.rb +14 -0
  40. data/lib/rggen/builtins/loaders/register_map/xls_loader.rb +19 -0
  41. data/lib/rggen/builtins/loaders/register_map/xlsx_ods_loader.rb +24 -0
  42. data/lib/rggen/builtins/register/accessibility.rb +23 -0
  43. data/lib/rggen/builtins/register/address_decoder.erb +16 -0
  44. data/lib/rggen/builtins/register/address_decoder.rb +92 -0
  45. data/lib/rggen/builtins/register/array.rb +133 -0
  46. data/lib/rggen/builtins/register/field_model_creator.rb +10 -0
  47. data/lib/rggen/builtins/register/field_model_declarations.rb +7 -0
  48. data/lib/rggen/builtins/register/name.rb +26 -0
  49. data/lib/rggen/builtins/register/offset_address.rb +55 -0
  50. data/lib/rggen/builtins/register/read_data.rb +36 -0
  51. data/lib/rggen/builtins/register/reg_model_constructor.rb +17 -0
  52. data/lib/rggen/builtins/register/reg_model_creation.rb +64 -0
  53. data/lib/rggen/builtins/register/reg_model_declaration.rb +13 -0
  54. data/lib/rggen/builtins/register/reg_model_definition.rb +22 -0
  55. data/lib/rggen/builtins/register/shadow.rb +130 -0
  56. data/lib/rggen/builtins/register/shadow_index_configurator.rb +53 -0
  57. data/lib/rggen/builtins/register/uniqueness_validator.rb +48 -0
  58. data/lib/rggen/builtins/register_block/apb.erb +27 -0
  59. data/lib/rggen/builtins/register_block/apb.rb +20 -0
  60. data/lib/rggen/builtins/register_block/base_address.rb +64 -0
  61. data/lib/rggen/builtins/register_block/block_model_constructor.rb +14 -0
  62. data/lib/rggen/builtins/register_block/block_model_default_map_creator.rb +39 -0
  63. data/lib/rggen/builtins/register_block/block_model_definition.rb +18 -0
  64. data/lib/rggen/builtins/register_block/byte_size.rb +37 -0
  65. data/lib/rggen/builtins/register_block/clock_reset.rb +8 -0
  66. data/lib/rggen/builtins/register_block/host_if.rb +46 -0
  67. data/lib/rggen/builtins/register_block/module_definition.rb +13 -0
  68. data/lib/rggen/builtins/register_block/name.rb +26 -0
  69. data/lib/rggen/builtins/register_block/ral_package_definition.rb +19 -0
  70. data/lib/rggen/builtins/register_block/reg_model_creator.rb +14 -0
  71. data/lib/rggen/builtins/register_block/reg_model_declarations.rb +7 -0
  72. data/lib/rggen/builtins/register_block/response_mux.erb +14 -0
  73. data/lib/rggen/builtins/register_block/response_mux.rb +16 -0
  74. data/lib/rggen/builtins/register_block/signal_declarations.rb +9 -0
  75. data/lib/rggen/builtins.rb +52 -0
  76. data/lib/rggen/commands.rb +23 -0
  77. data/lib/rggen/core_components/configuration/configuration_factory.rb +23 -0
  78. data/lib/rggen/core_components/configuration/item_factory.rb +13 -0
  79. data/lib/rggen/core_components/configuration/raise_error.rb +11 -0
  80. data/lib/rggen/core_components/configuration/setup.rb +14 -0
  81. data/lib/rggen/core_components/ral/item.rb +16 -0
  82. data/lib/rggen/core_components/ral/setup.rb +19 -0
  83. data/lib/rggen/core_components/register_map/bit_field_factory.rb +11 -0
  84. data/lib/rggen/core_components/register_map/component.rb +12 -0
  85. data/lib/rggen/core_components/register_map/generic_map.rb +69 -0
  86. data/lib/rggen/core_components/register_map/item.rb +22 -0
  87. data/lib/rggen/core_components/register_map/item_factory.rb +13 -0
  88. data/lib/rggen/core_components/register_map/loader.rb +13 -0
  89. data/lib/rggen/core_components/register_map/raise_error.rb +17 -0
  90. data/lib/rggen/core_components/register_map/register_block_factory.rb +29 -0
  91. data/lib/rggen/core_components/register_map/register_factory.rb +18 -0
  92. data/lib/rggen/core_components/register_map/register_map_factory.rb +21 -0
  93. data/lib/rggen/core_components/register_map/setup.rb +33 -0
  94. data/lib/rggen/core_components/rtl/component.rb +28 -0
  95. data/lib/rggen/core_components/rtl/item.rb +83 -0
  96. data/lib/rggen/core_components/rtl/setup.rb +19 -0
  97. data/lib/rggen/core_components.rb +23 -0
  98. data/lib/rggen/core_extensions/facets.rb +17 -0
  99. data/lib/rggen/core_extensions/forwardable.rb +26 -0
  100. data/lib/rggen/core_extensions/integer.rb +5 -0
  101. data/lib/rggen/core_extensions/math.rb +7 -0
  102. data/lib/rggen/exceptions.rb +22 -0
  103. data/lib/rggen/generator.rb +185 -0
  104. data/lib/rggen/input_base/component.rb +19 -0
  105. data/lib/rggen/input_base/component_factory.rb +58 -0
  106. data/lib/rggen/input_base/item.rb +170 -0
  107. data/lib/rggen/input_base/item_factory.rb +13 -0
  108. data/lib/rggen/input_base/loader.rb +14 -0
  109. data/lib/rggen/input_base/regexp_patterns.rb +29 -0
  110. data/lib/rggen/output_base/code_block.rb +72 -0
  111. data/lib/rggen/output_base/code_utility.rb +44 -0
  112. data/lib/rggen/output_base/component.rb +88 -0
  113. data/lib/rggen/output_base/component_factory.rb +32 -0
  114. data/lib/rggen/output_base/item.rb +175 -0
  115. data/lib/rggen/output_base/item_factory.rb +6 -0
  116. data/lib/rggen/output_base/line.rb +28 -0
  117. data/lib/rggen/output_base/template_utility.rb +29 -0
  118. data/lib/rggen/output_base/verilog_utility/class_definition.rb +23 -0
  119. data/lib/rggen/output_base/verilog_utility/declaration.rb +70 -0
  120. data/lib/rggen/output_base/verilog_utility/identifier.rb +29 -0
  121. data/lib/rggen/output_base/verilog_utility/module_definition.rb +47 -0
  122. data/lib/rggen/output_base/verilog_utility/package_definition.rb +67 -0
  123. data/lib/rggen/output_base/verilog_utility/structure_definition.rb +52 -0
  124. data/lib/rggen/output_base/verilog_utility/subroutine_definition.rb +43 -0
  125. data/lib/rggen/output_base/verilog_utility.rb +66 -0
  126. data/lib/rggen/version.rb +6 -0
  127. data/lib/rggen.rb +65 -0
  128. data/ral/compile.f +4 -0
  129. data/ral/rggen_ral_block.svh +84 -0
  130. data/ral/rggen_ral_field.svh +47 -0
  131. data/ral/rggen_ral_macros.svh +22 -0
  132. data/ral/rggen_ral_map.svh +124 -0
  133. data/ral/rggen_ral_pkg.sv +14 -0
  134. data/ral/rggen_ral_reg.svh +52 -0
  135. data/ral/rggen_ral_shadow_reg.svh +188 -0
  136. data/rggen.gemspec +45 -0
  137. data/rtl/bit_field/rggen_bit_field_rw.sv +28 -0
  138. data/rtl/register/rggen_address_decoder.sv +49 -0
  139. data/rtl/register_block/rggen_host_if_apb.sv +40 -0
  140. data/rtl/register_block/rggen_response_mux.sv +82 -0
  141. data/sample/sample.csv +14 -0
  142. data/sample/sample.json +4 -0
  143. data/sample/sample.xls +0 -0
  144. data/sample/sample.xlsx +0 -0
  145. data/sample/sample.yaml +2 -0
  146. data/sample/sample_0.sv +285 -0
  147. data/sample/sample_0_ral_pkg.sv +99 -0
  148. data/sample/sample_1.sv +172 -0
  149. data/sample/sample_1_ral_pkg.sv +53 -0
  150. data/sample/sample_setup.rb +21 -0
  151. data/setup/default.rb +11 -0
  152. metadata +296 -0
@@ -0,0 +1,83 @@
1
+ module RgGen
2
+ module RTL
3
+ class Item < OutputBase::Item
4
+ use_verilog_utility
5
+
6
+ def initialize(owner)
7
+ super(owner)
8
+ @identifiers = []
9
+ @signal_declarations = []
10
+ @port_declarations = []
11
+ @parameter_declarations = []
12
+ @localparam_declarations = []
13
+ end
14
+
15
+ attr_reader :identifiers
16
+ attr_reader :signal_declarations
17
+ attr_reader :port_declarations
18
+ attr_reader :parameter_declarations
19
+ attr_reader :localparam_declarations
20
+
21
+ private
22
+
23
+ class << self
24
+ private
25
+
26
+ def define_declaration_method(method_name)
27
+ define_method(method_name) do |handle_name, attributes = {}|
28
+ attributes[:name] ||= handle_name.to_s
29
+ add_identifier(handle_name, attributes[:name])
30
+ add_declaration(method_name, attributes)
31
+ end
32
+ private method_name
33
+ end
34
+ end
35
+
36
+ define_declaration_method :wire
37
+ define_declaration_method :reg
38
+ define_declaration_method :logic
39
+ define_declaration_method :input
40
+ define_declaration_method :output
41
+ define_declaration_method :parameter
42
+ define_declaration_method :localparam
43
+
44
+ def group(group_name, &body)
45
+ create_group(group_name)
46
+ instance_exec(&body)
47
+ @group = nil
48
+ end
49
+
50
+ def add_declaration(type, attributes)
51
+ attribute_key, declaration_type, declarations =
52
+ case type
53
+ when :wire, :reg, :logic
54
+ [:data_type, :variable, signal_declarations]
55
+ when :input, :output
56
+ [:direction, :port, port_declarations]
57
+ when :parameter
58
+ [:parameter_type, :parameter, parameter_declarations]
59
+ when :localparam
60
+ [:parameter_type, :parameter, localparam_declarations]
61
+ end
62
+ attributes[attribute_key] = type
63
+ declarations << create_declaration(declaration_type, attributes)
64
+ end
65
+
66
+ def add_identifier(handle_name, name)
67
+ identifier = create_identifier(name)
68
+ (@group || self).instance_exec do
69
+ instance_variable_set(handle_name.variablize, identifier)
70
+ attr_singleton_reader(handle_name)
71
+ end
72
+ identifiers << handle_name if @group.nil?
73
+ end
74
+
75
+ def create_group(group_name)
76
+ instance_variable_set(group_name.variablize, Object.new)
77
+ attr_singleton_reader(group_name)
78
+ identifiers << group_name
79
+ @group = __send__(group_name)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,19 @@
1
+ module RgGen
2
+ module RTL
3
+ output_component_store :rtl do
4
+ entry do
5
+ component_class OutputBase::Component
6
+ component_factory OutputBase::ComponentFactory
7
+ end
8
+
9
+ entry [:register_block, :register, :bit_field] do
10
+ component_class Component
11
+ component_factory OutputBase::ComponentFactory
12
+ item_base Item
13
+ item_factory OutputBase::ItemFactory
14
+ end
15
+
16
+ output_directory 'rtl'
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'core_components/configuration/raise_error'
2
+ require_relative 'core_components/configuration/configuration_factory'
3
+ require_relative 'core_components/configuration/item_factory'
4
+ require_relative 'core_components/configuration/setup'
5
+
6
+ require_relative 'core_components/register_map/generic_map'
7
+ require_relative 'core_components/register_map/loader'
8
+ require_relative 'core_components/register_map/raise_error'
9
+ require_relative 'core_components/register_map/component'
10
+ require_relative 'core_components/register_map/item'
11
+ require_relative 'core_components/register_map/register_map_factory'
12
+ require_relative 'core_components/register_map/register_block_factory'
13
+ require_relative 'core_components/register_map/register_factory'
14
+ require_relative 'core_components/register_map/bit_field_factory'
15
+ require_relative 'core_components/register_map/item_factory'
16
+ require_relative 'core_components/register_map/setup'
17
+
18
+ require_relative 'core_components/rtl/component'
19
+ require_relative 'core_components/rtl/item'
20
+ require_relative 'core_components/rtl/setup'
21
+
22
+ require_relative 'core_components/ral/item'
23
+ require_relative 'core_components/ral/setup'
@@ -0,0 +1,17 @@
1
+ require 'facets/enumerable/exclude'
2
+ require 'facets/enumerable/sum'
3
+ require 'facets/file/ext'
4
+ require 'facets/hash/symbolize_keys'
5
+ require 'facets/integer/multiple'
6
+ require 'facets/kernel/attr_singleton'
7
+ require 'facets/kernel/not'
8
+ require 'facets/kernel/not_nil'
9
+ require 'facets/module/attr_setter'
10
+ require 'facets/numeric/positive'
11
+ require 'facets/range/overlap'
12
+ require 'facets/regexp/op_add'
13
+ require 'facets/regexp/op_or'
14
+ require 'facets/string/indent'
15
+ require 'facets/string/quote'
16
+ require 'facets/string/variablize'
17
+ require 'facets/symbol/variablize'
@@ -0,0 +1,26 @@
1
+ module Forwardable
2
+ def def_class_delegator(method, ali = method)
3
+ def_delegator('self.class', method, ali)
4
+ end
5
+
6
+ def def_class_delegators(*methods)
7
+ def_instance_delegators('self.class', *methods)
8
+ end
9
+
10
+ alias_method :class_delegator , :def_class_delegator
11
+ alias_method :class_delegators, :def_class_delegators
12
+ end
13
+
14
+ module SingleForwardable
15
+ def def_object_delegator(target, method, ali = method)
16
+ define_singleton_method(ali) do |*args, &block|
17
+ target.__send__(method, *args, &block)
18
+ end
19
+ end
20
+
21
+ def def_object_delegators(target, *methods)
22
+ methods.each do |method|
23
+ def_object_delegator(target, method)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ class Integer
2
+ def pow2?
3
+ positive? && (ord & pred).zero?
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ module Math
2
+ module_function
3
+
4
+ def clog2(value)
5
+ Math.log2(value).ceil
6
+ end
7
+ end
@@ -0,0 +1,22 @@
1
+ module RgGen
2
+ class RgGenError < StandardError
3
+ end
4
+
5
+ class BuilderError < RgGenError
6
+ end
7
+
8
+ class LoadError < RgGenError
9
+ end
10
+
11
+ class ConfigurationError < RgGenError
12
+ end
13
+
14
+ class RegisterMapError < RgGenError
15
+ def initialize(message, position)
16
+ super(message)
17
+ @position = position
18
+ end
19
+
20
+ attr_reader :position
21
+ end
22
+ end
@@ -0,0 +1,185 @@
1
+ module RgGen
2
+ class Generator
3
+ Context = Struct.new(:options, :configuration, :register_map) do
4
+ def initialize
5
+ super
6
+ self.options = {}
7
+ end
8
+ end
9
+
10
+ class Option
11
+ def initialize(kind)
12
+ @kind = kind
13
+ end
14
+
15
+ attr_accessor :short
16
+ attr_accessor :long
17
+ attr_accessor :class
18
+ attr_writer :default
19
+ attr_writer :description
20
+ attr_writer :body
21
+
22
+ def on(parser, options)
23
+ options[@kind] = @default if @default
24
+ parser.on(*args) do |value|
25
+ parser.instance_exec(value, options, @kind, &body)
26
+ end
27
+ end
28
+
29
+ def args
30
+ [@short, @long, @class, description].compact
31
+ end
32
+
33
+ def description
34
+ return nil unless @description || @default
35
+ d = ''
36
+ d << @description.to_s
37
+ d << "(default: #{@default})" if @default
38
+ d
39
+ end
40
+
41
+ def body
42
+ @body || default_body
43
+ end
44
+
45
+ def default_body
46
+ proc do |value, options, kind|
47
+ options[kind] = value
48
+ end
49
+ end
50
+ end
51
+
52
+ class << self
53
+ def options
54
+ @options ||= []
55
+ end
56
+
57
+ private
58
+
59
+ def add_option(kind, &body)
60
+ options << Option.new(kind)
61
+ body.call(options.last)
62
+ end
63
+ end
64
+
65
+ add_option :setup do |option|
66
+ option.long = '--setup FILE'
67
+ option.default = File.join(RGGEN_HOME, 'setup', 'default.rb')
68
+ option.description = 'Specify a setup file to set up RgGen tool'
69
+ end
70
+
71
+ add_option :configuration do |option|
72
+ option.short = '-c'
73
+ option.long = '--configuration FILE'
74
+ option.description = 'Specify a configuration file ' \
75
+ 'for generated source code'
76
+ end
77
+
78
+ add_option :output do |option|
79
+ option.short = '-o'
80
+ option.long = '--output DIR'
81
+ option.default = './'
82
+ option.description = 'Specify output directory'
83
+ end
84
+
85
+ add_option :except do |option|
86
+ option.long = '--except [TYPE1,TYPE2,...]'
87
+ option.class = Array
88
+ option.description = 'Disable the given output file type(s)'
89
+ option.body = proc do |value, options, kind|
90
+ options[kind] ||= []
91
+ options[kind].concat(value.map(&:to_sym))
92
+ end
93
+ end
94
+
95
+ add_option :version do |option|
96
+ option.short = '-v'
97
+ option.long = '--version'
98
+ option.description = 'Display the version'
99
+ option.body = proc do
100
+ puts ver
101
+ exit
102
+ end
103
+ end
104
+
105
+ add_option :help do |option|
106
+ option.short = '-h'
107
+ option.long = '--help'
108
+ option.description = 'Display this message'
109
+ option.body = proc do
110
+ puts help
111
+ exit
112
+ end
113
+ end
114
+
115
+ def run(argv)
116
+ Context.new.tap do |context|
117
+ parse_options(argv, context)
118
+ load_setup(context)
119
+ load_configuration(context)
120
+ load_register_map(context, argv.first)
121
+ write_files(context)
122
+ end
123
+ end
124
+
125
+ private
126
+
127
+ def parse_options(argv, context)
128
+ option_parser(context.options).parse!(argv)
129
+ end
130
+
131
+ def option_parser(options)
132
+ OptionParser.new do |parser|
133
+ parser.version = RgGen::VERSION
134
+ parser.program_name = 'rggen'
135
+ parser.banner = 'Usage: rggen [options] REGISTER_MAP'
136
+ add_option_switches(parser, options)
137
+ end
138
+ end
139
+
140
+ def add_option_switches(parser, options)
141
+ self.class.options.each do |option|
142
+ option.on(parser, options)
143
+ end
144
+ end
145
+
146
+ def load_setup(context)
147
+ load(context.options[:setup])
148
+ end
149
+
150
+ def build_factory(component_name)
151
+ RgGen.builder.build_factory(component_name)
152
+ end
153
+
154
+ def load_configuration(context)
155
+ context.configuration =
156
+ build_factory(:configuration).create(context.options[:configuration])
157
+ end
158
+
159
+ def load_register_map(context, file)
160
+ context.register_map =
161
+ build_factory(:register_map).create(context.configuration, file)
162
+ end
163
+
164
+ def write_files(context)
165
+ file_generators(context).each do |generator|
166
+ generator.write_file(context.options[:output])
167
+ end
168
+ end
169
+
170
+ def file_generators(context)
171
+ available_output_components(context).map do |component|
172
+ build_factory(component).create(
173
+ context.configuration, context.register_map
174
+ )
175
+ end
176
+ end
177
+
178
+ def available_output_components(context)
179
+ except = context.options[:except]
180
+ RgGen.builder.stored_output_components.select do |component|
181
+ except.nil? || except.exclude?(component)
182
+ end
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,19 @@
1
+ module RgGen
2
+ module InputBase
3
+ class Component < Base::Component
4
+ def add_item(item)
5
+ super(item)
6
+ def_object_delegators(@items.last, *item.fields)
7
+ end
8
+
9
+ def fields
10
+ items.flat_map(&:fields)
11
+ end
12
+
13
+ def validate
14
+ items.each(&:validate)
15
+ children.each(&:validate)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,58 @@
1
+ module RgGen
2
+ module InputBase
3
+ class ComponentFactory < Base::ComponentFactory
4
+ attr_writer :loaders
5
+
6
+ def create(*args)
7
+ if @root_factory
8
+ file = args.pop
9
+ source = load(file)
10
+ args << source
11
+
12
+ component = super(*args)
13
+ component.validate
14
+ else
15
+ component = super(*args)
16
+ end
17
+ component
18
+ end
19
+
20
+ private
21
+
22
+ def create_items(component, *sources)
23
+ create_active_items(component, *sources)
24
+ create_passive_items(component, *sources[0..-2])
25
+ end
26
+
27
+ def create_passive_items(component, *sources)
28
+ passive_item_factories.each do |factory|
29
+ create_item(factory, component, *sources)
30
+ end
31
+ end
32
+
33
+ def active_item_factories
34
+ @item_factories.each_with_object({}) do |(name, factory), factories|
35
+ factories[name] = factory if factory.active_item_factory?
36
+ end
37
+ end
38
+
39
+ def passive_item_factories
40
+ @item_factories.each_value.select(&:passive_item_factory?)
41
+ end
42
+
43
+ def load(file)
44
+ load_file(file)
45
+ end
46
+
47
+ def load_file(file)
48
+ find_loader(file).load_file(file)
49
+ end
50
+
51
+ def find_loader(file)
52
+ loader = @loaders && @loaders.find { |l| l.acceptable?(file) }
53
+ return loader.new unless loader.nil?
54
+ fail RgGen::LoadError, "unsupported file type: #{File.ext(file)}"
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,170 @@
1
+ module RgGen
2
+ module InputBase
3
+ class Item < Base::Item
4
+ include RegxpPatterns
5
+
6
+ class InputMatcher
7
+ def initialize(pattern, options)
8
+ @options = options
9
+ @pattern =
10
+ if @options.fetch(:match_wholly, true)
11
+ /\A#{pattern}\z/
12
+ else
13
+ pattern
14
+ end
15
+ end
16
+
17
+ attr_reader :match_data
18
+
19
+ def match_automatically?
20
+ @options.fetch(:match_automatically, true)
21
+ end
22
+
23
+ def match(rhs)
24
+ rhs = rhs.to_s if @options[:convert_to_string]
25
+ rhs = delete_blanks(rhs) if @options.fetch(:ignore_blank, true)
26
+ @match_data =
27
+ case rhs
28
+ when @pattern
29
+ Regexp.last_match
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ BLANK_REGEXP = [
36
+ /\A[ \t]+/,
37
+ /(?<=\w)[ \t]+(?=[[:punct:]])/,
38
+ /(?<=[[:punct:]])[ \t]+(?=\w)/,
39
+ /[ \t]+\z/
40
+ ].inject(&:|).freeze
41
+
42
+ def delete_blanks(rhs)
43
+ return rhs unless rhs.respond_to?(:gsub)
44
+ rhs.gsub(BLANK_REGEXP, '')
45
+ end
46
+ end
47
+
48
+ define_helpers do
49
+ attr_reader :builders
50
+ attr_reader :validators
51
+ attr_reader :input_matcher
52
+
53
+ def field(field_name, options = {}, &body)
54
+ return if fields.include?(field_name)
55
+
56
+ define_method(field_name) do
57
+ field_method(field_name, options, body)
58
+ end
59
+
60
+ fields << field_name
61
+ end
62
+
63
+ def fields
64
+ @fields ||= []
65
+ end
66
+
67
+ def build(&body)
68
+ @builders ||= []
69
+ @builders << body
70
+ end
71
+
72
+ def validate(&body)
73
+ @validators ||= []
74
+ @validators << body
75
+ end
76
+
77
+ def input_pattern(pattern, options = {})
78
+ @input_matcher = InputMatcher.new(pattern, options)
79
+ end
80
+
81
+ def active_item?
82
+ !passive_item?
83
+ end
84
+
85
+ def passive_item?
86
+ @builders.nil? || @builders.empty?
87
+ end
88
+ end
89
+
90
+ def self.inherited(subclass)
91
+ [:@fields, :@builders, :@validators].each do |v|
92
+ subclass.inherit_class_instance_variable(v, self, &:dup)
93
+ end
94
+ subclass.inherit_class_instance_variable(:@input_matcher, self)
95
+ end
96
+
97
+ class_delegator :fields
98
+ class_delegator :builders
99
+ class_delegator :validators
100
+ class_delegator :input_matcher
101
+
102
+ def build(*sources)
103
+ return unless builders
104
+ pattern_match(sources.last) if match_automatically?
105
+ builders.each do |builder|
106
+ instance_exec(*sources, &builder)
107
+ end
108
+ end
109
+
110
+ def validate
111
+ return if @validated
112
+ return unless validators
113
+ validators.each do |validator|
114
+ instance_exec(&validator)
115
+ end
116
+ @validated = true
117
+ end
118
+
119
+ private
120
+
121
+ def pattern_match(rhs)
122
+ input_matcher && input_matcher.match(rhs)
123
+ end
124
+
125
+ def match_data
126
+ input_matcher && input_matcher.match_data
127
+ end
128
+
129
+ def pattern_matched?
130
+ match_data.not_nil?
131
+ end
132
+
133
+ def captures
134
+ match_data && match_data.captures
135
+ end
136
+
137
+ def match_automatically?
138
+ input_matcher && input_matcher.match_automatically?
139
+ end
140
+
141
+ def field_method(field_name, options, body)
142
+ validate if options[:need_validation]
143
+ if body
144
+ instance_exec(&body)
145
+ elsif options[:forward_to_helper]
146
+ self.class.__send__(field_name)
147
+ elsif options.key?(:forward_to)
148
+ __send__(options[:forward_to])
149
+ else
150
+ default_field_method(field_name, options[:default])
151
+ end
152
+ end
153
+
154
+ def default_field_method(field_name, default_value)
155
+ variable_name =
156
+ if field_name =~ /\A([a-zA-Z0-9]\w*)\?\z/
157
+ Regexp.last_match[1].variablize
158
+ else
159
+ field_name.variablize
160
+ end
161
+
162
+ if instance_variable_defined?(variable_name)
163
+ instance_variable_get(variable_name)
164
+ else
165
+ default_value
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,13 @@
1
+ module RgGen
2
+ module InputBase
3
+ class ItemFactory < Base::ItemFactory
4
+ def active_item_factory?
5
+ !passive_item_factory?
6
+ end
7
+
8
+ def passive_item_factory?
9
+ @target_items.nil? && @target_item.passive_item?
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module RgGen
2
+ module InputBase
3
+ class Loader
4
+ class << self
5
+ attr_writer :supported_types
6
+
7
+ def acceptable?(file_name)
8
+ ext = File.ext(file_name).to_sym
9
+ @supported_types.any? { |type| type.casecmp(ext) == 0 }
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ module RgGen
2
+ module InputBase
3
+ module RegxpPatterns
4
+ BIN_REGEXP = /0b(?:[01][01_]*)?[01]/i
5
+ OCT_REGEXP = /0o(?:[0-7][0-7_]*)?[0-7]/i
6
+ DEC_REGEXP = /(?:[1-9][\d_]*)?\d/
7
+ HEX_REGEXP = /0x(?:\h[\h_]*)?\h/i
8
+
9
+ UNSIGNED_NUMBER_REGEXP = (
10
+ /\b/ + (BIN_REGEXP | OCT_REGEXP | DEC_REGEXP | HEX_REGEXP) + /\b/
11
+ ).freeze
12
+ VARIABLE_NAME_REGEXP = /\b[a-z_][a-z0-9_]*\b/i
13
+
14
+ def self.included(klass)
15
+ klass.extend(self)
16
+ end
17
+
18
+ private
19
+
20
+ def number
21
+ UNSIGNED_NUMBER_REGEXP
22
+ end
23
+
24
+ def variable_name
25
+ VARIABLE_NAME_REGEXP
26
+ end
27
+ end
28
+ end
29
+ end