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.
- checksums.yaml +7 -0
- data/LICENSE +26 -0
- data/bin/idlc +10 -0
- data/lib/idlc/ast.rb +9611 -0
- data/lib/idlc/ast_decl.rb +22 -0
- data/lib/idlc/cli.rb +232 -0
- data/lib/idlc/idl.treetop +675 -0
- data/lib/idlc/idl_parser.rb +15386 -0
- data/lib/idlc/interfaces.rb +135 -0
- data/lib/idlc/log.rb +23 -0
- data/lib/idlc/passes/find_referenced_csrs.rb +39 -0
- data/lib/idlc/passes/find_return_values.rb +76 -0
- data/lib/idlc/passes/find_src_registers.rb +125 -0
- data/lib/idlc/passes/gen_adoc.rb +355 -0
- data/lib/idlc/passes/gen_option_adoc.rb +169 -0
- data/lib/idlc/passes/prune.rb +957 -0
- data/lib/idlc/passes/reachable_exceptions.rb +206 -0
- data/lib/idlc/passes/reachable_functions.rb +221 -0
- data/lib/idlc/symbol_table.rb +549 -0
- data/lib/idlc/syntax_node.rb +64 -0
- data/lib/idlc/type.rb +992 -0
- data/lib/idlc/version.rb +10 -0
- data/lib/idlc.rb +409 -0
- metadata +394 -0
|
@@ -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('"', """)}"]
|
|
128
|
+
#{true_expression.gen_option_adoc}
|
|
129
|
+
|
|
130
|
+
[when,"#{cond.invert(nil).gen_adoc.gsub('"', """)}"]
|
|
131
|
+
#{false_expression.gen_option_adoc}
|
|
132
|
+
|
|
133
|
+
ADOC
|
|
134
|
+
else
|
|
135
|
+
<<~ADOC
|
|
136
|
+
[when,"#{cond.gen_adoc.gsub('"', """)}"]
|
|
137
|
+
#{true_expression.gen_option_adoc}
|
|
138
|
+
|
|
139
|
+
[when,"!(#{cond.gen_adoc.gsub('"', """)})"]
|
|
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
|