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.
- checksums.yaml +7 -0
- data/CODE_OF_CONDUCT.md +46 -0
- data/LICENSE +21 -0
- data/README.md +46 -0
- data/exe/rggen +13 -0
- data/lib/rggen/core.rb +101 -0
- data/lib/rggen/core/base/component.rb +54 -0
- data/lib/rggen/core/base/component_factory.rb +84 -0
- data/lib/rggen/core/base/feature.rb +46 -0
- data/lib/rggen/core/base/feature_factory.rb +37 -0
- data/lib/rggen/core/base/hierarchical_accessors.rb +91 -0
- data/lib/rggen/core/base/hierarchical_feature_accessors.rb +83 -0
- data/lib/rggen/core/base/internal_struct.rb +21 -0
- data/lib/rggen/core/base/shared_context.rb +18 -0
- data/lib/rggen/core/builder.rb +13 -0
- data/lib/rggen/core/builder/builder.rb +150 -0
- data/lib/rggen/core/builder/category.rb +116 -0
- data/lib/rggen/core/builder/component_entry.rb +29 -0
- data/lib/rggen/core/builder/component_registry.rb +47 -0
- data/lib/rggen/core/builder/feature_registry.rb +126 -0
- data/lib/rggen/core/builder/input_component_registry.rb +35 -0
- data/lib/rggen/core/builder/list_feature_entry.rb +98 -0
- data/lib/rggen/core/builder/output_component_registry.rb +10 -0
- data/lib/rggen/core/builder/simple_feature_entry.rb +39 -0
- data/lib/rggen/core/cli.rb +29 -0
- data/lib/rggen/core/configuration.rb +19 -0
- data/lib/rggen/core/configuration/component.rb +10 -0
- data/lib/rggen/core/configuration/component_factory.rb +19 -0
- data/lib/rggen/core/configuration/error.rb +16 -0
- data/lib/rggen/core/configuration/feature.rb +13 -0
- data/lib/rggen/core/configuration/feature_factory.rb +11 -0
- data/lib/rggen/core/configuration/hash_loader.rb +15 -0
- data/lib/rggen/core/configuration/json_loader.rb +18 -0
- data/lib/rggen/core/configuration/loader.rb +11 -0
- data/lib/rggen/core/configuration/ruby_loader.rb +15 -0
- data/lib/rggen/core/configuration/yaml_loader.rb +18 -0
- data/lib/rggen/core/core_extensions/casecmp.rb +12 -0
- data/lib/rggen/core/core_extensions/forwardable.rb +12 -0
- data/lib/rggen/core/core_extensions/forwardable_workaround.rb +22 -0
- data/lib/rggen/core/core_extensions/object.rb +14 -0
- data/lib/rggen/core/dsl.rb +30 -0
- data/lib/rggen/core/exceptions.rb +29 -0
- data/lib/rggen/core/facets.rb +7 -0
- data/lib/rggen/core/generator.rb +51 -0
- data/lib/rggen/core/input_base/component.rb +30 -0
- data/lib/rggen/core/input_base/component_factory.rb +88 -0
- data/lib/rggen/core/input_base/feature.rb +130 -0
- data/lib/rggen/core/input_base/feature_factory.rb +80 -0
- data/lib/rggen/core/input_base/input_data.rb +98 -0
- data/lib/rggen/core/input_base/input_matcher.rb +79 -0
- data/lib/rggen/core/input_base/input_value.rb +34 -0
- data/lib/rggen/core/input_base/json_loader.rb +16 -0
- data/lib/rggen/core/input_base/loader.rb +44 -0
- data/lib/rggen/core/input_base/property.rb +76 -0
- data/lib/rggen/core/input_base/verifier.rb +41 -0
- data/lib/rggen/core/input_base/yaml_loader.rb +34 -0
- data/lib/rggen/core/options.rb +181 -0
- data/lib/rggen/core/output_base/code_generator.rb +59 -0
- data/lib/rggen/core/output_base/component.rb +100 -0
- data/lib/rggen/core/output_base/component_factory.rb +35 -0
- data/lib/rggen/core/output_base/erb_engine.rb +21 -0
- data/lib/rggen/core/output_base/feature.rb +147 -0
- data/lib/rggen/core/output_base/feature_factory.rb +13 -0
- data/lib/rggen/core/output_base/file_writer.rb +40 -0
- data/lib/rggen/core/output_base/template_engine.rb +27 -0
- data/lib/rggen/core/printers.rb +53 -0
- data/lib/rggen/core/register_map.rb +21 -0
- data/lib/rggen/core/register_map/component.rb +20 -0
- data/lib/rggen/core/register_map/component_factory.rb +19 -0
- data/lib/rggen/core/register_map/error.rb +16 -0
- data/lib/rggen/core/register_map/feature.rb +22 -0
- data/lib/rggen/core/register_map/feature_factory.rb +11 -0
- data/lib/rggen/core/register_map/hash_loader.rb +47 -0
- data/lib/rggen/core/register_map/input_data.rb +34 -0
- data/lib/rggen/core/register_map/json_loader.rb +18 -0
- data/lib/rggen/core/register_map/loader.rb +15 -0
- data/lib/rggen/core/register_map/ruby_loader.rb +15 -0
- data/lib/rggen/core/register_map/yaml_loader.rb +18 -0
- data/lib/rggen/core/utility/attribute_setter.rb +53 -0
- data/lib/rggen/core/utility/code_utility.rb +64 -0
- data/lib/rggen/core/utility/code_utility/code_block.rb +88 -0
- data/lib/rggen/core/utility/code_utility/line.rb +51 -0
- data/lib/rggen/core/utility/code_utility/source_file.rb +104 -0
- data/lib/rggen/core/utility/code_utility/structure_definition.rb +54 -0
- data/lib/rggen/core/utility/regexp_patterns.rb +38 -0
- data/lib/rggen/core/version.rb +10 -0
- metadata +188 -0
@@ -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,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
|