c-next 0.1.64 → 0.1.66
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/grammar/CNext.g4 +9 -2
- package/package.json +5 -1
- package/src/transpiler/logic/parser/grammar/CNext.interp +2 -1
- package/src/transpiler/logic/parser/grammar/CNextListener.ts +11 -0
- package/src/transpiler/logic/parser/grammar/CNextParser.ts +992 -870
- package/src/transpiler/logic/parser/grammar/CNextVisitor.ts +7 -0
- package/src/transpiler/logic/symbols/cnext/__tests__/FunctionCollector.test.ts +6 -6
- package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolAdapter.test.ts +179 -0
- package/src/transpiler/logic/symbols/cnext/__tests__/VariableCollector.test.ts +55 -0
- package/src/transpiler/logic/symbols/cnext/adapters/TSymbolAdapter.ts +76 -8
- package/src/transpiler/logic/symbols/cnext/collectors/FunctionCollector.ts +9 -10
- package/src/transpiler/logic/symbols/cnext/collectors/StructCollector.ts +7 -1
- package/src/transpiler/logic/symbols/cnext/collectors/VariableCollector.ts +33 -14
- package/src/transpiler/output/codegen/CodeGenerator.ts +243 -166
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.coverage.test.ts +1086 -0
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +254 -22
- package/src/transpiler/output/codegen/generators/declarationGenerators/ArrayDimensionUtils.ts +17 -9
- package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ArrayDimensionUtils.test.ts +5 -3
- package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ScopeGenerator.test.ts +12 -7
- package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +624 -12
- package/src/transpiler/output/codegen/generators/expressions/__tests__/PostfixExpressionGenerator.test.ts +819 -0
- package/src/transpiler/output/codegen/helpers/ParameterInputAdapter.ts +337 -0
- package/src/transpiler/output/codegen/helpers/ParameterSignatureBuilder.ts +135 -0
- package/src/transpiler/output/codegen/helpers/TypeGenerationHelper.ts +4 -0
- package/src/transpiler/output/codegen/helpers/VariableDeclarationFormatter.ts +118 -0
- package/src/transpiler/output/codegen/helpers/__tests__/ParameterInputAdapter.test.ts +426 -0
- package/src/transpiler/output/codegen/helpers/__tests__/ParameterSignatureBuilder.test.ts +315 -0
- package/src/transpiler/output/codegen/helpers/__tests__/VariableDeclarationFormatter.test.ts +333 -0
- package/src/transpiler/output/codegen/types/IParameterInput.ts +58 -0
- package/src/transpiler/output/codegen/types/IVariableFormatInput.ts +51 -0
- package/src/transpiler/output/headers/BaseHeaderGenerator.ts +20 -35
- package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +21 -48
- package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +0 -64
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IVariableFormatInput - Normalized input for variable declaration formatting.
|
|
3
|
+
*
|
|
4
|
+
* Phase 2 of unified code generation: Provides a single source of truth for
|
|
5
|
+
* variable declaration string generation, eliminating sync issues between
|
|
6
|
+
* .c/.cpp and .h/.hpp files.
|
|
7
|
+
*
|
|
8
|
+
* Unlike parameters (which have complex pass-by-value/reference semantics),
|
|
9
|
+
* variable declarations focus on:
|
|
10
|
+
* - Modifier ordering (extern, const, volatile)
|
|
11
|
+
* - Type formatting (including string<N> → char[N+1])
|
|
12
|
+
* - Array dimension placement
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Modifier flags for variable declarations.
|
|
17
|
+
* These are resolved before formatting - no CodeGenState access needed.
|
|
18
|
+
*/
|
|
19
|
+
interface IVariableModifiers {
|
|
20
|
+
/** Explicit const modifier */
|
|
21
|
+
isConst: boolean;
|
|
22
|
+
/** atomic modifier (maps to volatile in C) */
|
|
23
|
+
isAtomic: boolean;
|
|
24
|
+
/** Explicit volatile modifier */
|
|
25
|
+
isVolatile: boolean;
|
|
26
|
+
/** extern linkage (for headers or top-level const in C++) */
|
|
27
|
+
isExtern: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Normalized input for variable declaration formatting.
|
|
32
|
+
* All fields are pre-computed - the formatter is stateless.
|
|
33
|
+
*/
|
|
34
|
+
interface IVariableFormatInput {
|
|
35
|
+
/** Variable name */
|
|
36
|
+
name: string;
|
|
37
|
+
|
|
38
|
+
/** Original C-Next type (e.g., 'u32', 'string<32>') */
|
|
39
|
+
cnextType: string;
|
|
40
|
+
|
|
41
|
+
/** Mapped C type (e.g., 'uint32_t', 'char[33]') */
|
|
42
|
+
mappedType: string;
|
|
43
|
+
|
|
44
|
+
/** Pre-resolved modifier flags */
|
|
45
|
+
modifiers: IVariableModifiers;
|
|
46
|
+
|
|
47
|
+
/** Array dimensions as strings (e.g., ['10', '20']) */
|
|
48
|
+
arrayDimensions?: string[];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export default IVariableFormatInput;
|
|
@@ -12,6 +12,9 @@ import IHeaderOptions from "../codegen/types/IHeaderOptions";
|
|
|
12
12
|
import IHeaderTypeInput from "./generators/IHeaderTypeInput";
|
|
13
13
|
import typeUtils from "./generators/mapType";
|
|
14
14
|
import HeaderGeneratorUtils from "./HeaderGeneratorUtils";
|
|
15
|
+
// Unified parameter generation (Phase 1)
|
|
16
|
+
import ParameterInputAdapter from "../codegen/helpers/ParameterInputAdapter";
|
|
17
|
+
import ParameterSignatureBuilder from "../codegen/helpers/ParameterSignatureBuilder";
|
|
15
18
|
|
|
16
19
|
const { mapType } = typeUtils;
|
|
17
20
|
|
|
@@ -184,41 +187,23 @@ abstract class BaseHeaderGenerator {
|
|
|
184
187
|
passByValueSet?: ReadonlySet<string>,
|
|
185
188
|
allKnownEnums?: ReadonlySet<string>,
|
|
186
189
|
): string {
|
|
187
|
-
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
// Float types use standard pass-by-value
|
|
206
|
-
if (p.type === "f32" || p.type === "f64") {
|
|
207
|
-
return `${constMod}${baseType} ${p.name}`;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// Enum types use pass-by-value (like primitives)
|
|
211
|
-
if (allKnownEnums?.has(p.type)) {
|
|
212
|
-
return `${constMod}${baseType} ${p.name}`;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// Check if parameter should be passed by value
|
|
216
|
-
if (passByValueSet?.has(p.name)) {
|
|
217
|
-
return `${constMod}${baseType} ${p.name}`;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// Default: pass by reference using subclass-specific semantics
|
|
221
|
-
return `${autoConst}${constMod}${baseType}${this.getRefSuffix()} ${p.name}`;
|
|
190
|
+
// Pre-compute pass-by-value (ISR, float, enum, or explicitly marked)
|
|
191
|
+
const isPassByValue =
|
|
192
|
+
p.type === "ISR" ||
|
|
193
|
+
p.type === "f32" ||
|
|
194
|
+
p.type === "f64" ||
|
|
195
|
+
allKnownEnums?.has(p.type) ||
|
|
196
|
+
passByValueSet?.has(p.name) ||
|
|
197
|
+
false;
|
|
198
|
+
|
|
199
|
+
// Build normalized input using adapter
|
|
200
|
+
const input = ParameterInputAdapter.fromSymbol(p, {
|
|
201
|
+
mapType: (t) => mapType(t),
|
|
202
|
+
isPassByValue,
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// Use shared builder with subclass-specific ref suffix
|
|
206
|
+
return ParameterSignatureBuilder.build(input, this.getRefSuffix());
|
|
222
207
|
}
|
|
223
208
|
}
|
|
224
209
|
|
|
@@ -16,6 +16,8 @@ import IHeaderTypeInput from "./generators/IHeaderTypeInput";
|
|
|
16
16
|
import generateEnumHeader from "./generators/generateEnumHeader";
|
|
17
17
|
import generateStructHeader from "./generators/generateStructHeader";
|
|
18
18
|
import generateBitmapHeader from "./generators/generateBitmapHeader";
|
|
19
|
+
import VariableDeclarationFormatter from "../codegen/helpers/VariableDeclarationFormatter";
|
|
20
|
+
import type IVariableFormatInput from "../codegen/types/IVariableFormatInput";
|
|
19
21
|
|
|
20
22
|
const { mapType, isBuiltInType } = typeUtils;
|
|
21
23
|
|
|
@@ -202,39 +204,6 @@ class HeaderGeneratorUtils {
|
|
|
202
204
|
);
|
|
203
205
|
}
|
|
204
206
|
|
|
205
|
-
/**
|
|
206
|
-
* Format a variable declaration with proper C syntax
|
|
207
|
-
*
|
|
208
|
-
* In C, array dimensions follow the variable name, not the type:
|
|
209
|
-
* char greeting[33]; // Correct
|
|
210
|
-
* char[33] greeting; // Wrong
|
|
211
|
-
*
|
|
212
|
-
* Handles types that include embedded dimensions (like char[33] from
|
|
213
|
-
* mapType("string<32>")) and places them correctly after the variable name.
|
|
214
|
-
*/
|
|
215
|
-
static formatVariableDeclaration(
|
|
216
|
-
cnextType: string,
|
|
217
|
-
name: string,
|
|
218
|
-
additionalDims: string,
|
|
219
|
-
constPrefix: string,
|
|
220
|
-
volatilePrefix: string = "",
|
|
221
|
-
): string {
|
|
222
|
-
const cType = mapType(cnextType);
|
|
223
|
-
|
|
224
|
-
// Check if the mapped type has embedded array dimensions (e.g., char[33])
|
|
225
|
-
// This happens for string<N> types which map to char[N+1]
|
|
226
|
-
const embeddedMatch = /^(\w+)\[(\d+)\]$/.exec(cType);
|
|
227
|
-
if (embeddedMatch) {
|
|
228
|
-
const baseType = embeddedMatch[1];
|
|
229
|
-
const embeddedDim = embeddedMatch[2];
|
|
230
|
-
// Format: volatile const char name[additionalDims][embeddedDim]
|
|
231
|
-
return `${volatilePrefix}${constPrefix}${baseType} ${name}${additionalDims}[${embeddedDim}]`;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// No embedded dimensions - standard format
|
|
235
|
-
return `${volatilePrefix}${constPrefix}${cType} ${name}${additionalDims}`;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
207
|
/**
|
|
239
208
|
* Build headers to include from external type header mappings
|
|
240
209
|
*/
|
|
@@ -460,6 +429,8 @@ class HeaderGeneratorUtils {
|
|
|
460
429
|
|
|
461
430
|
/**
|
|
462
431
|
* Generate extern variable declarations section
|
|
432
|
+
*
|
|
433
|
+
* Uses VariableDeclarationFormatter for consistent formatting with CodeGenerator.
|
|
463
434
|
*/
|
|
464
435
|
static generateVariableSection(variables: ISymbol[]): string[] {
|
|
465
436
|
if (variables.length === 0) {
|
|
@@ -468,21 +439,23 @@ class HeaderGeneratorUtils {
|
|
|
468
439
|
|
|
469
440
|
const lines: string[] = ["/* External variables */"];
|
|
470
441
|
for (const sym of variables) {
|
|
471
|
-
|
|
472
|
-
const
|
|
473
|
-
|
|
474
|
-
sym.
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
442
|
+
// Build normalized input for the unified formatter
|
|
443
|
+
const input: IVariableFormatInput = {
|
|
444
|
+
name: sym.name,
|
|
445
|
+
cnextType: sym.type || "int",
|
|
446
|
+
mappedType: mapType(sym.type || "int"),
|
|
447
|
+
modifiers: {
|
|
448
|
+
isConst: sym.isConst ?? false,
|
|
449
|
+
isAtomic: sym.isAtomic ?? false,
|
|
450
|
+
isVolatile: false, // C-Next uses atomic, not volatile directly
|
|
451
|
+
isExtern: true, // Headers always use extern
|
|
452
|
+
},
|
|
453
|
+
arrayDimensions:
|
|
454
|
+
sym.isArray && sym.arrayDimensions ? sym.arrayDimensions : undefined,
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
const declaration = VariableDeclarationFormatter.format(input);
|
|
458
|
+
lines.push(`${declaration};`);
|
|
486
459
|
}
|
|
487
460
|
lines.push("");
|
|
488
461
|
return lines;
|
|
@@ -181,70 +181,6 @@ describe("HeaderGeneratorUtils", () => {
|
|
|
181
181
|
});
|
|
182
182
|
});
|
|
183
183
|
|
|
184
|
-
describe("formatVariableDeclaration", () => {
|
|
185
|
-
it("formats simple declaration", () => {
|
|
186
|
-
expect(
|
|
187
|
-
HeaderGeneratorUtils.formatVariableDeclaration("u32", "count", "", ""),
|
|
188
|
-
).toBe("uint32_t count");
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
it("formats declaration with const", () => {
|
|
192
|
-
expect(
|
|
193
|
-
HeaderGeneratorUtils.formatVariableDeclaration(
|
|
194
|
-
"u32",
|
|
195
|
-
"count",
|
|
196
|
-
"",
|
|
197
|
-
"const ",
|
|
198
|
-
),
|
|
199
|
-
).toBe("const uint32_t count");
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
it("formats declaration with volatile", () => {
|
|
203
|
-
expect(
|
|
204
|
-
HeaderGeneratorUtils.formatVariableDeclaration(
|
|
205
|
-
"u32",
|
|
206
|
-
"count",
|
|
207
|
-
"",
|
|
208
|
-
"",
|
|
209
|
-
"volatile ",
|
|
210
|
-
),
|
|
211
|
-
).toBe("volatile uint32_t count");
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
it("formats declaration with array dimensions", () => {
|
|
215
|
-
expect(
|
|
216
|
-
HeaderGeneratorUtils.formatVariableDeclaration(
|
|
217
|
-
"u32",
|
|
218
|
-
"values",
|
|
219
|
-
"[10]",
|
|
220
|
-
"",
|
|
221
|
-
),
|
|
222
|
-
).toBe("uint32_t values[10]");
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
it("formats string<N> type with embedded dimension", () => {
|
|
226
|
-
expect(
|
|
227
|
-
HeaderGeneratorUtils.formatVariableDeclaration(
|
|
228
|
-
"string<32>",
|
|
229
|
-
"name",
|
|
230
|
-
"",
|
|
231
|
-
"",
|
|
232
|
-
),
|
|
233
|
-
).toBe("char name[33]");
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
it("formats string<N> array with additional dimensions", () => {
|
|
237
|
-
expect(
|
|
238
|
-
HeaderGeneratorUtils.formatVariableDeclaration(
|
|
239
|
-
"string<16>",
|
|
240
|
-
"labels",
|
|
241
|
-
"[3]",
|
|
242
|
-
"",
|
|
243
|
-
),
|
|
244
|
-
).toBe("char labels[3][17]");
|
|
245
|
-
});
|
|
246
|
-
});
|
|
247
|
-
|
|
248
184
|
describe("getLocalTypeNames", () => {
|
|
249
185
|
it("extracts local type names from grouped symbols", () => {
|
|
250
186
|
const groups = {
|