c-next 0.2.15 → 0.2.17
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.
- package/README.md +16 -0
- package/dist/index.js +1403 -427
- package/dist/index.js.map +3 -3
- package/grammar/CNext.g4 +4 -0
- package/package.json +5 -1
- package/src/transpiler/Transpiler.ts +90 -22
- package/src/transpiler/__tests__/DualCodePaths.test.ts +1 -1
- package/src/transpiler/logic/analysis/FunctionCallAnalyzer.ts +57 -10
- package/src/transpiler/logic/analysis/InitializationAnalyzer.ts +186 -14
- package/src/transpiler/logic/analysis/SignedShiftAnalyzer.ts +124 -12
- package/src/transpiler/logic/analysis/__tests__/FunctionCallAnalyzer.test.ts +200 -0
- package/src/transpiler/logic/analysis/__tests__/InitializationAnalyzer.test.ts +386 -1
- package/src/transpiler/logic/analysis/__tests__/SignedShiftAnalyzer.test.ts +211 -0
- package/src/transpiler/logic/parser/grammar/CNext.interp +1 -1
- package/src/transpiler/logic/parser/grammar/CNextParser.ts +154 -86
- package/src/transpiler/logic/symbols/SymbolTable.ts +54 -12
- package/src/transpiler/logic/symbols/SymbolUtils.ts +21 -8
- package/src/transpiler/logic/symbols/__tests__/SymbolTable.test.ts +39 -4
- package/src/transpiler/logic/symbols/__tests__/SymbolUtils.test.ts +2 -1
- package/src/transpiler/logic/symbols/c/utils/DeclaratorUtils.ts +2 -1
- package/src/transpiler/logic/symbols/cnext/__tests__/CNextResolver.integration.test.ts +5 -2
- package/src/transpiler/logic/symbols/cnext/__tests__/ScopeCollector.test.ts +5 -2
- package/src/transpiler/logic/symbols/cnext/collectors/ScopeCollector.ts +7 -2
- package/src/transpiler/logic/symbols/cnext/collectors/VariableCollector.ts +15 -2
- package/src/transpiler/logic/symbols/cnext/utils/TypeUtils.ts +64 -50
- package/src/transpiler/logic/symbols/cpp/utils/DeclaratorUtils.ts +4 -2
- package/src/transpiler/output/codegen/CodeGenerator.ts +151 -94
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.coverage.test.ts +167 -18
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +150 -34
- package/src/transpiler/output/codegen/__tests__/TrackVariableTypeHelpers.test.ts +2 -2
- package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +11 -0
- package/src/transpiler/output/codegen/generators/declarationGenerators/ScopeGenerator.ts +32 -8
- package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ScopeGenerator.test.ts +91 -1
- package/src/transpiler/output/codegen/generators/expressions/BinaryExprGenerator.ts +43 -24
- package/src/transpiler/output/codegen/generators/expressions/CallExprGenerator.ts +48 -43
- package/src/transpiler/output/codegen/generators/expressions/ExpressionGenerator.ts +9 -2
- package/src/transpiler/output/codegen/generators/expressions/__tests__/CallExprGenerator.test.ts +44 -0
- package/src/transpiler/output/codegen/generators/expressions/__tests__/ExpressionGenerator.test.ts +82 -1
- package/src/transpiler/output/codegen/helpers/ParameterInputAdapter.ts +17 -3
- package/src/transpiler/output/codegen/helpers/ParameterSignatureBuilder.ts +17 -4
- package/src/transpiler/output/codegen/helpers/StringDeclHelper.ts +227 -32
- package/src/transpiler/output/codegen/helpers/SymbolLookupHelper.ts +0 -21
- package/src/transpiler/output/codegen/helpers/TypeGenerationHelper.ts +60 -39
- package/src/transpiler/output/codegen/helpers/TypeRegistrationEngine.ts +170 -36
- package/src/transpiler/output/codegen/helpers/VariableDeclHelper.ts +37 -39
- package/src/transpiler/output/codegen/helpers/__tests__/ParameterInputAdapter.test.ts +117 -0
- package/src/transpiler/output/codegen/helpers/__tests__/ParameterSignatureBuilder.test.ts +94 -2
- package/src/transpiler/output/codegen/helpers/__tests__/StringDeclHelper.test.ts +268 -1
- package/src/transpiler/output/codegen/helpers/__tests__/SymbolLookupHelper.test.ts +0 -64
- package/src/transpiler/output/codegen/helpers/__tests__/TypeRegistrationEngine.test.ts +101 -0
- package/src/transpiler/output/codegen/helpers/__tests__/VariableDeclHelper.test.ts +29 -5
- package/src/transpiler/output/codegen/types/ICallbackTypeInfo.ts +2 -1
- package/src/transpiler/output/codegen/types/IParameterInput.ts +7 -0
- package/src/transpiler/output/headers/BaseHeaderGenerator.ts +8 -0
- package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +75 -0
- package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +280 -0
- package/src/transpiler/output/headers/generators/IHeaderTypeInput.ts +13 -0
- package/src/transpiler/output/headers/generators/generateStructHeader.ts +48 -28
- package/src/transpiler/state/CodeGenState.ts +71 -6
- package/src/transpiler/state/__tests__/CodeGenState.test.ts +253 -11
- package/src/transpiler/types/symbols/c/ICFieldInfo.ts +6 -2
- package/src/transpiler/types/symbols/cpp/ICppFieldInfo.ts +5 -2
- package/src/utils/LiteralUtils.ts +23 -0
- package/src/utils/ScopeUtils.ts +19 -0
- package/src/utils/__tests__/LiteralUtils.test.ts +101 -0
- package/src/utils/__tests__/ScopeUtils.test.ts +10 -0
- package/src/utils/types/IParameterSymbol.ts +1 -0
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ import { hideBin } from "yargs/helpers";
|
|
|
11
11
|
// package.json
|
|
12
12
|
var package_default = {
|
|
13
13
|
name: "c-next",
|
|
14
|
-
version: "0.2.
|
|
14
|
+
version: "0.2.17",
|
|
15
15
|
description: "A safer C for embedded systems development. Transpiles to clean, readable C.",
|
|
16
16
|
packageManager: "npm@11.9.0",
|
|
17
17
|
type: "module",
|
|
@@ -35,6 +35,10 @@ var package_default = {
|
|
|
35
35
|
"test:update": "tsx scripts/test.ts --update",
|
|
36
36
|
"integration:transpile": "tsx scripts/test.ts --transpile-only",
|
|
37
37
|
"integration:execute": "tsx scripts/test.ts --execute-only",
|
|
38
|
+
"test:bugs": "tsx scripts/test.ts -- bugs",
|
|
39
|
+
"test:bugs:q": "tsx scripts/test.ts -- bugs -q",
|
|
40
|
+
"integration:bugs:transpile": "tsx scripts/test.ts -- bugs --transpile-only",
|
|
41
|
+
"integration:bugs:execute": "tsx scripts/test.ts -- bugs --execute-only",
|
|
38
42
|
analyze: "./scripts/static-analysis.sh",
|
|
39
43
|
clean: "rm -rf dist src/transpiler/logic/parser/grammar src/transpiler/logic/parser/c/grammar src/transpiler/logic/parser/cpp/grammar",
|
|
40
44
|
"prettier:check": "prettier --check .",
|
|
@@ -16039,21 +16043,10 @@ var CNextParser = class _CNextParser extends antlr2.Parser {
|
|
|
16039
16043
|
this.enterRule(localContext, 170, _CNextParser.RULE_arrayType);
|
|
16040
16044
|
let _la;
|
|
16041
16045
|
try {
|
|
16042
|
-
this.state =
|
|
16046
|
+
this.state = 939;
|
|
16043
16047
|
this.errorHandler.sync(this);
|
|
16044
|
-
switch (this.tokenStream.
|
|
16045
|
-
case
|
|
16046
|
-
case _CNextParser.U16:
|
|
16047
|
-
case _CNextParser.U32:
|
|
16048
|
-
case _CNextParser.U64:
|
|
16049
|
-
case _CNextParser.I8:
|
|
16050
|
-
case _CNextParser.I16:
|
|
16051
|
-
case _CNextParser.I32:
|
|
16052
|
-
case _CNextParser.I64:
|
|
16053
|
-
case _CNextParser.F32:
|
|
16054
|
-
case _CNextParser.F64:
|
|
16055
|
-
case _CNextParser.BOOL:
|
|
16056
|
-
case _CNextParser.ISR_TYPE:
|
|
16048
|
+
switch (this.interpreter.adaptivePredict(this.tokenStream, 98, this.context)) {
|
|
16049
|
+
case 1:
|
|
16057
16050
|
this.enterOuterAlt(localContext, 1);
|
|
16058
16051
|
{
|
|
16059
16052
|
this.state = 903;
|
|
@@ -16074,7 +16067,7 @@ var CNextParser = class _CNextParser extends antlr2.Parser {
|
|
|
16074
16067
|
} while (_la === 100);
|
|
16075
16068
|
}
|
|
16076
16069
|
break;
|
|
16077
|
-
case
|
|
16070
|
+
case 2:
|
|
16078
16071
|
this.enterOuterAlt(localContext, 2);
|
|
16079
16072
|
{
|
|
16080
16073
|
this.state = 909;
|
|
@@ -16095,7 +16088,7 @@ var CNextParser = class _CNextParser extends antlr2.Parser {
|
|
|
16095
16088
|
} while (_la === 100);
|
|
16096
16089
|
}
|
|
16097
16090
|
break;
|
|
16098
|
-
case
|
|
16091
|
+
case 3:
|
|
16099
16092
|
this.enterOuterAlt(localContext, 3);
|
|
16100
16093
|
{
|
|
16101
16094
|
this.state = 915;
|
|
@@ -16116,8 +16109,69 @@ var CNextParser = class _CNextParser extends antlr2.Parser {
|
|
|
16116
16109
|
} while (_la === 100);
|
|
16117
16110
|
}
|
|
16118
16111
|
break;
|
|
16119
|
-
|
|
16120
|
-
|
|
16112
|
+
case 4:
|
|
16113
|
+
this.enterOuterAlt(localContext, 4);
|
|
16114
|
+
{
|
|
16115
|
+
this.state = 921;
|
|
16116
|
+
this.scopedType();
|
|
16117
|
+
this.state = 923;
|
|
16118
|
+
this.errorHandler.sync(this);
|
|
16119
|
+
_la = this.tokenStream.LA(1);
|
|
16120
|
+
do {
|
|
16121
|
+
{
|
|
16122
|
+
{
|
|
16123
|
+
this.state = 922;
|
|
16124
|
+
this.arrayTypeDimension();
|
|
16125
|
+
}
|
|
16126
|
+
}
|
|
16127
|
+
this.state = 925;
|
|
16128
|
+
this.errorHandler.sync(this);
|
|
16129
|
+
_la = this.tokenStream.LA(1);
|
|
16130
|
+
} while (_la === 100);
|
|
16131
|
+
}
|
|
16132
|
+
break;
|
|
16133
|
+
case 5:
|
|
16134
|
+
this.enterOuterAlt(localContext, 5);
|
|
16135
|
+
{
|
|
16136
|
+
this.state = 927;
|
|
16137
|
+
this.qualifiedType();
|
|
16138
|
+
this.state = 929;
|
|
16139
|
+
this.errorHandler.sync(this);
|
|
16140
|
+
_la = this.tokenStream.LA(1);
|
|
16141
|
+
do {
|
|
16142
|
+
{
|
|
16143
|
+
{
|
|
16144
|
+
this.state = 928;
|
|
16145
|
+
this.arrayTypeDimension();
|
|
16146
|
+
}
|
|
16147
|
+
}
|
|
16148
|
+
this.state = 931;
|
|
16149
|
+
this.errorHandler.sync(this);
|
|
16150
|
+
_la = this.tokenStream.LA(1);
|
|
16151
|
+
} while (_la === 100);
|
|
16152
|
+
}
|
|
16153
|
+
break;
|
|
16154
|
+
case 6:
|
|
16155
|
+
this.enterOuterAlt(localContext, 6);
|
|
16156
|
+
{
|
|
16157
|
+
this.state = 933;
|
|
16158
|
+
this.globalType();
|
|
16159
|
+
this.state = 935;
|
|
16160
|
+
this.errorHandler.sync(this);
|
|
16161
|
+
_la = this.tokenStream.LA(1);
|
|
16162
|
+
do {
|
|
16163
|
+
{
|
|
16164
|
+
{
|
|
16165
|
+
this.state = 934;
|
|
16166
|
+
this.arrayTypeDimension();
|
|
16167
|
+
}
|
|
16168
|
+
}
|
|
16169
|
+
this.state = 937;
|
|
16170
|
+
this.errorHandler.sync(this);
|
|
16171
|
+
_la = this.tokenStream.LA(1);
|
|
16172
|
+
} while (_la === 100);
|
|
16173
|
+
}
|
|
16174
|
+
break;
|
|
16121
16175
|
}
|
|
16122
16176
|
} catch (re) {
|
|
16123
16177
|
if (re instanceof antlr2.RecognitionException) {
|
|
@@ -16138,18 +16192,18 @@ var CNextParser = class _CNextParser extends antlr2.Parser {
|
|
|
16138
16192
|
try {
|
|
16139
16193
|
this.enterOuterAlt(localContext, 1);
|
|
16140
16194
|
{
|
|
16141
|
-
this.state =
|
|
16195
|
+
this.state = 941;
|
|
16142
16196
|
this.match(_CNextParser.LBRACKET);
|
|
16143
|
-
this.state =
|
|
16197
|
+
this.state = 943;
|
|
16144
16198
|
this.errorHandler.sync(this);
|
|
16145
16199
|
_la = this.tokenStream.LA(1);
|
|
16146
16200
|
if ((_la & ~31) === 0 && (1 << _la & 2147532800) !== 0 || (_la - 32 & ~31) === 0 && (1 << _la - 32 & 1966091) !== 0 || (_la - 83 & ~31) === 0 && (1 << _la - 83 & 2130879681) !== 0) {
|
|
16147
16201
|
{
|
|
16148
|
-
this.state =
|
|
16202
|
+
this.state = 942;
|
|
16149
16203
|
this.expression();
|
|
16150
16204
|
}
|
|
16151
16205
|
}
|
|
16152
|
-
this.state =
|
|
16206
|
+
this.state = 945;
|
|
16153
16207
|
this.match(_CNextParser.RBRACKET);
|
|
16154
16208
|
}
|
|
16155
16209
|
} catch (re) {
|
|
@@ -16171,7 +16225,7 @@ var CNextParser = class _CNextParser extends antlr2.Parser {
|
|
|
16171
16225
|
try {
|
|
16172
16226
|
this.enterOuterAlt(localContext, 1);
|
|
16173
16227
|
{
|
|
16174
|
-
this.state =
|
|
16228
|
+
this.state = 947;
|
|
16175
16229
|
_la = this.tokenStream.LA(1);
|
|
16176
16230
|
if (!((_la - 31 & ~31) === 0 && (1 << _la - 31 & 3932167) !== 0 || (_la - 107 & ~31) === 0 && (1 << _la - 107 & 63) !== 0)) {
|
|
16177
16231
|
this.errorHandler.recoverInline(this);
|
|
@@ -16196,7 +16250,7 @@ var CNextParser = class _CNextParser extends antlr2.Parser {
|
|
|
16196
16250
|
4,
|
|
16197
16251
|
1,
|
|
16198
16252
|
117,
|
|
16199
|
-
|
|
16253
|
+
950,
|
|
16200
16254
|
2,
|
|
16201
16255
|
0,
|
|
16202
16256
|
7,
|
|
@@ -18171,9 +18225,51 @@ var CNextParser = class _CNextParser extends antlr2.Parser {
|
|
|
18171
18225
|
12,
|
|
18172
18226
|
85,
|
|
18173
18227
|
919,
|
|
18228
|
+
1,
|
|
18229
|
+
85,
|
|
18230
|
+
1,
|
|
18231
|
+
85,
|
|
18232
|
+
4,
|
|
18233
|
+
85,
|
|
18234
|
+
924,
|
|
18235
|
+
8,
|
|
18236
|
+
85,
|
|
18237
|
+
11,
|
|
18238
|
+
85,
|
|
18239
|
+
12,
|
|
18240
|
+
85,
|
|
18241
|
+
925,
|
|
18242
|
+
1,
|
|
18243
|
+
85,
|
|
18244
|
+
1,
|
|
18245
|
+
85,
|
|
18246
|
+
4,
|
|
18247
|
+
85,
|
|
18248
|
+
930,
|
|
18249
|
+
8,
|
|
18250
|
+
85,
|
|
18251
|
+
11,
|
|
18252
|
+
85,
|
|
18253
|
+
12,
|
|
18254
|
+
85,
|
|
18255
|
+
931,
|
|
18256
|
+
1,
|
|
18257
|
+
85,
|
|
18258
|
+
1,
|
|
18259
|
+
85,
|
|
18260
|
+
4,
|
|
18261
|
+
85,
|
|
18262
|
+
936,
|
|
18263
|
+
8,
|
|
18264
|
+
85,
|
|
18265
|
+
11,
|
|
18266
|
+
85,
|
|
18267
|
+
12,
|
|
18268
|
+
85,
|
|
18269
|
+
937,
|
|
18174
18270
|
3,
|
|
18175
18271
|
85,
|
|
18176
|
-
|
|
18272
|
+
940,
|
|
18177
18273
|
8,
|
|
18178
18274
|
85,
|
|
18179
18275
|
1,
|
|
@@ -18182,7 +18278,7 @@ var CNextParser = class _CNextParser extends antlr2.Parser {
|
|
|
18182
18278
|
86,
|
|
18183
18279
|
3,
|
|
18184
18280
|
86,
|
|
18185
|
-
|
|
18281
|
+
944,
|
|
18186
18282
|
8,
|
|
18187
18283
|
86,
|
|
18188
18284
|
1,
|
|
@@ -18348,7 +18444,7 @@ var CNextParser = class _CNextParser extends antlr2.Parser {
|
|
|
18348
18444
|
52,
|
|
18349
18445
|
107,
|
|
18350
18446
|
112,
|
|
18351
|
-
|
|
18447
|
+
1012,
|
|
18352
18448
|
0,
|
|
18353
18449
|
180,
|
|
18354
18450
|
1,
|
|
@@ -18860,19 +18956,19 @@ var CNextParser = class _CNextParser extends antlr2.Parser {
|
|
|
18860
18956
|
0,
|
|
18861
18957
|
0,
|
|
18862
18958
|
170,
|
|
18863
|
-
|
|
18959
|
+
939,
|
|
18864
18960
|
1,
|
|
18865
18961
|
0,
|
|
18866
18962
|
0,
|
|
18867
18963
|
0,
|
|
18868
18964
|
172,
|
|
18869
|
-
|
|
18965
|
+
941,
|
|
18870
18966
|
1,
|
|
18871
18967
|
0,
|
|
18872
18968
|
0,
|
|
18873
18969
|
0,
|
|
18874
18970
|
174,
|
|
18875
|
-
|
|
18971
|
+
947,
|
|
18876
18972
|
1,
|
|
18877
18973
|
0,
|
|
18878
18974
|
0,
|
|
@@ -24110,7 +24206,7 @@ var CNextParser = class _CNextParser extends antlr2.Parser {
|
|
|
24110
24206
|
0,
|
|
24111
24207
|
0,
|
|
24112
24208
|
908,
|
|
24113
|
-
|
|
24209
|
+
940,
|
|
24114
24210
|
1,
|
|
24115
24211
|
0,
|
|
24116
24212
|
0,
|
|
@@ -24152,7 +24248,7 @@ var CNextParser = class _CNextParser extends antlr2.Parser {
|
|
|
24152
24248
|
0,
|
|
24153
24249
|
0,
|
|
24154
24250
|
914,
|
|
24155
|
-
|
|
24251
|
+
940,
|
|
24156
24252
|
1,
|
|
24157
24253
|
0,
|
|
24158
24254
|
0,
|
|
@@ -24194,90 +24290,234 @@ var CNextParser = class _CNextParser extends antlr2.Parser {
|
|
|
24194
24290
|
0,
|
|
24195
24291
|
0,
|
|
24196
24292
|
920,
|
|
24197
|
-
|
|
24293
|
+
940,
|
|
24198
24294
|
1,
|
|
24199
24295
|
0,
|
|
24200
24296
|
0,
|
|
24201
24297
|
0,
|
|
24202
24298
|
921,
|
|
24299
|
+
923,
|
|
24300
|
+
3,
|
|
24301
|
+
152,
|
|
24302
|
+
76,
|
|
24303
|
+
0,
|
|
24304
|
+
922,
|
|
24305
|
+
924,
|
|
24306
|
+
3,
|
|
24307
|
+
172,
|
|
24308
|
+
86,
|
|
24309
|
+
0,
|
|
24310
|
+
923,
|
|
24311
|
+
922,
|
|
24312
|
+
1,
|
|
24313
|
+
0,
|
|
24314
|
+
0,
|
|
24315
|
+
0,
|
|
24316
|
+
924,
|
|
24317
|
+
925,
|
|
24318
|
+
1,
|
|
24319
|
+
0,
|
|
24320
|
+
0,
|
|
24321
|
+
0,
|
|
24322
|
+
925,
|
|
24323
|
+
923,
|
|
24324
|
+
1,
|
|
24325
|
+
0,
|
|
24326
|
+
0,
|
|
24327
|
+
0,
|
|
24328
|
+
925,
|
|
24329
|
+
926,
|
|
24330
|
+
1,
|
|
24331
|
+
0,
|
|
24332
|
+
0,
|
|
24333
|
+
0,
|
|
24334
|
+
926,
|
|
24335
|
+
940,
|
|
24336
|
+
1,
|
|
24337
|
+
0,
|
|
24338
|
+
0,
|
|
24339
|
+
0,
|
|
24340
|
+
927,
|
|
24341
|
+
929,
|
|
24342
|
+
3,
|
|
24343
|
+
156,
|
|
24344
|
+
78,
|
|
24345
|
+
0,
|
|
24346
|
+
928,
|
|
24347
|
+
930,
|
|
24348
|
+
3,
|
|
24349
|
+
172,
|
|
24350
|
+
86,
|
|
24351
|
+
0,
|
|
24352
|
+
929,
|
|
24353
|
+
928,
|
|
24354
|
+
1,
|
|
24355
|
+
0,
|
|
24356
|
+
0,
|
|
24357
|
+
0,
|
|
24358
|
+
930,
|
|
24359
|
+
931,
|
|
24360
|
+
1,
|
|
24361
|
+
0,
|
|
24362
|
+
0,
|
|
24363
|
+
0,
|
|
24364
|
+
931,
|
|
24365
|
+
929,
|
|
24366
|
+
1,
|
|
24367
|
+
0,
|
|
24368
|
+
0,
|
|
24369
|
+
0,
|
|
24370
|
+
931,
|
|
24371
|
+
932,
|
|
24372
|
+
1,
|
|
24373
|
+
0,
|
|
24374
|
+
0,
|
|
24375
|
+
0,
|
|
24376
|
+
932,
|
|
24377
|
+
940,
|
|
24378
|
+
1,
|
|
24379
|
+
0,
|
|
24380
|
+
0,
|
|
24381
|
+
0,
|
|
24382
|
+
933,
|
|
24383
|
+
935,
|
|
24384
|
+
3,
|
|
24385
|
+
154,
|
|
24386
|
+
77,
|
|
24387
|
+
0,
|
|
24388
|
+
934,
|
|
24389
|
+
936,
|
|
24390
|
+
3,
|
|
24391
|
+
172,
|
|
24392
|
+
86,
|
|
24393
|
+
0,
|
|
24394
|
+
935,
|
|
24395
|
+
934,
|
|
24396
|
+
1,
|
|
24397
|
+
0,
|
|
24398
|
+
0,
|
|
24399
|
+
0,
|
|
24400
|
+
936,
|
|
24401
|
+
937,
|
|
24402
|
+
1,
|
|
24403
|
+
0,
|
|
24404
|
+
0,
|
|
24405
|
+
0,
|
|
24406
|
+
937,
|
|
24407
|
+
935,
|
|
24408
|
+
1,
|
|
24409
|
+
0,
|
|
24410
|
+
0,
|
|
24411
|
+
0,
|
|
24412
|
+
937,
|
|
24413
|
+
938,
|
|
24414
|
+
1,
|
|
24415
|
+
0,
|
|
24416
|
+
0,
|
|
24417
|
+
0,
|
|
24418
|
+
938,
|
|
24419
|
+
940,
|
|
24420
|
+
1,
|
|
24421
|
+
0,
|
|
24422
|
+
0,
|
|
24423
|
+
0,
|
|
24424
|
+
939,
|
|
24203
24425
|
903,
|
|
24204
24426
|
1,
|
|
24205
24427
|
0,
|
|
24206
24428
|
0,
|
|
24207
24429
|
0,
|
|
24208
|
-
|
|
24430
|
+
939,
|
|
24209
24431
|
909,
|
|
24210
24432
|
1,
|
|
24211
24433
|
0,
|
|
24212
24434
|
0,
|
|
24213
24435
|
0,
|
|
24214
|
-
|
|
24436
|
+
939,
|
|
24215
24437
|
915,
|
|
24216
24438
|
1,
|
|
24217
24439
|
0,
|
|
24218
24440
|
0,
|
|
24219
24441
|
0,
|
|
24220
|
-
|
|
24442
|
+
939,
|
|
24443
|
+
921,
|
|
24444
|
+
1,
|
|
24445
|
+
0,
|
|
24446
|
+
0,
|
|
24447
|
+
0,
|
|
24448
|
+
939,
|
|
24449
|
+
927,
|
|
24450
|
+
1,
|
|
24451
|
+
0,
|
|
24452
|
+
0,
|
|
24453
|
+
0,
|
|
24454
|
+
939,
|
|
24455
|
+
933,
|
|
24456
|
+
1,
|
|
24457
|
+
0,
|
|
24458
|
+
0,
|
|
24459
|
+
0,
|
|
24460
|
+
940,
|
|
24221
24461
|
171,
|
|
24222
24462
|
1,
|
|
24223
24463
|
0,
|
|
24224
24464
|
0,
|
|
24225
24465
|
0,
|
|
24226
|
-
|
|
24227
|
-
|
|
24466
|
+
941,
|
|
24467
|
+
943,
|
|
24228
24468
|
5,
|
|
24229
24469
|
100,
|
|
24230
24470
|
0,
|
|
24231
24471
|
0,
|
|
24232
|
-
|
|
24233
|
-
|
|
24472
|
+
942,
|
|
24473
|
+
944,
|
|
24234
24474
|
3,
|
|
24235
24475
|
102,
|
|
24236
24476
|
51,
|
|
24237
24477
|
0,
|
|
24238
|
-
|
|
24239
|
-
|
|
24478
|
+
943,
|
|
24479
|
+
942,
|
|
24240
24480
|
1,
|
|
24241
24481
|
0,
|
|
24242
24482
|
0,
|
|
24243
24483
|
0,
|
|
24244
|
-
|
|
24245
|
-
|
|
24484
|
+
943,
|
|
24485
|
+
944,
|
|
24246
24486
|
1,
|
|
24247
24487
|
0,
|
|
24248
24488
|
0,
|
|
24249
24489
|
0,
|
|
24250
|
-
|
|
24251
|
-
|
|
24490
|
+
944,
|
|
24491
|
+
945,
|
|
24252
24492
|
1,
|
|
24253
24493
|
0,
|
|
24254
24494
|
0,
|
|
24255
24495
|
0,
|
|
24256
|
-
|
|
24257
|
-
|
|
24496
|
+
945,
|
|
24497
|
+
946,
|
|
24258
24498
|
5,
|
|
24259
24499
|
101,
|
|
24260
24500
|
0,
|
|
24261
24501
|
0,
|
|
24262
|
-
|
|
24502
|
+
946,
|
|
24263
24503
|
173,
|
|
24264
24504
|
1,
|
|
24265
24505
|
0,
|
|
24266
24506
|
0,
|
|
24267
24507
|
0,
|
|
24268
|
-
|
|
24269
|
-
|
|
24508
|
+
947,
|
|
24509
|
+
948,
|
|
24270
24510
|
7,
|
|
24271
24511
|
13,
|
|
24272
24512
|
0,
|
|
24273
24513
|
0,
|
|
24274
|
-
|
|
24514
|
+
948,
|
|
24275
24515
|
175,
|
|
24276
24516
|
1,
|
|
24277
24517
|
0,
|
|
24278
24518
|
0,
|
|
24279
24519
|
0,
|
|
24280
|
-
|
|
24520
|
+
100,
|
|
24281
24521
|
178,
|
|
24282
24522
|
180,
|
|
24283
24523
|
186,
|
|
@@ -24373,8 +24613,11 @@ var CNextParser = class _CNextParser extends antlr2.Parser {
|
|
|
24373
24613
|
907,
|
|
24374
24614
|
913,
|
|
24375
24615
|
919,
|
|
24376
|
-
|
|
24377
|
-
|
|
24616
|
+
925,
|
|
24617
|
+
931,
|
|
24618
|
+
937,
|
|
24619
|
+
939,
|
|
24620
|
+
943
|
|
24378
24621
|
];
|
|
24379
24622
|
static __ATN;
|
|
24380
24623
|
static get _ATN() {
|
|
@@ -27875,6 +28118,15 @@ var ArrayTypeContext = class extends antlr2.ParserRuleContext {
|
|
|
27875
28118
|
stringType() {
|
|
27876
28119
|
return this.getRuleContext(0, StringTypeContext);
|
|
27877
28120
|
}
|
|
28121
|
+
scopedType() {
|
|
28122
|
+
return this.getRuleContext(0, ScopedTypeContext);
|
|
28123
|
+
}
|
|
28124
|
+
qualifiedType() {
|
|
28125
|
+
return this.getRuleContext(0, QualifiedTypeContext);
|
|
28126
|
+
}
|
|
28127
|
+
globalType() {
|
|
28128
|
+
return this.getRuleContext(0, GlobalTypeContext);
|
|
28129
|
+
}
|
|
27878
28130
|
get ruleIndex() {
|
|
27879
28131
|
return CNextParser.RULE_arrayType;
|
|
27880
28132
|
}
|
|
@@ -111383,7 +111635,7 @@ var ESourceLanguage = /* @__PURE__ */ ((ESourceLanguage2) => {
|
|
|
111383
111635
|
var ESourceLanguage_default = ESourceLanguage;
|
|
111384
111636
|
|
|
111385
111637
|
// src/utils/LiteralUtils.ts
|
|
111386
|
-
var LiteralUtils = class {
|
|
111638
|
+
var LiteralUtils = class _LiteralUtils {
|
|
111387
111639
|
/**
|
|
111388
111640
|
* Check if a literal represents zero.
|
|
111389
111641
|
*
|
|
@@ -111418,8 +111670,25 @@ var LiteralUtils = class {
|
|
|
111418
111670
|
if (ctx.SUFFIXED_BINARY()) {
|
|
111419
111671
|
return text.startsWith("0b0u") || text.startsWith("0b0i") || text.startsWith("0B0u") || text.startsWith("0B0i");
|
|
111420
111672
|
}
|
|
111673
|
+
if (ctx.FLOAT_LITERAL()) {
|
|
111674
|
+
return _LiteralUtils.isFloatZero(text);
|
|
111675
|
+
}
|
|
111421
111676
|
return false;
|
|
111422
111677
|
}
|
|
111678
|
+
/**
|
|
111679
|
+
* Check if a float literal string represents zero.
|
|
111680
|
+
* Issue #1010: Detect float zero for division-by-zero checking.
|
|
111681
|
+
*
|
|
111682
|
+
* Handles: 0.0, .0, 0., 0.0f, 0.0F, 0.0e0, 0.0E0, etc.
|
|
111683
|
+
*
|
|
111684
|
+
* @param text - The float literal text
|
|
111685
|
+
* @returns true if the float is zero
|
|
111686
|
+
*/
|
|
111687
|
+
static isFloatZero(text) {
|
|
111688
|
+
const withoutSuffix = text.replace(/[fF]$/, "");
|
|
111689
|
+
const value = Number.parseFloat(withoutSuffix);
|
|
111690
|
+
return value === 0;
|
|
111691
|
+
}
|
|
111423
111692
|
/**
|
|
111424
111693
|
* Check if a literal is a floating-point number.
|
|
111425
111694
|
*
|
|
@@ -111792,19 +112061,17 @@ var SymbolTable = class {
|
|
|
111792
112061
|
/**
|
|
111793
112062
|
* Register struct fields in structFields map for cross-file type resolution.
|
|
111794
112063
|
* Called automatically when adding struct symbols.
|
|
112064
|
+
* Issue #981: Now preserves string dimensions (macro names) for proper array detection.
|
|
111795
112065
|
*/
|
|
111796
112066
|
registerStructFields(struct) {
|
|
111797
112067
|
const cName = SymbolNameUtils_default.getTranspiledCName(struct);
|
|
111798
112068
|
for (const [fieldName, fieldInfo] of struct.fields) {
|
|
111799
112069
|
const typeString = TypeResolver_default.getTypeName(fieldInfo.type);
|
|
111800
|
-
const numericDims = fieldInfo.dimensions?.filter(
|
|
111801
|
-
(d) => typeof d === "number"
|
|
111802
|
-
);
|
|
111803
112070
|
this.addStructField(
|
|
111804
112071
|
cName,
|
|
111805
112072
|
fieldName,
|
|
111806
112073
|
typeString,
|
|
111807
|
-
|
|
112074
|
+
fieldInfo.dimensions && fieldInfo.dimensions.length > 0 ? fieldInfo.dimensions : void 0
|
|
111808
112075
|
);
|
|
111809
112076
|
}
|
|
111810
112077
|
}
|
|
@@ -111917,6 +112184,7 @@ var SymbolTable = class {
|
|
|
111917
112184
|
// ========================================================================
|
|
111918
112185
|
/**
|
|
111919
112186
|
* Add a C symbol to the table
|
|
112187
|
+
* Issue #981: Also register struct fields for type resolution
|
|
111920
112188
|
*/
|
|
111921
112189
|
addCSymbol(symbol) {
|
|
111922
112190
|
const existing = this.cSymbols.get(symbol.name);
|
|
@@ -111931,6 +112199,23 @@ var SymbolTable = class {
|
|
|
111931
112199
|
} else {
|
|
111932
112200
|
this.cSymbolsByFile.set(symbol.sourceFile, [symbol]);
|
|
111933
112201
|
}
|
|
112202
|
+
if (symbol.kind === "struct" && symbol.fields) {
|
|
112203
|
+
this.registerCStructFields(symbol.name, symbol.fields);
|
|
112204
|
+
}
|
|
112205
|
+
}
|
|
112206
|
+
/**
|
|
112207
|
+
* Register C struct fields in structFields map for cross-file type resolution.
|
|
112208
|
+
* Issue #981: Required for macro-sized array field detection on local struct variables.
|
|
112209
|
+
*/
|
|
112210
|
+
registerCStructFields(structName, fields) {
|
|
112211
|
+
for (const [fieldName, fieldInfo] of fields) {
|
|
112212
|
+
this.addStructField(
|
|
112213
|
+
structName,
|
|
112214
|
+
fieldName,
|
|
112215
|
+
fieldInfo.type,
|
|
112216
|
+
fieldInfo.arrayDimensions
|
|
112217
|
+
);
|
|
112218
|
+
}
|
|
111934
112219
|
}
|
|
111935
112220
|
/**
|
|
111936
112221
|
* Add multiple C symbols at once
|
|
@@ -112265,11 +112550,12 @@ Rename the C-Next symbol to resolve.`
|
|
|
112265
112550
|
// Struct Field Information
|
|
112266
112551
|
// ========================================================================
|
|
112267
112552
|
/**
|
|
112268
|
-
* Add struct field information
|
|
112553
|
+
* Add struct field information.
|
|
112554
|
+
* Issue #981: Accept (number | string)[] for arrayDimensions to support macro-sized arrays.
|
|
112269
112555
|
* @param structName Name of the struct
|
|
112270
112556
|
* @param fieldName Name of the field
|
|
112271
112557
|
* @param fieldType Type of the field (e.g., "uint32_t")
|
|
112272
|
-
* @param arrayDimensions Optional array dimensions
|
|
112558
|
+
* @param arrayDimensions Optional array dimensions - numbers for resolved, strings for macros
|
|
112273
112559
|
*/
|
|
112274
112560
|
addStructField(structName, fieldName, fieldType, arrayDimensions) {
|
|
112275
112561
|
let fields = this.structFields.get(structName);
|
|
@@ -112279,7 +112565,7 @@ Rename the C-Next symbol to resolve.`
|
|
|
112279
112565
|
}
|
|
112280
112566
|
fields.set(fieldName, {
|
|
112281
112567
|
type: fieldType,
|
|
112282
|
-
arrayDimensions
|
|
112568
|
+
arrayDimensions: arrayDimensions ? [...arrayDimensions] : void 0
|
|
112283
112569
|
});
|
|
112284
112570
|
}
|
|
112285
112571
|
/**
|
|
@@ -112522,12 +112808,23 @@ Rename the C-Next symbol to resolve.`
|
|
|
112522
112808
|
* Issue #958: Check if a typedef aliases a struct type.
|
|
112523
112809
|
* Used for scope variables, function parameters, and local variables
|
|
112524
112810
|
* which should be pointers for C-header struct types.
|
|
112811
|
+
*
|
|
112812
|
+
* Issue #948: Performs query-time resolution - if the underlying struct
|
|
112813
|
+
* tag has a full body definition, this is NOT an external typedef struct
|
|
112814
|
+
* (it's a complete type that can use value semantics).
|
|
112815
|
+
*
|
|
112525
112816
|
* @param typeName The type name to check
|
|
112526
112817
|
* @returns true if this is a typedef'd struct type from C headers
|
|
112527
112818
|
*/
|
|
112528
112819
|
isTypedefStructType(typeName) {
|
|
112529
|
-
|
|
112530
|
-
|
|
112820
|
+
if (!this.structState.typedefStructTypes.has(typeName)) {
|
|
112821
|
+
return false;
|
|
112822
|
+
}
|
|
112823
|
+
const tag = this.structState.typedefToTag.get(typeName);
|
|
112824
|
+
if (tag && this.structState.structTagsWithBodies.has(tag)) {
|
|
112825
|
+
return false;
|
|
112826
|
+
}
|
|
112827
|
+
return true;
|
|
112531
112828
|
}
|
|
112532
112829
|
/**
|
|
112533
112830
|
* Issue #958: Get all typedef struct types for cache serialization.
|
|
@@ -112781,6 +113078,11 @@ var CodeGenState = class _CodeGenState {
|
|
|
112781
113078
|
static indentLevel = 0;
|
|
112782
113079
|
/** Whether we're inside a function body */
|
|
112783
113080
|
static inFunctionBody = false;
|
|
113081
|
+
/** Whether we're generating the RHS of a variable declaration initializer.
|
|
113082
|
+
* When true, struct literals use { .field = value } instead of (Type){ .field = value }
|
|
113083
|
+
* because plain designated initializers are valid C99 at any scope, while compound
|
|
113084
|
+
* literals are not constant expressions and fail at file scope on GCC < 13. */
|
|
113085
|
+
static inDeclarationInit = false;
|
|
112784
113086
|
/** Expected type for struct initializers and enum inference */
|
|
112785
113087
|
static expectedType = null;
|
|
112786
113088
|
/**
|
|
@@ -112893,6 +113195,7 @@ var CodeGenState = class _CodeGenState {
|
|
|
112893
113195
|
this.floatShadowCurrent = /* @__PURE__ */ new Set();
|
|
112894
113196
|
this.indentLevel = 0;
|
|
112895
113197
|
this.inFunctionBody = false;
|
|
113198
|
+
this.inDeclarationInit = false;
|
|
112896
113199
|
this.expectedType = null;
|
|
112897
113200
|
this.suppressBareEnumResolution = false;
|
|
112898
113201
|
this.mainArgsName = null;
|
|
@@ -112972,6 +113275,46 @@ var CodeGenState = class _CodeGenState {
|
|
|
112972
113275
|
this.suppressBareEnumResolution = savedSuppress;
|
|
112973
113276
|
}
|
|
112974
113277
|
}
|
|
113278
|
+
/** Execute fn with inDeclarationInit=true, restoring prior value on exit. */
|
|
113279
|
+
static withDeclarationInit(fn) {
|
|
113280
|
+
const saved = this.inDeclarationInit;
|
|
113281
|
+
this.inDeclarationInit = true;
|
|
113282
|
+
try {
|
|
113283
|
+
return fn();
|
|
113284
|
+
} finally {
|
|
113285
|
+
this.inDeclarationInit = saved;
|
|
113286
|
+
}
|
|
113287
|
+
}
|
|
113288
|
+
/** Execute fn with inDeclarationInit=false, restoring prior value on exit.
|
|
113289
|
+
* Used in sub-expression contexts (function args, ternary arms) where
|
|
113290
|
+
* plain designated initializers are not valid C. */
|
|
113291
|
+
static withoutDeclarationInit(fn) {
|
|
113292
|
+
const saved = this.inDeclarationInit;
|
|
113293
|
+
this.inDeclarationInit = false;
|
|
113294
|
+
try {
|
|
113295
|
+
return fn();
|
|
113296
|
+
} finally {
|
|
113297
|
+
this.inDeclarationInit = saved;
|
|
113298
|
+
}
|
|
113299
|
+
}
|
|
113300
|
+
/**
|
|
113301
|
+
* Execute fn with expectedType=null, restoring prior value on exit.
|
|
113302
|
+
* Issue #1032: Used in comparison contexts (relational/equality expressions)
|
|
113303
|
+
* where MISRA 7.2 U suffix should NOT be applied - comparing `i32 < 0`
|
|
113304
|
+
* should not generate `signedIdx < 0U` which changes comparison semantics.
|
|
113305
|
+
*/
|
|
113306
|
+
static withoutExpectedType(fn) {
|
|
113307
|
+
const savedType = this.expectedType;
|
|
113308
|
+
const savedSuppress = this.suppressBareEnumResolution;
|
|
113309
|
+
this.expectedType = null;
|
|
113310
|
+
this.suppressBareEnumResolution = false;
|
|
113311
|
+
try {
|
|
113312
|
+
return fn();
|
|
113313
|
+
} finally {
|
|
113314
|
+
this.expectedType = savedType;
|
|
113315
|
+
this.suppressBareEnumResolution = savedSuppress;
|
|
113316
|
+
}
|
|
113317
|
+
}
|
|
112975
113318
|
// ===========================================================================
|
|
112976
113319
|
// CONVENIENCE LOOKUP METHODS
|
|
112977
113320
|
// ===========================================================================
|
|
@@ -113508,14 +113851,27 @@ var CodeGenState = class _CodeGenState {
|
|
|
113508
113851
|
this.opaqueScopeVariables.add(qualifiedName);
|
|
113509
113852
|
}
|
|
113510
113853
|
/**
|
|
113511
|
-
* Check if
|
|
113512
|
-
* Used during
|
|
113854
|
+
* Check if generated code accesses an opaque scope variable (and is thus
|
|
113855
|
+
* already a pointer). Used during argument generation to decide whether an
|
|
113856
|
+
* address-of (&) prefix is needed.
|
|
113513
113857
|
*
|
|
113514
|
-
*
|
|
113515
|
-
*
|
|
113858
|
+
* Handles two forms:
|
|
113859
|
+
* - Direct access: "MyScope_widget" → the handle itself (pointer)
|
|
113860
|
+
* - Array-element access: "MyScope_widgets[i]" → an element of an opaque
|
|
113861
|
+
* handle array, which is itself a pointer (Issue #996)
|
|
113862
|
+
*
|
|
113863
|
+
* @param generatedCode - The generated access expression (e.g. "UI_widgets[i]")
|
|
113864
|
+
* @returns true if this resolves to an opaque scope variable (already a pointer)
|
|
113516
113865
|
*/
|
|
113517
|
-
static
|
|
113518
|
-
|
|
113866
|
+
static isOpaqueScopeVariableAccess(generatedCode) {
|
|
113867
|
+
if (this.opaqueScopeVariables.has(generatedCode)) {
|
|
113868
|
+
return true;
|
|
113869
|
+
}
|
|
113870
|
+
const bracketIndex = generatedCode.indexOf("[");
|
|
113871
|
+
if (bracketIndex === -1) {
|
|
113872
|
+
return false;
|
|
113873
|
+
}
|
|
113874
|
+
return this.opaqueScopeVariables.has(generatedCode.slice(0, bracketIndex));
|
|
113519
113875
|
}
|
|
113520
113876
|
// ===========================================================================
|
|
113521
113877
|
// C++ MODE HELPERS
|
|
@@ -113675,6 +114031,22 @@ var ScopeUtils = class _ScopeUtils {
|
|
|
113675
114031
|
return scope.name === "" && scope.parent === scope;
|
|
113676
114032
|
}
|
|
113677
114033
|
// ============================================================================
|
|
114034
|
+
// Visibility Utilities
|
|
114035
|
+
// ============================================================================
|
|
114036
|
+
/**
|
|
114037
|
+
* ADR-016: Get the default visibility for a scope member based on its type.
|
|
114038
|
+
*
|
|
114039
|
+
* Member-type-aware defaults reduce boilerplate:
|
|
114040
|
+
* - Functions: public by default (API surface)
|
|
114041
|
+
* - Variables/types: private by default (internal state)
|
|
114042
|
+
*
|
|
114043
|
+
* @param isFunction - Whether the member is a function declaration
|
|
114044
|
+
* @returns The default visibility for this member type
|
|
114045
|
+
*/
|
|
114046
|
+
static getDefaultVisibility(isFunction) {
|
|
114047
|
+
return isFunction ? "public" : "private";
|
|
114048
|
+
}
|
|
114049
|
+
// ============================================================================
|
|
113678
114050
|
// Path Utilities
|
|
113679
114051
|
// ============================================================================
|
|
113680
114052
|
/**
|
|
@@ -114409,41 +114781,73 @@ var TypeRegistrationEngine = class _TypeRegistrationEngine {
|
|
|
114409
114781
|
});
|
|
114410
114782
|
return true;
|
|
114411
114783
|
}
|
|
114784
|
+
/**
|
|
114785
|
+
* Issue #1029: Register type info for string arrays (string<N>[M]).
|
|
114786
|
+
*
|
|
114787
|
+
* String arrays are parsed as arrayType with stringType inside:
|
|
114788
|
+
* arrayType -> stringType arrayTypeDimension+
|
|
114789
|
+
*
|
|
114790
|
+
* For `string<32>[4] items`:
|
|
114791
|
+
* - stringType gives capacity 32
|
|
114792
|
+
* - arrayTypeDimension gives [4]
|
|
114793
|
+
* - Result: char items[4][33] with dimensions [4, 33]
|
|
114794
|
+
*/
|
|
114795
|
+
static _registerStringArrayType(registryName, arrayTypeCtx, arrayDim, isConst, overflowBehavior, isAtomic, callbacks) {
|
|
114796
|
+
const stringCtx = arrayTypeCtx.stringType();
|
|
114797
|
+
const intLiteral = stringCtx.INTEGER_LITERAL();
|
|
114798
|
+
if (!intLiteral) {
|
|
114799
|
+
return;
|
|
114800
|
+
}
|
|
114801
|
+
const capacity = Number.parseInt(intLiteral.getText(), 10);
|
|
114802
|
+
callbacks.requireInclude("string");
|
|
114803
|
+
const stringDim = capacity + 1;
|
|
114804
|
+
const arrayTypeDims = arrayTypeCtx.arrayTypeDimension().map((dim) => dim.expression()).filter((expr) => expr !== null).map((expr) => Number.parseInt(expr.getText(), 10)).filter((size) => !Number.isNaN(size));
|
|
114805
|
+
const additionalDims = ArrayDimensionParser_default.parseSimpleDimensions(arrayDim);
|
|
114806
|
+
const dimensions = [...arrayTypeDims, ...additionalDims, stringDim];
|
|
114807
|
+
CodeGenState.setVariableTypeInfo(registryName, {
|
|
114808
|
+
baseType: "char",
|
|
114809
|
+
bitWidth: 8,
|
|
114810
|
+
isArray: true,
|
|
114811
|
+
arrayDimensions: dimensions,
|
|
114812
|
+
isConst,
|
|
114813
|
+
isString: true,
|
|
114814
|
+
stringCapacity: capacity,
|
|
114815
|
+
overflowBehavior,
|
|
114816
|
+
isAtomic
|
|
114817
|
+
});
|
|
114818
|
+
}
|
|
114412
114819
|
// ============================================================================
|
|
114413
114820
|
// Array and standard type registration
|
|
114414
114821
|
// ============================================================================
|
|
114415
114822
|
static _registerArrayTypeVariable(registryName, arrayTypeCtx, arrayDim, isConst, overflowBehavior, isAtomic, callbacks) {
|
|
114416
|
-
|
|
114417
|
-
|
|
114418
|
-
if (arrayTypeCtx.primitiveType()) {
|
|
114419
|
-
baseType = arrayTypeCtx.primitiveType().getText();
|
|
114420
|
-
bitWidth = TYPE_WIDTH_default[baseType] || 0;
|
|
114421
|
-
} else if (arrayTypeCtx.userType()) {
|
|
114422
|
-
baseType = arrayTypeCtx.userType().getText();
|
|
114423
|
-
const combinedArrayDim = arrayDim ?? [];
|
|
114424
|
-
if (_TypeRegistrationEngine._tryRegisterEnumOrBitmapType(
|
|
114823
|
+
if (arrayTypeCtx.stringType()) {
|
|
114824
|
+
_TypeRegistrationEngine._registerStringArrayType(
|
|
114425
114825
|
registryName,
|
|
114426
|
-
|
|
114826
|
+
arrayTypeCtx,
|
|
114827
|
+
arrayDim,
|
|
114427
114828
|
isConst,
|
|
114428
|
-
combinedArrayDim,
|
|
114429
114829
|
overflowBehavior,
|
|
114430
114830
|
isAtomic,
|
|
114431
114831
|
callbacks
|
|
114432
|
-
)
|
|
114433
|
-
|
|
114434
|
-
|
|
114435
|
-
|
|
114436
|
-
|
|
114437
|
-
|
|
114438
|
-
|
|
114439
|
-
|
|
114440
|
-
|
|
114441
|
-
|
|
114442
|
-
|
|
114832
|
+
);
|
|
114833
|
+
return;
|
|
114834
|
+
}
|
|
114835
|
+
if (arrayTypeCtx.userType()) {
|
|
114836
|
+
const registered = _TypeRegistrationEngine._tryRegisterUserTypeArray(
|
|
114837
|
+
registryName,
|
|
114838
|
+
arrayTypeCtx,
|
|
114839
|
+
arrayDim,
|
|
114840
|
+
isConst,
|
|
114841
|
+
overflowBehavior,
|
|
114842
|
+
isAtomic,
|
|
114843
|
+
callbacks
|
|
114844
|
+
);
|
|
114845
|
+
if (registered) {
|
|
114443
114846
|
return;
|
|
114444
114847
|
}
|
|
114445
114848
|
}
|
|
114446
|
-
|
|
114849
|
+
const typeInfo = _TypeRegistrationEngine._extractArrayBaseTypeInfo(arrayTypeCtx);
|
|
114850
|
+
if (!typeInfo.baseType) {
|
|
114447
114851
|
return;
|
|
114448
114852
|
}
|
|
114449
114853
|
const arrayDimensions = _TypeRegistrationEngine._collectArrayDimensions(
|
|
@@ -114452,8 +114856,8 @@ var TypeRegistrationEngine = class _TypeRegistrationEngine {
|
|
|
114452
114856
|
callbacks
|
|
114453
114857
|
);
|
|
114454
114858
|
CodeGenState.setVariableTypeInfo(registryName, {
|
|
114455
|
-
baseType,
|
|
114456
|
-
bitWidth,
|
|
114859
|
+
baseType: typeInfo.baseType,
|
|
114860
|
+
bitWidth: typeInfo.bitWidth,
|
|
114457
114861
|
isArray: true,
|
|
114458
114862
|
arrayDimensions: arrayDimensions.length > 0 ? arrayDimensions : void 0,
|
|
114459
114863
|
isConst,
|
|
@@ -114461,6 +114865,64 @@ var TypeRegistrationEngine = class _TypeRegistrationEngine {
|
|
|
114461
114865
|
isAtomic
|
|
114462
114866
|
});
|
|
114463
114867
|
}
|
|
114868
|
+
/**
|
|
114869
|
+
* Extract base type and bit width from an array type context.
|
|
114870
|
+
* Handles primitive, qualified, scoped, and user types.
|
|
114871
|
+
*/
|
|
114872
|
+
static _extractArrayBaseTypeInfo(arrayTypeCtx) {
|
|
114873
|
+
if (arrayTypeCtx.primitiveType()) {
|
|
114874
|
+
const baseType = arrayTypeCtx.primitiveType().getText();
|
|
114875
|
+
return { baseType, bitWidth: TYPE_WIDTH_default[baseType] || 0 };
|
|
114876
|
+
}
|
|
114877
|
+
if (arrayTypeCtx.qualifiedType()) {
|
|
114878
|
+
const parts = arrayTypeCtx.qualifiedType().IDENTIFIER();
|
|
114879
|
+
return { baseType: parts.map((p) => p.getText()).join("_"), bitWidth: 0 };
|
|
114880
|
+
}
|
|
114881
|
+
if (arrayTypeCtx.scopedType()) {
|
|
114882
|
+
const typeName = arrayTypeCtx.scopedType().IDENTIFIER().getText();
|
|
114883
|
+
const baseType = CodeGenState.currentScope ? `${CodeGenState.currentScope}_${typeName}` : typeName;
|
|
114884
|
+
return { baseType, bitWidth: 0 };
|
|
114885
|
+
}
|
|
114886
|
+
if (arrayTypeCtx.globalType()) {
|
|
114887
|
+
const typeName = arrayTypeCtx.globalType().IDENTIFIER().getText();
|
|
114888
|
+
return { baseType: typeName, bitWidth: 0 };
|
|
114889
|
+
}
|
|
114890
|
+
if (arrayTypeCtx.userType()) {
|
|
114891
|
+
return { baseType: arrayTypeCtx.userType().getText(), bitWidth: 0 };
|
|
114892
|
+
}
|
|
114893
|
+
return { baseType: "", bitWidth: 0 };
|
|
114894
|
+
}
|
|
114895
|
+
/**
|
|
114896
|
+
* Try to register a user type array as enum or bitmap.
|
|
114897
|
+
* Returns true if registration was handled, false if it should fall through.
|
|
114898
|
+
*/
|
|
114899
|
+
static _tryRegisterUserTypeArray(registryName, arrayTypeCtx, arrayDim, isConst, overflowBehavior, isAtomic, callbacks) {
|
|
114900
|
+
const baseType = arrayTypeCtx.userType().getText();
|
|
114901
|
+
const combinedArrayDim = arrayDim ?? [];
|
|
114902
|
+
const registered = _TypeRegistrationEngine._tryRegisterEnumOrBitmapType(
|
|
114903
|
+
registryName,
|
|
114904
|
+
baseType,
|
|
114905
|
+
isConst,
|
|
114906
|
+
combinedArrayDim,
|
|
114907
|
+
overflowBehavior,
|
|
114908
|
+
isAtomic,
|
|
114909
|
+
callbacks
|
|
114910
|
+
);
|
|
114911
|
+
if (!registered) {
|
|
114912
|
+
return false;
|
|
114913
|
+
}
|
|
114914
|
+
const existingInfo = CodeGenState.getVariableTypeInfo(registryName);
|
|
114915
|
+
if (existingInfo) {
|
|
114916
|
+
const arrayTypeDim = _TypeRegistrationEngine.parseArrayTypeDimension(arrayTypeCtx);
|
|
114917
|
+
const allDims = arrayTypeDim ? [arrayTypeDim, ...existingInfo.arrayDimensions ?? []] : existingInfo.arrayDimensions;
|
|
114918
|
+
CodeGenState.setVariableTypeInfo(registryName, {
|
|
114919
|
+
...existingInfo,
|
|
114920
|
+
isArray: true,
|
|
114921
|
+
arrayDimensions: allDims
|
|
114922
|
+
});
|
|
114923
|
+
}
|
|
114924
|
+
return true;
|
|
114925
|
+
}
|
|
114464
114926
|
static _collectArrayDimensions(arrayTypeCtx, arrayDim, callbacks) {
|
|
114465
114927
|
const arrayDimensions = [];
|
|
114466
114928
|
for (const dim of arrayTypeCtx.arrayTypeDimension()) {
|
|
@@ -116956,18 +117418,10 @@ var generateEqualityExpr = (node, input, state, orchestrator) => {
|
|
|
116956
117418
|
const rightIsString = orchestrator.isStringExpression(exprs[1]);
|
|
116957
117419
|
if (leftIsString || rightIsString) {
|
|
116958
117420
|
effects.push({ type: "include", header: "string" });
|
|
116959
|
-
const leftResult =
|
|
116960
|
-
exprs[0],
|
|
116961
|
-
input,
|
|
116962
|
-
|
|
116963
|
-
orchestrator
|
|
116964
|
-
);
|
|
116965
|
-
const rightResult = generateRelationalExpr(
|
|
116966
|
-
exprs[1],
|
|
116967
|
-
input,
|
|
116968
|
-
state,
|
|
116969
|
-
orchestrator
|
|
116970
|
-
);
|
|
117421
|
+
const [leftResult, rightResult] = CodeGenState.withoutExpectedType(() => [
|
|
117422
|
+
generateRelationalExpr(exprs[0], input, state, orchestrator),
|
|
117423
|
+
generateRelationalExpr(exprs[1], input, state, orchestrator)
|
|
117424
|
+
]);
|
|
116971
117425
|
effects.push(...leftResult.effects, ...rightResult.effects);
|
|
116972
117426
|
const fullText = node.getText();
|
|
116973
117427
|
const isNotEqual = fullText.includes("!=");
|
|
@@ -116982,13 +117436,15 @@ var generateEqualityExpr = (node, input, state, orchestrator) => {
|
|
|
116982
117436
|
}
|
|
116983
117437
|
}
|
|
116984
117438
|
const operators = orchestrator.getOperatorsFromChildren(node);
|
|
116985
|
-
return
|
|
116986
|
-
|
|
116987
|
-
|
|
116988
|
-
|
|
116989
|
-
|
|
116990
|
-
|
|
116991
|
-
|
|
117439
|
+
return CodeGenState.withoutExpectedType(
|
|
117440
|
+
() => accumulateBinaryExprs(
|
|
117441
|
+
exprs,
|
|
117442
|
+
operators,
|
|
117443
|
+
"=",
|
|
117444
|
+
generateRelationalExpr,
|
|
117445
|
+
{ input, state, orchestrator },
|
|
117446
|
+
BinaryExprUtils_default.mapEqualityOperator
|
|
117447
|
+
)
|
|
116992
117448
|
);
|
|
116993
117449
|
};
|
|
116994
117450
|
var generateRelationalExpr = (node, input, state, orchestrator) => {
|
|
@@ -116997,11 +117453,13 @@ var generateRelationalExpr = (node, input, state, orchestrator) => {
|
|
|
116997
117453
|
return generateBitwiseOrExpr(exprs[0], input, state, orchestrator);
|
|
116998
117454
|
}
|
|
116999
117455
|
const operators = orchestrator.getOperatorsFromChildren(node);
|
|
117000
|
-
return
|
|
117001
|
-
|
|
117002
|
-
|
|
117003
|
-
|
|
117004
|
-
|
|
117456
|
+
return CodeGenState.withoutExpectedType(
|
|
117457
|
+
() => accumulateBinaryExprs(exprs, operators, "<", generateBitwiseOrExpr, {
|
|
117458
|
+
input,
|
|
117459
|
+
state,
|
|
117460
|
+
orchestrator
|
|
117461
|
+
})
|
|
117462
|
+
);
|
|
117005
117463
|
};
|
|
117006
117464
|
var generateBitwiseOrExpr = (node, input, state, orchestrator) => {
|
|
117007
117465
|
const effects = [];
|
|
@@ -117191,8 +117649,12 @@ var generateTernaryExpr = (node, _input, _state, orchestrator) => {
|
|
|
117191
117649
|
orchestrator.validateNoNestedTernary(falseExpr, "false branch");
|
|
117192
117650
|
orchestrator.validateTernaryConditionNoFunctionCall(condition);
|
|
117193
117651
|
const condCode = orchestrator.generateOrExpr(condition);
|
|
117194
|
-
const trueCode =
|
|
117195
|
-
|
|
117652
|
+
const trueCode = CodeGenState.withoutDeclarationInit(
|
|
117653
|
+
() => orchestrator.generateOrExpr(trueExpr)
|
|
117654
|
+
);
|
|
117655
|
+
const falseCode = CodeGenState.withoutDeclarationInit(
|
|
117656
|
+
() => orchestrator.generateOrExpr(falseExpr)
|
|
117657
|
+
);
|
|
117196
117658
|
return { code: `(${condCode}) ? ${trueCode} : ${falseCode}`, effects };
|
|
117197
117659
|
};
|
|
117198
117660
|
var expressionGenerators = {
|
|
@@ -117403,7 +117865,7 @@ var _generateCFunctionArg = (e, targetParam, input, orchestrator) => {
|
|
|
117403
117865
|
if (typeInfo?.isPointer) {
|
|
117404
117866
|
isPointerVariable = true;
|
|
117405
117867
|
}
|
|
117406
|
-
const isOpaqueScopeVar = CodeGenState.
|
|
117868
|
+
const isOpaqueScopeVar = CodeGenState.isOpaqueScopeVariableAccess(argCode);
|
|
117407
117869
|
const needsAddressOf = argType && !argType.endsWith("*") && !argCode.startsWith("&") && !targetParam.isArray && !isPointerVariable && !isOpaqueScopeVar && (orchestrator.isStructType(argType) || _parameterExpectsAddressOf(targetParam.baseType, argType, orchestrator));
|
|
117408
117870
|
const finalArgCode = needsAddressOf ? `&${argCode}` : argCode;
|
|
117409
117871
|
return wrapWithCppEnumCast(
|
|
@@ -117440,39 +117902,41 @@ var generateFunctionCall = (funcExpr, argCtx, input, _state, orchestrator) => {
|
|
|
117440
117902
|
trackPassThroughModifications(funcExpr, argExprs, orchestrator);
|
|
117441
117903
|
}
|
|
117442
117904
|
const sig = input.functionSignatures.get(funcExpr);
|
|
117443
|
-
const args =
|
|
117444
|
-
|
|
117445
|
-
|
|
117446
|
-
|
|
117447
|
-
|
|
117448
|
-
|
|
117449
|
-
|
|
117450
|
-
const targetParam = resolved.param;
|
|
117451
|
-
if (!isCNextFunc) {
|
|
117452
|
-
return _generateCFunctionArg(e, targetParam, input, orchestrator);
|
|
117453
|
-
}
|
|
117454
|
-
if (_shouldPassByValue(
|
|
117455
|
-
funcExpr,
|
|
117456
|
-
idx,
|
|
117457
|
-
targetParam,
|
|
117458
|
-
resolved.isCrossFile,
|
|
117459
|
-
orchestrator
|
|
117460
|
-
)) {
|
|
117461
|
-
const argCode = CodeGenState.withExpectedType(
|
|
117462
|
-
targetParam?.baseType,
|
|
117463
|
-
() => orchestrator.generateExpression(e),
|
|
117464
|
-
true
|
|
117465
|
-
// suppressEnumResolution
|
|
117905
|
+
const args = CodeGenState.withoutDeclarationInit(
|
|
117906
|
+
() => argExprs.map((e, idx) => {
|
|
117907
|
+
const resolved = CallExprUtils_default.resolveTargetParam(
|
|
117908
|
+
sig,
|
|
117909
|
+
idx,
|
|
117910
|
+
funcExpr,
|
|
117911
|
+
input.symbolTable
|
|
117466
117912
|
);
|
|
117467
|
-
|
|
117468
|
-
|
|
117469
|
-
e,
|
|
117470
|
-
|
|
117913
|
+
const targetParam = resolved.param;
|
|
117914
|
+
if (!isCNextFunc) {
|
|
117915
|
+
return _generateCFunctionArg(e, targetParam, input, orchestrator);
|
|
117916
|
+
}
|
|
117917
|
+
if (_shouldPassByValue(
|
|
117918
|
+
funcExpr,
|
|
117919
|
+
idx,
|
|
117920
|
+
targetParam,
|
|
117921
|
+
resolved.isCrossFile,
|
|
117471
117922
|
orchestrator
|
|
117472
|
-
)
|
|
117473
|
-
|
|
117474
|
-
|
|
117475
|
-
|
|
117923
|
+
)) {
|
|
117924
|
+
const argCode = CodeGenState.withExpectedType(
|
|
117925
|
+
targetParam?.baseType,
|
|
117926
|
+
() => orchestrator.generateExpression(e),
|
|
117927
|
+
true
|
|
117928
|
+
// suppressEnumResolution
|
|
117929
|
+
);
|
|
117930
|
+
return wrapWithCppEnumCast(
|
|
117931
|
+
argCode,
|
|
117932
|
+
e,
|
|
117933
|
+
targetParam?.baseType,
|
|
117934
|
+
orchestrator
|
|
117935
|
+
);
|
|
117936
|
+
}
|
|
117937
|
+
return orchestrator.generateFunctionArg(e, targetParam?.baseType);
|
|
117938
|
+
}).join(", ")
|
|
117939
|
+
);
|
|
117476
117940
|
return { code: `${funcExpr}(${args})`, effects };
|
|
117477
117941
|
};
|
|
117478
117942
|
var generateSafeDivMod = (funcName, argExprs, input, orchestrator, effects) => {
|
|
@@ -119915,7 +120379,9 @@ function generateInitializer(varDecl, isArray, orchestrator) {
|
|
|
119915
120379
|
const typeName = orchestrator.generateType(varDecl.type());
|
|
119916
120380
|
return CodeGenState.withExpectedType(
|
|
119917
120381
|
typeName,
|
|
119918
|
-
() =>
|
|
120382
|
+
() => CodeGenState.withDeclarationInit(
|
|
120383
|
+
() => ` = ${orchestrator.generateExpression(varDecl.expression())}`
|
|
120384
|
+
)
|
|
119919
120385
|
);
|
|
119920
120386
|
}
|
|
119921
120387
|
return ` = ${orchestrator.getZeroInitializer(varDecl.type(), isArray)}`;
|
|
@@ -119993,9 +120459,19 @@ function generateRegularVariable(varDecl, varName, scopeName, isPrivate, orchest
|
|
|
119993
120459
|
type = `${type}*`;
|
|
119994
120460
|
orchestrator.markOpaqueScopeVariable(fullName);
|
|
119995
120461
|
}
|
|
120462
|
+
const modifiers = VariableModifierBuilder_default.build(
|
|
120463
|
+
varDecl,
|
|
120464
|
+
false,
|
|
120465
|
+
// inFunctionBody - scope vars are file scope
|
|
120466
|
+
false,
|
|
120467
|
+
// hasInitializer - doesn't affect volatile/atomic handling
|
|
120468
|
+
false
|
|
120469
|
+
// cppMode - doesn't affect volatile/atomic handling
|
|
120470
|
+
);
|
|
120471
|
+
const staticPrefix = isPrivate ? "static " : "";
|
|
120472
|
+
const volatilePrefix = modifiers.atomic || modifiers.volatile;
|
|
119996
120473
|
const constPrefix = isConst ? "const " : "";
|
|
119997
|
-
|
|
119998
|
-
let decl = `${prefix}${constPrefix}${type} ${fullName}`;
|
|
120474
|
+
let decl = `${staticPrefix}${volatilePrefix}${constPrefix}${type} ${fullName}`;
|
|
119999
120475
|
decl += ArrayDimensionUtils_default.generateArrayTypeDimension(
|
|
120000
120476
|
arrayTypeCtx,
|
|
120001
120477
|
orchestrator
|
|
@@ -120004,7 +120480,7 @@ function generateRegularVariable(varDecl, varName, scopeName, isPrivate, orchest
|
|
|
120004
120480
|
decl += orchestrator.generateArrayDimensions(arrayDims);
|
|
120005
120481
|
}
|
|
120006
120482
|
decl += ArrayDimensionUtils_default.generateStringCapacityDim(varDecl.type());
|
|
120007
|
-
if (isOpaque || isExternalStruct) {
|
|
120483
|
+
if ((isOpaque || isExternalStruct) && !isArray) {
|
|
120008
120484
|
decl += " = NULL";
|
|
120009
120485
|
} else {
|
|
120010
120486
|
decl += generateInitializer(varDecl, isArray, orchestrator);
|
|
@@ -120061,7 +120537,9 @@ function generateEnumMembersFromAST(members, fullName, orchestrator) {
|
|
|
120061
120537
|
return lines;
|
|
120062
120538
|
}
|
|
120063
120539
|
function processScopeMember(member, scopeName, input, state, orchestrator) {
|
|
120064
|
-
const
|
|
120540
|
+
const explicitVisibility = member.visibilityModifier()?.getText();
|
|
120541
|
+
const isFunction = member.functionDeclaration() !== null;
|
|
120542
|
+
const visibility = explicitVisibility ?? ScopeUtils_default.getDefaultVisibility(isFunction);
|
|
120065
120543
|
const isPrivate = visibility === "private";
|
|
120066
120544
|
if (member.variableDeclaration()) {
|
|
120067
120545
|
const varDecl = member.variableDeclaration();
|
|
@@ -125837,19 +126315,6 @@ var SymbolLookupHelper = class _SymbolLookupHelper {
|
|
|
125837
126315
|
const symbols = symbolTable.getOverloads(name);
|
|
125838
126316
|
return symbols.some((sym) => sym.kind === "namespace");
|
|
125839
126317
|
}
|
|
125840
|
-
/**
|
|
125841
|
-
* Check if a type name is from a C++ header.
|
|
125842
|
-
* Issue #304: Used to determine whether to use {} or {0} for initialization.
|
|
125843
|
-
* C++ types with constructors may fail with {0} but work with {}.
|
|
125844
|
-
*/
|
|
125845
|
-
static isCppType(symbolTable, typeName) {
|
|
125846
|
-
if (!symbolTable) return false;
|
|
125847
|
-
const symbols = symbolTable.getOverloads(typeName);
|
|
125848
|
-
const cppTypeKinds = /* @__PURE__ */ new Set(["struct", "class", "type"]);
|
|
125849
|
-
return symbols.some(
|
|
125850
|
-
(sym) => sym.sourceLanguage === ESourceLanguage_default.Cpp && cppTypeKinds.has(sym.kind)
|
|
125851
|
-
);
|
|
125852
|
-
}
|
|
125853
126318
|
/**
|
|
125854
126319
|
* Check if a function is a C-Next function (uses pass-by-reference semantics).
|
|
125855
126320
|
* Returns true if the function is found in symbol table as C-Next.
|
|
@@ -126189,6 +126654,18 @@ var StringDeclHelper = class _StringDeclHelper {
|
|
|
126189
126654
|
* Returns { handled: false } if not a string type.
|
|
126190
126655
|
*/
|
|
126191
126656
|
static generateStringDecl(typeCtx, name, expression, arrayDims, modifiers, isConst, callbacks) {
|
|
126657
|
+
const arrayTypeCtx = typeCtx.arrayType?.();
|
|
126658
|
+
if (arrayTypeCtx?.stringType?.()) {
|
|
126659
|
+
return _StringDeclHelper._generateStringArrayFromArrayType(
|
|
126660
|
+
name,
|
|
126661
|
+
arrayTypeCtx,
|
|
126662
|
+
expression,
|
|
126663
|
+
arrayDims,
|
|
126664
|
+
modifiers,
|
|
126665
|
+
isConst,
|
|
126666
|
+
callbacks
|
|
126667
|
+
);
|
|
126668
|
+
}
|
|
126192
126669
|
const stringCtx = typeCtx.stringType();
|
|
126193
126670
|
if (!stringCtx) {
|
|
126194
126671
|
return { code: "", handled: false };
|
|
@@ -126215,6 +126692,122 @@ var StringDeclHelper = class _StringDeclHelper {
|
|
|
126215
126692
|
);
|
|
126216
126693
|
}
|
|
126217
126694
|
}
|
|
126695
|
+
/**
|
|
126696
|
+
* Issue #1029: Generate string array declaration from arrayType syntax.
|
|
126697
|
+
* Handles: string<32>[4] items -> char items[4][33] = {0};
|
|
126698
|
+
*/
|
|
126699
|
+
static _generateStringArrayFromArrayType(name, arrayTypeCtx, expression, trailingArrayDims, modifiers, isConst, callbacks) {
|
|
126700
|
+
const stringCtx = arrayTypeCtx.stringType();
|
|
126701
|
+
const intLiteral = stringCtx.INTEGER_LITERAL();
|
|
126702
|
+
if (!intLiteral) {
|
|
126703
|
+
throw new Error(
|
|
126704
|
+
"Error: String arrays require explicit capacity, e.g., string<64>[4]"
|
|
126705
|
+
);
|
|
126706
|
+
}
|
|
126707
|
+
const capacity = Number.parseInt(intLiteral.getText(), 10);
|
|
126708
|
+
callbacks.requireStringInclude();
|
|
126709
|
+
const {
|
|
126710
|
+
extern,
|
|
126711
|
+
const: constMod,
|
|
126712
|
+
atomic,
|
|
126713
|
+
volatile: volatileMod
|
|
126714
|
+
} = modifiers;
|
|
126715
|
+
let arrayDimStr = "";
|
|
126716
|
+
for (const dim of arrayTypeCtx.arrayTypeDimension()) {
|
|
126717
|
+
const sizeExpr = dim.expression();
|
|
126718
|
+
if (sizeExpr) {
|
|
126719
|
+
arrayDimStr += `[${sizeExpr.getText()}]`;
|
|
126720
|
+
} else {
|
|
126721
|
+
arrayDimStr += "[]";
|
|
126722
|
+
}
|
|
126723
|
+
}
|
|
126724
|
+
arrayDimStr += callbacks.generateArrayDimensions(trailingArrayDims);
|
|
126725
|
+
arrayDimStr += `[${capacity + 1}]`;
|
|
126726
|
+
let decl = `${extern}${constMod}${atomic}${volatileMod}char ${name}${arrayDimStr}`;
|
|
126727
|
+
CodeGenState.localArrays.add(name);
|
|
126728
|
+
if (!expression) {
|
|
126729
|
+
return { code: `${decl} = {0};`, handled: true };
|
|
126730
|
+
}
|
|
126731
|
+
CodeGenState.lastArrayInitCount = 0;
|
|
126732
|
+
CodeGenState.lastArrayFillValue = void 0;
|
|
126733
|
+
const initValue = callbacks.generateExpression(expression);
|
|
126734
|
+
const isArrayInit = CodeGenState.lastArrayInitCount > 0 || CodeGenState.lastArrayFillValue !== void 0;
|
|
126735
|
+
if (!isArrayInit) {
|
|
126736
|
+
throw new Error(
|
|
126737
|
+
`Error: String array initialization from variables not supported`
|
|
126738
|
+
);
|
|
126739
|
+
}
|
|
126740
|
+
const declaredSize = _StringDeclHelper._getArrayTypeDeclaredSize(arrayTypeCtx);
|
|
126741
|
+
if (declaredSize !== null) {
|
|
126742
|
+
const isFillAll = CodeGenState.lastArrayFillValue !== void 0;
|
|
126743
|
+
const elementCount = CodeGenState.lastArrayInitCount;
|
|
126744
|
+
if (!isFillAll && elementCount !== declaredSize) {
|
|
126745
|
+
throw new Error(
|
|
126746
|
+
`Error: Array size mismatch - declared [${declaredSize}] but got ${elementCount} elements`
|
|
126747
|
+
);
|
|
126748
|
+
}
|
|
126749
|
+
}
|
|
126750
|
+
const finalInitValue = _StringDeclHelper._expandFillAllForArrayType(
|
|
126751
|
+
initValue,
|
|
126752
|
+
arrayTypeCtx
|
|
126753
|
+
);
|
|
126754
|
+
const suppression = "// cppcheck-suppress misra-c2012-9.3\n// cppcheck-suppress misra-c2012-9.4\n";
|
|
126755
|
+
return {
|
|
126756
|
+
code: `${suppression}${decl} = ${finalInitValue};`,
|
|
126757
|
+
handled: true
|
|
126758
|
+
};
|
|
126759
|
+
}
|
|
126760
|
+
/**
|
|
126761
|
+
* Get the numeric size from the first arrayTypeDimension, or null if not numeric.
|
|
126762
|
+
* Used by arrayType-based string arrays (string<N>[M]).
|
|
126763
|
+
*/
|
|
126764
|
+
static _getArrayTypeDeclaredSize(arrayTypeCtx) {
|
|
126765
|
+
const dims = arrayTypeCtx.arrayTypeDimension();
|
|
126766
|
+
if (dims.length === 0) {
|
|
126767
|
+
return null;
|
|
126768
|
+
}
|
|
126769
|
+
const firstDimExpr = dims[0].expression();
|
|
126770
|
+
return _StringDeclHelper._parseNumericSize(firstDimExpr);
|
|
126771
|
+
}
|
|
126772
|
+
/**
|
|
126773
|
+
* Expand fill-all syntax for arrayType-based string arrays.
|
|
126774
|
+
* Delegates to the common fill-all expansion logic with size from arrayType.
|
|
126775
|
+
*/
|
|
126776
|
+
static _expandFillAllForArrayType(initValue, arrayTypeCtx) {
|
|
126777
|
+
const declaredSize = _StringDeclHelper._getArrayTypeDeclaredSize(arrayTypeCtx);
|
|
126778
|
+
return _StringDeclHelper._expandFillAll(initValue, declaredSize);
|
|
126779
|
+
}
|
|
126780
|
+
/**
|
|
126781
|
+
* Common fill-all expansion logic shared between arrayType and arrayDimension paths.
|
|
126782
|
+
*/
|
|
126783
|
+
static _expandFillAll(initValue, declaredSize) {
|
|
126784
|
+
const fillVal = CodeGenState.lastArrayFillValue;
|
|
126785
|
+
if (fillVal === void 0) {
|
|
126786
|
+
return initValue;
|
|
126787
|
+
}
|
|
126788
|
+
if (fillVal === '""') {
|
|
126789
|
+
return initValue;
|
|
126790
|
+
}
|
|
126791
|
+
if (declaredSize === null) {
|
|
126792
|
+
return initValue;
|
|
126793
|
+
}
|
|
126794
|
+
const elements = new Array(declaredSize).fill(fillVal);
|
|
126795
|
+
return `{${elements.join(", ")}}`;
|
|
126796
|
+
}
|
|
126797
|
+
/**
|
|
126798
|
+
* Parse a numeric size from an expression, or return null if not numeric.
|
|
126799
|
+
* Shared helper to eliminate duplicate parsing logic.
|
|
126800
|
+
*/
|
|
126801
|
+
static _parseNumericSize(expr) {
|
|
126802
|
+
if (!expr) {
|
|
126803
|
+
return null;
|
|
126804
|
+
}
|
|
126805
|
+
const sizeText = expr.getText();
|
|
126806
|
+
if (!/^\d+$/.exec(sizeText)) {
|
|
126807
|
+
return null;
|
|
126808
|
+
}
|
|
126809
|
+
return Number.parseInt(sizeText, 10);
|
|
126810
|
+
}
|
|
126218
126811
|
/**
|
|
126219
126812
|
* Generate bounded string declaration (string<N>).
|
|
126220
126813
|
*/
|
|
@@ -126268,16 +126861,33 @@ var StringDeclHelper = class _StringDeclHelper {
|
|
|
126268
126861
|
constMod
|
|
126269
126862
|
);
|
|
126270
126863
|
}
|
|
126271
|
-
|
|
126272
|
-
|
|
126864
|
+
const exprText = expression.getText();
|
|
126865
|
+
const isLiteral = _StringDeclHelper._validateStringInit(
|
|
126866
|
+
exprText,
|
|
126273
126867
|
capacity,
|
|
126274
126868
|
callbacks
|
|
126275
126869
|
);
|
|
126276
|
-
|
|
126277
|
-
|
|
126870
|
+
if (isLiteral) {
|
|
126871
|
+
const code = `${extern}${constMod}char ${name}[${capacity + 1}] = ${callbacks.generateExpression(expression)};`;
|
|
126872
|
+
return { code, handled: true };
|
|
126873
|
+
}
|
|
126874
|
+
if (!CodeGenState.inFunctionBody) {
|
|
126875
|
+
throw new Error(
|
|
126876
|
+
`Error: String initialization from variable cannot be used at global scope. Move the declaration inside a function, or use an empty initializer and assign later.`
|
|
126877
|
+
);
|
|
126878
|
+
}
|
|
126879
|
+
const srcExpr = callbacks.generateExpression(expression);
|
|
126880
|
+
const indent = FormatUtils_default.indent(CodeGenState.indentLevel);
|
|
126881
|
+
const lines = [];
|
|
126882
|
+
lines.push(
|
|
126883
|
+
`${constMod}char ${name}[${capacity + 1}] = "";`,
|
|
126884
|
+
`${indent}strcpy(${name}, ${srcExpr});`
|
|
126885
|
+
);
|
|
126886
|
+
return { code: lines.join("\n"), handled: true };
|
|
126278
126887
|
}
|
|
126279
126888
|
/**
|
|
126280
126889
|
* Validate string initialization (literal length and variable capacity)
|
|
126890
|
+
* Returns true if the expression is a string literal, false if it's a variable.
|
|
126281
126891
|
*/
|
|
126282
126892
|
static _validateStringInit(exprText, capacity, callbacks) {
|
|
126283
126893
|
if (exprText.startsWith('"') && exprText.endsWith('"')) {
|
|
@@ -126287,6 +126897,7 @@ var StringDeclHelper = class _StringDeclHelper {
|
|
|
126287
126897
|
`Error: String literal (${content} chars) exceeds string<${capacity}> capacity`
|
|
126288
126898
|
);
|
|
126289
126899
|
}
|
|
126900
|
+
return true;
|
|
126290
126901
|
}
|
|
126291
126902
|
const srcCapacity = callbacks.getStringExprCapacity(exprText);
|
|
126292
126903
|
if (srcCapacity !== null && srcCapacity > capacity) {
|
|
@@ -126294,6 +126905,7 @@ var StringDeclHelper = class _StringDeclHelper {
|
|
|
126294
126905
|
`Error: Cannot assign string<${srcCapacity}> to string<${capacity}> (potential truncation)`
|
|
126295
126906
|
);
|
|
126296
126907
|
}
|
|
126908
|
+
return false;
|
|
126297
126909
|
}
|
|
126298
126910
|
/**
|
|
126299
126911
|
* Generate string array declaration.
|
|
@@ -126381,35 +126993,19 @@ var StringDeclHelper = class _StringDeclHelper {
|
|
|
126381
126993
|
/**
|
|
126382
126994
|
* Expand fill-all syntax if needed.
|
|
126383
126995
|
* ["Hello"*] with size 3 -> {"Hello", "Hello", "Hello"}
|
|
126996
|
+
* Delegates to the common fill-all expansion logic with size from arrayDimension.
|
|
126384
126997
|
*/
|
|
126385
126998
|
static _expandFillAllIfNeeded(initValue, arrayDims) {
|
|
126386
|
-
const fillVal = CodeGenState.lastArrayFillValue;
|
|
126387
|
-
if (fillVal === void 0) {
|
|
126388
|
-
return initValue;
|
|
126389
|
-
}
|
|
126390
|
-
if (fillVal === '""') {
|
|
126391
|
-
return initValue;
|
|
126392
|
-
}
|
|
126393
126999
|
const declaredSize = _StringDeclHelper._getFirstDimNumericSize(arrayDims);
|
|
126394
|
-
|
|
126395
|
-
return initValue;
|
|
126396
|
-
}
|
|
126397
|
-
const elements = new Array(declaredSize).fill(fillVal);
|
|
126398
|
-
return `{${elements.join(", ")}}`;
|
|
127000
|
+
return _StringDeclHelper._expandFillAll(initValue, declaredSize);
|
|
126399
127001
|
}
|
|
126400
127002
|
/**
|
|
126401
127003
|
* Get the numeric size from the first array dimension, or null if not numeric.
|
|
127004
|
+
* Used by arrayDimension-based string arrays (string<N> arr[M]).
|
|
126402
127005
|
*/
|
|
126403
127006
|
static _getFirstDimNumericSize(arrayDims) {
|
|
126404
127007
|
const firstDimExpr = arrayDims[0]?.expression();
|
|
126405
|
-
|
|
126406
|
-
return null;
|
|
126407
|
-
}
|
|
126408
|
-
const sizeText = firstDimExpr.getText();
|
|
126409
|
-
if (!/^\d+$/.exec(sizeText)) {
|
|
126410
|
-
return null;
|
|
126411
|
-
}
|
|
126412
|
-
return Number.parseInt(sizeText, 10);
|
|
127008
|
+
return _StringDeclHelper._parseNumericSize(firstDimExpr);
|
|
126413
127009
|
}
|
|
126414
127010
|
/**
|
|
126415
127011
|
* Generate string concatenation declaration.
|
|
@@ -126603,24 +127199,14 @@ var VariableDeclHelper = class _VariableDeclHelper {
|
|
|
126603
127199
|
if (arrayDims.length === 0) {
|
|
126604
127200
|
return;
|
|
126605
127201
|
}
|
|
126606
|
-
if (typeCtx.arrayType()) {
|
|
126607
|
-
return;
|
|
126608
|
-
}
|
|
126609
|
-
if (arrayDims.length === 1 && !arrayDims[0].expression()) {
|
|
126610
|
-
return;
|
|
126611
|
-
}
|
|
126612
|
-
if (arrayDims.length > 1) {
|
|
126613
|
-
return;
|
|
126614
|
-
}
|
|
126615
|
-
if (typeCtx.qualifiedType() || typeCtx.scopedType() || typeCtx.globalType() || typeCtx.stringType()) {
|
|
126616
|
-
return;
|
|
126617
|
-
}
|
|
126618
127202
|
const baseType = _VariableDeclHelper.extractBaseTypeName(typeCtx);
|
|
126619
|
-
const
|
|
127203
|
+
const existingDims = typeCtx.arrayType() ? typeCtx.arrayType().arrayTypeDimension().map((d) => `[${d.expression()?.getText() ?? ""}]`).join("") : "";
|
|
127204
|
+
const trailingDims = arrayDims.map((dim) => `[${dim.expression()?.getText() ?? ""}]`).join("");
|
|
127205
|
+
const allDims = existingDims + trailingDims;
|
|
126620
127206
|
const line = ctx.start?.line ?? 0;
|
|
126621
127207
|
const col = ctx.start?.column ?? 0;
|
|
126622
127208
|
throw new Error(
|
|
126623
|
-
`${line}:${col} C-style array declaration is not allowed. Use '${baseType}${
|
|
127209
|
+
`${line}:${col} C-style array declaration is not allowed. Use '${baseType}${allDims} ${name}' instead of '${baseType}${existingDims} ${name}${trailingDims}'`
|
|
126624
127210
|
);
|
|
126625
127211
|
}
|
|
126626
127212
|
/**
|
|
@@ -126727,7 +127313,8 @@ ${assignments}`;
|
|
|
126727
127313
|
typeCtx,
|
|
126728
127314
|
callbacks
|
|
126729
127315
|
);
|
|
126730
|
-
const hasEmptyArrayDim = arrayDims.some((dim) => !dim.expression());
|
|
127316
|
+
const hasEmptyArrayDim = arrayDims.some((dim) => !dim.expression()) || (typeCtx.arrayType()?.arrayTypeDimension().some((dim) => !dim.expression()) ?? false);
|
|
127317
|
+
const hasEmptyArrayTypeDim = typeCtx.arrayType()?.arrayTypeDimension().some((dim) => !dim.expression()) ?? false;
|
|
126731
127318
|
const declaredSize = _VariableDeclHelper.parseArrayTypeDimension(typeCtx) ?? _VariableDeclHelper.parseFirstArrayDimension(arrayDims);
|
|
126732
127319
|
if (ctx.expression()) {
|
|
126733
127320
|
const arrayInitResult = ArrayInitHelper_default.processArrayInit(
|
|
@@ -126745,7 +127332,7 @@ ${assignments}`;
|
|
|
126745
127332
|
);
|
|
126746
127333
|
if (arrayInitResult) {
|
|
126747
127334
|
CodeGenState.localArrays.add(name);
|
|
126748
|
-
const fullDimSuffix = arrayTypeDimStr + arrayInitResult.dimensionSuffix;
|
|
127335
|
+
const fullDimSuffix = hasEmptyArrayTypeDim ? arrayInitResult.dimensionSuffix : arrayTypeDimStr + arrayInitResult.dimensionSuffix;
|
|
126749
127336
|
return {
|
|
126750
127337
|
handled: true,
|
|
126751
127338
|
code: `${decl}${fullDimSuffix} = ${arrayInitResult.initValue};`,
|
|
@@ -126780,7 +127367,9 @@ ${assignments}`;
|
|
|
126780
127367
|
getExpressionType: callbacks.getExpressionType
|
|
126781
127368
|
});
|
|
126782
127369
|
return CodeGenState.withExpectedType(typeName, () => {
|
|
126783
|
-
let exprCode =
|
|
127370
|
+
let exprCode = CodeGenState.withDeclarationInit(
|
|
127371
|
+
() => callbacks.generateExpression(ctx.expression())
|
|
127372
|
+
);
|
|
126784
127373
|
const exprType = callbacks.getExpressionType(ctx.expression());
|
|
126785
127374
|
if (exprType && NarrowingCastHelper_default.isCrossTypeCategoryConversion(exprType, typeName)) {
|
|
126786
127375
|
if (NarrowingCastHelper_default.isIntegerType(exprType) && NarrowingCastHelper_default.isFloatType(typeName)) {
|
|
@@ -127568,31 +128157,29 @@ var TypeGenerationHelper = class _TypeGenerationHelper {
|
|
|
127568
128157
|
return "char";
|
|
127569
128158
|
}
|
|
127570
128159
|
/**
|
|
127571
|
-
*
|
|
127572
|
-
*
|
|
128160
|
+
* Dispatch type generation for contexts that share common type accessors.
|
|
128161
|
+
* Handles scoped, qualified, global, primitive, string, and user types.
|
|
128162
|
+
* Used by both bare type contexts and array element type contexts.
|
|
128163
|
+
*
|
|
128164
|
+
* @returns The resolved C type string, or null if no matching type accessor found
|
|
127573
128165
|
*/
|
|
127574
|
-
static
|
|
127575
|
-
if (
|
|
127576
|
-
const type = ctx.primitiveType().getText();
|
|
127577
|
-
const result = _TypeGenerationHelper.generatePrimitiveType(type);
|
|
127578
|
-
return result.cType;
|
|
127579
|
-
}
|
|
127580
|
-
if (ctx.stringType()) {
|
|
128166
|
+
static dispatchTypeGeneration(accessors, deps) {
|
|
128167
|
+
if (accessors.stringType()) {
|
|
127581
128168
|
return _TypeGenerationHelper.generateStringType();
|
|
127582
128169
|
}
|
|
127583
|
-
if (
|
|
127584
|
-
const typeName =
|
|
128170
|
+
if (accessors.scopedType()) {
|
|
128171
|
+
const typeName = accessors.scopedType().IDENTIFIER().getText();
|
|
127585
128172
|
return _TypeGenerationHelper.generateScopedType(
|
|
127586
128173
|
typeName,
|
|
127587
128174
|
deps.currentScope
|
|
127588
128175
|
);
|
|
127589
128176
|
}
|
|
127590
|
-
if (
|
|
127591
|
-
const typeName =
|
|
128177
|
+
if (accessors.globalType()) {
|
|
128178
|
+
const typeName = accessors.globalType().IDENTIFIER().getText();
|
|
127592
128179
|
return _TypeGenerationHelper.generateGlobalType(typeName);
|
|
127593
128180
|
}
|
|
127594
|
-
if (
|
|
127595
|
-
const identifiers =
|
|
128181
|
+
if (accessors.qualifiedType()) {
|
|
128182
|
+
const identifiers = accessors.qualifiedType().IDENTIFIER();
|
|
127596
128183
|
const identifierNames = identifiers.map((id) => id.getText());
|
|
127597
128184
|
const isCpp = deps.isCppScopeSymbol(identifierNames[0]);
|
|
127598
128185
|
return _TypeGenerationHelper.generateQualifiedType(
|
|
@@ -127601,24 +128188,36 @@ var TypeGenerationHelper = class _TypeGenerationHelper {
|
|
|
127601
128188
|
deps.validateCrossScopeVisibility
|
|
127602
128189
|
);
|
|
127603
128190
|
}
|
|
127604
|
-
if (
|
|
127605
|
-
const
|
|
128191
|
+
if (accessors.primitiveType()) {
|
|
128192
|
+
const type = accessors.primitiveType().getText();
|
|
128193
|
+
return TYPE_MAP_default[type] || type;
|
|
128194
|
+
}
|
|
128195
|
+
if (accessors.userType()) {
|
|
128196
|
+
const typeName = accessors.userType().getText();
|
|
128197
|
+
if (typeName === "cstring") {
|
|
128198
|
+
return "char*";
|
|
128199
|
+
}
|
|
127606
128200
|
const needsStruct = deps.checkNeedsStructKeyword(typeName);
|
|
127607
128201
|
return _TypeGenerationHelper.generateUserType(typeName, needsStruct);
|
|
127608
128202
|
}
|
|
128203
|
+
return null;
|
|
128204
|
+
}
|
|
128205
|
+
/**
|
|
128206
|
+
* Full type generation using all dependencies.
|
|
128207
|
+
* This is the main entry point that handles all type contexts.
|
|
128208
|
+
*/
|
|
128209
|
+
static generate(ctx, deps) {
|
|
127609
128210
|
if (ctx.arrayType()) {
|
|
127610
128211
|
const arrCtx = ctx.arrayType();
|
|
127611
|
-
|
|
127612
|
-
|
|
127613
|
-
|
|
127614
|
-
|
|
127615
|
-
|
|
127616
|
-
|
|
127617
|
-
|
|
127618
|
-
|
|
127619
|
-
|
|
127620
|
-
needsStruct
|
|
127621
|
-
);
|
|
128212
|
+
const result2 = _TypeGenerationHelper.dispatchTypeGeneration(arrCtx, deps);
|
|
128213
|
+
if (result2 !== null) {
|
|
128214
|
+
return result2;
|
|
128215
|
+
}
|
|
128216
|
+
return ctx.getText();
|
|
128217
|
+
}
|
|
128218
|
+
const result = _TypeGenerationHelper.dispatchTypeGeneration(ctx, deps);
|
|
128219
|
+
if (result !== null) {
|
|
128220
|
+
return result;
|
|
127622
128221
|
}
|
|
127623
128222
|
if (ctx.getText() === "void") {
|
|
127624
128223
|
return "void";
|
|
@@ -128979,6 +129578,7 @@ var ParameterInputAdapter = class {
|
|
|
128979
129578
|
const isKnownStruct = deps.isKnownStruct(typeName);
|
|
128980
129579
|
const isKnownPrimitive = !!deps.typeMap[typeName];
|
|
128981
129580
|
const isTypedefStruct = deps.isTypedefStructType(typeName);
|
|
129581
|
+
const isOpaque = deps.isOpaqueType?.(typeName) ?? false;
|
|
128982
129582
|
const isAutoConst = !deps.isCallbackCompatible && !deps.isModified && !isConst;
|
|
128983
129583
|
const isPassByReference = deps.forcePassByReference || isKnownStruct || isKnownPrimitive || isTypedefStruct;
|
|
128984
129584
|
return {
|
|
@@ -128996,7 +129596,9 @@ var ParameterInputAdapter = class {
|
|
|
128996
129596
|
// and typedef struct params (C types expect pointers, not C++ references)
|
|
128997
129597
|
forcePointerSyntax: deps.forcePassByReference || isTypedefStruct || void 0,
|
|
128998
129598
|
// Issue #895: Preserve const from callback typedef signature
|
|
128999
|
-
forceConst: deps.forceConst
|
|
129599
|
+
forceConst: deps.forceConst,
|
|
129600
|
+
// Issue #995: Pass through opaque handle detection — rule applied in builder
|
|
129601
|
+
isOpaqueHandle: isOpaque || void 0
|
|
129000
129602
|
};
|
|
129001
129603
|
}
|
|
129002
129604
|
/**
|
|
@@ -129043,7 +129645,9 @@ var ParameterInputAdapter = class {
|
|
|
129043
129645
|
isPassByValue: isCallbackPointer ? false : deps.isPassByValue,
|
|
129044
129646
|
isPassByReference: isCallbackPointer ? true : !deps.isPassByValue,
|
|
129045
129647
|
forcePointerSyntax: isCallbackPointer || void 0,
|
|
129046
|
-
forceConst: param.isCallbackConst || void 0
|
|
129648
|
+
forceConst: param.isCallbackConst || void 0,
|
|
129649
|
+
// Issue #995: Pass through opaque handle detection — rule applied in builder
|
|
129650
|
+
isOpaqueHandle: param.isOpaqueHandle || void 0
|
|
129047
129651
|
};
|
|
129048
129652
|
}
|
|
129049
129653
|
/**
|
|
@@ -129085,13 +129689,12 @@ var ParameterInputAdapter = class {
|
|
|
129085
129689
|
dims.push(String(capacity + 1));
|
|
129086
129690
|
}
|
|
129087
129691
|
}
|
|
129088
|
-
const isAutoConst = !deps.isModified && !isConst;
|
|
129089
129692
|
return {
|
|
129090
129693
|
name,
|
|
129091
129694
|
baseType: typeName,
|
|
129092
129695
|
mappedType,
|
|
129093
129696
|
isConst,
|
|
129094
|
-
isAutoConst,
|
|
129697
|
+
isAutoConst: false,
|
|
129095
129698
|
isArray: true,
|
|
129096
129699
|
arrayDimensions: dims,
|
|
129097
129700
|
isCallback: false,
|
|
@@ -129169,6 +129772,9 @@ var ParameterSignatureBuilder = class {
|
|
|
129169
129772
|
if (param.isString && !param.isArray) {
|
|
129170
129773
|
return this._buildStringParam(param);
|
|
129171
129774
|
}
|
|
129775
|
+
if (param.isOpaqueHandle) {
|
|
129776
|
+
return this._buildRefParam(param, refSuffix);
|
|
129777
|
+
}
|
|
129172
129778
|
if (param.isPassByReference) {
|
|
129173
129779
|
return this._buildRefParam(param, refSuffix);
|
|
129174
129780
|
}
|
|
@@ -129213,14 +129819,16 @@ var ParameterSignatureBuilder = class {
|
|
|
129213
129819
|
/**
|
|
129214
129820
|
* Build pass-by-reference parameter signature.
|
|
129215
129821
|
* C mode: const Point* p
|
|
129216
|
-
* C++ mode: const Point& p (unless forcePointerSyntax)
|
|
129822
|
+
* C++ mode: const Point& p (unless forcePointerSyntax or isOpaqueHandle)
|
|
129217
129823
|
*
|
|
129218
129824
|
* Issue #895: When forcePointerSyntax is set, always use pointer syntax
|
|
129219
129825
|
* because C callback typedefs expect pointers, not C++ references.
|
|
129826
|
+
* Issue #995: Opaque handles must use pointer syntax because C APIs
|
|
129827
|
+
* expect pointers to incomplete struct types (e.g., widget_t*).
|
|
129220
129828
|
*/
|
|
129221
129829
|
static _buildRefParam(param, refSuffix) {
|
|
129222
129830
|
const constPrefix = this._getConstPrefix(param);
|
|
129223
|
-
const actualSuffix = param.forcePointerSyntax ? "*" : refSuffix;
|
|
129831
|
+
const actualSuffix = param.forcePointerSyntax || param.isOpaqueHandle ? "*" : refSuffix;
|
|
129224
129832
|
return `${constPrefix}${param.mappedType}${actualSuffix} ${param.name}`;
|
|
129225
129833
|
}
|
|
129226
129834
|
/**
|
|
@@ -129234,9 +129842,12 @@ var ParameterSignatureBuilder = class {
|
|
|
129234
129842
|
* Get const prefix combining explicit const, auto-const, and forced const.
|
|
129235
129843
|
* Priority: forceConst > isConst > isAutoConst
|
|
129236
129844
|
* Issue #895: forceConst preserves const from callback typedef signature.
|
|
129845
|
+
* Issue #995: Opaque handles suppress auto-const (they must be passed to
|
|
129846
|
+
* C APIs that expect non-const pointers).
|
|
129237
129847
|
*/
|
|
129238
129848
|
static _getConstPrefix(param) {
|
|
129239
|
-
|
|
129849
|
+
const effectiveAutoConst = param.isOpaqueHandle ? false : param.isAutoConst;
|
|
129850
|
+
if (param.forceConst || param.isConst || effectiveAutoConst) {
|
|
129240
129851
|
return "const ";
|
|
129241
129852
|
}
|
|
129242
129853
|
return "";
|
|
@@ -129833,6 +130444,7 @@ var CodeGenerator = class _CodeGenerator {
|
|
|
129833
130444
|
* Part of IOrchestrator interface.
|
|
129834
130445
|
* ADR-045: Used to detect string comparisons and generate strcmp().
|
|
129835
130446
|
* Issue #137: Extended to handle array element access (e.g., names[0])
|
|
130447
|
+
* Issue #1030: Extended to handle struct member access (e.g., person.name)
|
|
129836
130448
|
*/
|
|
129837
130449
|
isStringExpression(ctx) {
|
|
129838
130450
|
const text = ctx.getText();
|
|
@@ -129845,6 +130457,9 @@ var CodeGenerator = class _CodeGenerator {
|
|
|
129845
130457
|
return true;
|
|
129846
130458
|
}
|
|
129847
130459
|
}
|
|
130460
|
+
if (this._isStructMemberStringExpression(text)) {
|
|
130461
|
+
return true;
|
|
130462
|
+
}
|
|
129848
130463
|
return this._isArrayAccessStringExpression(text);
|
|
129849
130464
|
}
|
|
129850
130465
|
/**
|
|
@@ -129872,6 +130487,36 @@ var CodeGenerator = class _CodeGenerator {
|
|
|
129872
130487
|
typeInfo.isArray && typeInfo.baseType && TypeCheckUtils_default.isString(typeInfo.baseType)
|
|
129873
130488
|
);
|
|
129874
130489
|
}
|
|
130490
|
+
/**
|
|
130491
|
+
* Check if struct member access expression evaluates to a string.
|
|
130492
|
+
* Issue #1030: Handles patterns like person.name, config.key
|
|
130493
|
+
*/
|
|
130494
|
+
_isStructMemberStringExpression(text) {
|
|
130495
|
+
if (text.endsWith(".char_count") || text.endsWith(".capacity") || text.endsWith(".size") || text.endsWith(".length") || text.endsWith(".bit_length") || text.endsWith(".byte_length") || text.endsWith(".element_count")) {
|
|
130496
|
+
return false;
|
|
130497
|
+
}
|
|
130498
|
+
const memberMatch = /^([a-zA-Z_]\w*)\.([a-zA-Z_]\w*)$/.exec(text);
|
|
130499
|
+
if (!memberMatch) {
|
|
130500
|
+
return false;
|
|
130501
|
+
}
|
|
130502
|
+
const [, varName, fieldName] = memberMatch;
|
|
130503
|
+
const typeInfo = CodeGenState.getVariableTypeInfo(varName);
|
|
130504
|
+
if (!typeInfo) {
|
|
130505
|
+
return false;
|
|
130506
|
+
}
|
|
130507
|
+
const structTypeName = typeInfo.baseType;
|
|
130508
|
+
if (!structTypeName) {
|
|
130509
|
+
return false;
|
|
130510
|
+
}
|
|
130511
|
+
const fieldType = CodeGenState.getStructFieldType(
|
|
130512
|
+
structTypeName,
|
|
130513
|
+
fieldName
|
|
130514
|
+
);
|
|
130515
|
+
if (!fieldType) {
|
|
130516
|
+
return false;
|
|
130517
|
+
}
|
|
130518
|
+
return fieldType.startsWith("string");
|
|
130519
|
+
}
|
|
129875
130520
|
/**
|
|
129876
130521
|
* Get type of additive expression.
|
|
129877
130522
|
* Part of IOrchestrator interface - delegates to private implementation.
|
|
@@ -130269,21 +130914,21 @@ var CodeGenerator = class _CodeGenerator {
|
|
|
130269
130914
|
*/
|
|
130270
130915
|
getZeroInitializer(typeCtx, isArray) {
|
|
130271
130916
|
if (isArray) {
|
|
130272
|
-
return this.
|
|
130917
|
+
return this._getAggregateZeroInitBrace();
|
|
130273
130918
|
}
|
|
130274
130919
|
const resolved = this._resolveTypeNameFromContext(typeCtx);
|
|
130275
130920
|
if (resolved) {
|
|
130276
130921
|
if (CodeGenState.symbols.knownEnums.has(resolved.name)) {
|
|
130277
130922
|
return this._getEnumZeroValue(resolved.name, resolved.separator);
|
|
130278
130923
|
}
|
|
130279
|
-
|
|
130280
|
-
return "{}";
|
|
130281
|
-
}
|
|
130282
|
-
return "{0}";
|
|
130924
|
+
return this._getAggregateZeroInitBrace();
|
|
130283
130925
|
}
|
|
130284
130926
|
if (typeCtx.templateType()) {
|
|
130285
130927
|
return "{}";
|
|
130286
130928
|
}
|
|
130929
|
+
if (typeCtx.stringType()) {
|
|
130930
|
+
return '""';
|
|
130931
|
+
}
|
|
130287
130932
|
if (typeCtx.primitiveType()) {
|
|
130288
130933
|
const primType = typeCtx.primitiveType().getText();
|
|
130289
130934
|
return _CodeGenerator.PRIMITIVE_ZERO_VALUES.get(primType) ?? "0";
|
|
@@ -130395,7 +131040,7 @@ var CodeGenerator = class _CodeGenerator {
|
|
|
130395
131040
|
const constMod = p.isConst ? "const " : "";
|
|
130396
131041
|
if (p.isArray) {
|
|
130397
131042
|
return `${constMod}${p.type} ${p.name}${p.arrayDims}`;
|
|
130398
|
-
} else if (p.
|
|
131043
|
+
} else if (p.isStruct) {
|
|
130399
131044
|
const ptrOrRef = this.isCppMode() ? "&" : "*";
|
|
130400
131045
|
return `${constMod}${p.type}${ptrOrRef}`;
|
|
130401
131046
|
} else {
|
|
@@ -130595,7 +131240,15 @@ typedef ${callbackInfo.returnType} (*${callbackInfo.typedefName})(${paramList});
|
|
|
130595
131240
|
return "__GLOBAL_PREFIX__";
|
|
130596
131241
|
}
|
|
130597
131242
|
if (ctx.IDENTIFIER()) {
|
|
130598
|
-
|
|
131243
|
+
const id = ctx.IDENTIFIER().getText();
|
|
131244
|
+
if (id === "break" || id === "continue") {
|
|
131245
|
+
const line = ctx.start?.line ?? 0;
|
|
131246
|
+
const col = ctx.start?.column ?? 0;
|
|
131247
|
+
throw new Error(
|
|
131248
|
+
`${line}:${col} error[E0703]: '${id}' is not supported in C-Next - use structured conditions instead`
|
|
131249
|
+
);
|
|
131250
|
+
}
|
|
131251
|
+
return this._resolveIdentifierExpression(id);
|
|
130599
131252
|
}
|
|
130600
131253
|
if (ctx.literal()) {
|
|
130601
131254
|
return this._generateLiteralExpression(ctx.literal());
|
|
@@ -130840,14 +131493,6 @@ typedef ${callbackInfo.returnType} (*${callbackInfo.typedefName})(${paramList});
|
|
|
130840
131493
|
}
|
|
130841
131494
|
return identifiers.join("_");
|
|
130842
131495
|
}
|
|
130843
|
-
/**
|
|
130844
|
-
* Issue #304: Check if a type name is from a C++ header
|
|
130845
|
-
* Used to determine whether to use {} or {0} for initialization.
|
|
130846
|
-
* C++ types with constructors may fail with {0} but work with {}.
|
|
130847
|
-
*/
|
|
130848
|
-
isCppType(typeName) {
|
|
130849
|
-
return SymbolLookupHelper_default.isCppType(CodeGenState.symbolTable, typeName);
|
|
130850
|
-
}
|
|
130851
131496
|
/**
|
|
130852
131497
|
* Generate C code from a C-Next program
|
|
130853
131498
|
* @param tree The parsed C-Next program
|
|
@@ -131278,6 +131923,7 @@ typedef ${callbackInfo.returnType} (*${callbackInfo.typedefName})(${paramList});
|
|
|
131278
131923
|
const arrayTypeCtx = param.type().arrayType();
|
|
131279
131924
|
const isArray = dims.length > 0 || arrayTypeCtx !== null;
|
|
131280
131925
|
const isCallbackParam = CodeGenState.callbackTypes.has(typeName);
|
|
131926
|
+
const isStruct = this.isStructType(typeName);
|
|
131281
131927
|
let paramType;
|
|
131282
131928
|
let isPointer;
|
|
131283
131929
|
if (isCallbackParam) {
|
|
@@ -131286,7 +131932,7 @@ typedef ${callbackInfo.returnType} (*${callbackInfo.typedefName})(${paramList});
|
|
|
131286
131932
|
isPointer = false;
|
|
131287
131933
|
} else {
|
|
131288
131934
|
paramType = this.generateType(param.type());
|
|
131289
|
-
isPointer = !isArray;
|
|
131935
|
+
isPointer = !isArray && isStruct;
|
|
131290
131936
|
}
|
|
131291
131937
|
let arrayDims;
|
|
131292
131938
|
if (dims.length > 0) {
|
|
@@ -131304,6 +131950,7 @@ typedef ${callbackInfo.returnType} (*${callbackInfo.typedefName})(${paramList});
|
|
|
131304
131950
|
type: paramType,
|
|
131305
131951
|
isConst,
|
|
131306
131952
|
isPointer,
|
|
131953
|
+
isStruct,
|
|
131307
131954
|
isArray,
|
|
131308
131955
|
arrayDims
|
|
131309
131956
|
});
|
|
@@ -131649,7 +132296,7 @@ typedef ${callbackInfo.returnType} (*${callbackInfo.typedefName})(${paramList});
|
|
|
131649
132296
|
}
|
|
131650
132297
|
decl += this._getStringCapacityDimension(varDecl.type());
|
|
131651
132298
|
if (varDecl.expression()) {
|
|
131652
|
-
decl += ` = ${this.generateExpression(varDecl.expression())}`;
|
|
132299
|
+
decl += ` = ${CodeGenState.withDeclarationInit(() => this.generateExpression(varDecl.expression()))}`;
|
|
131653
132300
|
} else {
|
|
131654
132301
|
decl += ` = ${this.getZeroInitializer(varDecl.type(), isArray)}`;
|
|
131655
132302
|
}
|
|
@@ -131842,21 +132489,13 @@ typedef ${callbackInfo.returnType} (*${callbackInfo.typedefName})(${paramList});
|
|
|
131842
132489
|
needsStructKeyword
|
|
131843
132490
|
);
|
|
131844
132491
|
if (!fieldList) {
|
|
131845
|
-
|
|
132492
|
+
if (isCppClass) return "{}";
|
|
132493
|
+
return CodeGenState.inDeclarationInit ? "{ 0 }" : `(${castType}){ 0 }`;
|
|
131846
132494
|
}
|
|
131847
132495
|
const structFieldTypes = CodeGenState.symbolTable?.getStructFieldTypes(typeName);
|
|
131848
132496
|
const fields = fieldList.fieldInitializer().map((field) => {
|
|
131849
132497
|
const fieldName = field.IDENTIFIER().getText();
|
|
131850
|
-
|
|
131851
|
-
if (structFieldTypes?.has(fieldName)) {
|
|
131852
|
-
fieldType = structFieldTypes.get(fieldName);
|
|
131853
|
-
if (fieldType.includes("_")) {
|
|
131854
|
-
const parts = fieldType.split("_");
|
|
131855
|
-
if (parts.length > 1 && this.isCppScopeSymbol(parts[0])) {
|
|
131856
|
-
fieldType = parts.join("::");
|
|
131857
|
-
}
|
|
131858
|
-
}
|
|
131859
|
-
}
|
|
132498
|
+
const fieldType = this._resolveFieldType(fieldName, structFieldTypes);
|
|
131860
132499
|
const value = CodeGenState.withExpectedType(
|
|
131861
132500
|
fieldType,
|
|
131862
132501
|
() => this.generateExpression(field.expression())
|
|
@@ -131872,10 +132511,35 @@ typedef ${callbackInfo.returnType} (*${callbackInfo.typedefName})(${paramList});
|
|
|
131872
132511
|
return "{}";
|
|
131873
132512
|
}
|
|
131874
132513
|
const fieldInits = fields.map((f) => `.${f.fieldName} = ${f.value}`);
|
|
132514
|
+
return this.formatStructInitializer(typeName, castType, fieldInits);
|
|
132515
|
+
}
|
|
132516
|
+
formatStructInitializer(typeName, castType, fieldInits) {
|
|
132517
|
+
const initializer = `{ ${fieldInits.join(", ")} }`;
|
|
132518
|
+
if (CodeGenState.inDeclarationInit) {
|
|
132519
|
+
return initializer;
|
|
132520
|
+
}
|
|
131875
132521
|
if (CodeGenState.cppMode && (typeName.startsWith("struct {") || typeName.startsWith("union {"))) {
|
|
131876
|
-
return
|
|
132522
|
+
return initializer;
|
|
132523
|
+
}
|
|
132524
|
+
if (!CodeGenState.inFunctionBody) {
|
|
132525
|
+
return initializer;
|
|
131877
132526
|
}
|
|
131878
|
-
return `(${castType})
|
|
132527
|
+
return `(${castType})${initializer}`;
|
|
132528
|
+
}
|
|
132529
|
+
/**
|
|
132530
|
+
* Resolve the C type string for a named struct field, converting C++ underscore-separated
|
|
132531
|
+
* names to :: notation. Returns undefined if the field is not in the type map.
|
|
132532
|
+
* Issue #502: C-Next stores C++ types with _ separator; codegen needs ::.
|
|
132533
|
+
*/
|
|
132534
|
+
_resolveFieldType(fieldName, structFieldTypes) {
|
|
132535
|
+
if (!structFieldTypes?.has(fieldName)) return void 0;
|
|
132536
|
+
const fieldType = structFieldTypes.get(fieldName);
|
|
132537
|
+
if (!fieldType.includes("_")) return fieldType;
|
|
132538
|
+
const parts = fieldType.split("_");
|
|
132539
|
+
if (parts.length > 1 && this.isCppScopeSymbol(parts[0])) {
|
|
132540
|
+
return parts.join("::");
|
|
132541
|
+
}
|
|
132542
|
+
return fieldType;
|
|
131879
132543
|
}
|
|
131880
132544
|
/**
|
|
131881
132545
|
* ADR-035: Generate array initializer
|
|
@@ -132018,7 +132682,9 @@ typedef ${callbackInfo.returnType} (*${callbackInfo.typedefName})(${paramList});
|
|
|
132018
132682
|
isCallbackCompatible,
|
|
132019
132683
|
forcePassByReference,
|
|
132020
132684
|
forceConst,
|
|
132021
|
-
isTypedefStructType: (t) => CodeGenState.symbolTable?.isTypedefStructType(t) ?? false
|
|
132685
|
+
isTypedefStructType: (t) => CodeGenState.symbolTable?.isTypedefStructType(t) ?? false,
|
|
132686
|
+
// Issue #995: Opaque handles should not get auto-const
|
|
132687
|
+
isOpaqueType: (t) => CodeGenState.isOpaqueType(t)
|
|
132022
132688
|
});
|
|
132023
132689
|
return ParameterSignatureBuilder_default.build(input, CppModeHelper_default.refOrPtr());
|
|
132024
132690
|
}
|
|
@@ -132249,26 +132915,13 @@ typedef ${callbackInfo.returnType} (*${callbackInfo.typedefName})(${paramList});
|
|
|
132249
132915
|
// _generateVariableInitializer, _validateIntegerInitializer, _finalizeCppClassAssignments,
|
|
132250
132916
|
// and _generateConstructorDecl have been extracted to VariableDeclHelper.ts
|
|
132251
132917
|
/**
|
|
132252
|
-
*
|
|
132253
|
-
* Issue #379: C++
|
|
132918
|
+
* Brace initializer that zero-initializes an aggregate (struct or array).
|
|
132919
|
+
* Issue #379 / #1004: C++ uses value-initialization ({}), which is valid for
|
|
132920
|
+
* any aggregate element type (POD, struct, class) including enum-first
|
|
132921
|
+
* structs where {0} is an invalid int->enum narrowing; C uses {0}.
|
|
132254
132922
|
*/
|
|
132255
|
-
|
|
132256
|
-
|
|
132257
|
-
const typeName = typeCtx.userType().getText();
|
|
132258
|
-
if (this._needsEmptyBraceInit(typeName)) {
|
|
132259
|
-
return "{}";
|
|
132260
|
-
}
|
|
132261
|
-
}
|
|
132262
|
-
if (typeCtx.arrayType()?.userType()) {
|
|
132263
|
-
const typeName = typeCtx.arrayType().userType().getText();
|
|
132264
|
-
if (this._needsEmptyBraceInit(typeName)) {
|
|
132265
|
-
return "{}";
|
|
132266
|
-
}
|
|
132267
|
-
}
|
|
132268
|
-
if (typeCtx.templateType()) {
|
|
132269
|
-
return "{}";
|
|
132270
|
-
}
|
|
132271
|
-
return "{0}";
|
|
132923
|
+
_getAggregateZeroInitBrace() {
|
|
132924
|
+
return CodeGenState.cppMode ? "{}" : "{0}";
|
|
132272
132925
|
}
|
|
132273
132926
|
/**
|
|
132274
132927
|
* Get zero initializer for an enum type.
|
|
@@ -132293,49 +132946,35 @@ typedef ${callbackInfo.returnType} (*${callbackInfo.typedefName})(${paramList});
|
|
|
132293
132946
|
}
|
|
132294
132947
|
/**
|
|
132295
132948
|
* Resolve full type name from any TypeContext variant.
|
|
132296
|
-
* Returns { name, separator
|
|
132949
|
+
* Returns { name, separator } or null if not a named type.
|
|
132297
132950
|
* ADR-016: Handles scoped, global, qualified, and user types
|
|
132298
|
-
* checkCppType: only true for userType (original behavior preserved)
|
|
132299
132951
|
*/
|
|
132300
132952
|
_resolveTypeNameFromContext(typeCtx) {
|
|
132301
132953
|
if (typeCtx.scopedType()) {
|
|
132302
132954
|
const localName = typeCtx.scopedType().IDENTIFIER().getText();
|
|
132303
132955
|
const name = CodeGenState.currentScope ? `${CodeGenState.currentScope}_${localName}` : localName;
|
|
132304
|
-
return { name, separator: "_"
|
|
132956
|
+
return { name, separator: "_" };
|
|
132305
132957
|
}
|
|
132306
132958
|
if (typeCtx.globalType()) {
|
|
132307
132959
|
return {
|
|
132308
132960
|
name: typeCtx.globalType().IDENTIFIER().getText(),
|
|
132309
|
-
separator: "_"
|
|
132310
|
-
checkCppType: false
|
|
132961
|
+
separator: "_"
|
|
132311
132962
|
};
|
|
132312
132963
|
}
|
|
132313
132964
|
if (typeCtx.qualifiedType()) {
|
|
132314
132965
|
const parts = typeCtx.qualifiedType().IDENTIFIER();
|
|
132315
132966
|
const name = this.resolveQualifiedType(parts.map((id) => id.getText()));
|
|
132316
132967
|
const separator = name.includes("::") ? "::" : "_";
|
|
132317
|
-
return { name, separator
|
|
132968
|
+
return { name, separator };
|
|
132318
132969
|
}
|
|
132319
132970
|
if (typeCtx.userType()) {
|
|
132320
132971
|
return {
|
|
132321
132972
|
name: typeCtx.userType().getText(),
|
|
132322
|
-
separator: "_"
|
|
132323
|
-
checkCppType: true
|
|
132973
|
+
separator: "_"
|
|
132324
132974
|
};
|
|
132325
132975
|
}
|
|
132326
132976
|
return null;
|
|
132327
132977
|
}
|
|
132328
|
-
/**
|
|
132329
|
-
* Check if a type needs empty brace initialization {}.
|
|
132330
|
-
* Issue #304: C++ types with constructors may fail with {0}
|
|
132331
|
-
* Issue #309: Unknown user types in C++ mode may have non-trivial constructors
|
|
132332
|
-
*/
|
|
132333
|
-
_needsEmptyBraceInit(typeName) {
|
|
132334
|
-
if (this.isCppType(typeName)) {
|
|
132335
|
-
return true;
|
|
132336
|
-
}
|
|
132337
|
-
return CodeGenState.cppMode && !this.isKnownStruct(typeName);
|
|
132338
|
-
}
|
|
132339
132978
|
/**
|
|
132340
132979
|
* Generate a safe bit mask expression.
|
|
132341
132980
|
* Avoids undefined behavior when width >= 32 for 32-bit integers.
|
|
@@ -132715,7 +133354,7 @@ typedef ${callbackInfo.returnType} (*${callbackInfo.typedefName})(${paramList});
|
|
|
132715
133354
|
const maxComparison = `((${floatCastType})${maxValue})`;
|
|
132716
133355
|
const finalCast = CppModeHelper_default.cast(targetType, `(${expr})`);
|
|
132717
133356
|
const castMax = CppModeHelper_default.cast(targetType, maxValue);
|
|
132718
|
-
const castMin =
|
|
133357
|
+
const castMin = CppModeHelper_default.cast(targetType, minValue);
|
|
132719
133358
|
return `((${expr}) > ${maxComparison} ? ${castMax} : (${expr}) < ${minComparison} ? ${castMin} : ${finalCast})`;
|
|
132720
133359
|
}
|
|
132721
133360
|
/**
|
|
@@ -133091,6 +133730,30 @@ var generateEnumHeader_default = generateEnumHeader;
|
|
|
133091
133730
|
|
|
133092
133731
|
// src/transpiler/output/headers/generators/generateStructHeader.ts
|
|
133093
133732
|
var { mapType: mapType2 } = mapType_default;
|
|
133733
|
+
function resolveFieldCType(fieldType, input) {
|
|
133734
|
+
const callbackInfo = input.callbackTypes?.get(fieldType);
|
|
133735
|
+
if (callbackInfo) {
|
|
133736
|
+
return callbackInfo.typedefName;
|
|
133737
|
+
}
|
|
133738
|
+
const convertedType = CppNamespaceUtils_default.convertToCppNamespace(
|
|
133739
|
+
fieldType,
|
|
133740
|
+
input.symbolTable
|
|
133741
|
+
);
|
|
133742
|
+
return mapType2(convertedType);
|
|
133743
|
+
}
|
|
133744
|
+
function generateFieldLine(fieldName, cType, dims) {
|
|
133745
|
+
const dimSuffix = dims && dims.length > 0 ? dims.map((d) => `[${d}]`).join("") : "";
|
|
133746
|
+
const embeddedMatch = /^(\w+)\[(\d+)\]$/.exec(cType);
|
|
133747
|
+
if (!embeddedMatch) {
|
|
133748
|
+
return ` ${cType} ${fieldName}${dimSuffix};`;
|
|
133749
|
+
}
|
|
133750
|
+
const baseType = embeddedMatch[1];
|
|
133751
|
+
const embeddedDim = embeddedMatch[2];
|
|
133752
|
+
if (dims && dims.length > 0) {
|
|
133753
|
+
return ` ${baseType} ${fieldName}${dimSuffix};`;
|
|
133754
|
+
}
|
|
133755
|
+
return ` ${baseType} ${fieldName}[${embeddedDim}];`;
|
|
133756
|
+
}
|
|
133094
133757
|
function generateStructHeader(name, input) {
|
|
133095
133758
|
const fields = input.structFields.get(name);
|
|
133096
133759
|
if (!fields || fields.size === 0) {
|
|
@@ -133100,25 +133763,9 @@ function generateStructHeader(name, input) {
|
|
|
133100
133763
|
const lines = [];
|
|
133101
133764
|
lines.push(`typedef struct ${name} {`);
|
|
133102
133765
|
for (const [fieldName, fieldType] of fields) {
|
|
133103
|
-
const
|
|
133104
|
-
fieldType,
|
|
133105
|
-
input.symbolTable
|
|
133106
|
-
);
|
|
133107
|
-
const cType = mapType2(convertedType);
|
|
133766
|
+
const cType = resolveFieldCType(fieldType, input);
|
|
133108
133767
|
const dims = dimensions?.get(fieldName);
|
|
133109
|
-
|
|
133110
|
-
const embeddedMatch = /^(\w+)\[(\d+)\]$/.exec(cType);
|
|
133111
|
-
if (embeddedMatch) {
|
|
133112
|
-
const baseType = embeddedMatch[1];
|
|
133113
|
-
const embeddedDim = embeddedMatch[2];
|
|
133114
|
-
if (dims && dims.length > 0) {
|
|
133115
|
-
lines.push(` ${baseType} ${fieldName}${dimSuffix};`);
|
|
133116
|
-
} else {
|
|
133117
|
-
lines.push(` ${baseType} ${fieldName}[${embeddedDim}];`);
|
|
133118
|
-
}
|
|
133119
|
-
} else {
|
|
133120
|
-
lines.push(` ${cType} ${fieldName}${dimSuffix};`);
|
|
133121
|
-
}
|
|
133768
|
+
lines.push(generateFieldLine(fieldName, cType, dims));
|
|
133122
133769
|
}
|
|
133123
133770
|
lines.push(`} ${name};`);
|
|
133124
133771
|
return lines.join("\n");
|
|
@@ -133511,6 +134158,59 @@ var HeaderGeneratorUtils = class _HeaderGeneratorUtils {
|
|
|
133511
134158
|
lines.push("");
|
|
133512
134159
|
return lines;
|
|
133513
134160
|
}
|
|
134161
|
+
/**
|
|
134162
|
+
* ADR-029: Generate forward declarations for structs used in callback typedefs.
|
|
134163
|
+
* This ensures struct types can be used in callback parameter types before
|
|
134164
|
+
* the full struct definition.
|
|
134165
|
+
*/
|
|
134166
|
+
static generateCallbackStructForwardDecls(structs, typeInput) {
|
|
134167
|
+
if (!typeInput?.callbackTypes || typeInput.callbackTypes.size === 0) {
|
|
134168
|
+
return [];
|
|
134169
|
+
}
|
|
134170
|
+
const usedStructTypes = /* @__PURE__ */ new Set();
|
|
134171
|
+
for (const [, cbInfo] of typeInput.callbackTypes) {
|
|
134172
|
+
for (const p of cbInfo.parameters) {
|
|
134173
|
+
if (p.isStruct) {
|
|
134174
|
+
usedStructTypes.add(p.type);
|
|
134175
|
+
}
|
|
134176
|
+
}
|
|
134177
|
+
}
|
|
134178
|
+
if (usedStructTypes.size === 0) {
|
|
134179
|
+
return [];
|
|
134180
|
+
}
|
|
134181
|
+
const localStructNames = new Set(structs.map((s) => s.name));
|
|
134182
|
+
const lines = [];
|
|
134183
|
+
for (const structType of usedStructTypes) {
|
|
134184
|
+
if (localStructNames.has(structType)) {
|
|
134185
|
+
lines.push(`typedef struct ${structType} ${structType};`);
|
|
134186
|
+
}
|
|
134187
|
+
}
|
|
134188
|
+
return lines.length > 0 ? [...lines, ""] : [];
|
|
134189
|
+
}
|
|
134190
|
+
/**
|
|
134191
|
+
* ADR-029: Generate callback typedef section
|
|
134192
|
+
* Generates function pointer typedefs for callbacks used as struct field types
|
|
134193
|
+
*/
|
|
134194
|
+
static generateCallbackTypedefSection(typeInput, isCppMode) {
|
|
134195
|
+
if (!typeInput?.callbackTypes || typeInput.callbackTypes.size === 0) {
|
|
134196
|
+
return [];
|
|
134197
|
+
}
|
|
134198
|
+
const lines = ["/* Callback typedefs */"];
|
|
134199
|
+
for (const [, cbInfo] of typeInput.callbackTypes) {
|
|
134200
|
+
const params = cbInfo.parameters.length > 0 ? cbInfo.parameters.map((p) => {
|
|
134201
|
+
if (p.isStruct) {
|
|
134202
|
+
const ptrOrRef = isCppMode ? "&" : "*";
|
|
134203
|
+
return `${p.type}${ptrOrRef}`;
|
|
134204
|
+
}
|
|
134205
|
+
return p.type;
|
|
134206
|
+
}).join(", ") : "void";
|
|
134207
|
+
lines.push(
|
|
134208
|
+
`typedef ${cbInfo.returnType} (*${cbInfo.typedefName})(${params});`
|
|
134209
|
+
);
|
|
134210
|
+
}
|
|
134211
|
+
lines.push("");
|
|
134212
|
+
return lines;
|
|
134213
|
+
}
|
|
133514
134214
|
/**
|
|
133515
134215
|
* Generate struct and class definitions section
|
|
133516
134216
|
*/
|
|
@@ -133638,6 +134338,14 @@ var BaseHeaderGenerator = class {
|
|
|
133638
134338
|
...HeaderGeneratorUtils_default.generateEnumSection(groups.enums, typeInput),
|
|
133639
134339
|
...HeaderGeneratorUtils_default.generateBitmapSection(groups.bitmaps, typeInput),
|
|
133640
134340
|
...HeaderGeneratorUtils_default.generateTypeAliasSection(groups.types),
|
|
134341
|
+
...HeaderGeneratorUtils_default.generateCallbackStructForwardDecls(
|
|
134342
|
+
groups.structs,
|
|
134343
|
+
typeInput
|
|
134344
|
+
),
|
|
134345
|
+
...HeaderGeneratorUtils_default.generateCallbackTypedefSection(
|
|
134346
|
+
typeInput,
|
|
134347
|
+
options.cppMode
|
|
134348
|
+
),
|
|
133641
134349
|
...HeaderGeneratorUtils_default.generateStructSection(
|
|
133642
134350
|
groups.structs,
|
|
133643
134351
|
groups.classes,
|
|
@@ -133976,24 +134684,32 @@ var EnumCollector = class {
|
|
|
133976
134684
|
var EnumCollector_default = EnumCollector;
|
|
133977
134685
|
|
|
133978
134686
|
// src/transpiler/logic/symbols/cnext/utils/TypeUtils.ts
|
|
133979
|
-
function resolveScopedType(scopedTypeCtx, scopeName) {
|
|
133980
|
-
const typeName = scopedTypeCtx.IDENTIFIER().getText();
|
|
133981
|
-
return scopeName ? `${scopeName}_${typeName}` : typeName;
|
|
133982
|
-
}
|
|
133983
134687
|
function resolveStringType(stringCtx) {
|
|
133984
134688
|
const intLiteral = stringCtx.INTEGER_LITERAL();
|
|
133985
134689
|
return intLiteral ? `string<${intLiteral.getText()}>` : "string";
|
|
133986
134690
|
}
|
|
133987
|
-
function
|
|
133988
|
-
if (
|
|
133989
|
-
|
|
134691
|
+
function dispatchTypeResolution(accessors, scopeName) {
|
|
134692
|
+
if (accessors.scopedType()) {
|
|
134693
|
+
const typeName = accessors.scopedType().IDENTIFIER().getText();
|
|
134694
|
+
return scopeName ? `${scopeName}_${typeName}` : typeName;
|
|
134695
|
+
}
|
|
134696
|
+
if (accessors.globalType()) {
|
|
134697
|
+
return accessors.globalType().IDENTIFIER().getText();
|
|
133990
134698
|
}
|
|
133991
|
-
if (
|
|
133992
|
-
|
|
134699
|
+
if (accessors.qualifiedType()) {
|
|
134700
|
+
const identifiers = accessors.qualifiedType().IDENTIFIER();
|
|
134701
|
+
return identifiers.map((id) => id.getText()).join("_");
|
|
133993
134702
|
}
|
|
133994
|
-
|
|
133995
|
-
|
|
133996
|
-
|
|
134703
|
+
if (accessors.userType()) {
|
|
134704
|
+
return accessors.userType().getText();
|
|
134705
|
+
}
|
|
134706
|
+
if (accessors.primitiveType()) {
|
|
134707
|
+
return accessors.primitiveType().getText();
|
|
134708
|
+
}
|
|
134709
|
+
if (accessors.stringType()) {
|
|
134710
|
+
return resolveStringType(accessors.stringType());
|
|
134711
|
+
}
|
|
134712
|
+
return null;
|
|
133997
134713
|
}
|
|
133998
134714
|
var TypeUtils = class {
|
|
133999
134715
|
/**
|
|
@@ -134007,27 +134723,18 @@ var TypeUtils = class {
|
|
|
134007
134723
|
*/
|
|
134008
134724
|
static getTypeName(ctx, scopeName) {
|
|
134009
134725
|
if (!ctx) return "void";
|
|
134010
|
-
if (ctx.scopedType()) {
|
|
134011
|
-
return resolveScopedType(ctx.scopedType(), scopeName);
|
|
134012
|
-
}
|
|
134013
|
-
if (ctx.globalType()) {
|
|
134014
|
-
return ctx.globalType().IDENTIFIER().getText();
|
|
134015
|
-
}
|
|
134016
|
-
if (ctx.qualifiedType()) {
|
|
134017
|
-
const identifiers = ctx.qualifiedType().IDENTIFIER();
|
|
134018
|
-
return identifiers.map((id) => id.getText()).join("_");
|
|
134019
|
-
}
|
|
134020
|
-
if (ctx.userType()) {
|
|
134021
|
-
return ctx.userType().getText();
|
|
134022
|
-
}
|
|
134023
|
-
if (ctx.primitiveType()) {
|
|
134024
|
-
return ctx.primitiveType().getText();
|
|
134025
|
-
}
|
|
134026
|
-
if (ctx.stringType()) {
|
|
134027
|
-
return resolveStringType(ctx.stringType());
|
|
134028
|
-
}
|
|
134029
134726
|
if (ctx.arrayType()) {
|
|
134030
|
-
|
|
134727
|
+
const result2 = dispatchTypeResolution(ctx.arrayType(), scopeName);
|
|
134728
|
+
if (result2 !== null) {
|
|
134729
|
+
return result2;
|
|
134730
|
+
}
|
|
134731
|
+
const text = ctx.arrayType().getText();
|
|
134732
|
+
const bracketIdx = text.indexOf("[");
|
|
134733
|
+
return bracketIdx > 0 ? text.substring(0, bracketIdx) : text;
|
|
134734
|
+
}
|
|
134735
|
+
const result = dispatchTypeResolution(ctx, scopeName);
|
|
134736
|
+
if (result !== null) {
|
|
134737
|
+
return result;
|
|
134031
134738
|
}
|
|
134032
134739
|
return ctx.getText();
|
|
134033
134740
|
}
|
|
@@ -134393,13 +135100,22 @@ var VariableCollector = class _VariableCollector {
|
|
|
134393
135100
|
return dimensions;
|
|
134394
135101
|
}
|
|
134395
135102
|
/**
|
|
134396
|
-
* Collect dimensions from C-Next style arrayType syntax (u16[8] arr, u16[4][4] arr).
|
|
135103
|
+
* Collect dimensions from C-Next style arrayType syntax (u16[8] arr, u16[4][4] arr, u16[] arr).
|
|
135104
|
+
* Handles size inference from initializer when dimension is empty.
|
|
134397
135105
|
*/
|
|
134398
|
-
static collectArrayTypeDimensions(arrayTypeCtx, constValues) {
|
|
135106
|
+
static collectArrayTypeDimensions(arrayTypeCtx, constValues, initExpr) {
|
|
134399
135107
|
const dimensions = [];
|
|
134400
135108
|
for (const dim of arrayTypeCtx.arrayTypeDimension()) {
|
|
134401
135109
|
const sizeExpr = dim.expression();
|
|
134402
|
-
if (!sizeExpr)
|
|
135110
|
+
if (!sizeExpr) {
|
|
135111
|
+
if (initExpr) {
|
|
135112
|
+
const inferredSize = ArrayInitializerUtils_default.getInferredSize(initExpr);
|
|
135113
|
+
if (inferredSize !== void 0) {
|
|
135114
|
+
dimensions.push(inferredSize);
|
|
135115
|
+
}
|
|
135116
|
+
}
|
|
135117
|
+
continue;
|
|
135118
|
+
}
|
|
134403
135119
|
const dimText = sizeExpr.getText();
|
|
134404
135120
|
const literalSize = LiteralUtils_default.parseIntegerLiteral(dimText);
|
|
134405
135121
|
if (literalSize !== void 0) {
|
|
@@ -134441,7 +135157,8 @@ var VariableCollector = class _VariableCollector {
|
|
|
134441
135157
|
arrayDimensions.push(
|
|
134442
135158
|
..._VariableCollector.collectArrayTypeDimensions(
|
|
134443
135159
|
arrayTypeCtx,
|
|
134444
|
-
constValues
|
|
135160
|
+
constValues,
|
|
135161
|
+
initExpr
|
|
134445
135162
|
)
|
|
134446
135163
|
);
|
|
134447
135164
|
}
|
|
@@ -134560,7 +135277,9 @@ var ScopeCollector = class {
|
|
|
134560
135277
|
const memberSymbols = [];
|
|
134561
135278
|
for (const member of ctx.scopeMember()) {
|
|
134562
135279
|
const visibilityMod = member.visibilityModifier();
|
|
134563
|
-
const
|
|
135280
|
+
const explicitVisibility = visibilityMod?.getText();
|
|
135281
|
+
const isFunction = member.functionDeclaration() !== null;
|
|
135282
|
+
const visibility = explicitVisibility ?? ScopeUtils_default.getDefaultVisibility(isFunction);
|
|
134564
135283
|
const isPublic = visibility === "public";
|
|
134565
135284
|
if (member.variableDeclaration()) {
|
|
134566
135285
|
const varDecl = member.variableDeclaration();
|
|
@@ -135250,12 +135969,15 @@ var TSymbolInfoAdapter_default = TSymbolInfoAdapter;
|
|
|
135250
135969
|
var RESERVED_FIELD_NAMES = /* @__PURE__ */ new Set([]);
|
|
135251
135970
|
function parseArrayDimensions2(text) {
|
|
135252
135971
|
const dimensions = [];
|
|
135253
|
-
const arrayMatches = text.match(/\[(
|
|
135972
|
+
const arrayMatches = text.match(/\[([^\]]+)\]/g);
|
|
135254
135973
|
if (arrayMatches) {
|
|
135255
135974
|
for (const match of arrayMatches) {
|
|
135256
|
-
const
|
|
135257
|
-
|
|
135258
|
-
|
|
135975
|
+
const content = match.slice(1, -1).trim();
|
|
135976
|
+
const numericValue = Number.parseInt(content, 10);
|
|
135977
|
+
if (!Number.isNaN(numericValue) && String(numericValue) === content) {
|
|
135978
|
+
dimensions.push(numericValue);
|
|
135979
|
+
} else {
|
|
135980
|
+
dimensions.push(content);
|
|
135259
135981
|
}
|
|
135260
135982
|
}
|
|
135261
135983
|
}
|
|
@@ -135453,6 +136175,7 @@ var DeclaratorUtils = class _DeclaratorUtils {
|
|
|
135453
136175
|
}
|
|
135454
136176
|
/**
|
|
135455
136177
|
* Extract array dimensions from a declarator.
|
|
136178
|
+
* Issue #981: Returns (number | string)[] to support macro-sized arrays.
|
|
135456
136179
|
*/
|
|
135457
136180
|
static extractArrayDimensions(declarator) {
|
|
135458
136181
|
const directDecl = declarator.directDeclarator?.();
|
|
@@ -136607,6 +137330,7 @@ var DeclaratorUtils2 = class _DeclaratorUtils {
|
|
|
136607
137330
|
}
|
|
136608
137331
|
/**
|
|
136609
137332
|
* Extract array dimensions from a declarator.
|
|
137333
|
+
* Issue #981: Returns (number | string)[] to support macro-sized arrays.
|
|
136610
137334
|
*/
|
|
136611
137335
|
static extractArrayDimensions(declarator) {
|
|
136612
137336
|
const ptrDecl = declarator.pointerDeclarator?.();
|
|
@@ -136624,6 +137348,7 @@ var DeclaratorUtils2 = class _DeclaratorUtils {
|
|
|
136624
137348
|
}
|
|
136625
137349
|
/**
|
|
136626
137350
|
* Extract array dimensions from a noPointerDeclarator.
|
|
137351
|
+
* Issue #981: Returns (number | string)[] to support macro-sized arrays.
|
|
136627
137352
|
*/
|
|
136628
137353
|
static extractArrayDimensionsFromNoPtr(noPtr) {
|
|
136629
137354
|
return SymbolUtils_default.parseArrayDimensions(noPtr.getText());
|
|
@@ -138795,19 +139520,28 @@ var InitializationListener = class extends CNextListener {
|
|
|
138795
139520
|
if (!baseId) {
|
|
138796
139521
|
return;
|
|
138797
139522
|
}
|
|
139523
|
+
const target = this._resolveAssignmentTarget(baseId, postfixOps);
|
|
139524
|
+
const isCompoundAssignment = ctx.assignmentOperator().ASSIGN() === null;
|
|
139525
|
+
if (isCompoundAssignment) {
|
|
139526
|
+
const { line, column } = ParserUtils_default.getPosition(ctx);
|
|
139527
|
+
this.analyzer.checkRead(target.varName, line, column, target.fieldName);
|
|
139528
|
+
}
|
|
139529
|
+
this.analyzer.recordAssignment(target.varName, target.fieldName);
|
|
139530
|
+
};
|
|
139531
|
+
/**
|
|
139532
|
+
* Resolve an assignment target to its variable name and optional field name.
|
|
139533
|
+
* Single classification path used by both read checks and assignment recording.
|
|
139534
|
+
*/
|
|
139535
|
+
_resolveAssignmentTarget(baseId, postfixOps) {
|
|
138798
139536
|
if (postfixOps.length === 0) {
|
|
138799
|
-
|
|
138800
|
-
return;
|
|
139537
|
+
return { varName: baseId };
|
|
138801
139538
|
}
|
|
138802
139539
|
const { identifiers, hasSubscript } = PostfixAnalysisUtils_default(baseId, postfixOps);
|
|
138803
139540
|
if (identifiers.length >= 2 && !hasSubscript) {
|
|
138804
|
-
|
|
138805
|
-
const fieldName = identifiers[1];
|
|
138806
|
-
this.analyzer.recordAssignment(varName, fieldName);
|
|
138807
|
-
} else {
|
|
138808
|
-
this.analyzer.recordAssignment(baseId);
|
|
139541
|
+
return { varName: identifiers[0], fieldName: identifiers[1] };
|
|
138809
139542
|
}
|
|
138810
|
-
|
|
139543
|
+
return { varName: baseId };
|
|
139544
|
+
}
|
|
138811
139545
|
// ========================================================================
|
|
138812
139546
|
// Function Call Arguments (ADR-006: pass-by-reference may initialize)
|
|
138813
139547
|
// ========================================================================
|
|
@@ -139045,27 +139779,128 @@ var InitializationAnalyzer = class {
|
|
|
139045
139779
|
}
|
|
139046
139780
|
/**
|
|
139047
139781
|
* Process scope member variable declarations (ADR-016)
|
|
139782
|
+
* Issue #1019: Scope members require explicit initialization like locals
|
|
139048
139783
|
*/
|
|
139049
139784
|
_processScopeMembers(decl) {
|
|
139050
139785
|
const scopeDecl = decl.scopeDeclaration();
|
|
139051
139786
|
if (!scopeDecl) return;
|
|
139052
139787
|
const scopeName = scopeDecl.IDENTIFIER().getText();
|
|
139788
|
+
const assignedMembers = this._findAssignedScopeMembers(scopeDecl);
|
|
139053
139789
|
for (const member of scopeDecl.scopeMember()) {
|
|
139054
|
-
this._processScopeMemberVariable(member, scopeName);
|
|
139790
|
+
this._processScopeMemberVariable(member, scopeName, assignedMembers);
|
|
139791
|
+
}
|
|
139792
|
+
}
|
|
139793
|
+
/**
|
|
139794
|
+
* Scan all functions in a scope to find which members are assigned.
|
|
139795
|
+
* Issue #1019: A member assigned in ANY function is considered initialized
|
|
139796
|
+
* for reads in other functions within the same scope.
|
|
139797
|
+
*/
|
|
139798
|
+
_findAssignedScopeMembers(scopeDecl) {
|
|
139799
|
+
const assigned = /* @__PURE__ */ new Set();
|
|
139800
|
+
for (const member of scopeDecl.scopeMember()) {
|
|
139801
|
+
const funcDecl = member.functionDeclaration();
|
|
139802
|
+
if (!funcDecl) continue;
|
|
139803
|
+
const body = funcDecl.block();
|
|
139804
|
+
if (!body) continue;
|
|
139805
|
+
this._collectAssignmentsInBlock(body, assigned);
|
|
139806
|
+
}
|
|
139807
|
+
return assigned;
|
|
139808
|
+
}
|
|
139809
|
+
/**
|
|
139810
|
+
* Recursively collect variable names that are assigned in a block.
|
|
139811
|
+
* Looks for assignment statements targeting bare identifiers or this.member.
|
|
139812
|
+
*/
|
|
139813
|
+
_collectAssignmentsInBlock(block, assigned) {
|
|
139814
|
+
for (const stmt of block.statement()) {
|
|
139815
|
+
this._collectAssignmentsInStatement(stmt, assigned);
|
|
139816
|
+
}
|
|
139817
|
+
}
|
|
139818
|
+
/**
|
|
139819
|
+
* Collect assignments from a single statement, recursing into nested blocks.
|
|
139820
|
+
*/
|
|
139821
|
+
_collectAssignmentsInStatement(stmt, assigned) {
|
|
139822
|
+
this._collectDirectAssignment(stmt, assigned);
|
|
139823
|
+
this._collectFromControlFlow(stmt, assigned);
|
|
139824
|
+
this._collectFromSwitch(stmt, assigned);
|
|
139825
|
+
this._collectFromBlock(stmt, assigned);
|
|
139826
|
+
}
|
|
139827
|
+
/**
|
|
139828
|
+
* Collect assignment from the statement itself (if it's an assignment).
|
|
139829
|
+
*/
|
|
139830
|
+
_collectDirectAssignment(stmt, assigned) {
|
|
139831
|
+
const assignStmt = stmt.assignmentStatement();
|
|
139832
|
+
if (!assignStmt) return;
|
|
139833
|
+
const target = assignStmt.assignmentTarget();
|
|
139834
|
+
if (!target) return;
|
|
139835
|
+
const id = target.IDENTIFIER()?.getText();
|
|
139836
|
+
if (id) {
|
|
139837
|
+
assigned.add(id);
|
|
139838
|
+
}
|
|
139839
|
+
}
|
|
139840
|
+
/**
|
|
139841
|
+
* Recurse into control flow statements (if, while, do-while, for).
|
|
139842
|
+
*/
|
|
139843
|
+
_collectFromControlFlow(stmt, assigned) {
|
|
139844
|
+
const ifStmt = stmt.ifStatement();
|
|
139845
|
+
if (ifStmt) {
|
|
139846
|
+
for (const childStmt of ifStmt.statement()) {
|
|
139847
|
+
this._collectAssignmentsInStatement(childStmt, assigned);
|
|
139848
|
+
}
|
|
139849
|
+
}
|
|
139850
|
+
const whileBody = stmt.whileStatement()?.statement();
|
|
139851
|
+
if (whileBody) {
|
|
139852
|
+
this._collectAssignmentsInStatement(whileBody, assigned);
|
|
139853
|
+
}
|
|
139854
|
+
const doWhileBody = stmt.doWhileStatement()?.block();
|
|
139855
|
+
if (doWhileBody) {
|
|
139856
|
+
this._collectAssignmentsInBlock(doWhileBody, assigned);
|
|
139857
|
+
}
|
|
139858
|
+
const forBody = stmt.forStatement()?.statement();
|
|
139859
|
+
if (forBody) {
|
|
139860
|
+
this._collectAssignmentsInStatement(forBody, assigned);
|
|
139861
|
+
}
|
|
139862
|
+
}
|
|
139863
|
+
/**
|
|
139864
|
+
* Recurse into switch statement cases.
|
|
139865
|
+
*/
|
|
139866
|
+
_collectFromSwitch(stmt, assigned) {
|
|
139867
|
+
const switchStmt = stmt.switchStatement();
|
|
139868
|
+
if (!switchStmt) return;
|
|
139869
|
+
for (const switchCase of switchStmt.switchCase()) {
|
|
139870
|
+
const caseBlock = switchCase.block();
|
|
139871
|
+
if (caseBlock) {
|
|
139872
|
+
this._collectAssignmentsInBlock(caseBlock, assigned);
|
|
139873
|
+
}
|
|
139874
|
+
}
|
|
139875
|
+
const defaultBlock = switchStmt.defaultCase()?.block();
|
|
139876
|
+
if (defaultBlock) {
|
|
139877
|
+
this._collectAssignmentsInBlock(defaultBlock, assigned);
|
|
139878
|
+
}
|
|
139879
|
+
}
|
|
139880
|
+
/**
|
|
139881
|
+
* Recurse into standalone block statement.
|
|
139882
|
+
*/
|
|
139883
|
+
_collectFromBlock(stmt, assigned) {
|
|
139884
|
+
const block = stmt.block();
|
|
139885
|
+
if (block) {
|
|
139886
|
+
this._collectAssignmentsInBlock(block, assigned);
|
|
139055
139887
|
}
|
|
139056
139888
|
}
|
|
139057
139889
|
/**
|
|
139058
139890
|
* Process a single scope member variable
|
|
139059
139891
|
*/
|
|
139060
|
-
_processScopeMemberVariable(member, scopeName) {
|
|
139892
|
+
_processScopeMemberVariable(member, scopeName, assignedMembers) {
|
|
139061
139893
|
const memberVar = member.variableDeclaration();
|
|
139062
139894
|
if (!memberVar) return;
|
|
139063
139895
|
const varName = memberVar.IDENTIFIER().getText();
|
|
139064
139896
|
const fullName = `${scopeName}_${varName}`;
|
|
139065
139897
|
const { line, column } = ParserUtils_default.getPosition(memberVar);
|
|
139066
139898
|
const typeName = this._extractUserTypeName(memberVar.type());
|
|
139067
|
-
|
|
139068
|
-
|
|
139899
|
+
const hasInlineInit = memberVar.expression() !== null;
|
|
139900
|
+
const isAssignedInScope = assignedMembers.has(varName);
|
|
139901
|
+
const hasInitializer = hasInlineInit || isAssignedInScope;
|
|
139902
|
+
this.declareVariable(varName, line, column, hasInitializer, typeName);
|
|
139903
|
+
this.declareVariable(fullName, line, column, hasInitializer, typeName);
|
|
139069
139904
|
}
|
|
139070
139905
|
/**
|
|
139071
139906
|
* Extract user type name from a type context
|
|
@@ -139564,14 +140399,18 @@ var FunctionCallListener = class extends CNextListener {
|
|
|
139564
140399
|
const primary = ctx.primaryExpression();
|
|
139565
140400
|
const baseName = this.extractBaseName(primary);
|
|
139566
140401
|
if (!baseName) return;
|
|
139567
|
-
const { resolvedName, foundCall } = this.resolveCallTarget(
|
|
140402
|
+
const { resolvedName, foundCall, isGlobalCall } = this.resolveCallTarget(
|
|
140403
|
+
ops,
|
|
140404
|
+
baseName
|
|
140405
|
+
);
|
|
139568
140406
|
if (!foundCall) return;
|
|
139569
140407
|
const { line, column } = ParserUtils_default.getPosition(ctx);
|
|
139570
140408
|
this.analyzer.checkFunctionCall(
|
|
139571
140409
|
resolvedName,
|
|
139572
140410
|
line,
|
|
139573
140411
|
column,
|
|
139574
|
-
this.currentScope
|
|
140412
|
+
this.currentScope,
|
|
140413
|
+
isGlobalCall
|
|
139575
140414
|
);
|
|
139576
140415
|
};
|
|
139577
140416
|
/**
|
|
@@ -139584,6 +140423,9 @@ var FunctionCallListener = class extends CNextListener {
|
|
|
139584
140423
|
if (primary.THIS()) {
|
|
139585
140424
|
return "this";
|
|
139586
140425
|
}
|
|
140426
|
+
if (primary.GLOBAL()) {
|
|
140427
|
+
return "global";
|
|
140428
|
+
}
|
|
139587
140429
|
return null;
|
|
139588
140430
|
}
|
|
139589
140431
|
/**
|
|
@@ -139593,11 +140435,15 @@ var FunctionCallListener = class extends CNextListener {
|
|
|
139593
140435
|
*/
|
|
139594
140436
|
resolveCallTarget(ops, baseName) {
|
|
139595
140437
|
let resolvedName = baseName;
|
|
140438
|
+
let isGlobalCall = baseName === "global";
|
|
139596
140439
|
for (const op of ops) {
|
|
139597
140440
|
if (op.IDENTIFIER()) {
|
|
139598
140441
|
const resolved = this.resolveMemberAccess(resolvedName, op);
|
|
139599
140442
|
if (resolved === null) {
|
|
139600
|
-
return { resolvedName, foundCall: false };
|
|
140443
|
+
return { resolvedName, foundCall: false, isGlobalCall };
|
|
140444
|
+
}
|
|
140445
|
+
if (isGlobalCall && this.analyzer.isScope(resolvedName)) {
|
|
140446
|
+
isGlobalCall = false;
|
|
139601
140447
|
}
|
|
139602
140448
|
resolvedName = resolved;
|
|
139603
140449
|
continue;
|
|
@@ -139605,11 +140451,11 @@ var FunctionCallListener = class extends CNextListener {
|
|
|
139605
140451
|
if (op.argumentList() || op.getChildCount() === 2) {
|
|
139606
140452
|
const text = op.getText();
|
|
139607
140453
|
if (text.startsWith("(")) {
|
|
139608
|
-
return { resolvedName, foundCall: true };
|
|
140454
|
+
return { resolvedName, foundCall: true, isGlobalCall };
|
|
139609
140455
|
}
|
|
139610
140456
|
}
|
|
139611
140457
|
}
|
|
139612
|
-
return { resolvedName, foundCall: false };
|
|
140458
|
+
return { resolvedName, foundCall: false, isGlobalCall };
|
|
139613
140459
|
}
|
|
139614
140460
|
/**
|
|
139615
140461
|
* Resolve member access pattern. Returns new name or null if not a C-Next function.
|
|
@@ -139619,6 +140465,9 @@ var FunctionCallListener = class extends CNextListener {
|
|
|
139619
140465
|
if (resolvedName === "this" && this.currentScope) {
|
|
139620
140466
|
return `${this.currentScope}_${memberName}`;
|
|
139621
140467
|
}
|
|
140468
|
+
if (resolvedName === "global") {
|
|
140469
|
+
return memberName;
|
|
140470
|
+
}
|
|
139622
140471
|
if (this.analyzer.isScope(resolvedName)) {
|
|
139623
140472
|
return `${resolvedName}_${memberName}`;
|
|
139624
140473
|
}
|
|
@@ -140017,8 +140866,9 @@ var FunctionCallAnalyzer = class {
|
|
|
140017
140866
|
* @param line Source line number
|
|
140018
140867
|
* @param column Source column number
|
|
140019
140868
|
* @param currentScope The current scope name (if inside a scope)
|
|
140869
|
+
* @param isGlobalCall Whether the call used global. prefix
|
|
140020
140870
|
*/
|
|
140021
|
-
checkFunctionCall(name, line, column, currentScope) {
|
|
140871
|
+
checkFunctionCall(name, line, column, currentScope, isGlobalCall = false) {
|
|
140022
140872
|
if (this.currentFunctionName && name === this.currentFunctionName) {
|
|
140023
140873
|
this.errors.push({
|
|
140024
140874
|
code: "E0423",
|
|
@@ -140044,17 +140894,19 @@ var FunctionCallAnalyzer = class {
|
|
|
140044
140894
|
if (this.callableVariables.has(name)) {
|
|
140045
140895
|
return;
|
|
140046
140896
|
}
|
|
140047
|
-
if (currentScope) {
|
|
140897
|
+
if (currentScope && !isGlobalCall) {
|
|
140048
140898
|
const qualifiedName = `${currentScope}_${name}`;
|
|
140049
140899
|
if (this.definedFunctions.has(qualifiedName)) {
|
|
140050
140900
|
return;
|
|
140051
140901
|
}
|
|
140052
140902
|
}
|
|
140903
|
+
const isLocalFunction = this.allLocalFunctions.has(name);
|
|
140053
140904
|
const header = this.findStdlibHeader(name);
|
|
140054
|
-
|
|
140055
|
-
|
|
140056
|
-
|
|
140057
|
-
|
|
140905
|
+
const message = this.buildUndefinedFunctionMessage(
|
|
140906
|
+
name,
|
|
140907
|
+
header,
|
|
140908
|
+
isGlobalCall && !isLocalFunction
|
|
140909
|
+
);
|
|
140058
140910
|
this.errors.push({
|
|
140059
140911
|
code: "E0422",
|
|
140060
140912
|
functionName: name,
|
|
@@ -140063,6 +140915,23 @@ var FunctionCallAnalyzer = class {
|
|
|
140063
140915
|
message
|
|
140064
140916
|
});
|
|
140065
140917
|
}
|
|
140918
|
+
/**
|
|
140919
|
+
* Issue #985: Build error message for undefined function calls.
|
|
140920
|
+
* Adjusts hint based on whether the call used global. prefix.
|
|
140921
|
+
*/
|
|
140922
|
+
buildUndefinedFunctionMessage(name, header, isGlobalCall) {
|
|
140923
|
+
if (isGlobalCall && header) {
|
|
140924
|
+
return `'${name}' is not declared in any included header; add #include <${header}>`;
|
|
140925
|
+
}
|
|
140926
|
+
if (isGlobalCall) {
|
|
140927
|
+
return `'${name}' is not declared in any included header`;
|
|
140928
|
+
}
|
|
140929
|
+
let message = `function '${name}' called before definition`;
|
|
140930
|
+
if (header) {
|
|
140931
|
+
message += `; hint: '${name}' is available from ${header} \u2014 try global.${name}()`;
|
|
140932
|
+
}
|
|
140933
|
+
return message;
|
|
140934
|
+
}
|
|
140066
140935
|
/**
|
|
140067
140936
|
* Check if a function is defined externally (from included files)
|
|
140068
140937
|
* This includes C/C++ headers AND C-Next includes.
|
|
@@ -140588,46 +141457,56 @@ var ArrayIndexTypeAnalyzer_default = ArrayIndexTypeAnalyzer;
|
|
|
140588
141457
|
import { ParseTreeWalker as ParseTreeWalker9 } from "antlr4ng";
|
|
140589
141458
|
var SignedVariableCollector = class extends CNextListener {
|
|
140590
141459
|
signedVars = /* @__PURE__ */ new Set();
|
|
141460
|
+
// Track all variable types (for resolving struct member chains)
|
|
141461
|
+
varTypes = /* @__PURE__ */ new Map();
|
|
140591
141462
|
getSignedVars() {
|
|
140592
141463
|
return this.signedVars;
|
|
140593
141464
|
}
|
|
141465
|
+
getVarTypes() {
|
|
141466
|
+
return this.varTypes;
|
|
141467
|
+
}
|
|
140594
141468
|
/**
|
|
140595
|
-
* Track a typed identifier
|
|
141469
|
+
* Track a typed identifier - add to signedVars if signed, always track type
|
|
140596
141470
|
*/
|
|
140597
|
-
|
|
140598
|
-
if (!typeCtx) return;
|
|
141471
|
+
trackType(typeCtx, identifier) {
|
|
141472
|
+
if (!typeCtx || !identifier) return;
|
|
140599
141473
|
const typeName = typeCtx.getText();
|
|
140600
|
-
|
|
140601
|
-
|
|
140602
|
-
|
|
141474
|
+
const varName = identifier.getText();
|
|
141475
|
+
this.varTypes.set(varName, typeName);
|
|
141476
|
+
if (TypeConstants_default.SIGNED_TYPES.includes(typeName)) {
|
|
141477
|
+
this.signedVars.add(varName);
|
|
141478
|
+
}
|
|
140603
141479
|
}
|
|
140604
141480
|
/**
|
|
140605
141481
|
* Track variable declarations with signed types
|
|
140606
141482
|
*/
|
|
140607
141483
|
enterVariableDeclaration = (ctx) => {
|
|
140608
|
-
this.
|
|
141484
|
+
this.trackType(ctx.type(), ctx.IDENTIFIER());
|
|
140609
141485
|
};
|
|
140610
141486
|
/**
|
|
140611
141487
|
* Track function parameters with signed types
|
|
140612
141488
|
*/
|
|
140613
141489
|
enterParameter = (ctx) => {
|
|
140614
|
-
this.
|
|
141490
|
+
this.trackType(ctx.type(), ctx.IDENTIFIER());
|
|
140615
141491
|
};
|
|
140616
141492
|
/**
|
|
140617
141493
|
* Track for-loop variable declarations with signed types
|
|
140618
141494
|
*/
|
|
140619
141495
|
enterForVarDecl = (ctx) => {
|
|
140620
|
-
this.
|
|
141496
|
+
this.trackType(ctx.type(), ctx.IDENTIFIER());
|
|
140621
141497
|
};
|
|
140622
141498
|
};
|
|
140623
141499
|
var SignedShiftListener = class extends CNextListener {
|
|
140624
141500
|
analyzer;
|
|
140625
141501
|
// eslint-disable-next-line @typescript-eslint/lines-between-class-members
|
|
140626
141502
|
signedVars;
|
|
140627
|
-
|
|
141503
|
+
// eslint-disable-next-line @typescript-eslint/lines-between-class-members
|
|
141504
|
+
varTypes;
|
|
141505
|
+
constructor(analyzer, signedVars, varTypes) {
|
|
140628
141506
|
super();
|
|
140629
141507
|
this.analyzer = analyzer;
|
|
140630
141508
|
this.signedVars = signedVars;
|
|
141509
|
+
this.varTypes = varTypes;
|
|
140631
141510
|
}
|
|
140632
141511
|
/**
|
|
140633
141512
|
* Check shift expressions for signed operands
|
|
@@ -140648,6 +141527,69 @@ var SignedShiftListener = class extends CNextListener {
|
|
|
140648
141527
|
}
|
|
140649
141528
|
}
|
|
140650
141529
|
};
|
|
141530
|
+
/**
|
|
141531
|
+
* Check compound shift-assign statements for signed targets
|
|
141532
|
+
* assignmentStatement: assignmentTarget assignmentOperator expression ';'
|
|
141533
|
+
* Issue #1008: <<<- and >><- must also be rejected on signed types
|
|
141534
|
+
*
|
|
141535
|
+
* Handles both simple identifiers (x <<<- 2) and member chains (s.x <<<- 2)
|
|
141536
|
+
*/
|
|
141537
|
+
enterAssignmentStatement = (ctx) => {
|
|
141538
|
+
const opCtx = ctx.assignmentOperator();
|
|
141539
|
+
if (!opCtx) return;
|
|
141540
|
+
const isLeftShiftAssign = opCtx.LSHIFT_ASSIGN() !== null;
|
|
141541
|
+
const isRightShiftAssign = opCtx.RSHIFT_ASSIGN() !== null;
|
|
141542
|
+
if (!isLeftShiftAssign && !isRightShiftAssign) return;
|
|
141543
|
+
const target = ctx.assignmentTarget();
|
|
141544
|
+
if (!target) return;
|
|
141545
|
+
const identifier = target.IDENTIFIER();
|
|
141546
|
+
if (!identifier) return;
|
|
141547
|
+
const baseName = identifier.getText();
|
|
141548
|
+
const postfixOps = target.postfixTargetOp();
|
|
141549
|
+
if (this.isSignedTarget(baseName, postfixOps)) {
|
|
141550
|
+
const operator = isLeftShiftAssign ? "<<<-" : ">><-";
|
|
141551
|
+
const { line, column } = ParserUtils_default.getPosition(target);
|
|
141552
|
+
this.analyzer.addError(line, column, operator);
|
|
141553
|
+
}
|
|
141554
|
+
};
|
|
141555
|
+
/**
|
|
141556
|
+
* Resolve the final type of an assignment target, handling member chains.
|
|
141557
|
+
* Returns true if the final target is a signed type.
|
|
141558
|
+
*
|
|
141559
|
+
* Examples:
|
|
141560
|
+
* - "x" with no postfix ops → check if x is signed
|
|
141561
|
+
* - "s" with postfixOps [".x"] → check if s.x field is signed
|
|
141562
|
+
* - "arr" with postfixOps ["[0]", ".field"] → check if field is signed
|
|
141563
|
+
*/
|
|
141564
|
+
isSignedTarget(baseName, postfixOps) {
|
|
141565
|
+
if (postfixOps.length === 0) {
|
|
141566
|
+
return this.signedVars.has(baseName);
|
|
141567
|
+
}
|
|
141568
|
+
let currentType = this.varTypes.get(baseName);
|
|
141569
|
+
if (!currentType) {
|
|
141570
|
+
return false;
|
|
141571
|
+
}
|
|
141572
|
+
for (const op of postfixOps) {
|
|
141573
|
+
const memberIdent = op.IDENTIFIER();
|
|
141574
|
+
if (memberIdent) {
|
|
141575
|
+
const fieldName = memberIdent.getText();
|
|
141576
|
+
const fieldType = CodeGenState.getStructFieldType(
|
|
141577
|
+
currentType,
|
|
141578
|
+
fieldName
|
|
141579
|
+
);
|
|
141580
|
+
if (!fieldType) {
|
|
141581
|
+
return false;
|
|
141582
|
+
}
|
|
141583
|
+
currentType = fieldType;
|
|
141584
|
+
} else {
|
|
141585
|
+
const bracketIndex = currentType.indexOf("[");
|
|
141586
|
+
if (bracketIndex !== -1) {
|
|
141587
|
+
currentType = currentType.substring(0, bracketIndex);
|
|
141588
|
+
}
|
|
141589
|
+
}
|
|
141590
|
+
}
|
|
141591
|
+
return TypeConstants_default.SIGNED_TYPES.includes(currentType);
|
|
141592
|
+
}
|
|
140651
141593
|
/**
|
|
140652
141594
|
* Check if an additive expression contains a signed type operand
|
|
140653
141595
|
*/
|
|
@@ -140715,7 +141657,8 @@ var SignedShiftAnalyzer = class {
|
|
|
140715
141657
|
const collector = new SignedVariableCollector();
|
|
140716
141658
|
ParseTreeWalker9.DEFAULT.walk(collector, tree);
|
|
140717
141659
|
const signedVars = collector.getSignedVars();
|
|
140718
|
-
const
|
|
141660
|
+
const varTypes = collector.getVarTypes();
|
|
141661
|
+
const listener = new SignedShiftListener(this, signedVars, varTypes);
|
|
140719
141662
|
ParseTreeWalker9.DEFAULT.walk(listener, tree);
|
|
140720
141663
|
return this.errors;
|
|
140721
141664
|
}
|
|
@@ -142423,7 +143366,12 @@ var Transpiler = class {
|
|
|
142423
143366
|
this.state.getAllHeaderDirectives(),
|
|
142424
143367
|
CodeGenState.symbolTable
|
|
142425
143368
|
);
|
|
142426
|
-
const
|
|
143369
|
+
const callbackTypesForHeader = this._buildCallbackTypesForHeader();
|
|
143370
|
+
const typeInputWithSymbolTable = typeInput ? {
|
|
143371
|
+
...typeInput,
|
|
143372
|
+
symbolTable: CodeGenState.symbolTable,
|
|
143373
|
+
callbackTypes: callbackTypesForHeader
|
|
143374
|
+
} : void 0;
|
|
142427
143375
|
const unmodifiedParams = this.codeGenerator.getFunctionUnmodifiedParams();
|
|
142428
143376
|
const headerSymbols = this.convertToHeaderSymbols(
|
|
142429
143377
|
exportedSymbols,
|
|
@@ -142445,6 +143393,32 @@ var Transpiler = class {
|
|
|
142445
143393
|
basename6(sourcePath)
|
|
142446
143394
|
);
|
|
142447
143395
|
}
|
|
143396
|
+
/**
|
|
143397
|
+
* ADR-029: Build callback types for header generation.
|
|
143398
|
+
* Only includes callbacks that are actually used as struct field types.
|
|
143399
|
+
* Converts CodeGenState.callbackTypes to the format expected by IHeaderTypeInput.
|
|
143400
|
+
*/
|
|
143401
|
+
_buildCallbackTypesForHeader() {
|
|
143402
|
+
const result = /* @__PURE__ */ new Map();
|
|
143403
|
+
const usedCallbackTypes = /* @__PURE__ */ new Set();
|
|
143404
|
+
for (const [, funcName] of CodeGenState.callbackFieldTypes) {
|
|
143405
|
+
usedCallbackTypes.add(funcName);
|
|
143406
|
+
}
|
|
143407
|
+
for (const funcName of usedCallbackTypes) {
|
|
143408
|
+
const cbInfo = CodeGenState.callbackTypes.get(funcName);
|
|
143409
|
+
if (cbInfo) {
|
|
143410
|
+
result.set(funcName, {
|
|
143411
|
+
typedefName: cbInfo.typedefName,
|
|
143412
|
+
returnType: cbInfo.returnType,
|
|
143413
|
+
parameters: cbInfo.parameters.map((p) => ({
|
|
143414
|
+
type: p.type,
|
|
143415
|
+
isStruct: p.isStruct
|
|
143416
|
+
}))
|
|
143417
|
+
});
|
|
143418
|
+
}
|
|
143419
|
+
}
|
|
143420
|
+
return result;
|
|
143421
|
+
}
|
|
142448
143422
|
/**
|
|
142449
143423
|
* Collect external enum sources from included C-Next files.
|
|
142450
143424
|
*/
|
|
@@ -142491,25 +143465,27 @@ var Transpiler = class {
|
|
|
142491
143465
|
);
|
|
142492
143466
|
const callbackTypedefType = typedefName ? CodeGenState.getTypedefType(typedefName) : void 0;
|
|
142493
143467
|
if (callbackTypedefType) {
|
|
142494
|
-
const
|
|
143468
|
+
const updatedParams2 = TypedefParamParser_default.resolveCallbackParams(
|
|
142495
143469
|
headerSymbol.parameters,
|
|
142496
143470
|
callbackTypedefType
|
|
142497
143471
|
);
|
|
142498
|
-
return { ...headerSymbol, parameters:
|
|
143472
|
+
return { ...headerSymbol, parameters: updatedParams2 };
|
|
142499
143473
|
}
|
|
142500
143474
|
const unmodified = unmodifiedParams.get(headerSymbol.name);
|
|
142501
|
-
|
|
142502
|
-
const
|
|
142503
|
-
|
|
142504
|
-
|
|
142505
|
-
|
|
142506
|
-
|
|
142507
|
-
|
|
142508
|
-
|
|
142509
|
-
|
|
142510
|
-
|
|
142511
|
-
|
|
142512
|
-
|
|
143475
|
+
const updatedParams = headerSymbol.parameters.map((param) => {
|
|
143476
|
+
const isOpaque = CodeGenState.isOpaqueType(param.type ?? "");
|
|
143477
|
+
const isPointerParam = !param.isConst && !param.isArray && param.type !== "f32" && param.type !== "f64" && param.type !== "ISR" && !knownEnums.has(param.type ?? "");
|
|
143478
|
+
const shouldAutoConst = unmodified && isPointerParam && unmodified.has(param.name);
|
|
143479
|
+
if (shouldAutoConst || isOpaque) {
|
|
143480
|
+
return {
|
|
143481
|
+
...param,
|
|
143482
|
+
isAutoConst: shouldAutoConst || void 0,
|
|
143483
|
+
isOpaqueHandle: isOpaque || void 0
|
|
143484
|
+
};
|
|
143485
|
+
}
|
|
143486
|
+
return param;
|
|
143487
|
+
});
|
|
143488
|
+
return { ...headerSymbol, parameters: updatedParams };
|
|
142513
143489
|
});
|
|
142514
143490
|
}
|
|
142515
143491
|
// ===========================================================================
|