c-next 0.1.66 → 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 +1 -1
- package/src/transpiler/Transpiler.ts +49 -42
- package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolAdapter.test.ts +32 -82
- package/src/transpiler/logic/symbols/cnext/adapters/TSymbolAdapter.ts +17 -61
- package/src/transpiler/output/codegen/CodeGenerator.ts +22 -59
- 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 +5 -4
- 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/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/StringDeclHelper.ts +1 -1
- 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__/StringDeclHelper.test.ts +1 -1
- 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 → 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
|
@@ -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,
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dependencies provided to assignment handlers (ADR-109).
|
|
3
|
-
*
|
|
4
|
-
* Handlers need access to various CodeGenerator capabilities without
|
|
5
|
-
* taking a direct dependency on the full CodeGenerator class. This
|
|
6
|
-
* interface defines the subset of functionality handlers need.
|
|
7
|
-
*/
|
|
8
|
-
import * as Parser from "../../../../logic/parser/grammar/CNextParser";
|
|
9
|
-
import ICodeGenSymbols from "../../../../types/ICodeGenSymbols";
|
|
10
|
-
import TTypeInfo from "../../types/TTypeInfo";
|
|
11
|
-
import ITargetCapabilities from "../../types/ITargetCapabilities";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Dependencies for assignment handlers.
|
|
15
|
-
*
|
|
16
|
-
* These are provided by CodeGenerator to enable handlers to:
|
|
17
|
-
* - Look up type information
|
|
18
|
-
* - Access symbol tables
|
|
19
|
-
* - Generate expressions
|
|
20
|
-
* - Track side effects (needsString, clampOps)
|
|
21
|
-
*/
|
|
22
|
-
interface IHandlerDeps {
|
|
23
|
-
// === Symbol information ===
|
|
24
|
-
|
|
25
|
-
/** Read-only symbol info (registers, bitmaps, structs, etc.) */
|
|
26
|
-
readonly symbols: ICodeGenSymbols;
|
|
27
|
-
|
|
28
|
-
/** Type registry: variable name -> type info */
|
|
29
|
-
readonly typeRegistry: ReadonlyMap<string, TTypeInfo>;
|
|
30
|
-
|
|
31
|
-
/** Current scope name (for this.* resolution), null if not in scope */
|
|
32
|
-
readonly currentScope: string | null;
|
|
33
|
-
|
|
34
|
-
/** Parameters of current function */
|
|
35
|
-
readonly currentParameters: ReadonlyMap<
|
|
36
|
-
string,
|
|
37
|
-
{ isStruct?: boolean; isArray?: boolean }
|
|
38
|
-
>;
|
|
39
|
-
|
|
40
|
-
/** Target platform capabilities */
|
|
41
|
-
readonly targetCapabilities: ITargetCapabilities;
|
|
42
|
-
|
|
43
|
-
// === Expression generation ===
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Generate C code for an expression.
|
|
47
|
-
*/
|
|
48
|
-
generateExpression(ctx: Parser.ExpressionContext): string;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Try to evaluate an expression as a compile-time constant.
|
|
52
|
-
* Returns undefined if not a constant.
|
|
53
|
-
*/
|
|
54
|
-
tryEvaluateConstant(ctx: Parser.ExpressionContext): number | undefined;
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Generate the C target string for an assignment target.
|
|
58
|
-
*/
|
|
59
|
-
generateAssignmentTarget(ctx: Parser.AssignmentTargetContext): string;
|
|
60
|
-
|
|
61
|
-
// === Type checking ===
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Check if a type name is a known struct.
|
|
65
|
-
*/
|
|
66
|
-
isKnownStruct(typeName: string): boolean;
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Check if a name is a known scope.
|
|
70
|
-
*/
|
|
71
|
-
isKnownScope(name: string): boolean;
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Get member type info for a struct field.
|
|
75
|
-
*/
|
|
76
|
-
getMemberTypeInfo(structType: string, memberName: string): TTypeInfo | null;
|
|
77
|
-
|
|
78
|
-
// === Validation ===
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Validate bitmap field literal fits in field width.
|
|
82
|
-
*/
|
|
83
|
-
validateBitmapFieldLiteral(
|
|
84
|
-
expr: Parser.ExpressionContext,
|
|
85
|
-
width: number,
|
|
86
|
-
fieldName: string,
|
|
87
|
-
): void;
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Validate cross-scope visibility for member access.
|
|
91
|
-
*/
|
|
92
|
-
validateCrossScopeVisibility(scopeName: string, memberName: string): void;
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Check array bounds for compile-time constant indices.
|
|
96
|
-
*/
|
|
97
|
-
checkArrayBounds(
|
|
98
|
-
arrayName: string,
|
|
99
|
-
dimensions: readonly number[],
|
|
100
|
-
indexExprs: readonly Parser.ExpressionContext[],
|
|
101
|
-
line: number,
|
|
102
|
-
): void;
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Analyze a member chain target for bit access.
|
|
106
|
-
* Returns { isBitAccess: false } if not bit access.
|
|
107
|
-
* Returns { isBitAccess: true, baseTarget, bitIndex, baseType } if bit access detected.
|
|
108
|
-
*/
|
|
109
|
-
analyzeMemberChainForBitAccess(targetCtx: Parser.AssignmentTargetContext): {
|
|
110
|
-
isBitAccess: boolean;
|
|
111
|
-
baseTarget?: string;
|
|
112
|
-
bitIndex?: string;
|
|
113
|
-
baseType?: string;
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
// === Float bit indexing ===
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Generate float bit write using shadow variable + memcpy.
|
|
120
|
-
* Returns the full statement for writing bits to a float variable.
|
|
121
|
-
* Returns null if typeInfo is not a float type.
|
|
122
|
-
*/
|
|
123
|
-
generateFloatBitWrite(
|
|
124
|
-
name: string,
|
|
125
|
-
typeInfo: TTypeInfo,
|
|
126
|
-
bitIndex: string,
|
|
127
|
-
width: string | null,
|
|
128
|
-
value: string,
|
|
129
|
-
): string | null;
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Convert boolean expression to integer: true -> "1", false -> "0", else "(expr ? 1 : 0)"
|
|
133
|
-
*/
|
|
134
|
-
foldBooleanToInt(expr: string): string;
|
|
135
|
-
|
|
136
|
-
// === Side effects ===
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Mark that string.h is needed (for strncpy, memcpy).
|
|
140
|
-
*/
|
|
141
|
-
markNeedsString(): void;
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Mark that a clamp operation helper is used.
|
|
145
|
-
*/
|
|
146
|
-
markClampOpUsed(op: string, typeName: string): void;
|
|
147
|
-
|
|
148
|
-
// === Atomic operations ===
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Generate atomic read-modify-write operation.
|
|
152
|
-
*/
|
|
153
|
-
generateAtomicRMW(
|
|
154
|
-
target: string,
|
|
155
|
-
cOp: string,
|
|
156
|
-
value: string,
|
|
157
|
-
typeInfo: TTypeInfo,
|
|
158
|
-
): string;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export default IHandlerDeps;
|