c-next 0.1.65 → 0.1.67
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/package.json +5 -1
- package/src/transpiler/Transpiler.ts +49 -42
- package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolAdapter.test.ts +129 -0
- package/src/transpiler/logic/symbols/cnext/adapters/TSymbolAdapter.ts +27 -3
- package/src/transpiler/output/codegen/CodeGenerator.ts +131 -186
- package/src/transpiler/output/codegen/TypeResolver.ts +2 -2
- package/src/transpiler/output/codegen/TypeValidator.ts +1 -1
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.coverage.test.ts +1087 -0
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +665 -1315
- package/src/transpiler/output/codegen/__tests__/TypeResolver.test.ts +1 -1
- package/src/transpiler/output/codegen/__tests__/TypeValidator.resolution.test.ts +1 -1
- package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +1 -1
- package/src/transpiler/output/codegen/analysis/MemberChainAnalyzer.ts +1 -1
- package/src/transpiler/output/codegen/analysis/StringLengthCounter.ts +1 -1
- package/src/transpiler/output/codegen/analysis/__tests__/MemberChainAnalyzer.test.ts +1 -1
- package/src/transpiler/output/codegen/analysis/__tests__/StringLengthCounter.test.ts +1 -1
- package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +1 -1
- package/src/transpiler/output/codegen/assignment/__tests__/AssignmentClassifier.test.ts +1 -1
- package/src/transpiler/output/codegen/assignment/handlers/AccessPatternHandlers.ts +24 -27
- package/src/transpiler/output/codegen/assignment/handlers/ArrayHandlers.ts +25 -18
- package/src/transpiler/output/codegen/assignment/handlers/BitAccessHandlers.ts +27 -33
- package/src/transpiler/output/codegen/assignment/handlers/BitmapHandlers.ts +39 -42
- package/src/transpiler/output/codegen/assignment/handlers/RegisterHandlers.ts +39 -97
- package/src/transpiler/output/codegen/assignment/handlers/RegisterUtils.ts +75 -0
- package/src/transpiler/output/codegen/assignment/handlers/SimpleHandler.ts +9 -6
- package/src/transpiler/output/codegen/assignment/handlers/SpecialHandlers.ts +30 -22
- package/src/transpiler/output/codegen/assignment/handlers/StringHandlers.ts +42 -50
- package/src/transpiler/output/codegen/assignment/handlers/TAssignmentHandler.ts +6 -5
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/AccessPatternHandlers.test.ts +81 -134
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/ArrayHandlers.test.ts +85 -124
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitAccessHandlers.test.ts +82 -124
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitmapHandlers.test.ts +135 -297
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/RegisterHandlers.test.ts +105 -227
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/RegisterUtils.test.ts +214 -1
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/SpecialHandlers.test.ts +66 -127
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/StringHandlers.test.ts +37 -83
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/handlerTestUtils.ts +162 -0
- package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +618 -12
- package/src/transpiler/output/codegen/generators/expressions/__tests__/PostfixExpressionGenerator.test.ts +819 -0
- package/src/transpiler/output/codegen/helpers/ArrayInitHelper.ts +1 -1
- package/src/transpiler/output/codegen/helpers/AssignmentExpectedTypeResolver.ts +1 -1
- package/src/transpiler/output/codegen/helpers/AssignmentValidator.ts +1 -1
- package/src/transpiler/output/codegen/helpers/CppModeHelper.ts +1 -1
- package/src/transpiler/output/codegen/helpers/EnumAssignmentValidator.ts +1 -1
- package/src/transpiler/output/codegen/helpers/FloatBitHelper.ts +1 -1
- 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/StringDeclHelper.ts +1 -1
- package/src/transpiler/output/codegen/helpers/VariableDeclarationFormatter.ts +118 -0
- package/src/transpiler/output/codegen/helpers/__tests__/ArrayInitHelper.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentExpectedTypeResolver.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentValidator.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/CppModeHelper.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/EnumAssignmentValidator.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/FloatBitHelper.test.ts +1 -1
- 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__/StringDeclHelper.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/VariableDeclarationFormatter.test.ts +333 -0
- package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +1 -1
- package/src/transpiler/output/codegen/resolution/ScopeResolver.ts +1 -1
- package/src/transpiler/output/codegen/resolution/SizeofResolver.ts +1 -1
- package/src/transpiler/output/codegen/resolution/__tests__/EnumTypeResolver.test.ts +1 -1
- package/src/transpiler/output/codegen/resolution/__tests__/SizeofResolver.test.ts +1 -1
- package/src/transpiler/output/codegen/types/ICodeGenApi.ts +57 -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
- package/src/transpiler/{output/codegen → state}/CodeGenState.ts +46 -26
- package/src/transpiler/{output/codegen → state}/__tests__/CodeGenState.test.ts +12 -2
- package/src/transpiler/output/codegen/assignment/handlers/IHandlerDeps.ts +0 -161
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for CodeGenerator methods accessible via CodeGenState.generator.
|
|
3
|
+
*
|
|
4
|
+
* Defines the subset of CodeGenerator methods needed by assignment handlers.
|
|
5
|
+
* Handlers cast CodeGenState.generator to this interface.
|
|
6
|
+
*/
|
|
7
|
+
import type TTypeInfo from "./TTypeInfo";
|
|
8
|
+
|
|
9
|
+
interface ICodeGenApi {
|
|
10
|
+
/** Generate C expression from AST context */
|
|
11
|
+
generateExpression(ctx: unknown): string;
|
|
12
|
+
|
|
13
|
+
/** Generate assignment target (lvalue) from AST context */
|
|
14
|
+
generateAssignmentTarget(ctx: unknown): string;
|
|
15
|
+
|
|
16
|
+
/** Try to evaluate expression as compile-time constant */
|
|
17
|
+
tryEvaluateConstant(ctx: unknown): number | undefined;
|
|
18
|
+
|
|
19
|
+
/** Generate atomic read-modify-write operation */
|
|
20
|
+
generateAtomicRMW(
|
|
21
|
+
target: string,
|
|
22
|
+
op: string,
|
|
23
|
+
value: string,
|
|
24
|
+
typeInfo: TTypeInfo,
|
|
25
|
+
): string;
|
|
26
|
+
|
|
27
|
+
/** Generate float bit write operation (returns null if not applicable) */
|
|
28
|
+
generateFloatBitWrite(
|
|
29
|
+
name: string,
|
|
30
|
+
typeInfo: TTypeInfo,
|
|
31
|
+
bitIndex: string,
|
|
32
|
+
width: string | null,
|
|
33
|
+
value: string,
|
|
34
|
+
): string | null;
|
|
35
|
+
|
|
36
|
+
/** Validate cross-scope member visibility */
|
|
37
|
+
validateCrossScopeVisibility(scopeName: string, memberName: string): void;
|
|
38
|
+
|
|
39
|
+
/** Analyze member chain for bit access patterns */
|
|
40
|
+
analyzeMemberChainForBitAccess(ctx: unknown): {
|
|
41
|
+
isBitAccess: boolean;
|
|
42
|
+
baseTarget?: string;
|
|
43
|
+
bitIndex?: string;
|
|
44
|
+
baseType?: string;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/** Get type info for struct member */
|
|
48
|
+
getMemberTypeInfo(structType: string, fieldName: string): TTypeInfo | null;
|
|
49
|
+
|
|
50
|
+
/** Check if name is a known scope */
|
|
51
|
+
isKnownScope(name: string): boolean;
|
|
52
|
+
|
|
53
|
+
/** Check if name is a known struct */
|
|
54
|
+
isKnownStruct(name: string): boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default ICodeGenApi;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalized parameter input for signature generation
|
|
3
|
+
*
|
|
4
|
+
* This interface serves as the contract between ParameterInputAdapter
|
|
5
|
+
* (which normalizes AST or symbol data) and ParameterSignatureBuilder
|
|
6
|
+
* (which generates the final C/C++ parameter string).
|
|
7
|
+
*
|
|
8
|
+
* All decisions are pre-computed before reaching the builder:
|
|
9
|
+
* - Type classification (callback, string, array, etc.)
|
|
10
|
+
* - Const qualifiers (explicit and auto-inferred)
|
|
11
|
+
* - Pass-by-value vs pass-by-reference
|
|
12
|
+
* - Array dimensions
|
|
13
|
+
*/
|
|
14
|
+
interface IParameterInput {
|
|
15
|
+
/** Parameter name */
|
|
16
|
+
name: string;
|
|
17
|
+
|
|
18
|
+
/** Original C-Next type: 'u32', 'string<32>', 'Point', etc. */
|
|
19
|
+
baseType: string;
|
|
20
|
+
|
|
21
|
+
/** Mapped C type: 'uint32_t', 'char', 'Point', etc. */
|
|
22
|
+
mappedType: string;
|
|
23
|
+
|
|
24
|
+
/** Explicit const modifier from source code */
|
|
25
|
+
isConst: boolean;
|
|
26
|
+
|
|
27
|
+
/** Inferred const for unmodified parameters (computed from CodeGenState.modifiedParameters) */
|
|
28
|
+
isAutoConst: boolean;
|
|
29
|
+
|
|
30
|
+
/** Whether this is an array type */
|
|
31
|
+
isArray: boolean;
|
|
32
|
+
|
|
33
|
+
/** Array dimensions as strings: ['10', '20'] or ['33'] for string capacity */
|
|
34
|
+
arrayDimensions?: string[];
|
|
35
|
+
|
|
36
|
+
/** Whether this is a callback type (from CodeGenState.callbackTypes) */
|
|
37
|
+
isCallback: boolean;
|
|
38
|
+
|
|
39
|
+
/** The typedef name for callback types (e.g., 'HandleClickCallback') */
|
|
40
|
+
callbackTypedefName?: string;
|
|
41
|
+
|
|
42
|
+
/** Whether this is a string type (bounded or unbounded) */
|
|
43
|
+
isString: boolean;
|
|
44
|
+
|
|
45
|
+
/** Whether this is an unbounded string (no capacity) */
|
|
46
|
+
isUnboundedString?: boolean;
|
|
47
|
+
|
|
48
|
+
/** String capacity for non-array strings (used for tracking, not output) */
|
|
49
|
+
stringCapacity?: number;
|
|
50
|
+
|
|
51
|
+
/** Whether to use pass-by-value semantics (ISR, float, enum, small primitive) */
|
|
52
|
+
isPassByValue: boolean;
|
|
53
|
+
|
|
54
|
+
/** Whether to use pass-by-reference semantics (known struct or known primitive) */
|
|
55
|
+
isPassByReference: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export default IParameterInput;
|
|
@@ -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 = {
|
|
@@ -5,26 +5,31 @@
|
|
|
5
5
|
* Eliminates dependency injection complexity and makes debugging easier.
|
|
6
6
|
*
|
|
7
7
|
* Usage:
|
|
8
|
-
* import CodeGenState from "
|
|
8
|
+
* import CodeGenState from "../state/CodeGenState";
|
|
9
9
|
* const type = CodeGenState.typeRegistry.get(name);
|
|
10
10
|
* if (CodeGenState.isKnownStruct(name)) { ... }
|
|
11
11
|
*
|
|
12
12
|
* Lifecycle:
|
|
13
13
|
* 1. CodeGenerator.generate() calls CodeGenState.reset()
|
|
14
|
-
* 2. CodeGenerator
|
|
14
|
+
* 2. CodeGenerator sets CodeGenState.generator = this
|
|
15
15
|
* 3. All generators/helpers read from CodeGenState directly
|
|
16
16
|
* 4. State persists for the duration of one generate() call
|
|
17
|
+
*
|
|
18
|
+
* SymbolTable ownership:
|
|
19
|
+
* CodeGenState owns the single SymbolTable instance. It persists across
|
|
20
|
+
* reset() calls (which are per-file). The Transpiler clears it via
|
|
21
|
+
* CodeGenState.symbolTable.clear() at the start of each run().
|
|
17
22
|
*/
|
|
18
23
|
|
|
19
|
-
import SymbolTable from "
|
|
20
|
-
import ICodeGenSymbols from "
|
|
21
|
-
import TTypeInfo from "
|
|
22
|
-
import TParameterInfo from "
|
|
23
|
-
import IFunctionSignature from "
|
|
24
|
-
import ICallbackTypeInfo from "
|
|
25
|
-
import ITargetCapabilities from "
|
|
26
|
-
import TOverflowBehavior from "
|
|
27
|
-
import TYPE_WIDTH from "
|
|
24
|
+
import SymbolTable from "../logic/symbols/SymbolTable";
|
|
25
|
+
import ICodeGenSymbols from "../types/ICodeGenSymbols";
|
|
26
|
+
import TTypeInfo from "../output/codegen/types/TTypeInfo";
|
|
27
|
+
import TParameterInfo from "../output/codegen/types/TParameterInfo";
|
|
28
|
+
import IFunctionSignature from "../output/codegen/types/IFunctionSignature";
|
|
29
|
+
import ICallbackTypeInfo from "../output/codegen/types/ICallbackTypeInfo";
|
|
30
|
+
import ITargetCapabilities from "../output/codegen/types/ITargetCapabilities";
|
|
31
|
+
import TOverflowBehavior from "../output/codegen/types/TOverflowBehavior";
|
|
32
|
+
import TYPE_WIDTH from "../output/codegen/types/TYPE_WIDTH";
|
|
28
33
|
|
|
29
34
|
/**
|
|
30
35
|
* Default target capabilities (safe fallback)
|
|
@@ -62,6 +67,16 @@ interface ICallGraphEntry {
|
|
|
62
67
|
* during code generation.
|
|
63
68
|
*/
|
|
64
69
|
export default class CodeGenState {
|
|
70
|
+
// ===========================================================================
|
|
71
|
+
// GENERATOR REFERENCE (for handler access)
|
|
72
|
+
// ===========================================================================
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Reference to the CodeGenerator instance for handlers to call methods.
|
|
76
|
+
* Typed as unknown to avoid circular dependencies - handlers cast as needed.
|
|
77
|
+
*/
|
|
78
|
+
static generator: unknown = null;
|
|
79
|
+
|
|
65
80
|
// ===========================================================================
|
|
66
81
|
// SYMBOL DATA (read-only after initialization)
|
|
67
82
|
// ===========================================================================
|
|
@@ -69,8 +84,11 @@ export default class CodeGenState {
|
|
|
69
84
|
/** ADR-055: Pre-collected symbol info from CNextResolver + TSymbolInfoAdapter */
|
|
70
85
|
static symbols: ICodeGenSymbols | null = null;
|
|
71
86
|
|
|
72
|
-
/** External symbol table for cross-language interop (C headers)
|
|
73
|
-
|
|
87
|
+
/** External symbol table for cross-language interop (C headers).
|
|
88
|
+
* Owned by CodeGenState; persists across per-file reset() calls.
|
|
89
|
+
* Cleared via symbolTable.clear() at the start of each Transpiler run.
|
|
90
|
+
*/
|
|
91
|
+
static symbolTable: SymbolTable = new SymbolTable();
|
|
74
92
|
|
|
75
93
|
// ===========================================================================
|
|
76
94
|
// TYPE TRACKING
|
|
@@ -277,9 +295,13 @@ export default class CodeGenState {
|
|
|
277
295
|
* Called at the start of CodeGenerator.generate()
|
|
278
296
|
*/
|
|
279
297
|
static reset(targetCapabilities?: ITargetCapabilities): void {
|
|
298
|
+
// Generator reference
|
|
299
|
+
this.generator = null;
|
|
300
|
+
|
|
280
301
|
// Symbol data
|
|
281
302
|
this.symbols = null;
|
|
282
|
-
|
|
303
|
+
// Note: symbolTable is NOT reset here — it persists across per-file generates.
|
|
304
|
+
// It is cleared via symbolTable.clear() at the start of each Transpiler run.
|
|
283
305
|
|
|
284
306
|
// Type tracking
|
|
285
307
|
this.typeRegistry = new Map();
|
|
@@ -388,7 +410,7 @@ export default class CodeGenState {
|
|
|
388
410
|
static isKnownStruct(name: string): boolean {
|
|
389
411
|
if (this.symbols?.knownStructs.has(name)) return true;
|
|
390
412
|
if (this.symbols?.knownBitmaps.has(name)) return true;
|
|
391
|
-
if (this.symbolTable
|
|
413
|
+
if (this.symbolTable.getStructFields(name)) return true;
|
|
392
414
|
return false;
|
|
393
415
|
}
|
|
394
416
|
|
|
@@ -553,17 +575,15 @@ export default class CodeGenState {
|
|
|
553
575
|
fieldName: string,
|
|
554
576
|
): { type: string; dimensions?: (number | string)[] } | null {
|
|
555
577
|
// First check SymbolTable (C header structs)
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
};
|
|
566
|
-
}
|
|
578
|
+
const fieldInfo = this.symbolTable.getStructFieldInfo(
|
|
579
|
+
structType,
|
|
580
|
+
fieldName,
|
|
581
|
+
);
|
|
582
|
+
if (fieldInfo) {
|
|
583
|
+
return {
|
|
584
|
+
type: fieldInfo.type,
|
|
585
|
+
dimensions: fieldInfo.arrayDimensions,
|
|
586
|
+
};
|
|
567
587
|
}
|
|
568
588
|
|
|
569
589
|
// Fall back to local C-Next struct fields
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import { describe, it, expect, beforeEach } from "vitest";
|
|
6
6
|
import CodeGenState from "../CodeGenState";
|
|
7
|
-
import TTypeInfo from "
|
|
8
|
-
import ICodeGenSymbols from "
|
|
7
|
+
import TTypeInfo from "../../output/codegen/types/TTypeInfo";
|
|
8
|
+
import ICodeGenSymbols from "../../types/ICodeGenSymbols";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Create a minimal mock ICodeGenSymbols with default empty collections.
|
|
@@ -76,6 +76,16 @@ describe("CodeGenState", () => {
|
|
|
76
76
|
expect(CodeGenState.indentLevel).toBe(0);
|
|
77
77
|
});
|
|
78
78
|
|
|
79
|
+
it("resets generator reference", () => {
|
|
80
|
+
// Simulate having a generator set
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
82
|
+
CodeGenState.generator = {} as any;
|
|
83
|
+
|
|
84
|
+
CodeGenState.reset();
|
|
85
|
+
|
|
86
|
+
expect(CodeGenState.generator).toBeNull();
|
|
87
|
+
});
|
|
88
|
+
|
|
79
89
|
it("accepts custom target capabilities", () => {
|
|
80
90
|
const customTarget = {
|
|
81
91
|
hasFPU: true,
|