c-next 0.1.61 → 0.1.63
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 +86 -63
- package/grammar/CNext.g4 +3 -17
- package/package.json +1 -1
- package/src/cli/serve/ServeCommand.ts +57 -45
- package/src/lib/__tests__/parseCHeader.mocked.test.ts +145 -0
- package/src/transpiler/Transpiler.ts +603 -613
- package/src/transpiler/__tests__/DualCodePaths.test.ts +5 -1
- package/src/transpiler/__tests__/Transpiler.coverage.test.ts +2 -99
- package/src/transpiler/__tests__/Transpiler.test.ts +3 -26
- package/src/transpiler/data/IncludeTreeWalker.ts +1 -1
- package/src/transpiler/logic/analysis/InitializationAnalyzer.ts +23 -52
- package/src/transpiler/logic/parser/grammar/CNext.interp +1 -3
- package/src/transpiler/logic/parser/grammar/CNextListener.ts +0 -22
- package/src/transpiler/logic/parser/grammar/CNextParser.ts +665 -1084
- package/src/transpiler/logic/parser/grammar/CNextVisitor.ts +0 -14
- package/src/transpiler/logic/symbols/CppSymbolCollector.ts +67 -43
- package/src/transpiler/logic/symbols/cnext/collectors/StructCollector.ts +156 -70
- package/src/transpiler/logic/symbols/cnext/collectors/VariableCollector.ts +31 -6
- package/src/transpiler/logic/symbols/cnext/utils/TypeUtils.ts +43 -11
- package/src/transpiler/output/codegen/CodeGenState.ts +811 -0
- package/src/transpiler/output/codegen/CodeGenerator.ts +1410 -2587
- package/src/transpiler/output/codegen/TypeResolver.ts +193 -149
- package/src/transpiler/output/codegen/TypeValidator.ts +148 -370
- package/src/transpiler/output/codegen/__tests__/CodeGenState.test.ts +446 -0
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +2082 -52
- package/src/transpiler/output/codegen/__tests__/TrackVariableTypeHelpers.test.ts +1 -1
- package/src/transpiler/output/codegen/__tests__/TypeResolver.test.ts +435 -196
- package/src/transpiler/output/codegen/__tests__/TypeValidator.resolution.test.ts +51 -67
- package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +495 -471
- package/src/transpiler/output/codegen/analysis/MemberChainAnalyzer.ts +227 -66
- package/src/transpiler/output/codegen/analysis/StringLengthCounter.ts +55 -58
- package/src/transpiler/output/codegen/analysis/__tests__/MemberChainAnalyzer.test.ts +288 -275
- package/src/transpiler/output/codegen/analysis/__tests__/StringLengthCounter.test.ts +101 -144
- package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +195 -133
- package/src/transpiler/output/codegen/assignment/AssignmentContextBuilder.ts +24 -74
- package/src/transpiler/output/codegen/assignment/AssignmentKind.ts +3 -0
- package/src/transpiler/output/codegen/assignment/IAssignmentContext.ts +3 -0
- package/src/transpiler/output/codegen/assignment/__tests__/AssignmentClassifier.test.ts +290 -320
- package/src/transpiler/output/codegen/assignment/handlers/BitAccessHandlers.ts +42 -0
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitAccessHandlers.test.ts +76 -2
- package/src/transpiler/output/codegen/generators/GeneratorRegistry.ts +12 -0
- package/src/transpiler/output/codegen/generators/IOrchestrator.ts +5 -1
- package/src/transpiler/output/codegen/generators/__tests__/GeneratorRegistry.test.ts +28 -1
- package/src/transpiler/output/codegen/generators/declarationGenerators/ArrayDimensionUtils.ts +67 -0
- package/src/transpiler/output/codegen/generators/declarationGenerators/RegisterGenerator.ts +11 -24
- package/src/transpiler/output/codegen/generators/declarationGenerators/RegisterMacroGenerator.ts +64 -0
- package/src/transpiler/output/codegen/generators/declarationGenerators/ScopeGenerator.ts +137 -61
- package/src/transpiler/output/codegen/generators/declarationGenerators/ScopedRegisterGenerator.ts +18 -27
- package/src/transpiler/output/codegen/generators/declarationGenerators/StructGenerator.ts +100 -23
- package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ArrayDimensionUtils.test.ts +125 -0
- package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ScopeGenerator.test.ts +157 -4
- package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +5 -1
- package/src/transpiler/output/codegen/generators/statements/ControlFlowGenerator.ts +1 -17
- package/src/transpiler/output/codegen/generators/support/HelperGenerator.ts +23 -22
- package/src/transpiler/output/codegen/helpers/ArrayAccessHelper.ts +129 -0
- package/src/transpiler/output/codegen/helpers/ArrayInitHelper.ts +54 -61
- package/src/transpiler/output/codegen/helpers/AssignmentExpectedTypeResolver.ts +40 -44
- package/src/transpiler/output/codegen/helpers/AssignmentTargetExtractor.ts +17 -45
- package/src/transpiler/output/codegen/helpers/AssignmentValidator.ts +83 -78
- package/src/transpiler/output/codegen/helpers/CppModeHelper.ts +22 -30
- package/src/transpiler/output/codegen/helpers/EnumAssignmentValidator.ts +108 -50
- package/src/transpiler/output/codegen/helpers/FloatBitHelper.ts +16 -31
- package/src/transpiler/output/codegen/helpers/MemberSeparatorResolver.ts +10 -3
- package/src/transpiler/output/codegen/helpers/StringDeclHelper.ts +103 -96
- package/src/transpiler/output/codegen/helpers/SymbolLookupHelper.ts +44 -0
- package/src/transpiler/output/codegen/helpers/TypeGenerationHelper.ts +9 -0
- package/src/transpiler/output/codegen/helpers/__tests__/ArrayAccessHelper.test.ts +479 -0
- package/src/transpiler/output/codegen/helpers/__tests__/ArrayInitHelper.test.ts +58 -103
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentExpectedTypeResolver.test.ts +97 -40
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentValidator.test.ts +223 -128
- package/src/transpiler/output/codegen/helpers/__tests__/CppModeHelper.test.ts +68 -41
- package/src/transpiler/output/codegen/helpers/__tests__/EnumAssignmentValidator.test.ts +198 -47
- package/src/transpiler/output/codegen/helpers/__tests__/FloatBitHelper.test.ts +39 -37
- package/src/transpiler/output/codegen/helpers/__tests__/MemberSeparatorResolver.test.ts +1 -0
- package/src/transpiler/output/codegen/helpers/__tests__/StringDeclHelper.test.ts +191 -453
- package/src/transpiler/output/codegen/helpers/__tests__/SymbolLookupHelper.test.ts +201 -0
- package/src/transpiler/output/codegen/helpers/__tests__/TypeGenerationHelper.test.ts +50 -0
- package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +229 -0
- package/src/transpiler/output/codegen/resolution/ScopeResolver.ts +60 -0
- package/src/transpiler/output/codegen/resolution/SizeofResolver.ts +177 -0
- package/src/transpiler/output/codegen/resolution/__tests__/EnumTypeResolver.test.ts +336 -0
- package/src/transpiler/output/codegen/resolution/__tests__/SizeofResolver.test.ts +201 -0
- package/src/transpiler/output/codegen/types/IArrayAccessDeps.ts +23 -0
- package/src/transpiler/output/codegen/types/IArrayAccessInfo.ts +26 -0
- package/src/transpiler/output/codegen/types/IMemberSeparatorDeps.ts +7 -0
- package/src/transpiler/output/codegen/utils/CodegenParserUtils.ts +98 -0
- package/src/transpiler/output/codegen/utils/ExpressionUnwrapper.ts +22 -22
- package/src/transpiler/output/codegen/utils/__tests__/CodegenParserUtils.test.ts +228 -0
- package/src/transpiler/types/IFileResult.ts +0 -4
- package/src/transpiler/types/IPipelineFile.ts +27 -0
- package/src/transpiler/types/IPipelineInput.ts +23 -0
- package/src/transpiler/types/TranspilerState.ts +1 -1
- package/src/utils/FormatUtils.ts +28 -2
- package/src/utils/MapUtils.ts +25 -0
- package/src/utils/PostfixAnalysisUtils.ts +48 -0
- package/src/utils/__tests__/FormatUtils.test.ts +42 -0
- package/src/utils/__tests__/MapUtils.test.ts +85 -0
- package/src/utils/constants/OperatorMappings.ts +19 -0
- package/src/transpiler/logic/StandaloneContextBuilder.ts +0 -150
- package/src/transpiler/logic/__tests__/StandaloneContextBuilder.test.ts +0 -647
- package/src/transpiler/output/codegen/types/ITypeResolverDeps.ts +0 -23
- package/src/transpiler/output/codegen/types/ITypeValidatorDeps.ts +0 -53
- package/src/transpiler/types/ITranspileContext.ts +0 -49
- package/src/transpiler/types/ITranspileContribution.ts +0 -32
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
1
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
2
2
|
import AssignmentClassifier from "../AssignmentClassifier";
|
|
3
3
|
import AssignmentKind from "../AssignmentKind";
|
|
4
4
|
import IAssignmentContext from "../IAssignmentContext";
|
|
5
|
+
import CodeGenState from "../../CodeGenState";
|
|
5
6
|
import TTypeInfo from "../../types/TTypeInfo";
|
|
6
7
|
|
|
7
8
|
// ========================================================================
|
|
@@ -33,6 +34,7 @@ function createMockContext(
|
|
|
33
34
|
firstIdTypeInfo: null,
|
|
34
35
|
memberAccessDepth: 0,
|
|
35
36
|
subscriptDepth: 0,
|
|
37
|
+
lastSubscriptExprCount: 1, // default: 1 expression (array element, single bit)
|
|
36
38
|
isSimpleIdentifier: true,
|
|
37
39
|
isSimpleThisAccess: false,
|
|
38
40
|
isSimpleGlobalAccess: false,
|
|
@@ -54,72 +56,46 @@ function createTypeInfo(overrides: Partial<TTypeInfo> = {}): TTypeInfo {
|
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
/**
|
|
57
|
-
*
|
|
59
|
+
* Helper to set up CodeGenState.symbols with minimal fields.
|
|
58
60
|
*/
|
|
59
|
-
function
|
|
60
|
-
overrides:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
bitmapBackingType: new Map(),
|
|
98
|
-
bitmapBitWidth: new Map(),
|
|
99
|
-
scopedRegisters: new Map(),
|
|
100
|
-
registerMemberAccess: new Map(),
|
|
101
|
-
registerMemberTypes,
|
|
102
|
-
registerBaseAddresses: new Map(),
|
|
103
|
-
registerMemberOffsets: new Map(),
|
|
104
|
-
registerMemberCTypes: new Map(),
|
|
105
|
-
scopeVariableUsage: new Map(),
|
|
106
|
-
scopePrivateConstValues: new Map(),
|
|
107
|
-
functionReturnTypes: new Map(),
|
|
108
|
-
getSingleFunctionForVariable: () => null,
|
|
109
|
-
hasPublicSymbols: () => false,
|
|
110
|
-
},
|
|
111
|
-
typeRegistry,
|
|
112
|
-
currentScope: overrides.currentScope ?? null,
|
|
113
|
-
isKnownStruct: (name: string) => knownStructs.has(name),
|
|
114
|
-
isKnownScope: (name: string) => knownScopes.has(name),
|
|
115
|
-
getMemberTypeInfo: (structType: string, memberName: string) => {
|
|
116
|
-
const fields = structFields.get(structType);
|
|
117
|
-
const fieldType = fields?.get(memberName);
|
|
118
|
-
if (fieldType) {
|
|
119
|
-
return createTypeInfo({ baseType: fieldType });
|
|
120
|
-
}
|
|
121
|
-
return null;
|
|
122
|
-
},
|
|
61
|
+
function setupSymbols(
|
|
62
|
+
overrides: {
|
|
63
|
+
knownRegisters?: Set<string>;
|
|
64
|
+
knownScopes?: Set<string>;
|
|
65
|
+
knownStructs?: Set<string>;
|
|
66
|
+
bitmapFields?: Map<string, Map<string, { offset: number; width: number }>>;
|
|
67
|
+
registerMemberTypes?: Map<string, string>;
|
|
68
|
+
structFields?: Map<string, Map<string, string>>;
|
|
69
|
+
structFieldArrays?: Map<string, Set<string>>;
|
|
70
|
+
structFieldDimensions?: Map<string, Map<string, readonly number[]>>;
|
|
71
|
+
} = {},
|
|
72
|
+
): void {
|
|
73
|
+
CodeGenState.symbols = {
|
|
74
|
+
knownScopes: overrides.knownScopes ?? new Set(),
|
|
75
|
+
knownStructs: overrides.knownStructs ?? new Set(),
|
|
76
|
+
knownRegisters: overrides.knownRegisters ?? new Set(),
|
|
77
|
+
knownEnums: new Set<string>(),
|
|
78
|
+
knownBitmaps: new Set<string>(),
|
|
79
|
+
scopeMembers: new Map<string, Set<string>>(),
|
|
80
|
+
scopeMemberVisibility: new Map(),
|
|
81
|
+
structFields: overrides.structFields ?? new Map(),
|
|
82
|
+
structFieldArrays: overrides.structFieldArrays ?? new Map(),
|
|
83
|
+
structFieldDimensions: overrides.structFieldDimensions ?? new Map(),
|
|
84
|
+
enumMembers: new Map(),
|
|
85
|
+
bitmapFields: overrides.bitmapFields ?? new Map(),
|
|
86
|
+
bitmapBackingType: new Map(),
|
|
87
|
+
bitmapBitWidth: new Map(),
|
|
88
|
+
scopedRegisters: new Map(),
|
|
89
|
+
registerMemberAccess: new Map(),
|
|
90
|
+
registerMemberTypes: overrides.registerMemberTypes ?? new Map(),
|
|
91
|
+
registerBaseAddresses: new Map(),
|
|
92
|
+
registerMemberOffsets: new Map(),
|
|
93
|
+
registerMemberCTypes: new Map(),
|
|
94
|
+
scopeVariableUsage: new Map(),
|
|
95
|
+
scopePrivateConstValues: new Map(),
|
|
96
|
+
functionReturnTypes: new Map(),
|
|
97
|
+
getSingleFunctionForVariable: () => null,
|
|
98
|
+
hasPublicSymbols: () => false,
|
|
123
99
|
};
|
|
124
100
|
}
|
|
125
101
|
|
|
@@ -127,29 +103,28 @@ function createMockDeps(
|
|
|
127
103
|
// SIMPLE Assignment
|
|
128
104
|
// ========================================================================
|
|
129
105
|
describe("AssignmentClassifier - SIMPLE", () => {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
106
|
+
beforeEach(() => {
|
|
107
|
+
CodeGenState.reset();
|
|
108
|
+
setupSymbols();
|
|
109
|
+
});
|
|
133
110
|
|
|
111
|
+
it("classifies simple identifier assignment", () => {
|
|
134
112
|
const ctx = createMockContext({
|
|
135
113
|
identifiers: ["x"],
|
|
136
114
|
isSimpleIdentifier: true,
|
|
137
115
|
});
|
|
138
116
|
|
|
139
|
-
expect(
|
|
117
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(AssignmentKind.SIMPLE);
|
|
140
118
|
});
|
|
141
119
|
|
|
142
120
|
it("classifies unknown pattern as SIMPLE fallback", () => {
|
|
143
|
-
const deps = createMockDeps();
|
|
144
|
-
const classifier = new AssignmentClassifier(deps);
|
|
145
|
-
|
|
146
121
|
const ctx = createMockContext({
|
|
147
122
|
identifiers: ["unknown"],
|
|
148
123
|
hasMemberAccess: true,
|
|
149
124
|
isSimpleIdentifier: false,
|
|
150
125
|
});
|
|
151
126
|
|
|
152
|
-
expect(
|
|
127
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(AssignmentKind.SIMPLE);
|
|
153
128
|
});
|
|
154
129
|
});
|
|
155
130
|
|
|
@@ -157,19 +132,19 @@ describe("AssignmentClassifier - SIMPLE", () => {
|
|
|
157
132
|
// Bitmap Field Assignments
|
|
158
133
|
// ========================================================================
|
|
159
134
|
describe("AssignmentClassifier - Bitmap Fields", () => {
|
|
135
|
+
beforeEach(() => {
|
|
136
|
+
CodeGenState.reset();
|
|
137
|
+
});
|
|
138
|
+
|
|
160
139
|
it("classifies single-bit bitmap field", () => {
|
|
161
140
|
const bitmapFields = new Map([
|
|
162
141
|
["StatusFlags", new Map([["Running", { offset: 0, width: 1 }]])],
|
|
163
142
|
]);
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
]);
|
|
170
|
-
|
|
171
|
-
const deps = createMockDeps({ bitmapFields, typeRegistry });
|
|
172
|
-
const classifier = new AssignmentClassifier(deps);
|
|
143
|
+
setupSymbols({ bitmapFields });
|
|
144
|
+
CodeGenState.typeRegistry.set(
|
|
145
|
+
"flags",
|
|
146
|
+
createTypeInfo({ isBitmap: true, bitmapTypeName: "StatusFlags" }),
|
|
147
|
+
);
|
|
173
148
|
|
|
174
149
|
const ctx = createMockContext({
|
|
175
150
|
identifiers: ["flags", "Running"],
|
|
@@ -177,7 +152,7 @@ describe("AssignmentClassifier - Bitmap Fields", () => {
|
|
|
177
152
|
isSimpleIdentifier: false,
|
|
178
153
|
});
|
|
179
154
|
|
|
180
|
-
expect(
|
|
155
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
181
156
|
AssignmentKind.BITMAP_FIELD_SINGLE_BIT,
|
|
182
157
|
);
|
|
183
158
|
});
|
|
@@ -186,15 +161,11 @@ describe("AssignmentClassifier - Bitmap Fields", () => {
|
|
|
186
161
|
const bitmapFields = new Map([
|
|
187
162
|
["StatusFlags", new Map([["Mode", { offset: 4, width: 4 }]])],
|
|
188
163
|
]);
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
]);
|
|
195
|
-
|
|
196
|
-
const deps = createMockDeps({ bitmapFields, typeRegistry });
|
|
197
|
-
const classifier = new AssignmentClassifier(deps);
|
|
164
|
+
setupSymbols({ bitmapFields });
|
|
165
|
+
CodeGenState.typeRegistry.set(
|
|
166
|
+
"flags",
|
|
167
|
+
createTypeInfo({ isBitmap: true, bitmapTypeName: "StatusFlags" }),
|
|
168
|
+
);
|
|
198
169
|
|
|
199
170
|
const ctx = createMockContext({
|
|
200
171
|
identifiers: ["flags", "Mode"],
|
|
@@ -202,7 +173,7 @@ describe("AssignmentClassifier - Bitmap Fields", () => {
|
|
|
202
173
|
isSimpleIdentifier: false,
|
|
203
174
|
});
|
|
204
175
|
|
|
205
|
-
expect(
|
|
176
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
206
177
|
AssignmentKind.BITMAP_FIELD_MULTI_BIT,
|
|
207
178
|
);
|
|
208
179
|
});
|
|
@@ -213,13 +184,7 @@ describe("AssignmentClassifier - Bitmap Fields", () => {
|
|
|
213
184
|
]);
|
|
214
185
|
const knownRegisters = new Set(["MOTOR"]);
|
|
215
186
|
const registerMemberTypes = new Map([["MOTOR_CTRL", "ControlBits"]]);
|
|
216
|
-
|
|
217
|
-
const deps = createMockDeps({
|
|
218
|
-
bitmapFields,
|
|
219
|
-
knownRegisters,
|
|
220
|
-
registerMemberTypes,
|
|
221
|
-
});
|
|
222
|
-
const classifier = new AssignmentClassifier(deps);
|
|
187
|
+
setupSymbols({ bitmapFields, knownRegisters, registerMemberTypes });
|
|
223
188
|
|
|
224
189
|
const ctx = createMockContext({
|
|
225
190
|
identifiers: ["MOTOR", "CTRL", "Enable"],
|
|
@@ -227,7 +192,7 @@ describe("AssignmentClassifier - Bitmap Fields", () => {
|
|
|
227
192
|
isSimpleIdentifier: false,
|
|
228
193
|
});
|
|
229
194
|
|
|
230
|
-
expect(
|
|
195
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
231
196
|
AssignmentKind.REGISTER_MEMBER_BITMAP_FIELD,
|
|
232
197
|
);
|
|
233
198
|
});
|
|
@@ -240,17 +205,11 @@ describe("AssignmentClassifier - Bitmap Fields", () => {
|
|
|
240
205
|
const structFields = new Map([
|
|
241
206
|
["Device", new Map([["flags", "DeviceFlags"]])],
|
|
242
207
|
]);
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
bitmapFields,
|
|
249
|
-
knownStructs,
|
|
250
|
-
structFields,
|
|
251
|
-
typeRegistry,
|
|
252
|
-
});
|
|
253
|
-
const classifier = new AssignmentClassifier(deps);
|
|
208
|
+
setupSymbols({ bitmapFields, knownStructs, structFields });
|
|
209
|
+
CodeGenState.typeRegistry.set(
|
|
210
|
+
"device",
|
|
211
|
+
createTypeInfo({ baseType: "Device" }),
|
|
212
|
+
);
|
|
254
213
|
|
|
255
214
|
const ctx = createMockContext({
|
|
256
215
|
identifiers: ["device", "flags", "Active"],
|
|
@@ -258,7 +217,7 @@ describe("AssignmentClassifier - Bitmap Fields", () => {
|
|
|
258
217
|
isSimpleIdentifier: false,
|
|
259
218
|
});
|
|
260
219
|
|
|
261
|
-
expect(
|
|
220
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
262
221
|
AssignmentKind.STRUCT_MEMBER_BITMAP_FIELD,
|
|
263
222
|
);
|
|
264
223
|
});
|
|
@@ -268,13 +227,13 @@ describe("AssignmentClassifier - Bitmap Fields", () => {
|
|
|
268
227
|
// Integer Bit Access
|
|
269
228
|
// ========================================================================
|
|
270
229
|
describe("AssignmentClassifier - Integer Bit Access", () => {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
230
|
+
beforeEach(() => {
|
|
231
|
+
CodeGenState.reset();
|
|
232
|
+
setupSymbols();
|
|
233
|
+
});
|
|
275
234
|
|
|
276
|
-
|
|
277
|
-
|
|
235
|
+
it("classifies single bit access on integer", () => {
|
|
236
|
+
CodeGenState.typeRegistry.set("flags", createTypeInfo({ baseType: "u8" }));
|
|
278
237
|
|
|
279
238
|
const ctx = createMockContext({
|
|
280
239
|
identifiers: ["flags"],
|
|
@@ -283,16 +242,11 @@ describe("AssignmentClassifier - Integer Bit Access", () => {
|
|
|
283
242
|
isSimpleIdentifier: false,
|
|
284
243
|
});
|
|
285
244
|
|
|
286
|
-
expect(
|
|
245
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(AssignmentKind.INTEGER_BIT);
|
|
287
246
|
});
|
|
288
247
|
|
|
289
248
|
it("classifies bit range access on integer", () => {
|
|
290
|
-
|
|
291
|
-
["flags", createTypeInfo({ baseType: "u32" })],
|
|
292
|
-
]);
|
|
293
|
-
|
|
294
|
-
const deps = createMockDeps({ typeRegistry });
|
|
295
|
-
const classifier = new AssignmentClassifier(deps);
|
|
249
|
+
CodeGenState.typeRegistry.set("flags", createTypeInfo({ baseType: "u32" }));
|
|
296
250
|
|
|
297
251
|
const ctx = createMockContext({
|
|
298
252
|
identifiers: ["flags"],
|
|
@@ -302,9 +256,12 @@ describe("AssignmentClassifier - Integer Bit Access", () => {
|
|
|
302
256
|
],
|
|
303
257
|
hasArrayAccess: true,
|
|
304
258
|
isSimpleIdentifier: false,
|
|
259
|
+
lastSubscriptExprCount: 2, // bit range has 2 expressions [start, width]
|
|
305
260
|
});
|
|
306
261
|
|
|
307
|
-
expect(
|
|
262
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
263
|
+
AssignmentKind.INTEGER_BIT_RANGE,
|
|
264
|
+
);
|
|
308
265
|
});
|
|
309
266
|
});
|
|
310
267
|
|
|
@@ -312,19 +269,19 @@ describe("AssignmentClassifier - Integer Bit Access", () => {
|
|
|
312
269
|
// Array Assignments
|
|
313
270
|
// ========================================================================
|
|
314
271
|
describe("AssignmentClassifier - Array Access", () => {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
createTypeInfo({
|
|
320
|
-
isArray: true,
|
|
321
|
-
arrayDimensions: [10],
|
|
322
|
-
}),
|
|
323
|
-
],
|
|
324
|
-
]);
|
|
272
|
+
beforeEach(() => {
|
|
273
|
+
CodeGenState.reset();
|
|
274
|
+
setupSymbols();
|
|
275
|
+
});
|
|
325
276
|
|
|
326
|
-
|
|
327
|
-
|
|
277
|
+
it("classifies simple array element", () => {
|
|
278
|
+
CodeGenState.typeRegistry.set(
|
|
279
|
+
"arr",
|
|
280
|
+
createTypeInfo({
|
|
281
|
+
isArray: true,
|
|
282
|
+
arrayDimensions: [10],
|
|
283
|
+
}),
|
|
284
|
+
);
|
|
328
285
|
|
|
329
286
|
const ctx = createMockContext({
|
|
330
287
|
identifiers: ["arr"],
|
|
@@ -333,22 +290,19 @@ describe("AssignmentClassifier - Array Access", () => {
|
|
|
333
290
|
isSimpleIdentifier: false,
|
|
334
291
|
});
|
|
335
292
|
|
|
336
|
-
expect(
|
|
293
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
294
|
+
AssignmentKind.ARRAY_ELEMENT,
|
|
295
|
+
);
|
|
337
296
|
});
|
|
338
297
|
|
|
339
298
|
it("classifies array slice", () => {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
],
|
|
348
|
-
]);
|
|
349
|
-
|
|
350
|
-
const deps = createMockDeps({ typeRegistry });
|
|
351
|
-
const classifier = new AssignmentClassifier(deps);
|
|
299
|
+
CodeGenState.typeRegistry.set(
|
|
300
|
+
"buffer",
|
|
301
|
+
createTypeInfo({
|
|
302
|
+
isArray: true,
|
|
303
|
+
arrayDimensions: [100],
|
|
304
|
+
}),
|
|
305
|
+
);
|
|
352
306
|
|
|
353
307
|
const ctx = createMockContext({
|
|
354
308
|
identifiers: ["buffer"],
|
|
@@ -358,9 +312,10 @@ describe("AssignmentClassifier - Array Access", () => {
|
|
|
358
312
|
],
|
|
359
313
|
hasArrayAccess: true,
|
|
360
314
|
isSimpleIdentifier: false,
|
|
315
|
+
lastSubscriptExprCount: 2, // slice has 2 expressions [start, length]
|
|
361
316
|
});
|
|
362
317
|
|
|
363
|
-
expect(
|
|
318
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(AssignmentKind.ARRAY_SLICE);
|
|
364
319
|
});
|
|
365
320
|
});
|
|
366
321
|
|
|
@@ -368,28 +323,30 @@ describe("AssignmentClassifier - Array Access", () => {
|
|
|
368
323
|
// String Assignments
|
|
369
324
|
// ========================================================================
|
|
370
325
|
describe("AssignmentClassifier - String Assignments", () => {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
createTypeInfo({
|
|
376
|
-
baseType: "string<32>",
|
|
377
|
-
isString: true,
|
|
378
|
-
stringCapacity: 32,
|
|
379
|
-
}),
|
|
380
|
-
],
|
|
381
|
-
]);
|
|
326
|
+
beforeEach(() => {
|
|
327
|
+
CodeGenState.reset();
|
|
328
|
+
setupSymbols();
|
|
329
|
+
});
|
|
382
330
|
|
|
383
|
-
|
|
384
|
-
|
|
331
|
+
it("classifies simple string variable", () => {
|
|
332
|
+
CodeGenState.typeRegistry.set(
|
|
333
|
+
"name",
|
|
334
|
+
createTypeInfo({
|
|
335
|
+
baseType: "string<32>",
|
|
336
|
+
isString: true,
|
|
337
|
+
stringCapacity: 32,
|
|
338
|
+
}),
|
|
339
|
+
);
|
|
385
340
|
|
|
386
341
|
const ctx = createMockContext({
|
|
387
342
|
identifiers: ["name"],
|
|
388
343
|
isSimpleIdentifier: true,
|
|
389
|
-
firstIdTypeInfo: typeRegistry.get("name")!,
|
|
344
|
+
firstIdTypeInfo: CodeGenState.typeRegistry.get("name")!,
|
|
390
345
|
});
|
|
391
346
|
|
|
392
|
-
expect(
|
|
347
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
348
|
+
AssignmentKind.STRING_SIMPLE,
|
|
349
|
+
);
|
|
393
350
|
});
|
|
394
351
|
|
|
395
352
|
it("classifies struct field string", () => {
|
|
@@ -397,12 +354,11 @@ describe("AssignmentClassifier - String Assignments", () => {
|
|
|
397
354
|
const structFields = new Map([
|
|
398
355
|
["Person", new Map([["name", "string<64>"]])],
|
|
399
356
|
]);
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
const classifier = new AssignmentClassifier(deps);
|
|
357
|
+
setupSymbols({ knownStructs, structFields });
|
|
358
|
+
CodeGenState.typeRegistry.set(
|
|
359
|
+
"person",
|
|
360
|
+
createTypeInfo({ baseType: "Person" }),
|
|
361
|
+
);
|
|
406
362
|
|
|
407
363
|
const ctx = createMockContext({
|
|
408
364
|
identifiers: ["person", "name"],
|
|
@@ -410,7 +366,9 @@ describe("AssignmentClassifier - String Assignments", () => {
|
|
|
410
366
|
isSimpleIdentifier: false,
|
|
411
367
|
});
|
|
412
368
|
|
|
413
|
-
expect(
|
|
369
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
370
|
+
AssignmentKind.STRING_STRUCT_FIELD,
|
|
371
|
+
);
|
|
414
372
|
});
|
|
415
373
|
});
|
|
416
374
|
|
|
@@ -418,19 +376,19 @@ describe("AssignmentClassifier - String Assignments", () => {
|
|
|
418
376
|
// Special Compound Assignments
|
|
419
377
|
// ========================================================================
|
|
420
378
|
describe("AssignmentClassifier - Special Compound", () => {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
createTypeInfo({
|
|
426
|
-
baseType: "u32",
|
|
427
|
-
isAtomic: true,
|
|
428
|
-
}),
|
|
429
|
-
],
|
|
430
|
-
]);
|
|
379
|
+
beforeEach(() => {
|
|
380
|
+
CodeGenState.reset();
|
|
381
|
+
setupSymbols();
|
|
382
|
+
});
|
|
431
383
|
|
|
432
|
-
|
|
433
|
-
|
|
384
|
+
it("classifies atomic RMW", () => {
|
|
385
|
+
CodeGenState.typeRegistry.set(
|
|
386
|
+
"counter",
|
|
387
|
+
createTypeInfo({
|
|
388
|
+
baseType: "u32",
|
|
389
|
+
isAtomic: true,
|
|
390
|
+
}),
|
|
391
|
+
);
|
|
434
392
|
|
|
435
393
|
const ctx = createMockContext({
|
|
436
394
|
identifiers: ["counter"],
|
|
@@ -439,22 +397,17 @@ describe("AssignmentClassifier - Special Compound", () => {
|
|
|
439
397
|
cOp: "+=",
|
|
440
398
|
});
|
|
441
399
|
|
|
442
|
-
expect(
|
|
400
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(AssignmentKind.ATOMIC_RMW);
|
|
443
401
|
});
|
|
444
402
|
|
|
445
403
|
it("classifies overflow clamp", () => {
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
],
|
|
454
|
-
]);
|
|
455
|
-
|
|
456
|
-
const deps = createMockDeps({ typeRegistry });
|
|
457
|
-
const classifier = new AssignmentClassifier(deps);
|
|
404
|
+
CodeGenState.typeRegistry.set(
|
|
405
|
+
"saturated",
|
|
406
|
+
createTypeInfo({
|
|
407
|
+
baseType: "u8",
|
|
408
|
+
overflowBehavior: "clamp",
|
|
409
|
+
}),
|
|
410
|
+
);
|
|
458
411
|
|
|
459
412
|
const ctx = createMockContext({
|
|
460
413
|
identifiers: ["saturated"],
|
|
@@ -463,22 +416,19 @@ describe("AssignmentClassifier - Special Compound", () => {
|
|
|
463
416
|
cOp: "+=",
|
|
464
417
|
});
|
|
465
418
|
|
|
466
|
-
expect(
|
|
419
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
420
|
+
AssignmentKind.OVERFLOW_CLAMP,
|
|
421
|
+
);
|
|
467
422
|
});
|
|
468
423
|
|
|
469
424
|
it("does not classify float as overflow clamp", () => {
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
],
|
|
478
|
-
]);
|
|
479
|
-
|
|
480
|
-
const deps = createMockDeps({ typeRegistry });
|
|
481
|
-
const classifier = new AssignmentClassifier(deps);
|
|
425
|
+
CodeGenState.typeRegistry.set(
|
|
426
|
+
"value",
|
|
427
|
+
createTypeInfo({
|
|
428
|
+
baseType: "f32",
|
|
429
|
+
overflowBehavior: "clamp",
|
|
430
|
+
}),
|
|
431
|
+
);
|
|
482
432
|
|
|
483
433
|
const ctx = createMockContext({
|
|
484
434
|
identifiers: ["value"],
|
|
@@ -488,7 +438,7 @@ describe("AssignmentClassifier - Special Compound", () => {
|
|
|
488
438
|
});
|
|
489
439
|
|
|
490
440
|
// Floats use native arithmetic, so not OVERFLOW_CLAMP
|
|
491
|
-
expect(
|
|
441
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(AssignmentKind.SIMPLE);
|
|
492
442
|
});
|
|
493
443
|
});
|
|
494
444
|
|
|
@@ -496,10 +446,13 @@ describe("AssignmentClassifier - Special Compound", () => {
|
|
|
496
446
|
// Global/This Prefix Patterns
|
|
497
447
|
// ========================================================================
|
|
498
448
|
describe("AssignmentClassifier - Prefix Patterns", () => {
|
|
449
|
+
beforeEach(() => {
|
|
450
|
+
CodeGenState.reset();
|
|
451
|
+
});
|
|
452
|
+
|
|
499
453
|
it("classifies global.member", () => {
|
|
500
454
|
const knownScopes = new Set(["Counter"]);
|
|
501
|
-
|
|
502
|
-
const classifier = new AssignmentClassifier(deps);
|
|
455
|
+
setupSymbols({ knownScopes });
|
|
503
456
|
|
|
504
457
|
const ctx = createMockContext({
|
|
505
458
|
identifiers: ["Counter", "value"],
|
|
@@ -508,12 +461,13 @@ describe("AssignmentClassifier - Prefix Patterns", () => {
|
|
|
508
461
|
isSimpleIdentifier: false,
|
|
509
462
|
});
|
|
510
463
|
|
|
511
|
-
expect(
|
|
464
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
465
|
+
AssignmentKind.GLOBAL_MEMBER,
|
|
466
|
+
);
|
|
512
467
|
});
|
|
513
468
|
|
|
514
469
|
it("classifies global.arr[i]", () => {
|
|
515
|
-
|
|
516
|
-
const classifier = new AssignmentClassifier(deps);
|
|
470
|
+
setupSymbols();
|
|
517
471
|
|
|
518
472
|
const ctx = createMockContext({
|
|
519
473
|
identifiers: ["arr"],
|
|
@@ -524,12 +478,14 @@ describe("AssignmentClassifier - Prefix Patterns", () => {
|
|
|
524
478
|
isSimpleIdentifier: false,
|
|
525
479
|
});
|
|
526
480
|
|
|
527
|
-
expect(
|
|
481
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
482
|
+
AssignmentKind.GLOBAL_ARRAY,
|
|
483
|
+
);
|
|
528
484
|
});
|
|
529
485
|
|
|
530
486
|
it("classifies this.member", () => {
|
|
531
|
-
|
|
532
|
-
|
|
487
|
+
setupSymbols();
|
|
488
|
+
CodeGenState.currentScope = "Counter";
|
|
533
489
|
|
|
534
490
|
const ctx = createMockContext({
|
|
535
491
|
identifiers: ["count"],
|
|
@@ -538,12 +494,12 @@ describe("AssignmentClassifier - Prefix Patterns", () => {
|
|
|
538
494
|
isSimpleIdentifier: false,
|
|
539
495
|
});
|
|
540
496
|
|
|
541
|
-
expect(
|
|
497
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(AssignmentKind.THIS_MEMBER);
|
|
542
498
|
});
|
|
543
499
|
|
|
544
500
|
it("classifies this.arr[i]", () => {
|
|
545
|
-
|
|
546
|
-
|
|
501
|
+
setupSymbols();
|
|
502
|
+
CodeGenState.currentScope = "Buffer";
|
|
547
503
|
|
|
548
504
|
const ctx = createMockContext({
|
|
549
505
|
identifiers: ["data"],
|
|
@@ -554,7 +510,7 @@ describe("AssignmentClassifier - Prefix Patterns", () => {
|
|
|
554
510
|
isSimpleIdentifier: false,
|
|
555
511
|
});
|
|
556
512
|
|
|
557
|
-
expect(
|
|
513
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(AssignmentKind.THIS_ARRAY);
|
|
558
514
|
});
|
|
559
515
|
});
|
|
560
516
|
|
|
@@ -562,10 +518,13 @@ describe("AssignmentClassifier - Prefix Patterns", () => {
|
|
|
562
518
|
// Register Bit Access
|
|
563
519
|
// ========================================================================
|
|
564
520
|
describe("AssignmentClassifier - Register Bit Access", () => {
|
|
521
|
+
beforeEach(() => {
|
|
522
|
+
CodeGenState.reset();
|
|
523
|
+
});
|
|
524
|
+
|
|
565
525
|
it("classifies register single bit", () => {
|
|
566
526
|
const knownRegisters = new Set(["GPIO7"]);
|
|
567
|
-
|
|
568
|
-
const classifier = new AssignmentClassifier(deps);
|
|
527
|
+
setupSymbols({ knownRegisters });
|
|
569
528
|
|
|
570
529
|
const ctx = createMockContext({
|
|
571
530
|
identifiers: ["GPIO7", "DR_SET"],
|
|
@@ -575,13 +534,14 @@ describe("AssignmentClassifier - Register Bit Access", () => {
|
|
|
575
534
|
isSimpleIdentifier: false,
|
|
576
535
|
});
|
|
577
536
|
|
|
578
|
-
expect(
|
|
537
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
538
|
+
AssignmentKind.REGISTER_BIT,
|
|
539
|
+
);
|
|
579
540
|
});
|
|
580
541
|
|
|
581
542
|
it("classifies register bit range", () => {
|
|
582
543
|
const knownRegisters = new Set(["GPIO7"]);
|
|
583
|
-
|
|
584
|
-
const classifier = new AssignmentClassifier(deps);
|
|
544
|
+
setupSymbols({ knownRegisters });
|
|
585
545
|
|
|
586
546
|
const ctx = createMockContext({
|
|
587
547
|
identifiers: ["GPIO7", "DR_SET"],
|
|
@@ -594,18 +554,16 @@ describe("AssignmentClassifier - Register Bit Access", () => {
|
|
|
594
554
|
isSimpleIdentifier: false,
|
|
595
555
|
});
|
|
596
556
|
|
|
597
|
-
expect(
|
|
557
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
558
|
+
AssignmentKind.REGISTER_BIT_RANGE,
|
|
559
|
+
);
|
|
598
560
|
});
|
|
599
561
|
|
|
600
562
|
it("classifies scoped register bit", () => {
|
|
601
563
|
const knownScopes = new Set(["Teensy4"]);
|
|
602
564
|
const knownRegisters = new Set(["Teensy4_GPIO7"]);
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
knownRegisters,
|
|
606
|
-
currentScope: "Teensy4",
|
|
607
|
-
});
|
|
608
|
-
const classifier = new AssignmentClassifier(deps);
|
|
565
|
+
setupSymbols({ knownScopes, knownRegisters });
|
|
566
|
+
CodeGenState.currentScope = "Teensy4";
|
|
609
567
|
|
|
610
568
|
const ctx = createMockContext({
|
|
611
569
|
identifiers: ["GPIO7", "DR_SET"],
|
|
@@ -616,7 +574,9 @@ describe("AssignmentClassifier - Register Bit Access", () => {
|
|
|
616
574
|
isSimpleIdentifier: false,
|
|
617
575
|
});
|
|
618
576
|
|
|
619
|
-
expect(
|
|
577
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
578
|
+
AssignmentKind.SCOPED_REGISTER_BIT,
|
|
579
|
+
);
|
|
620
580
|
});
|
|
621
581
|
});
|
|
622
582
|
|
|
@@ -624,6 +584,10 @@ describe("AssignmentClassifier - Register Bit Access", () => {
|
|
|
624
584
|
// Scoped Register Bitmap Field (4-id pattern)
|
|
625
585
|
// ========================================================================
|
|
626
586
|
describe("AssignmentClassifier - Scoped Register Bitmap Field", () => {
|
|
587
|
+
beforeEach(() => {
|
|
588
|
+
CodeGenState.reset();
|
|
589
|
+
});
|
|
590
|
+
|
|
627
591
|
it("classifies Scope.REG.MEMBER.field as SCOPED_REGISTER_MEMBER_BITMAP_FIELD", () => {
|
|
628
592
|
const bitmapFields = new Map([
|
|
629
593
|
["ControlBits", new Map([["Enable", { offset: 0, width: 1 }]])],
|
|
@@ -633,14 +597,12 @@ describe("AssignmentClassifier - Scoped Register Bitmap Field", () => {
|
|
|
633
597
|
const registerMemberTypes = new Map([
|
|
634
598
|
["Teensy4_GPIO7_ICR1", "ControlBits"],
|
|
635
599
|
]);
|
|
636
|
-
|
|
637
|
-
const deps = createMockDeps({
|
|
600
|
+
setupSymbols({
|
|
638
601
|
bitmapFields,
|
|
639
602
|
knownScopes,
|
|
640
603
|
knownRegisters,
|
|
641
604
|
registerMemberTypes,
|
|
642
605
|
});
|
|
643
|
-
const classifier = new AssignmentClassifier(deps);
|
|
644
606
|
|
|
645
607
|
const ctx = createMockContext({
|
|
646
608
|
identifiers: ["Teensy4", "GPIO7", "ICR1", "Enable"],
|
|
@@ -648,14 +610,13 @@ describe("AssignmentClassifier - Scoped Register Bitmap Field", () => {
|
|
|
648
610
|
isSimpleIdentifier: false,
|
|
649
611
|
});
|
|
650
612
|
|
|
651
|
-
expect(
|
|
613
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
652
614
|
AssignmentKind.SCOPED_REGISTER_MEMBER_BITMAP_FIELD,
|
|
653
615
|
);
|
|
654
616
|
});
|
|
655
617
|
|
|
656
618
|
it("returns null for unknown scope in 4-id pattern", () => {
|
|
657
|
-
|
|
658
|
-
const classifier = new AssignmentClassifier(deps);
|
|
619
|
+
setupSymbols();
|
|
659
620
|
|
|
660
621
|
const ctx = createMockContext({
|
|
661
622
|
identifiers: ["UnknownScope", "REG", "MEMBER", "field"],
|
|
@@ -663,7 +624,7 @@ describe("AssignmentClassifier - Scoped Register Bitmap Field", () => {
|
|
|
663
624
|
isSimpleIdentifier: false,
|
|
664
625
|
});
|
|
665
626
|
|
|
666
|
-
expect(
|
|
627
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(AssignmentKind.SIMPLE);
|
|
667
628
|
});
|
|
668
629
|
});
|
|
669
630
|
|
|
@@ -671,24 +632,24 @@ describe("AssignmentClassifier - Scoped Register Bitmap Field", () => {
|
|
|
671
632
|
// Bitmap Array Element Field
|
|
672
633
|
// ========================================================================
|
|
673
634
|
describe("AssignmentClassifier - Bitmap Array Element Field", () => {
|
|
635
|
+
beforeEach(() => {
|
|
636
|
+
CodeGenState.reset();
|
|
637
|
+
});
|
|
638
|
+
|
|
674
639
|
it("classifies bitmapArr[i].field as BITMAP_ARRAY_ELEMENT_FIELD", () => {
|
|
675
640
|
const bitmapFields = new Map([
|
|
676
641
|
["StatusFlags", new Map([["Active", { offset: 0, width: 1 }]])],
|
|
677
642
|
]);
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
]);
|
|
689
|
-
|
|
690
|
-
const deps = createMockDeps({ bitmapFields, typeRegistry });
|
|
691
|
-
const classifier = new AssignmentClassifier(deps);
|
|
643
|
+
setupSymbols({ bitmapFields });
|
|
644
|
+
CodeGenState.typeRegistry.set(
|
|
645
|
+
"flagsArr",
|
|
646
|
+
createTypeInfo({
|
|
647
|
+
isBitmap: true,
|
|
648
|
+
isArray: true,
|
|
649
|
+
bitmapTypeName: "StatusFlags",
|
|
650
|
+
arrayDimensions: [10],
|
|
651
|
+
}),
|
|
652
|
+
);
|
|
692
653
|
|
|
693
654
|
const ctx = createMockContext({
|
|
694
655
|
identifiers: ["flagsArr", "Active"],
|
|
@@ -698,7 +659,7 @@ describe("AssignmentClassifier - Bitmap Array Element Field", () => {
|
|
|
698
659
|
isSimpleIdentifier: false,
|
|
699
660
|
});
|
|
700
661
|
|
|
701
|
-
expect(
|
|
662
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
702
663
|
AssignmentKind.BITMAP_ARRAY_ELEMENT_FIELD,
|
|
703
664
|
);
|
|
704
665
|
});
|
|
@@ -708,20 +669,20 @@ describe("AssignmentClassifier - Bitmap Array Element Field", () => {
|
|
|
708
669
|
// Multi-dim Array with Bit Indexing
|
|
709
670
|
// ========================================================================
|
|
710
671
|
describe("AssignmentClassifier - Multi-dim Array Bit Indexing", () => {
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
createTypeInfo({
|
|
716
|
-
baseType: "u32",
|
|
717
|
-
isArray: true,
|
|
718
|
-
arrayDimensions: [4, 4],
|
|
719
|
-
}),
|
|
720
|
-
],
|
|
721
|
-
]);
|
|
672
|
+
beforeEach(() => {
|
|
673
|
+
CodeGenState.reset();
|
|
674
|
+
setupSymbols();
|
|
675
|
+
});
|
|
722
676
|
|
|
723
|
-
|
|
724
|
-
|
|
677
|
+
it("classifies matrix[i][j][bit] as ARRAY_ELEMENT_BIT", () => {
|
|
678
|
+
CodeGenState.typeRegistry.set(
|
|
679
|
+
"matrix",
|
|
680
|
+
createTypeInfo({
|
|
681
|
+
baseType: "u32",
|
|
682
|
+
isArray: true,
|
|
683
|
+
arrayDimensions: [4, 4],
|
|
684
|
+
}),
|
|
685
|
+
);
|
|
725
686
|
|
|
726
687
|
const ctx = createMockContext({
|
|
727
688
|
identifiers: ["matrix"],
|
|
@@ -735,23 +696,20 @@ describe("AssignmentClassifier - Multi-dim Array Bit Indexing", () => {
|
|
|
735
696
|
isSimpleIdentifier: false,
|
|
736
697
|
});
|
|
737
698
|
|
|
738
|
-
expect(
|
|
699
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
700
|
+
AssignmentKind.ARRAY_ELEMENT_BIT,
|
|
701
|
+
);
|
|
739
702
|
});
|
|
740
703
|
|
|
741
704
|
it("classifies matrix[i][j] as MULTI_DIM_ARRAY_ELEMENT", () => {
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
],
|
|
751
|
-
]);
|
|
752
|
-
|
|
753
|
-
const deps = createMockDeps({ typeRegistry });
|
|
754
|
-
const classifier = new AssignmentClassifier(deps);
|
|
705
|
+
CodeGenState.typeRegistry.set(
|
|
706
|
+
"matrix",
|
|
707
|
+
createTypeInfo({
|
|
708
|
+
baseType: "u32",
|
|
709
|
+
isArray: true,
|
|
710
|
+
arrayDimensions: [4, 4],
|
|
711
|
+
}),
|
|
712
|
+
);
|
|
755
713
|
|
|
756
714
|
const ctx = createMockContext({
|
|
757
715
|
identifiers: ["matrix"],
|
|
@@ -764,7 +722,7 @@ describe("AssignmentClassifier - Multi-dim Array Bit Indexing", () => {
|
|
|
764
722
|
isSimpleIdentifier: false,
|
|
765
723
|
});
|
|
766
724
|
|
|
767
|
-
expect(
|
|
725
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
768
726
|
AssignmentKind.MULTI_DIM_ARRAY_ELEMENT,
|
|
769
727
|
);
|
|
770
728
|
});
|
|
@@ -774,13 +732,14 @@ describe("AssignmentClassifier - Multi-dim Array Bit Indexing", () => {
|
|
|
774
732
|
// Scoped Register Bit Range via This Prefix
|
|
775
733
|
// ========================================================================
|
|
776
734
|
describe("AssignmentClassifier - Scoped Register Bit Range", () => {
|
|
735
|
+
beforeEach(() => {
|
|
736
|
+
CodeGenState.reset();
|
|
737
|
+
});
|
|
738
|
+
|
|
777
739
|
it("classifies this.reg[start, width] as SCOPED_REGISTER_BIT_RANGE", () => {
|
|
778
740
|
const knownRegisters = new Set(["Teensy4_GPIO7"]);
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
currentScope: "Teensy4",
|
|
782
|
-
});
|
|
783
|
-
const classifier = new AssignmentClassifier(deps);
|
|
741
|
+
setupSymbols({ knownRegisters });
|
|
742
|
+
CodeGenState.currentScope = "Teensy4";
|
|
784
743
|
|
|
785
744
|
const ctx = createMockContext({
|
|
786
745
|
identifiers: ["GPIO7", "ICR1"],
|
|
@@ -797,7 +756,7 @@ describe("AssignmentClassifier - Scoped Register Bit Range", () => {
|
|
|
797
756
|
isSimpleIdentifier: false,
|
|
798
757
|
});
|
|
799
758
|
|
|
800
|
-
expect(
|
|
759
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
801
760
|
AssignmentKind.SCOPED_REGISTER_BIT_RANGE,
|
|
802
761
|
);
|
|
803
762
|
});
|
|
@@ -807,10 +766,13 @@ describe("AssignmentClassifier - Scoped Register Bit Range", () => {
|
|
|
807
766
|
// Register Bit Access via classifyMemberWithSubscript (non-scoped, 2+ ids)
|
|
808
767
|
// ========================================================================
|
|
809
768
|
describe("AssignmentClassifier - Register Bit via MemberWithSubscript", () => {
|
|
769
|
+
beforeEach(() => {
|
|
770
|
+
CodeGenState.reset();
|
|
771
|
+
});
|
|
772
|
+
|
|
810
773
|
it("classifies REG.MEMBER[bit] as REGISTER_BIT (non-this, non-global)", () => {
|
|
811
774
|
const knownRegisters = new Set(["TIMER"]);
|
|
812
|
-
|
|
813
|
-
const classifier = new AssignmentClassifier(deps);
|
|
775
|
+
setupSymbols({ knownRegisters });
|
|
814
776
|
|
|
815
777
|
const ctx = createMockContext({
|
|
816
778
|
identifiers: ["TIMER", "CTRL"],
|
|
@@ -820,13 +782,14 @@ describe("AssignmentClassifier - Register Bit via MemberWithSubscript", () => {
|
|
|
820
782
|
isSimpleIdentifier: false,
|
|
821
783
|
});
|
|
822
784
|
|
|
823
|
-
expect(
|
|
785
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
786
|
+
AssignmentKind.REGISTER_BIT,
|
|
787
|
+
);
|
|
824
788
|
});
|
|
825
789
|
|
|
826
790
|
it("classifies REG.MEMBER[start, width] as REGISTER_BIT_RANGE (non-this)", () => {
|
|
827
791
|
const knownRegisters = new Set(["TIMER"]);
|
|
828
|
-
|
|
829
|
-
const classifier = new AssignmentClassifier(deps);
|
|
792
|
+
setupSymbols({ knownRegisters });
|
|
830
793
|
|
|
831
794
|
const ctx = createMockContext({
|
|
832
795
|
identifiers: ["TIMER", "CTRL"],
|
|
@@ -839,14 +802,15 @@ describe("AssignmentClassifier - Register Bit via MemberWithSubscript", () => {
|
|
|
839
802
|
isSimpleIdentifier: false,
|
|
840
803
|
});
|
|
841
804
|
|
|
842
|
-
expect(
|
|
805
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
806
|
+
AssignmentKind.REGISTER_BIT_RANGE,
|
|
807
|
+
);
|
|
843
808
|
});
|
|
844
809
|
|
|
845
810
|
it("classifies Scope.REG.MEMBER[bit] as REGISTER_BIT via memberWithSubscript", () => {
|
|
846
811
|
const knownScopes = new Set(["Teensy4"]);
|
|
847
812
|
const knownRegisters = new Set(["Teensy4_GPIO7"]);
|
|
848
|
-
|
|
849
|
-
const classifier = new AssignmentClassifier(deps);
|
|
813
|
+
setupSymbols({ knownScopes, knownRegisters });
|
|
850
814
|
|
|
851
815
|
const ctx = createMockContext({
|
|
852
816
|
identifiers: ["Teensy4", "GPIO7", "DR_SET"],
|
|
@@ -856,7 +820,9 @@ describe("AssignmentClassifier - Register Bit via MemberWithSubscript", () => {
|
|
|
856
820
|
isSimpleIdentifier: false,
|
|
857
821
|
});
|
|
858
822
|
|
|
859
|
-
expect(
|
|
823
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
824
|
+
AssignmentKind.REGISTER_BIT,
|
|
825
|
+
);
|
|
860
826
|
});
|
|
861
827
|
});
|
|
862
828
|
|
|
@@ -864,19 +830,18 @@ describe("AssignmentClassifier - Register Bit via MemberWithSubscript", () => {
|
|
|
864
830
|
// This Prefix - Scoped Register Bitmap Field
|
|
865
831
|
// ========================================================================
|
|
866
832
|
describe("AssignmentClassifier - This Prefix Register Bitmap", () => {
|
|
833
|
+
beforeEach(() => {
|
|
834
|
+
CodeGenState.reset();
|
|
835
|
+
});
|
|
836
|
+
|
|
867
837
|
it("classifies this.REG.MEMBER.field as SCOPED_REGISTER_MEMBER_BITMAP_FIELD", () => {
|
|
868
838
|
const knownRegisters = new Set(["Motor_GPIO7"]);
|
|
869
839
|
const registerMemberTypes = new Map([["Motor_GPIO7_ICR1", "CtrlBits"]]);
|
|
870
840
|
const bitmapFields = new Map([
|
|
871
841
|
["CtrlBits", new Map([["Enable", { offset: 0, width: 1 }]])],
|
|
872
842
|
]);
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
registerMemberTypes,
|
|
876
|
-
bitmapFields,
|
|
877
|
-
currentScope: "Motor",
|
|
878
|
-
});
|
|
879
|
-
const classifier = new AssignmentClassifier(deps);
|
|
843
|
+
setupSymbols({ knownRegisters, registerMemberTypes, bitmapFields });
|
|
844
|
+
CodeGenState.currentScope = "Motor";
|
|
880
845
|
|
|
881
846
|
const ctx = createMockContext({
|
|
882
847
|
identifiers: ["GPIO7", "ICR1", "Enable"],
|
|
@@ -885,7 +850,7 @@ describe("AssignmentClassifier - This Prefix Register Bitmap", () => {
|
|
|
885
850
|
isSimpleIdentifier: false,
|
|
886
851
|
});
|
|
887
852
|
|
|
888
|
-
expect(
|
|
853
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
889
854
|
AssignmentKind.SCOPED_REGISTER_MEMBER_BITMAP_FIELD,
|
|
890
855
|
);
|
|
891
856
|
});
|
|
@@ -895,15 +860,18 @@ describe("AssignmentClassifier - This Prefix Register Bitmap", () => {
|
|
|
895
860
|
// Member Chain
|
|
896
861
|
// ========================================================================
|
|
897
862
|
describe("AssignmentClassifier - Member Chain", () => {
|
|
863
|
+
beforeEach(() => {
|
|
864
|
+
CodeGenState.reset();
|
|
865
|
+
});
|
|
866
|
+
|
|
898
867
|
it("classifies complex member chain as MEMBER_CHAIN", () => {
|
|
899
868
|
const knownStructs = new Set(["Config"]);
|
|
900
869
|
const structFields = new Map([["Config", new Map([["items", "Item"]])]]);
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
const classifier = new AssignmentClassifier(deps);
|
|
870
|
+
setupSymbols({ knownStructs, structFields });
|
|
871
|
+
CodeGenState.typeRegistry.set(
|
|
872
|
+
"config",
|
|
873
|
+
createTypeInfo({ baseType: "Config" }),
|
|
874
|
+
);
|
|
907
875
|
|
|
908
876
|
const ctx = createMockContext({
|
|
909
877
|
identifiers: ["config", "items"],
|
|
@@ -913,6 +881,8 @@ describe("AssignmentClassifier - Member Chain", () => {
|
|
|
913
881
|
isSimpleIdentifier: false,
|
|
914
882
|
});
|
|
915
883
|
|
|
916
|
-
expect(
|
|
884
|
+
expect(AssignmentClassifier.classify(ctx)).toBe(
|
|
885
|
+
AssignmentKind.MEMBER_CHAIN,
|
|
886
|
+
);
|
|
917
887
|
});
|
|
918
888
|
});
|