c-next 0.1.65 → 0.1.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -1
- package/src/transpiler/Transpiler.ts +49 -42
- package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolAdapter.test.ts +129 -0
- package/src/transpiler/logic/symbols/cnext/adapters/TSymbolAdapter.ts +27 -3
- package/src/transpiler/output/codegen/CodeGenerator.ts +131 -186
- package/src/transpiler/output/codegen/TypeResolver.ts +2 -2
- package/src/transpiler/output/codegen/TypeValidator.ts +1 -1
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.coverage.test.ts +1087 -0
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +665 -1315
- package/src/transpiler/output/codegen/__tests__/TypeResolver.test.ts +1 -1
- package/src/transpiler/output/codegen/__tests__/TypeValidator.resolution.test.ts +1 -1
- package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +1 -1
- package/src/transpiler/output/codegen/analysis/MemberChainAnalyzer.ts +1 -1
- package/src/transpiler/output/codegen/analysis/StringLengthCounter.ts +1 -1
- package/src/transpiler/output/codegen/analysis/__tests__/MemberChainAnalyzer.test.ts +1 -1
- package/src/transpiler/output/codegen/analysis/__tests__/StringLengthCounter.test.ts +1 -1
- package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +1 -1
- package/src/transpiler/output/codegen/assignment/__tests__/AssignmentClassifier.test.ts +1 -1
- package/src/transpiler/output/codegen/assignment/handlers/AccessPatternHandlers.ts +24 -27
- package/src/transpiler/output/codegen/assignment/handlers/ArrayHandlers.ts +25 -18
- package/src/transpiler/output/codegen/assignment/handlers/BitAccessHandlers.ts +27 -33
- package/src/transpiler/output/codegen/assignment/handlers/BitmapHandlers.ts +39 -42
- package/src/transpiler/output/codegen/assignment/handlers/RegisterHandlers.ts +39 -97
- package/src/transpiler/output/codegen/assignment/handlers/RegisterUtils.ts +75 -0
- package/src/transpiler/output/codegen/assignment/handlers/SimpleHandler.ts +9 -6
- package/src/transpiler/output/codegen/assignment/handlers/SpecialHandlers.ts +30 -22
- package/src/transpiler/output/codegen/assignment/handlers/StringHandlers.ts +42 -50
- package/src/transpiler/output/codegen/assignment/handlers/TAssignmentHandler.ts +6 -5
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/AccessPatternHandlers.test.ts +81 -134
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/ArrayHandlers.test.ts +85 -124
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitAccessHandlers.test.ts +82 -124
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitmapHandlers.test.ts +135 -297
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/RegisterHandlers.test.ts +105 -227
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/RegisterUtils.test.ts +214 -1
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/SpecialHandlers.test.ts +66 -127
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/StringHandlers.test.ts +37 -83
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/handlerTestUtils.ts +162 -0
- package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +618 -12
- package/src/transpiler/output/codegen/generators/expressions/__tests__/PostfixExpressionGenerator.test.ts +819 -0
- package/src/transpiler/output/codegen/helpers/ArrayInitHelper.ts +1 -1
- package/src/transpiler/output/codegen/helpers/AssignmentExpectedTypeResolver.ts +1 -1
- package/src/transpiler/output/codegen/helpers/AssignmentValidator.ts +1 -1
- package/src/transpiler/output/codegen/helpers/CppModeHelper.ts +1 -1
- package/src/transpiler/output/codegen/helpers/EnumAssignmentValidator.ts +1 -1
- package/src/transpiler/output/codegen/helpers/FloatBitHelper.ts +1 -1
- package/src/transpiler/output/codegen/helpers/ParameterInputAdapter.ts +337 -0
- package/src/transpiler/output/codegen/helpers/ParameterSignatureBuilder.ts +135 -0
- package/src/transpiler/output/codegen/helpers/StringDeclHelper.ts +1 -1
- package/src/transpiler/output/codegen/helpers/VariableDeclarationFormatter.ts +118 -0
- package/src/transpiler/output/codegen/helpers/__tests__/ArrayInitHelper.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentExpectedTypeResolver.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentValidator.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/CppModeHelper.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/EnumAssignmentValidator.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/FloatBitHelper.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/ParameterInputAdapter.test.ts +426 -0
- package/src/transpiler/output/codegen/helpers/__tests__/ParameterSignatureBuilder.test.ts +315 -0
- package/src/transpiler/output/codegen/helpers/__tests__/StringDeclHelper.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/VariableDeclarationFormatter.test.ts +333 -0
- package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +1 -1
- package/src/transpiler/output/codegen/resolution/ScopeResolver.ts +1 -1
- package/src/transpiler/output/codegen/resolution/SizeofResolver.ts +1 -1
- package/src/transpiler/output/codegen/resolution/__tests__/EnumTypeResolver.test.ts +1 -1
- package/src/transpiler/output/codegen/resolution/__tests__/SizeofResolver.test.ts +1 -1
- package/src/transpiler/output/codegen/types/ICodeGenApi.ts +57 -0
- package/src/transpiler/output/codegen/types/IParameterInput.ts +58 -0
- package/src/transpiler/output/codegen/types/IVariableFormatInput.ts +51 -0
- package/src/transpiler/output/headers/BaseHeaderGenerator.ts +20 -35
- package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +21 -48
- package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +0 -64
- package/src/transpiler/{output/codegen → state}/CodeGenState.ts +46 -26
- package/src/transpiler/{output/codegen → state}/__tests__/CodeGenState.test.ts +12 -2
- package/src/transpiler/output/codegen/assignment/handlers/IHandlerDeps.ts +0 -161
|
@@ -3,53 +3,21 @@
|
|
|
3
3
|
* Tests bitmap field assignment handler functions.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { describe, expect, it, vi } from "vitest";
|
|
6
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
7
|
+
|
|
8
|
+
// Mock TypeValidator before imports
|
|
9
|
+
vi.mock("../../../TypeValidator", () => ({
|
|
10
|
+
default: {
|
|
11
|
+
validateBitmapFieldLiteral: vi.fn(),
|
|
12
|
+
},
|
|
13
|
+
}));
|
|
14
|
+
|
|
7
15
|
import bitmapHandlers from "../BitmapHandlers";
|
|
8
16
|
import AssignmentKind from "../../AssignmentKind";
|
|
9
17
|
import IAssignmentContext from "../../IAssignmentContext";
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* Create mock dependencies for testing.
|
|
14
|
-
*/
|
|
15
|
-
function createMockDeps(overrides: Record<string, unknown> = {}): IHandlerDeps {
|
|
16
|
-
const base = {
|
|
17
|
-
typeRegistry: new Map(),
|
|
18
|
-
symbols: {
|
|
19
|
-
structFields: new Map(),
|
|
20
|
-
structFieldDimensions: new Map(),
|
|
21
|
-
bitmapFields: new Map(),
|
|
22
|
-
registerMemberAccess: new Map(),
|
|
23
|
-
registerBaseAddresses: new Map(),
|
|
24
|
-
registerMemberOffsets: new Map(),
|
|
25
|
-
registerMemberTypes: new Map(),
|
|
26
|
-
},
|
|
27
|
-
currentScope: null,
|
|
28
|
-
currentParameters: new Map(),
|
|
29
|
-
targetCapabilities: { hasLDREX: false },
|
|
30
|
-
generateAssignmentTarget: vi.fn().mockReturnValue("target"),
|
|
31
|
-
generateExpression: vi
|
|
32
|
-
.fn()
|
|
33
|
-
.mockImplementation((ctx) => ctx?.mockValue ?? "0"),
|
|
34
|
-
markNeedsString: vi.fn(),
|
|
35
|
-
markClampOpUsed: vi.fn(),
|
|
36
|
-
isKnownScope: vi.fn().mockReturnValue(false),
|
|
37
|
-
isKnownStruct: vi.fn().mockReturnValue(false),
|
|
38
|
-
validateCrossScopeVisibility: vi.fn(),
|
|
39
|
-
validateBitmapFieldLiteral: vi.fn(),
|
|
40
|
-
checkArrayBounds: vi.fn(),
|
|
41
|
-
analyzeMemberChainForBitAccess: vi
|
|
42
|
-
.fn()
|
|
43
|
-
.mockReturnValue({ isBitAccess: false }),
|
|
44
|
-
tryEvaluateConstant: vi.fn().mockReturnValue(undefined),
|
|
45
|
-
getMemberTypeInfo: vi.fn().mockReturnValue(null),
|
|
46
|
-
generateFloatBitWrite: vi.fn().mockReturnValue(null),
|
|
47
|
-
foldBooleanToInt: vi.fn().mockImplementation((expr) => expr),
|
|
48
|
-
generateAtomicRMW: vi.fn().mockReturnValue("atomic_rmw"),
|
|
49
|
-
...overrides,
|
|
50
|
-
};
|
|
51
|
-
return base as unknown as IHandlerDeps;
|
|
52
|
-
}
|
|
18
|
+
import CodeGenState from "../../../../../state/CodeGenState";
|
|
19
|
+
import TypeValidator from "../../../TypeValidator";
|
|
20
|
+
import HandlerTestUtils from "./handlerTestUtils";
|
|
53
21
|
|
|
54
22
|
/**
|
|
55
23
|
* Create mock context for testing.
|
|
@@ -81,6 +49,12 @@ function createMockContext(
|
|
|
81
49
|
}
|
|
82
50
|
|
|
83
51
|
describe("BitmapHandlers", () => {
|
|
52
|
+
beforeEach(() => {
|
|
53
|
+
CodeGenState.reset();
|
|
54
|
+
HandlerTestUtils.setupMockGenerator();
|
|
55
|
+
HandlerTestUtils.setupMockSymbols();
|
|
56
|
+
});
|
|
57
|
+
|
|
84
58
|
describe("handler registration", () => {
|
|
85
59
|
it("registers all expected bitmap assignment kinds", () => {
|
|
86
60
|
const kinds = bitmapHandlers.map(([kind]) => kind);
|
|
@@ -107,27 +81,17 @@ describe("BitmapHandlers", () => {
|
|
|
107
81
|
)?.[1];
|
|
108
82
|
|
|
109
83
|
it("generates single-bit read-modify-write", () => {
|
|
110
|
-
|
|
84
|
+
CodeGenState.typeRegistry = new Map([
|
|
111
85
|
["flags", { bitmapTypeName: "StatusFlags", baseType: "u8" }],
|
|
112
|
-
]);
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
typeRegistry,
|
|
118
|
-
symbols: {
|
|
119
|
-
structFields: new Map(),
|
|
120
|
-
structFieldDimensions: new Map(),
|
|
121
|
-
bitmapFields,
|
|
122
|
-
registerMemberAccess: new Map(),
|
|
123
|
-
registerBaseAddresses: new Map(),
|
|
124
|
-
registerMemberOffsets: new Map(),
|
|
125
|
-
registerMemberTypes: new Map(),
|
|
126
|
-
},
|
|
86
|
+
]) as any;
|
|
87
|
+
HandlerTestUtils.setupMockSymbols({
|
|
88
|
+
bitmapFields: new Map([
|
|
89
|
+
["StatusFlags", new Map([["Running", { offset: 0, width: 1 }]])],
|
|
90
|
+
]),
|
|
127
91
|
});
|
|
128
92
|
const ctx = createMockContext();
|
|
129
93
|
|
|
130
|
-
const result = getHandler()!(ctx
|
|
94
|
+
const result = getHandler()!(ctx);
|
|
131
95
|
|
|
132
96
|
expect(result).toContain("flags =");
|
|
133
97
|
expect(result).toContain("& ~(1 << 0)");
|
|
@@ -135,114 +99,73 @@ describe("BitmapHandlers", () => {
|
|
|
135
99
|
});
|
|
136
100
|
|
|
137
101
|
it("generates single-bit write with correct offset", () => {
|
|
138
|
-
|
|
102
|
+
CodeGenState.typeRegistry = new Map([
|
|
139
103
|
["flags", { bitmapTypeName: "StatusFlags", baseType: "u8" }],
|
|
140
|
-
]);
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
typeRegistry,
|
|
146
|
-
symbols: {
|
|
147
|
-
structFields: new Map(),
|
|
148
|
-
structFieldDimensions: new Map(),
|
|
149
|
-
bitmapFields,
|
|
150
|
-
registerMemberAccess: new Map(),
|
|
151
|
-
registerBaseAddresses: new Map(),
|
|
152
|
-
registerMemberOffsets: new Map(),
|
|
153
|
-
registerMemberTypes: new Map(),
|
|
154
|
-
},
|
|
104
|
+
]) as any;
|
|
105
|
+
HandlerTestUtils.setupMockSymbols({
|
|
106
|
+
bitmapFields: new Map([
|
|
107
|
+
["StatusFlags", new Map([["Active", { offset: 3, width: 1 }]])],
|
|
108
|
+
]),
|
|
155
109
|
});
|
|
156
110
|
const ctx = createMockContext({
|
|
157
111
|
identifiers: ["flags", "Active"],
|
|
158
112
|
});
|
|
159
113
|
|
|
160
|
-
const result = getHandler()!(ctx
|
|
114
|
+
const result = getHandler()!(ctx);
|
|
161
115
|
|
|
162
116
|
expect(result).toContain("<< 3");
|
|
163
117
|
});
|
|
164
118
|
|
|
165
119
|
it("throws on unknown bitmap field", () => {
|
|
166
|
-
|
|
120
|
+
CodeGenState.typeRegistry = new Map([
|
|
167
121
|
["flags", { bitmapTypeName: "StatusFlags", baseType: "u8" }],
|
|
168
|
-
]);
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
typeRegistry,
|
|
172
|
-
symbols: {
|
|
173
|
-
structFields: new Map(),
|
|
174
|
-
structFieldDimensions: new Map(),
|
|
175
|
-
bitmapFields,
|
|
176
|
-
registerMemberAccess: new Map(),
|
|
177
|
-
registerBaseAddresses: new Map(),
|
|
178
|
-
registerMemberOffsets: new Map(),
|
|
179
|
-
registerMemberTypes: new Map(),
|
|
180
|
-
},
|
|
122
|
+
]) as any;
|
|
123
|
+
HandlerTestUtils.setupMockSymbols({
|
|
124
|
+
bitmapFields: new Map([["StatusFlags", new Map()]]),
|
|
181
125
|
});
|
|
182
126
|
const ctx = createMockContext({
|
|
183
127
|
identifiers: ["flags", "Unknown"],
|
|
184
128
|
});
|
|
185
129
|
|
|
186
|
-
expect(() => getHandler()!(ctx
|
|
130
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
187
131
|
"Unknown bitmap field 'Unknown' on type 'StatusFlags'",
|
|
188
132
|
);
|
|
189
133
|
});
|
|
190
134
|
|
|
191
135
|
it("throws on compound assignment", () => {
|
|
192
|
-
|
|
136
|
+
CodeGenState.typeRegistry = new Map([
|
|
193
137
|
["flags", { bitmapTypeName: "StatusFlags", baseType: "u8" }],
|
|
194
|
-
]);
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
typeRegistry,
|
|
200
|
-
symbols: {
|
|
201
|
-
structFields: new Map(),
|
|
202
|
-
structFieldDimensions: new Map(),
|
|
203
|
-
bitmapFields,
|
|
204
|
-
registerMemberAccess: new Map(),
|
|
205
|
-
registerBaseAddresses: new Map(),
|
|
206
|
-
registerMemberOffsets: new Map(),
|
|
207
|
-
registerMemberTypes: new Map(),
|
|
208
|
-
},
|
|
138
|
+
]) as any;
|
|
139
|
+
HandlerTestUtils.setupMockSymbols({
|
|
140
|
+
bitmapFields: new Map([
|
|
141
|
+
["StatusFlags", new Map([["Running", { offset: 0, width: 1 }]])],
|
|
142
|
+
]),
|
|
209
143
|
});
|
|
210
144
|
const ctx = createMockContext({
|
|
211
145
|
isCompound: true,
|
|
212
146
|
cnextOp: "+<-",
|
|
213
147
|
});
|
|
214
148
|
|
|
215
|
-
expect(() => getHandler()!(ctx
|
|
149
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
216
150
|
"Compound assignment operators not supported for bitmap field access",
|
|
217
151
|
);
|
|
218
152
|
});
|
|
219
153
|
|
|
220
154
|
it("validates bitmap field literal", () => {
|
|
221
|
-
|
|
155
|
+
CodeGenState.typeRegistry = new Map([
|
|
222
156
|
["flags", { bitmapTypeName: "StatusFlags", baseType: "u8" }],
|
|
223
|
-
]);
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
const deps = createMockDeps({
|
|
229
|
-
typeRegistry,
|
|
230
|
-
validateBitmapFieldLiteral,
|
|
231
|
-
symbols: {
|
|
232
|
-
structFields: new Map(),
|
|
233
|
-
structFieldDimensions: new Map(),
|
|
234
|
-
bitmapFields,
|
|
235
|
-
registerMemberAccess: new Map(),
|
|
236
|
-
registerBaseAddresses: new Map(),
|
|
237
|
-
registerMemberOffsets: new Map(),
|
|
238
|
-
registerMemberTypes: new Map(),
|
|
239
|
-
},
|
|
157
|
+
]) as any;
|
|
158
|
+
HandlerTestUtils.setupMockSymbols({
|
|
159
|
+
bitmapFields: new Map([
|
|
160
|
+
["StatusFlags", new Map([["Running", { offset: 0, width: 1 }]])],
|
|
161
|
+
]),
|
|
240
162
|
});
|
|
241
163
|
const ctx = createMockContext();
|
|
164
|
+
vi.mocked(TypeValidator.validateBitmapFieldLiteral).mockClear();
|
|
242
165
|
|
|
243
|
-
getHandler()!(ctx
|
|
166
|
+
getHandler()!(ctx);
|
|
244
167
|
|
|
245
|
-
expect(validateBitmapFieldLiteral).toHaveBeenCalledWith(
|
|
168
|
+
expect(TypeValidator.validateBitmapFieldLiteral).toHaveBeenCalledWith(
|
|
246
169
|
ctx.valueCtx,
|
|
247
170
|
1,
|
|
248
171
|
"Running",
|
|
@@ -257,30 +180,20 @@ describe("BitmapHandlers", () => {
|
|
|
257
180
|
)?.[1];
|
|
258
181
|
|
|
259
182
|
it("generates multi-bit read-modify-write with mask", () => {
|
|
260
|
-
|
|
183
|
+
CodeGenState.typeRegistry = new Map([
|
|
261
184
|
["flags", { bitmapTypeName: "StatusFlags", baseType: "u8" }],
|
|
262
|
-
]);
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
typeRegistry,
|
|
268
|
-
symbols: {
|
|
269
|
-
structFields: new Map(),
|
|
270
|
-
structFieldDimensions: new Map(),
|
|
271
|
-
bitmapFields,
|
|
272
|
-
registerMemberAccess: new Map(),
|
|
273
|
-
registerBaseAddresses: new Map(),
|
|
274
|
-
registerMemberOffsets: new Map(),
|
|
275
|
-
registerMemberTypes: new Map(),
|
|
276
|
-
},
|
|
185
|
+
]) as any;
|
|
186
|
+
HandlerTestUtils.setupMockSymbols({
|
|
187
|
+
bitmapFields: new Map([
|
|
188
|
+
["StatusFlags", new Map([["Mode", { offset: 4, width: 3 }]])],
|
|
189
|
+
]),
|
|
277
190
|
});
|
|
278
191
|
const ctx = createMockContext({
|
|
279
192
|
identifiers: ["flags", "Mode"],
|
|
280
193
|
generatedValue: "3",
|
|
281
194
|
});
|
|
282
195
|
|
|
283
|
-
const result = getHandler()!(ctx
|
|
196
|
+
const result = getHandler()!(ctx);
|
|
284
197
|
|
|
285
198
|
expect(result).toContain("flags =");
|
|
286
199
|
expect(result).toContain("& ~(0x7 << 4)");
|
|
@@ -289,30 +202,20 @@ describe("BitmapHandlers", () => {
|
|
|
289
202
|
});
|
|
290
203
|
|
|
291
204
|
it("generates correct mask for 2-bit field", () => {
|
|
292
|
-
|
|
205
|
+
CodeGenState.typeRegistry = new Map([
|
|
293
206
|
["config", { bitmapTypeName: "Config", baseType: "u8" }],
|
|
294
|
-
]);
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
typeRegistry,
|
|
300
|
-
symbols: {
|
|
301
|
-
structFields: new Map(),
|
|
302
|
-
structFieldDimensions: new Map(),
|
|
303
|
-
bitmapFields,
|
|
304
|
-
registerMemberAccess: new Map(),
|
|
305
|
-
registerBaseAddresses: new Map(),
|
|
306
|
-
registerMemberOffsets: new Map(),
|
|
307
|
-
registerMemberTypes: new Map(),
|
|
308
|
-
},
|
|
207
|
+
]) as any;
|
|
208
|
+
HandlerTestUtils.setupMockSymbols({
|
|
209
|
+
bitmapFields: new Map([
|
|
210
|
+
["Config", new Map([["Priority", { offset: 0, width: 2 }]])],
|
|
211
|
+
]),
|
|
309
212
|
});
|
|
310
213
|
const ctx = createMockContext({
|
|
311
214
|
identifiers: ["config", "Priority"],
|
|
312
215
|
generatedValue: "2",
|
|
313
216
|
});
|
|
314
217
|
|
|
315
|
-
const result = getHandler()!(ctx
|
|
218
|
+
const result = getHandler()!(ctx);
|
|
316
219
|
|
|
317
220
|
expect(result).toContain("0x3");
|
|
318
221
|
});
|
|
@@ -325,31 +228,23 @@ describe("BitmapHandlers", () => {
|
|
|
325
228
|
)?.[1];
|
|
326
229
|
|
|
327
230
|
it("generates array element bitmap field assignment", () => {
|
|
328
|
-
|
|
231
|
+
CodeGenState.typeRegistry = new Map([
|
|
329
232
|
["flagsArray", { bitmapTypeName: "StatusFlags", baseType: "u8" }],
|
|
330
|
-
]);
|
|
331
|
-
|
|
332
|
-
["StatusFlags", new Map([["Active", { offset: 0, width: 1 }]])],
|
|
333
|
-
]);
|
|
334
|
-
const deps = createMockDeps({
|
|
335
|
-
typeRegistry,
|
|
233
|
+
]) as any;
|
|
234
|
+
HandlerTestUtils.setupMockGenerator({
|
|
336
235
|
generateExpression: vi.fn().mockReturnValue("i"),
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
registerBaseAddresses: new Map(),
|
|
343
|
-
registerMemberOffsets: new Map(),
|
|
344
|
-
registerMemberTypes: new Map(),
|
|
345
|
-
},
|
|
236
|
+
});
|
|
237
|
+
HandlerTestUtils.setupMockSymbols({
|
|
238
|
+
bitmapFields: new Map([
|
|
239
|
+
["StatusFlags", new Map([["Active", { offset: 0, width: 1 }]])],
|
|
240
|
+
]),
|
|
346
241
|
});
|
|
347
242
|
const ctx = createMockContext({
|
|
348
243
|
identifiers: ["flagsArray", "Active"],
|
|
349
244
|
subscripts: [{ mockValue: "i" } as never],
|
|
350
245
|
});
|
|
351
246
|
|
|
352
|
-
const result = getHandler()!(ctx
|
|
247
|
+
const result = getHandler()!(ctx);
|
|
353
248
|
|
|
354
249
|
expect(result).toContain("flagsArray[i] =");
|
|
355
250
|
expect(result).toContain("& ~(1 << 0)");
|
|
@@ -363,28 +258,23 @@ describe("BitmapHandlers", () => {
|
|
|
363
258
|
)?.[1];
|
|
364
259
|
|
|
365
260
|
it("generates struct member bitmap field assignment", () => {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
registerMemberAccess: new Map(),
|
|
378
|
-
registerBaseAddresses: new Map(),
|
|
379
|
-
registerMemberOffsets: new Map(),
|
|
380
|
-
registerMemberTypes: new Map(),
|
|
381
|
-
},
|
|
261
|
+
CodeGenState.typeRegistry = new Map([
|
|
262
|
+
["device", { baseType: "Device" }],
|
|
263
|
+
]) as any;
|
|
264
|
+
HandlerTestUtils.setupMockSymbols({
|
|
265
|
+
bitmapFields: new Map([
|
|
266
|
+
["StatusFlags", new Map([["Active", { offset: 2, width: 1 }]])],
|
|
267
|
+
]),
|
|
268
|
+
// structFields maps struct type -> field name -> field type
|
|
269
|
+
structFields: new Map([
|
|
270
|
+
["Device", new Map([["flags", "StatusFlags"]])],
|
|
271
|
+
]),
|
|
382
272
|
});
|
|
383
273
|
const ctx = createMockContext({
|
|
384
274
|
identifiers: ["device", "flags", "Active"],
|
|
385
275
|
});
|
|
386
276
|
|
|
387
|
-
const result = getHandler()!(ctx
|
|
277
|
+
const result = getHandler()!(ctx);
|
|
388
278
|
|
|
389
279
|
expect(result).toContain("device.flags =");
|
|
390
280
|
expect(result).toContain("<< 2");
|
|
@@ -398,26 +288,17 @@ describe("BitmapHandlers", () => {
|
|
|
398
288
|
)?.[1];
|
|
399
289
|
|
|
400
290
|
it("generates register member bitmap field assignment", () => {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
symbols: {
|
|
407
|
-
structFields: new Map(),
|
|
408
|
-
structFieldDimensions: new Map(),
|
|
409
|
-
bitmapFields,
|
|
410
|
-
registerMemberAccess: new Map(),
|
|
411
|
-
registerBaseAddresses: new Map(),
|
|
412
|
-
registerMemberOffsets: new Map(),
|
|
413
|
-
registerMemberTypes,
|
|
414
|
-
},
|
|
291
|
+
HandlerTestUtils.setupMockSymbols({
|
|
292
|
+
bitmapFields: new Map([
|
|
293
|
+
["MotorCtrl", new Map([["Running", { offset: 0, width: 1 }]])],
|
|
294
|
+
]),
|
|
295
|
+
registerMemberTypes: new Map([["MOTOR_CTRL", "MotorCtrl"]]),
|
|
415
296
|
});
|
|
416
297
|
const ctx = createMockContext({
|
|
417
298
|
identifiers: ["MOTOR", "CTRL", "Running"],
|
|
418
299
|
});
|
|
419
300
|
|
|
420
|
-
const result = getHandler()!(ctx
|
|
301
|
+
const result = getHandler()!(ctx);
|
|
421
302
|
|
|
422
303
|
expect(result).toContain("MOTOR_CTRL =");
|
|
423
304
|
expect(result).toContain("& ~(1 << 0)");
|
|
@@ -431,21 +312,12 @@ describe("BitmapHandlers", () => {
|
|
|
431
312
|
)?.[1];
|
|
432
313
|
|
|
433
314
|
it("generates this-prefixed scoped register bitmap field", () => {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
symbols: {
|
|
441
|
-
structFields: new Map(),
|
|
442
|
-
structFieldDimensions: new Map(),
|
|
443
|
-
bitmapFields,
|
|
444
|
-
registerMemberAccess: new Map(),
|
|
445
|
-
registerBaseAddresses: new Map(),
|
|
446
|
-
registerMemberOffsets: new Map(),
|
|
447
|
-
registerMemberTypes,
|
|
448
|
-
},
|
|
315
|
+
CodeGenState.currentScope = "Motor";
|
|
316
|
+
HandlerTestUtils.setupMockSymbols({
|
|
317
|
+
bitmapFields: new Map([
|
|
318
|
+
["ICR1Bits", new Map([["LED", { offset: 6, width: 2 }]])],
|
|
319
|
+
]),
|
|
320
|
+
registerMemberTypes: new Map([["Motor_GPIO7_ICR1", "ICR1Bits"]]),
|
|
449
321
|
});
|
|
450
322
|
const ctx = createMockContext({
|
|
451
323
|
identifiers: ["GPIO7", "ICR1", "LED"],
|
|
@@ -453,29 +325,22 @@ describe("BitmapHandlers", () => {
|
|
|
453
325
|
generatedValue: "value",
|
|
454
326
|
});
|
|
455
327
|
|
|
456
|
-
const result = getHandler()!(ctx
|
|
328
|
+
const result = getHandler()!(ctx);
|
|
457
329
|
|
|
458
330
|
expect(result).toContain("Motor_GPIO7_ICR1 =");
|
|
459
331
|
expect(result).toContain("<< 6");
|
|
460
332
|
});
|
|
461
333
|
|
|
462
334
|
it("generates scope-prefixed register bitmap field", () => {
|
|
463
|
-
const bitmapFields = new Map([
|
|
464
|
-
["ICR1Bits", new Map([["LED", { offset: 6, width: 2 }]])],
|
|
465
|
-
]);
|
|
466
|
-
const registerMemberTypes = new Map([["Motor_GPIO7_ICR1", "ICR1Bits"]]);
|
|
467
335
|
const validateCrossScopeVisibility = vi.fn();
|
|
468
|
-
|
|
336
|
+
HandlerTestUtils.setupMockGenerator({
|
|
469
337
|
validateCrossScopeVisibility,
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
registerMemberOffsets: new Map(),
|
|
477
|
-
registerMemberTypes,
|
|
478
|
-
},
|
|
338
|
+
});
|
|
339
|
+
HandlerTestUtils.setupMockSymbols({
|
|
340
|
+
bitmapFields: new Map([
|
|
341
|
+
["ICR1Bits", new Map([["LED", { offset: 6, width: 2 }]])],
|
|
342
|
+
]),
|
|
343
|
+
registerMemberTypes: new Map([["Motor_GPIO7_ICR1", "ICR1Bits"]]),
|
|
479
344
|
});
|
|
480
345
|
const ctx = createMockContext({
|
|
481
346
|
identifiers: ["Motor", "GPIO7", "ICR1", "LED"],
|
|
@@ -483,7 +348,7 @@ describe("BitmapHandlers", () => {
|
|
|
483
348
|
generatedValue: "value",
|
|
484
349
|
});
|
|
485
350
|
|
|
486
|
-
const result = getHandler()!(ctx
|
|
351
|
+
const result = getHandler()!(ctx);
|
|
487
352
|
|
|
488
353
|
expect(result).toContain("Motor_GPIO7_ICR1 =");
|
|
489
354
|
expect(validateCrossScopeVisibility).toHaveBeenCalledWith(
|
|
@@ -493,41 +358,32 @@ describe("BitmapHandlers", () => {
|
|
|
493
358
|
});
|
|
494
359
|
|
|
495
360
|
it("throws when 'this' used outside scope", () => {
|
|
496
|
-
|
|
361
|
+
CodeGenState.currentScope = null;
|
|
497
362
|
const ctx = createMockContext({
|
|
498
363
|
identifiers: ["GPIO7", "ICR1", "LED"],
|
|
499
364
|
hasThis: true,
|
|
500
365
|
});
|
|
501
366
|
|
|
502
|
-
expect(() => getHandler()!(ctx
|
|
367
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
503
368
|
"'this' can only be used inside a scope",
|
|
504
369
|
);
|
|
505
370
|
});
|
|
506
371
|
|
|
507
372
|
it("generates write-only pattern for wo register", () => {
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
symbols: {
|
|
516
|
-
structFields: new Map(),
|
|
517
|
-
structFieldDimensions: new Map(),
|
|
518
|
-
bitmapFields,
|
|
519
|
-
registerMemberAccess,
|
|
520
|
-
registerBaseAddresses: new Map(),
|
|
521
|
-
registerMemberOffsets: new Map(),
|
|
522
|
-
registerMemberTypes,
|
|
523
|
-
},
|
|
373
|
+
CodeGenState.currentScope = "Motor";
|
|
374
|
+
HandlerTestUtils.setupMockSymbols({
|
|
375
|
+
bitmapFields: new Map([
|
|
376
|
+
["SetBits", new Map([["LED", { offset: 0, width: 1 }]])],
|
|
377
|
+
]),
|
|
378
|
+
registerMemberTypes: new Map([["Motor_GPIO7_SET", "SetBits"]]),
|
|
379
|
+
registerMemberAccess: new Map([["Motor_GPIO7_SET", "wo"]]),
|
|
524
380
|
});
|
|
525
381
|
const ctx = createMockContext({
|
|
526
382
|
identifiers: ["GPIO7", "SET", "LED"],
|
|
527
383
|
hasThis: true,
|
|
528
384
|
});
|
|
529
385
|
|
|
530
|
-
const result = getHandler()!(ctx
|
|
386
|
+
const result = getHandler()!(ctx);
|
|
531
387
|
|
|
532
388
|
// Write-only should not use RMW pattern
|
|
533
389
|
expect(result).not.toContain("& ~");
|
|
@@ -535,58 +391,40 @@ describe("BitmapHandlers", () => {
|
|
|
535
391
|
});
|
|
536
392
|
|
|
537
393
|
it("generates write-only pattern for w1s register", () => {
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
symbols: {
|
|
546
|
-
structFields: new Map(),
|
|
547
|
-
structFieldDimensions: new Map(),
|
|
548
|
-
bitmapFields,
|
|
549
|
-
registerMemberAccess,
|
|
550
|
-
registerBaseAddresses: new Map(),
|
|
551
|
-
registerMemberOffsets: new Map(),
|
|
552
|
-
registerMemberTypes,
|
|
553
|
-
},
|
|
394
|
+
CodeGenState.currentScope = "Motor";
|
|
395
|
+
HandlerTestUtils.setupMockSymbols({
|
|
396
|
+
bitmapFields: new Map([
|
|
397
|
+
["SetBits", new Map([["LED", { offset: 3, width: 1 }]])],
|
|
398
|
+
]),
|
|
399
|
+
registerMemberTypes: new Map([["Motor_GPIO7_SET", "SetBits"]]),
|
|
400
|
+
registerMemberAccess: new Map([["Motor_GPIO7_SET", "w1s"]]),
|
|
554
401
|
});
|
|
555
402
|
const ctx = createMockContext({
|
|
556
403
|
identifiers: ["GPIO7", "SET", "LED"],
|
|
557
404
|
hasThis: true,
|
|
558
405
|
});
|
|
559
406
|
|
|
560
|
-
const result = getHandler()!(ctx
|
|
407
|
+
const result = getHandler()!(ctx);
|
|
561
408
|
|
|
562
409
|
expect(result).not.toContain("& ~");
|
|
563
410
|
expect(result).toContain("<< 3");
|
|
564
411
|
});
|
|
565
412
|
|
|
566
413
|
it("generates write-only pattern for w1c register", () => {
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
symbols: {
|
|
575
|
-
structFields: new Map(),
|
|
576
|
-
structFieldDimensions: new Map(),
|
|
577
|
-
bitmapFields,
|
|
578
|
-
registerMemberAccess,
|
|
579
|
-
registerBaseAddresses: new Map(),
|
|
580
|
-
registerMemberOffsets: new Map(),
|
|
581
|
-
registerMemberTypes,
|
|
582
|
-
},
|
|
414
|
+
CodeGenState.currentScope = "Motor";
|
|
415
|
+
HandlerTestUtils.setupMockSymbols({
|
|
416
|
+
bitmapFields: new Map([
|
|
417
|
+
["ClearBits", new Map([["LED", { offset: 5, width: 1 }]])],
|
|
418
|
+
]),
|
|
419
|
+
registerMemberTypes: new Map([["Motor_GPIO7_CLR", "ClearBits"]]),
|
|
420
|
+
registerMemberAccess: new Map([["Motor_GPIO7_CLR", "w1c"]]),
|
|
583
421
|
});
|
|
584
422
|
const ctx = createMockContext({
|
|
585
423
|
identifiers: ["GPIO7", "CLR", "LED"],
|
|
586
424
|
hasThis: true,
|
|
587
425
|
});
|
|
588
426
|
|
|
589
|
-
const result = getHandler()!(ctx
|
|
427
|
+
const result = getHandler()!(ctx);
|
|
590
428
|
|
|
591
429
|
expect(result).not.toContain("& ~");
|
|
592
430
|
expect(result).toContain("<< 5");
|