idlc 0.1.1

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.
@@ -0,0 +1,355 @@
1
+ # typed: false
2
+ # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
3
+ # SPDX-License-Identifier: BSD-3-Clause-Clear
4
+
5
+ # frozen_string_literal: true
6
+
7
+ require_relative "../ast"
8
+
9
+ class Idl::AstNode
10
+ def gen_adoc(indent = 0, indent_spaces: 2)
11
+ internal_error "must implement gen_adoc for #{self.class.name}"
12
+ end
13
+ end
14
+
15
+ module Idl
16
+ class NoopAst < AstNode
17
+ def gen_adoc(indent = 0, indent_spaces: 2) = ""
18
+ end
19
+ class AryRangeAssignmentAst < AstNode
20
+ def gen_adoc(indent = 0, indent_spaces: 2)
21
+ "#{' ' * indent}#{variable.gen_adoc(indent, indent_spaces:)}[#{msb.gen_adoc(0, indent_spaces:)}:#{lsb.gen_adoc(0, indent_spaces:)}] = #{write_value.gen_adoc(0, indent_spaces:)}"
22
+ end
23
+ end
24
+ class ArrayLiteralAst < AstNode
25
+ def gen_adoc(indent = 0, indent_spaces: 2)
26
+ "#{' ' * indent}[#{entries.map{ |e| e.gen_adoc(0) }.join(", ")}]"
27
+ end
28
+ end
29
+ class ConditionalReturnStatementAst < AstNode
30
+ def gen_adoc(indent = 0, indent_spaces: 2)
31
+ "#{' ' * indent}#{return_expression.gen_adoc(indent, indent_spaces:)} if (#{condition.gen_adoc(0, indent_spaces:)});"
32
+ end
33
+ end
34
+ class ReturnExpressionAst < AstNode
35
+ def gen_adoc(indent = 0, indent_spaces: 2)
36
+ "#{' ' * indent}return #{return_value_nodes.map { |r| r.gen_adoc(0, indent_spaces:) }.join(', ')}"
37
+ end
38
+ end
39
+ class IfBodyAst < AstNode
40
+ def gen_adoc(indent = 0, indent_spaces: 2)
41
+ adoc = []
42
+ children.each do |e|
43
+ adoc << e.gen_adoc(indent, indent_spaces:)
44
+ end
45
+ adoc.join("\n")
46
+ end
47
+ end
48
+
49
+ class PostIncrementExpressionAst < AstNode
50
+ def gen_adoc(indent, indent_spaces: 2)
51
+ "#{' ' * indent}#{rval.gen_adoc(indent, indent_spaces:)}++"
52
+ end
53
+ end
54
+ class PostDecrementExpressionAst < AstNode
55
+ def gen_adoc(indent, indent_spaces: 2)
56
+ "#{' ' * indent}#{rval.gen_adoc(indent, indent_spaces:)}--"
57
+ end
58
+ end
59
+ class StringLiteralAst < AstNode
60
+ def gen_adoc(indent, indent_spaces: 2)
61
+ # text_value will include leading and trailing quotes
62
+ "#{' ' * indent}#{text_value}"
63
+ end
64
+ end
65
+ class DontCareReturnAst < AstNode
66
+ def gen_adoc(indent, indent_spaces: 2)
67
+ "#{' ' * indent}-"
68
+ end
69
+ end
70
+ class UserTypeNameAst < AstNode
71
+ def gen_adoc(indent, indent_spaces: 2)
72
+ "#{' ' * indent}#{text_value}"
73
+ end
74
+ end
75
+ class MultiVariableAssignmentAst < AstNode
76
+ def gen_adoc(indent, indent_spaces: 2)
77
+ "#{' ' * indent}(#{variables.map { |v| v.gen_adoc(0, indent_spaces:) }.join(', ')} = #{function_call.gen_adoc(0, indent_spaces:)})"
78
+ end
79
+ end
80
+ class CsrFunctionCallAst < AstNode
81
+ def gen_adoc(indent, indent_spaces: 2)
82
+ args_adoc = args.map { |arg| arg.gen_adoc(0) }
83
+ "#{' ' * indent}#{csr.gen_adoc(indent, indent_spaces:)}.#{function_name}(#{args_adoc.join(', ')})"
84
+ end
85
+ end
86
+ class CsrSoftwareWriteAst < AstNode
87
+ def gen_adoc(indent, indent_spaces: 2)
88
+ "#{' ' * indent}#{csr.gen_adoc(indent, indent_spaces:)}.sw_write(#{expression.gen_adoc(0, indent_spaces:)})"
89
+ end
90
+ end
91
+ class FieldAccessExpressionAst < AstNode
92
+ def gen_adoc(indent, indent_spaces: 2)
93
+ "#{' ' * indent}#{obj.gen_adoc(indent, indent_spaces:)}.#{@field_name}"
94
+ end
95
+ end
96
+ class FieldAssignmentAst < AstNode
97
+ def gen_adoc(indent, indent_spaces: 2)
98
+ "#{id.gen_adoc(0, indent_spaces:)}.#{@field_name} = #{rhs.gen_adoc(0, indent_spaces:)}"
99
+ end
100
+ end
101
+ class ConcatenationExpressionAst < AstNode
102
+ def gen_adoc(indent, indent_spaces: 2)
103
+ "#{' ' * indent}{#{expressions.map { |e| e.gen_adoc(0, indent_spaces:) }.join(', ')}}"
104
+ end
105
+ end
106
+ class BitsCastAst < AstNode
107
+ def gen_adoc(indent, indent_spaces: 2)
108
+ "#{' ' * indent}$bits(#{expr.gen_adoc(0, indent_spaces:)})"
109
+ end
110
+ end
111
+ class EnumCastAst < AstNode
112
+ def gen_adoc(indent, indent_spaces: 2)
113
+ "#{' ' * indent}$enum(#{enum_name.gen_adoc(0, indent_spaces:)}, #{expression.gen_adoc(0, indent_spaces:)})"
114
+ end
115
+ end
116
+ class CsrFieldAssignmentAst < AstNode
117
+ def gen_adoc(indent, indent_spaces: 2)
118
+ "#{' ' * indent}#{csr_field.gen_adoc(indent, indent_spaces:)} = #{write_value.gen_adoc(0, indent_spaces:)}"
119
+ end
120
+ end
121
+ class EnumRefAst < AstNode
122
+ def gen_adoc(indent, indent_spaces: 2)
123
+ "#{' ' * indent}#{class_name}::#{member_name}"
124
+ end
125
+ end
126
+ class EnumSizeAst < AstNode
127
+ def gen_adoc(indent, indent_spaces: 2)
128
+ "#{' ' * indent}$enum_size(#{enum_class.gen_adoc(0, indent_spaces:)})"
129
+ end
130
+ end
131
+ class EnumElementSizeAst < AstNode
132
+ def gen_adoc(indent, indent_spaces: 2)
133
+ "#{' ' * indent}$enum_element_size(#{enum_class.gen_adoc(0, indent_spaces:)})"
134
+ end
135
+ end
136
+ class EnumArrayCastAst < AstNode
137
+ def gen_adoc(indent, indent_spaces: 2)
138
+ "#{' ' * indent}$enum_to_a(#{enum_class.gen_adoc(0, indent_spaces:)})"
139
+ end
140
+ end
141
+ class ParenExpressionAst < AstNode
142
+ def gen_adoc(indent = 0, indent_spaces: 2)
143
+ "#{' ' * indent}(#{expression.gen_adoc(indent, indent_spaces:)})"
144
+ end
145
+ end
146
+ class IntLiteralAst < AstNode
147
+ def gen_adoc(indent = 0, indent_spaces: 2)
148
+ raise "?" if text_value.empty?
149
+ "#{' ' * indent}#{text_value}"
150
+ end
151
+ end
152
+ class TrueExpressionAst < AstNode
153
+ def gen_adoc(indent = 0, indent_spaces: 2)
154
+ "#{' ' * indent}true"
155
+ end
156
+ end
157
+ class FalseExpressionAst < AstNode
158
+ def gen_adoc(indent = 0, indent_spaces: 2)
159
+ "#{' ' * indent}false"
160
+ end
161
+ end
162
+ class IdAst < AstNode
163
+ def gen_adoc(indent = 0, indent_spaces: 2)
164
+ "#{' ' * indent}#{text_value}"
165
+ end
166
+ end
167
+ class SignCastAst < AstNode
168
+ def gen_adoc(indent = 0, indent_spaces: 2)
169
+ "#{' ' * indent}$signed+++(+++#{expression.gen_adoc(0, indent_spaces:)})"
170
+ end
171
+ end
172
+ class AryRangeAccessAst < AstNode
173
+ def gen_adoc(indent = 0, indent_spaces: 2)
174
+ "#{' ' * indent}#{var.gen_adoc(indent, indent_spaces:)}[#{msb.gen_adoc(0, indent_spaces:)}:#{lsb.gen_adoc(0, indent_spaces:)}]"
175
+ end
176
+ end
177
+
178
+ class VariableDeclarationAst < AstNode
179
+ def gen_adoc(indent = 0, indent_spaces: 2)
180
+ "#{' ' * indent}#{type_name.gen_adoc(0, indent_spaces:)} #{id.gen_adoc(0, indent_spaces:)}"
181
+ end
182
+ end
183
+
184
+ class MultiVariableDeclarationAst < AstNode
185
+ def gen_adoc(indent = 0, indent_spaces: 2)
186
+ "#{' ' * indent}#{type_name.gen_adoc(0, indent_spaces:)} #{var_name_nodes.map { |var| var.gen_adoc(0, indent_spaces:) }.join(', ')}"
187
+ end
188
+ end
189
+
190
+ class TernaryOperatorExpressionAst < AstNode
191
+ def gen_adoc(indent = 0, indent_spaces: 2)
192
+ "#{' ' * indent}#{condition.gen_adoc(0, indent_spaces:)} ? #{true_expression.gen_adoc(0, indent_spaces:)} : #{false_expression.gen_adoc(0, indent_spaces:)}"
193
+ end
194
+ end
195
+
196
+ class BuiltinTypeNameAst < AstNode
197
+ def gen_adoc(indent = 0, indent_spaces: 2)
198
+ if @type_name == "Bits"
199
+ "#{' ' * indent}Bits<#{bits_expression.gen_adoc(0, indent_spaces:)}>"
200
+ else
201
+ to_idl
202
+ end
203
+ end
204
+ end
205
+
206
+ class ForLoopAst < AstNode
207
+ def gen_adoc(indent = 0, indent_spaces: 2)
208
+ lines = ["#{' ' * indent}for pass:[(]#{init.gen_adoc(0, indent_spaces:)}; #{condition.gen_adoc(0, indent_spaces:)}; #{update.gen_adoc(0, indent_spaces:)}) {"]
209
+ stmts.each do |s|
210
+ lines << s.gen_adoc(indent + indent_spaces, indent_spaces:)
211
+ end
212
+ lines << "#{' ' * indent}}"
213
+ lines.join("\n")
214
+ end
215
+ end
216
+
217
+ class BuiltinVariableAst < AstNode
218
+ def gen_adoc(indent = 0, indent_spaces: 2)
219
+ name
220
+ end
221
+ end
222
+
223
+ class VariableDeclarationWithInitializationAst < AstNode
224
+ def gen_adoc(indent = 0, indent_spaces: 2)
225
+ if ary_size.nil?
226
+ "#{' ' * indent}#{type_name.gen_adoc(0, indent_spaces:)} #{lhs.gen_adoc(0, indent_spaces:)} = #{rhs.gen_adoc(0, indent_spaces:)}"
227
+ else
228
+ "#{' ' * indent}#{type_name.gen_adoc(0, indent_spaces:)} #{lhs.gen_adoc(0, indent_spaces:)}[#{ary_size.gen_adoc(0, indent_spaces:)}] = #{rhs.gen_adoc(0, indent_spaces:)}"
229
+ end
230
+ end
231
+ end
232
+
233
+ class AryElementAccessAst < AstNode
234
+ def gen_adoc(indent = 0, indent_spaces: 2)
235
+ "#{' ' * indent}#{var.gen_adoc(indent, indent_spaces:)}[#{index.gen_adoc(0, indent_spaces:)}]"
236
+ end
237
+ end
238
+
239
+ class BinaryExpressionAst < AstNode
240
+ def gen_adoc(indent = 0, indent_spaces: 2)
241
+ "#{' ' * indent}#{lhs.gen_adoc(0, indent_spaces:)} #{op.sub("+", "pass:[+]").sub("`", "pass:[`]")} #{rhs.gen_adoc(0, indent_spaces:)}"
242
+ end
243
+ end
244
+
245
+ class VariableAssignmentAst < AstNode
246
+ def gen_adoc(indent = 0, indent_spaces: 2)
247
+ "#{' ' * indent}#{lhs.gen_adoc(0, indent_spaces:)} = #{rhs.gen_adoc(0, indent_spaces:)}"
248
+ end
249
+ end
250
+
251
+ class PcAssignmentAst < AstNode
252
+ def gen_adoc(indent = 0, indent_spaces: 2)
253
+ "#{' ' * indent}$pc = #{rhs.gen_adoc(0, indent_spaces:)}"
254
+ end
255
+ end
256
+
257
+ class AryElementAssignmentAst < AstNode
258
+ def gen_adoc(indent = 0, indent_spaces: 2)
259
+ "#{' ' * indent}#{lhs.gen_adoc(0, indent_spaces:)}[#{idx.gen_adoc(0, indent_spaces:)}] = #{rhs.gen_adoc(0, indent_spaces:)}"
260
+ end
261
+ end
262
+
263
+ class StatementAst < AstNode
264
+ def gen_adoc(indent = 0, indent_spaces: 2)
265
+ "#{' ' * indent}#{action.gen_adoc(0, indent_spaces:)};"
266
+ end
267
+ end
268
+
269
+ class UnaryOperatorExpressionAst < AstNode
270
+ def gen_adoc(indent = 0, indent_spaces: 2)
271
+ "#{' ' * indent}#{op}#{exp.gen_adoc(0, indent_spaces:)}"
272
+ end
273
+ end
274
+
275
+ class ReturnStatementAst < AstNode
276
+ def gen_adoc(indent = 0, indent_spaces: 2)
277
+ "#{' ' * indent}return #{return_value_nodes.map { |v| v.gen_adoc(0, indent_spaces:) }.join(', ')};"
278
+ end
279
+ end
280
+
281
+ class ReplicationExpressionAst < AstNode
282
+ def gen_adoc(indent = 0, indent_spaces: 2)
283
+ "#{' ' * indent}{#{n.gen_adoc(0, indent_spaces:)}{#{v.gen_adoc(indent, indent_spaces:)}}}"
284
+ end
285
+ end
286
+
287
+ class ConditionalStatementAst < AstNode
288
+ def gen_adoc(indent = 0, indent_spaces: 2)
289
+ "#{' ' * indent}#{action.gen_adoc(0, indent_spaces:)} if (#{condition.gen_adoc(0, indent_spaces:)});"
290
+ end
291
+ end
292
+
293
+ class FunctionCallExpressionAst < AstNode
294
+ def gen_adoc(indent = 0, indent_spaces: 2)
295
+ func_link = "%%UDB_DOC_LINK%func;#{name};#{name}%%"
296
+ "#{' ' * indent}" + func_link + "pass:[(]#{arg_nodes.map { |a| a.gen_adoc(0, indent_spaces:) }.join(', ')})"
297
+ end
298
+ end
299
+
300
+ class ArraySizeAst < AstNode
301
+ def gen_adoc(indent = 0, indent_spaces: 2)
302
+ "#{' ' * indent}$array_size(#{expression.gen_adoc(0, indent_spaces:)})"
303
+ end
304
+ end
305
+
306
+ class ArrayIncludesAst < AstNode
307
+ def gen_adoc(indent = 0, indent_spaces: 2)
308
+ "#{' ' * indent}$array_includes?(#{ary.gen_adoc(0, indent_spaces:)}, #{expr.gen_adoc(0, indent_spaces:)})"
309
+ end
310
+ end
311
+
312
+ class FunctionBodyAst < AstNode
313
+ def gen_adoc(indent = 0, indent_spaces: 2)
314
+ statements.map { |s| "#{' ' * indent}#{s.gen_adoc(0, indent_spaces:)}" }.join("\n")
315
+ end
316
+ end
317
+
318
+ class CsrFieldReadExpressionAst < AstNode
319
+ def gen_adoc(indent = 0, indent_spaces: 2)
320
+ csr_link = "%%UDB_DOC_LINK%csr;#{csr_name};#{csr_name}%%"
321
+ field_link = "%%UDB_DOC_LINK%csr_field;#{csr_name}*#{@field_name};#{@field_name}%%"
322
+ "#{' ' * indent}" + "CSR[#{csr_link}].#{field_link}"
323
+ end
324
+ end
325
+
326
+ class CsrReadExpressionAst < AstNode
327
+ def gen_adoc(indent = 0, indent_spaces: 2)
328
+ "#{' ' * indent}" + "CSR[%%UDB_DOC_LINK%csr;#{csr_name};#{text_value}%%]"
329
+ end
330
+ end
331
+
332
+ class IfAst < AstNode
333
+ def gen_adoc(indent = 0, indent_spaces: 2)
334
+ lines = ["#{' ' * indent}if pass:[(]#{if_cond.gen_adoc(0, indent_spaces:)}) {"]
335
+ if_body.stmts.each do |s|
336
+ lines << s.gen_adoc(indent + indent_spaces, indent_spaces:)
337
+ end
338
+ elseifs.each do |eif|
339
+ lines << "#{' ' * indent}} else if pass:[(]#{eif.cond.gen_adoc(0, indent_spaces:)}) {"
340
+ eif.body.stmts.each do |s|
341
+ lines << s.gen_adoc(indent + indent_spaces, indent_spaces:)
342
+ end
343
+ end
344
+ unless final_else_body.stmts.empty?
345
+ lines << "#{' ' * indent}} else {"
346
+ final_else_body.stmts.each do |s|
347
+ lines << s.gen_adoc(indent + indent_spaces, indent_spaces:)
348
+ end
349
+ end
350
+ lines << "#{' ' * indent}}"
351
+
352
+ lines.join("\n")
353
+ end
354
+ end
355
+ end
@@ -0,0 +1,169 @@
1
+ # typed: false
2
+ # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
3
+ # SPDX-License-Identifier: BSD-3-Clause-Clear
4
+
5
+ # frozen_string_literal: true
6
+
7
+ require_relative "../ast"
8
+
9
+ module Idl
10
+ class AstNode
11
+ # Generates asciidoc to document an implementation option.
12
+ #
13
+ # The result is *not* IDL code, but pretty-ified Asciidoc for document layout
14
+ #
15
+ # @return [String] Asciidoc source
16
+ def gen_option_adoc
17
+ internal_error "must implement gen_option_adoc for #{self.class.name}"
18
+ end
19
+ end
20
+
21
+ class FunctionBodyAst < AstNode
22
+ def gen_option_adoc
23
+ statements.map(&:gen_option_adoc).join("\n")
24
+ end
25
+ end
26
+
27
+ class FunctionCallExpressionAst < AstNode
28
+ def gen_option_adoc
29
+ gen_adoc(0)
30
+ end
31
+ end
32
+
33
+ class IfAst < AstNode
34
+ def gen_option_adoc
35
+ adoc =
36
+ <<~ADOC
37
+ [when,"#{if_cond.to_idl}"]
38
+ #{if_body.gen_option_adoc}
39
+ ADOC
40
+ elseifs.each do |eif|
41
+ adoc << <<~ADOC
42
+ [when,"#{eif.cond.to_idl}"]
43
+ #{eif.body.gen_option_adoc}
44
+ ADOC
45
+ end
46
+ unless final_else_body.nil?
47
+ if elseifs.empty?
48
+ if if_cond.is_a?(BinaryExpressionAst) || if_cond.is_a?(UnaryOperatorExpressionAst)
49
+ adoc << <<~ADOC
50
+ [when,"#{if_cond.invert(nil).to_idl}"]
51
+ #{final_else_body.gen_option_adoc}
52
+ ADOC
53
+ else
54
+ adoc << <<~ADOC
55
+ [when,"!(#{if_cond.to_idl})"]
56
+ #{final_else_body.gen_option_adoc}
57
+ ADOC
58
+ end
59
+ else
60
+ adoc << <<~ADOC
61
+ [when,"else"]
62
+ #{final_else_body.gen_option_adoc}
63
+ ADOC
64
+ end
65
+ end
66
+ adoc
67
+ end
68
+ end
69
+
70
+ class IfBodyAst < AstNode
71
+ def gen_option_adoc
72
+ stmts.map(&:gen_option_adoc).join("\n")
73
+ end
74
+ end
75
+
76
+ class ReturnStatementAst < AstNode
77
+ def gen_option_adoc
78
+ return_expression.gen_option_adoc
79
+ end
80
+ end
81
+
82
+ class StatementAst < AstNode
83
+ def gen_option_adoc
84
+ action.gen_option_adoc
85
+ end
86
+ end
87
+
88
+ class TrueExpressionAst < AstNode
89
+ def gen_option_adoc = "true"
90
+ end
91
+
92
+ class FalseExpressionAst < AstNode
93
+ def gen_option_adoc = "false"
94
+ end
95
+
96
+ class IdAst < AstNode
97
+ def gen_option_adoc
98
+ text_value
99
+ end
100
+ end
101
+
102
+ class IntLiteralAst < AstNode
103
+ def gen_option_adoc
104
+ if value(nil) == 1 << 65
105
+ "UNDEFINED_LEGAL"
106
+ elsif value(nil) == 1 << 66
107
+ "UNDEFINED_LEGAL_DETERMINISTIC"
108
+ else
109
+ text_value
110
+ end
111
+ end
112
+ end
113
+
114
+ class ReturnExpressionAst < AstNode
115
+ def gen_option_adoc
116
+ raise "unexpected" if return_value_nodes.size != 1
117
+
118
+ return_value_nodes[0].gen_option_adoc
119
+ end
120
+ end
121
+
122
+ class TernaryOperatorExpressionAst < AstNode
123
+ def gen_option_adoc
124
+ cond = condition.is_a?(ParenExpressionAst) ? condition.expression : condition
125
+ if cond.is_a?(BinaryExpressionAst) || cond.is_a?(UnaryOperatorExpressionAst)
126
+ <<~ADOC
127
+ [when,"#{cond.gen_adoc.gsub('"', "&quot;")}"]
128
+ #{true_expression.gen_option_adoc}
129
+
130
+ [when,"#{cond.invert(nil).gen_adoc.gsub('"', "&quot;")}"]
131
+ #{false_expression.gen_option_adoc}
132
+
133
+ ADOC
134
+ else
135
+ <<~ADOC
136
+ [when,"#{cond.gen_adoc.gsub('"', "&quot;")}"]
137
+ #{true_expression.gen_option_adoc}
138
+
139
+ [when,"!(#{cond.gen_adoc.gsub('"', "&quot;")})"]
140
+ #{false_expression.gen_option_adoc}
141
+
142
+ ADOC
143
+ end
144
+ end
145
+ end
146
+
147
+ class EnumRefAst < AstNode
148
+ def gen_option_adoc
149
+ if class_name == "CsrFieldType"
150
+ case member_name
151
+ when "RW", "RO"
152
+ member_name
153
+ when "ROH"
154
+ "RO-H"
155
+ when "RWR"
156
+ "RW-R"
157
+ when "RWH"
158
+ "RW-H"
159
+ when "RWRH"
160
+ "RW-RH"
161
+ else
162
+ raise "unexpected"
163
+ end
164
+ else
165
+ raise "Unexpected"
166
+ end
167
+ end
168
+ end
169
+ end