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