rggen-core 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/CODE_OF_CONDUCT.md +46 -0
  3. data/LICENSE +21 -0
  4. data/README.md +46 -0
  5. data/exe/rggen +13 -0
  6. data/lib/rggen/core.rb +101 -0
  7. data/lib/rggen/core/base/component.rb +54 -0
  8. data/lib/rggen/core/base/component_factory.rb +84 -0
  9. data/lib/rggen/core/base/feature.rb +46 -0
  10. data/lib/rggen/core/base/feature_factory.rb +37 -0
  11. data/lib/rggen/core/base/hierarchical_accessors.rb +91 -0
  12. data/lib/rggen/core/base/hierarchical_feature_accessors.rb +83 -0
  13. data/lib/rggen/core/base/internal_struct.rb +21 -0
  14. data/lib/rggen/core/base/shared_context.rb +18 -0
  15. data/lib/rggen/core/builder.rb +13 -0
  16. data/lib/rggen/core/builder/builder.rb +150 -0
  17. data/lib/rggen/core/builder/category.rb +116 -0
  18. data/lib/rggen/core/builder/component_entry.rb +29 -0
  19. data/lib/rggen/core/builder/component_registry.rb +47 -0
  20. data/lib/rggen/core/builder/feature_registry.rb +126 -0
  21. data/lib/rggen/core/builder/input_component_registry.rb +35 -0
  22. data/lib/rggen/core/builder/list_feature_entry.rb +98 -0
  23. data/lib/rggen/core/builder/output_component_registry.rb +10 -0
  24. data/lib/rggen/core/builder/simple_feature_entry.rb +39 -0
  25. data/lib/rggen/core/cli.rb +29 -0
  26. data/lib/rggen/core/configuration.rb +19 -0
  27. data/lib/rggen/core/configuration/component.rb +10 -0
  28. data/lib/rggen/core/configuration/component_factory.rb +19 -0
  29. data/lib/rggen/core/configuration/error.rb +16 -0
  30. data/lib/rggen/core/configuration/feature.rb +13 -0
  31. data/lib/rggen/core/configuration/feature_factory.rb +11 -0
  32. data/lib/rggen/core/configuration/hash_loader.rb +15 -0
  33. data/lib/rggen/core/configuration/json_loader.rb +18 -0
  34. data/lib/rggen/core/configuration/loader.rb +11 -0
  35. data/lib/rggen/core/configuration/ruby_loader.rb +15 -0
  36. data/lib/rggen/core/configuration/yaml_loader.rb +18 -0
  37. data/lib/rggen/core/core_extensions/casecmp.rb +12 -0
  38. data/lib/rggen/core/core_extensions/forwardable.rb +12 -0
  39. data/lib/rggen/core/core_extensions/forwardable_workaround.rb +22 -0
  40. data/lib/rggen/core/core_extensions/object.rb +14 -0
  41. data/lib/rggen/core/dsl.rb +30 -0
  42. data/lib/rggen/core/exceptions.rb +29 -0
  43. data/lib/rggen/core/facets.rb +7 -0
  44. data/lib/rggen/core/generator.rb +51 -0
  45. data/lib/rggen/core/input_base/component.rb +30 -0
  46. data/lib/rggen/core/input_base/component_factory.rb +88 -0
  47. data/lib/rggen/core/input_base/feature.rb +130 -0
  48. data/lib/rggen/core/input_base/feature_factory.rb +80 -0
  49. data/lib/rggen/core/input_base/input_data.rb +98 -0
  50. data/lib/rggen/core/input_base/input_matcher.rb +79 -0
  51. data/lib/rggen/core/input_base/input_value.rb +34 -0
  52. data/lib/rggen/core/input_base/json_loader.rb +16 -0
  53. data/lib/rggen/core/input_base/loader.rb +44 -0
  54. data/lib/rggen/core/input_base/property.rb +76 -0
  55. data/lib/rggen/core/input_base/verifier.rb +41 -0
  56. data/lib/rggen/core/input_base/yaml_loader.rb +34 -0
  57. data/lib/rggen/core/options.rb +181 -0
  58. data/lib/rggen/core/output_base/code_generator.rb +59 -0
  59. data/lib/rggen/core/output_base/component.rb +100 -0
  60. data/lib/rggen/core/output_base/component_factory.rb +35 -0
  61. data/lib/rggen/core/output_base/erb_engine.rb +21 -0
  62. data/lib/rggen/core/output_base/feature.rb +147 -0
  63. data/lib/rggen/core/output_base/feature_factory.rb +13 -0
  64. data/lib/rggen/core/output_base/file_writer.rb +40 -0
  65. data/lib/rggen/core/output_base/template_engine.rb +27 -0
  66. data/lib/rggen/core/printers.rb +53 -0
  67. data/lib/rggen/core/register_map.rb +21 -0
  68. data/lib/rggen/core/register_map/component.rb +20 -0
  69. data/lib/rggen/core/register_map/component_factory.rb +19 -0
  70. data/lib/rggen/core/register_map/error.rb +16 -0
  71. data/lib/rggen/core/register_map/feature.rb +22 -0
  72. data/lib/rggen/core/register_map/feature_factory.rb +11 -0
  73. data/lib/rggen/core/register_map/hash_loader.rb +47 -0
  74. data/lib/rggen/core/register_map/input_data.rb +34 -0
  75. data/lib/rggen/core/register_map/json_loader.rb +18 -0
  76. data/lib/rggen/core/register_map/loader.rb +15 -0
  77. data/lib/rggen/core/register_map/ruby_loader.rb +15 -0
  78. data/lib/rggen/core/register_map/yaml_loader.rb +18 -0
  79. data/lib/rggen/core/utility/attribute_setter.rb +53 -0
  80. data/lib/rggen/core/utility/code_utility.rb +64 -0
  81. data/lib/rggen/core/utility/code_utility/code_block.rb +88 -0
  82. data/lib/rggen/core/utility/code_utility/line.rb +51 -0
  83. data/lib/rggen/core/utility/code_utility/source_file.rb +104 -0
  84. data/lib/rggen/core/utility/code_utility/structure_definition.rb +54 -0
  85. data/lib/rggen/core/utility/regexp_patterns.rb +38 -0
  86. data/lib/rggen/core/version.rb +10 -0
  87. metadata +188 -0
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module RegisterMap
6
+ class FeatureFactory < InputBase::FeatureFactory
7
+ include RaiseError
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module RegisterMap
6
+ module HashLoader
7
+ def format(read_data, file)
8
+ format_data(:register_map, register_map, read_data, file)
9
+ rescue TypeError => e
10
+ raise Core::LoadError.new(e.message, file)
11
+ end
12
+
13
+ private
14
+
15
+ CHILD_HIERARCHY = {
16
+ register_map: :register_block,
17
+ register_block: :register,
18
+ register: :bit_field
19
+ }.freeze
20
+
21
+ CHILD_HIERARCHY_KEY = {
22
+ register_map: :register_blocks,
23
+ register_block: :registers,
24
+ register: :bit_fields
25
+ }.freeze
26
+
27
+ def format_data(hierarchy, input_data, read_data, file)
28
+ read_data = Hash(read_data)
29
+ input_data.values(read_data, file)
30
+ read_data_for_child(hierarchy, read_data).each do |data|
31
+ format_data(
32
+ CHILD_HIERARCHY[hierarchy],
33
+ input_data.child,
34
+ data,
35
+ file
36
+ )
37
+ end
38
+ end
39
+
40
+ def read_data_for_child(hierarchy, read_data)
41
+ key = CHILD_HIERARCHY_KEY[hierarchy]
42
+ Array(key && read_data[key])
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module RegisterMap
6
+ class BitFieldData < InputBase::InputData
7
+ end
8
+
9
+ class RegisterData < InputBase::InputData
10
+ alias_method :bit_field, :child
11
+
12
+ def child_data_class
13
+ BitFieldData
14
+ end
15
+ end
16
+
17
+ class RegisterBlockData < InputBase::InputData
18
+ alias_method :register, :child
19
+
20
+ def child_data_class
21
+ RegisterData
22
+ end
23
+ end
24
+
25
+ class RegisterMapData < InputBase::InputData
26
+ alias_method :register_block, :child
27
+
28
+ def child_data_class
29
+ RegisterBlockData
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module RegisterMap
6
+ class JSONLoader < Loader
7
+ include HashLoader
8
+ include InputBase::JSONLoader
9
+
10
+ support_types [:json]
11
+
12
+ def read_file(file)
13
+ load_json(file)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module RegisterMap
6
+ class Loader < InputBase::Loader
7
+ private
8
+
9
+ def register_map
10
+ input_data
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module RegisterMap
6
+ class RubyLoader < Loader
7
+ support_types [:rb]
8
+
9
+ def read_file(file)
10
+ register_map.load_file(file)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module RegisterMap
6
+ class YAMLLoader < Loader
7
+ include HashLoader
8
+ include InputBase::YAMLLoader
9
+
10
+ support_types [:yaml, :yml]
11
+
12
+ def read_file(file)
13
+ load_yaml(file)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Utility
6
+ module AttributeSetter
7
+ module Extension
8
+ def attributes
9
+ @attributes ||= []
10
+ end
11
+
12
+ private
13
+
14
+ DEFAULT_VALUE = Object.new.freeze
15
+
16
+ def define_attribute(name, default_value = nil)
17
+ attributes << name.to_sym
18
+ variable_name = "@#{name}"
19
+ define_method(name) do |value = DEFAULT_VALUE|
20
+ if value.equal?(DEFAULT_VALUE)
21
+ attribute_value_get(variable_name, default_value)
22
+ else
23
+ instance_variable_set(variable_name, value)
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def self.included(class_or_module)
30
+ class_or_module.extend(Extension)
31
+ end
32
+
33
+ def apply_attributes(**attributes)
34
+ attributes.each do |name, value|
35
+ __send__(name, value) if self.class.attributes.include?(name)
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def attribute_value_get(variable_name, default_value)
42
+ if instance_variable_defined?(variable_name)
43
+ instance_variable_get(variable_name)
44
+ elsif default_value.is_a?(Proc)
45
+ instance_exec(&default_value)
46
+ else
47
+ default_value
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Utility
6
+ module CodeUtility
7
+ def create_blank_code
8
+ code_block
9
+ end
10
+
11
+ private
12
+
13
+ def newline
14
+ "\n"
15
+ end
16
+
17
+ alias_method :nl, :newline
18
+
19
+ def comma
20
+ ','
21
+ end
22
+
23
+ def colon
24
+ ':'
25
+ end
26
+
27
+ def semicolon
28
+ ';'
29
+ end
30
+
31
+ def space(size = 1)
32
+ ' ' * size
33
+ end
34
+
35
+ def string(expression)
36
+ "\"#{expression}\""
37
+ end
38
+
39
+ def code_block(indent = 0, &body)
40
+ CodeBlock.new(indent, &body)
41
+ end
42
+
43
+ def indent(code, indent_size)
44
+ code << nl unless code.last_line_empty?
45
+ code.indent += indent_size
46
+ block_given? && yield(code)
47
+ code << nl unless code.last_line_empty?
48
+ code.indent -= indent_size
49
+ end
50
+
51
+ def wrap(code, head, tail)
52
+ code << head
53
+ block_given? && yield(code)
54
+ code << tail
55
+ end
56
+
57
+ def loop_index(level = 1)
58
+ return '' unless level.positive?
59
+ (1...level).inject(+'i') { |index, _| index.next! }
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Utility
6
+ module CodeUtility
7
+ class CodeBlock
8
+ def initialize(indent = 0)
9
+ @indent = indent
10
+ @lines = []
11
+ add_line
12
+ block_given? && yield(self)
13
+ end
14
+
15
+ attr_reader :indent
16
+
17
+ def <<(rhs)
18
+ return push_string(rhs) if rhs.is_a?(String)
19
+ return push_code_block(rhs) if rhs.is_a?(CodeBlock)
20
+ return rhs.inject(self, :<<) if rhs.is_a?(Array)
21
+ return self << rhs.to_code if rhs.respond_to?(:to_code)
22
+ push_word(rhs)
23
+ end
24
+
25
+ def indent=(indent)
26
+ @indent = indent
27
+ last_line.indent = indent
28
+ end
29
+
30
+ def last_line_empty?
31
+ last_line.empty?
32
+ end
33
+
34
+ def to_s
35
+ @lines.map(&:to_s).each(&:rstrip!).join(newline)
36
+ end
37
+
38
+ def eval_block(&block)
39
+ return unless block_given?
40
+ block.arity.zero? ? self << yield : yield(self)
41
+ end
42
+
43
+ private
44
+
45
+ def add_line
46
+ line = Line.new(@indent)
47
+ @lines << line
48
+ end
49
+
50
+ def push_string(rhs)
51
+ rhs += newline if rhs.end_with?(newline)
52
+ rhs.each_line.with_index do |line, i|
53
+ i.positive? && add_line
54
+ push_word(line.chomp)
55
+ end
56
+ self
57
+ end
58
+
59
+ def push_code_block(rhs)
60
+ rhs.lines.each_with_index do |line, i|
61
+ i.positive? && add_line
62
+ line.empty? || (last_line.indent += line.indent)
63
+ last_line.concat(line)
64
+ end
65
+ self
66
+ end
67
+
68
+ def last_line
69
+ @lines.last
70
+ end
71
+
72
+ def push_word(word)
73
+ last_line << word
74
+ self
75
+ end
76
+
77
+ def newline
78
+ "\n"
79
+ end
80
+
81
+ protected
82
+
83
+ attr_reader :lines
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Utility
6
+ module CodeUtility
7
+ class Line
8
+ def initialize(indent = 0)
9
+ @indent = indent
10
+ @words = []
11
+ end
12
+
13
+ attr_reader :indent
14
+
15
+ def indent=(indent)
16
+ empty? && (@indent = indent)
17
+ end
18
+
19
+ def <<(word)
20
+ @words << word
21
+ self
22
+ end
23
+
24
+ def concat(line)
25
+ @words.concat(line.words)
26
+ end
27
+
28
+ def empty?
29
+ @words.all?(&method(:empty_word?))
30
+ end
31
+
32
+ def to_s
33
+ [' ' * (@indent || 0), *@words].join
34
+ end
35
+
36
+ private
37
+
38
+ def empty_word?(word)
39
+ return true if word.nil?
40
+ return false unless word.respond_to?(:empty?)
41
+ word.empty?
42
+ end
43
+
44
+ protected
45
+
46
+ attr_reader :words
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Utility
6
+ module CodeUtility
7
+ class SourceFile
8
+ include CodeUtility
9
+
10
+ class << self
11
+ attr_setter :ifndef_keyword
12
+ attr_setter :endif_keyword
13
+ attr_setter :define_keyword
14
+ attr_setter :include_keyword
15
+ end
16
+
17
+ def initialize(file_path)
18
+ @file_path = file_path
19
+ block_given? && yield(self)
20
+ end
21
+
22
+ attr_reader :file_path
23
+
24
+ def header(&block)
25
+ @file_header = -> { block.call(@file_path) }
26
+ end
27
+
28
+ def include_guard
29
+ @guard_macro =
30
+ if block_given?
31
+ yield(default_guard_macro)
32
+ else
33
+ default_guard_macro
34
+ end
35
+ end
36
+
37
+ def include_files(files)
38
+ @include_files ||= []
39
+ @include_files.concat(Array(files))
40
+ end
41
+
42
+ def include_file(file)
43
+ include_files([file])
44
+ end
45
+
46
+ def body(&block)
47
+ @bodies ||= []
48
+ @bodies << block
49
+ end
50
+
51
+ def to_code
52
+ CodeBlock.new do |code|
53
+ code_blocks.each { |block| execute_code_block(code, block, true) }
54
+ end
55
+ end
56
+
57
+ def to_s
58
+ to_code.to_s
59
+ end
60
+
61
+ private
62
+
63
+ def code_blocks
64
+ [
65
+ @file_header,
66
+ include_guard_header,
67
+ include_file_block,
68
+ *Array(@bodies),
69
+ include_guard_footer
70
+ ].compact
71
+ end
72
+
73
+ def execute_code_block(code, code_block, insert_newline)
74
+ code.eval_block(&code_block)
75
+ code << nl if insert_newline && !code.last_line_empty?
76
+ end
77
+
78
+ def default_guard_macro
79
+ File.basename(file_path).upcase.gsub(/\W/, '_')
80
+ end
81
+
82
+ def include_guard_header
83
+ @guard_macro && lambda do
84
+ [self.class.ifndef_keyword, self.class.define_keyword]
85
+ .flat_map { |keyword| [keyword, space, @guard_macro, nl] }
86
+ end
87
+ end
88
+
89
+ def include_file_block
90
+ @include_files && lambda do
91
+ keyword = self.class.include_keyword
92
+ @include_files
93
+ .flat_map { |file| [keyword, space, string(file), nl] }
94
+ end
95
+ end
96
+
97
+ def include_guard_footer
98
+ @guard_macro && (-> { self.class.endif_keyword })
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end