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.
Files changed (73) hide show
  1. package/package.json +5 -1
  2. package/src/transpiler/Transpiler.ts +49 -42
  3. package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolAdapter.test.ts +129 -0
  4. package/src/transpiler/logic/symbols/cnext/adapters/TSymbolAdapter.ts +27 -3
  5. package/src/transpiler/output/codegen/CodeGenerator.ts +131 -186
  6. package/src/transpiler/output/codegen/TypeResolver.ts +2 -2
  7. package/src/transpiler/output/codegen/TypeValidator.ts +1 -1
  8. package/src/transpiler/output/codegen/__tests__/CodeGenerator.coverage.test.ts +1087 -0
  9. package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +665 -1315
  10. package/src/transpiler/output/codegen/__tests__/TypeResolver.test.ts +1 -1
  11. package/src/transpiler/output/codegen/__tests__/TypeValidator.resolution.test.ts +1 -1
  12. package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +1 -1
  13. package/src/transpiler/output/codegen/analysis/MemberChainAnalyzer.ts +1 -1
  14. package/src/transpiler/output/codegen/analysis/StringLengthCounter.ts +1 -1
  15. package/src/transpiler/output/codegen/analysis/__tests__/MemberChainAnalyzer.test.ts +1 -1
  16. package/src/transpiler/output/codegen/analysis/__tests__/StringLengthCounter.test.ts +1 -1
  17. package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +1 -1
  18. package/src/transpiler/output/codegen/assignment/__tests__/AssignmentClassifier.test.ts +1 -1
  19. package/src/transpiler/output/codegen/assignment/handlers/AccessPatternHandlers.ts +24 -27
  20. package/src/transpiler/output/codegen/assignment/handlers/ArrayHandlers.ts +25 -18
  21. package/src/transpiler/output/codegen/assignment/handlers/BitAccessHandlers.ts +27 -33
  22. package/src/transpiler/output/codegen/assignment/handlers/BitmapHandlers.ts +39 -42
  23. package/src/transpiler/output/codegen/assignment/handlers/RegisterHandlers.ts +39 -97
  24. package/src/transpiler/output/codegen/assignment/handlers/RegisterUtils.ts +75 -0
  25. package/src/transpiler/output/codegen/assignment/handlers/SimpleHandler.ts +9 -6
  26. package/src/transpiler/output/codegen/assignment/handlers/SpecialHandlers.ts +30 -22
  27. package/src/transpiler/output/codegen/assignment/handlers/StringHandlers.ts +42 -50
  28. package/src/transpiler/output/codegen/assignment/handlers/TAssignmentHandler.ts +6 -5
  29. package/src/transpiler/output/codegen/assignment/handlers/__tests__/AccessPatternHandlers.test.ts +81 -134
  30. package/src/transpiler/output/codegen/assignment/handlers/__tests__/ArrayHandlers.test.ts +85 -124
  31. package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitAccessHandlers.test.ts +82 -124
  32. package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitmapHandlers.test.ts +135 -297
  33. package/src/transpiler/output/codegen/assignment/handlers/__tests__/RegisterHandlers.test.ts +105 -227
  34. package/src/transpiler/output/codegen/assignment/handlers/__tests__/RegisterUtils.test.ts +214 -1
  35. package/src/transpiler/output/codegen/assignment/handlers/__tests__/SpecialHandlers.test.ts +66 -127
  36. package/src/transpiler/output/codegen/assignment/handlers/__tests__/StringHandlers.test.ts +37 -83
  37. package/src/transpiler/output/codegen/assignment/handlers/__tests__/handlerTestUtils.ts +162 -0
  38. package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +618 -12
  39. package/src/transpiler/output/codegen/generators/expressions/__tests__/PostfixExpressionGenerator.test.ts +819 -0
  40. package/src/transpiler/output/codegen/helpers/ArrayInitHelper.ts +1 -1
  41. package/src/transpiler/output/codegen/helpers/AssignmentExpectedTypeResolver.ts +1 -1
  42. package/src/transpiler/output/codegen/helpers/AssignmentValidator.ts +1 -1
  43. package/src/transpiler/output/codegen/helpers/CppModeHelper.ts +1 -1
  44. package/src/transpiler/output/codegen/helpers/EnumAssignmentValidator.ts +1 -1
  45. package/src/transpiler/output/codegen/helpers/FloatBitHelper.ts +1 -1
  46. package/src/transpiler/output/codegen/helpers/ParameterInputAdapter.ts +337 -0
  47. package/src/transpiler/output/codegen/helpers/ParameterSignatureBuilder.ts +135 -0
  48. package/src/transpiler/output/codegen/helpers/StringDeclHelper.ts +1 -1
  49. package/src/transpiler/output/codegen/helpers/VariableDeclarationFormatter.ts +118 -0
  50. package/src/transpiler/output/codegen/helpers/__tests__/ArrayInitHelper.test.ts +1 -1
  51. package/src/transpiler/output/codegen/helpers/__tests__/AssignmentExpectedTypeResolver.test.ts +1 -1
  52. package/src/transpiler/output/codegen/helpers/__tests__/AssignmentValidator.test.ts +1 -1
  53. package/src/transpiler/output/codegen/helpers/__tests__/CppModeHelper.test.ts +1 -1
  54. package/src/transpiler/output/codegen/helpers/__tests__/EnumAssignmentValidator.test.ts +1 -1
  55. package/src/transpiler/output/codegen/helpers/__tests__/FloatBitHelper.test.ts +1 -1
  56. package/src/transpiler/output/codegen/helpers/__tests__/ParameterInputAdapter.test.ts +426 -0
  57. package/src/transpiler/output/codegen/helpers/__tests__/ParameterSignatureBuilder.test.ts +315 -0
  58. package/src/transpiler/output/codegen/helpers/__tests__/StringDeclHelper.test.ts +1 -1
  59. package/src/transpiler/output/codegen/helpers/__tests__/VariableDeclarationFormatter.test.ts +333 -0
  60. package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +1 -1
  61. package/src/transpiler/output/codegen/resolution/ScopeResolver.ts +1 -1
  62. package/src/transpiler/output/codegen/resolution/SizeofResolver.ts +1 -1
  63. package/src/transpiler/output/codegen/resolution/__tests__/EnumTypeResolver.test.ts +1 -1
  64. package/src/transpiler/output/codegen/resolution/__tests__/SizeofResolver.test.ts +1 -1
  65. package/src/transpiler/output/codegen/types/ICodeGenApi.ts +57 -0
  66. package/src/transpiler/output/codegen/types/IParameterInput.ts +58 -0
  67. package/src/transpiler/output/codegen/types/IVariableFormatInput.ts +51 -0
  68. package/src/transpiler/output/headers/BaseHeaderGenerator.ts +20 -35
  69. package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +21 -48
  70. package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +0 -64
  71. package/src/transpiler/{output/codegen → state}/CodeGenState.ts +46 -26
  72. package/src/transpiler/{output/codegen → state}/__tests__/CodeGenState.test.ts +12 -2
  73. package/src/transpiler/output/codegen/assignment/handlers/IHandlerDeps.ts +0 -161
@@ -3,53 +3,12 @@
3
3
  * Tests register bit 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
7
  import registerHandlers from "../RegisterHandlers";
8
8
  import AssignmentKind from "../../AssignmentKind";
9
9
  import IAssignmentContext from "../../IAssignmentContext";
10
- import IHandlerDeps from "../IHandlerDeps";
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
- }
10
+ import CodeGenState from "../../../../../state/CodeGenState";
11
+ import HandlerTestUtils from "./handlerTestUtils";
53
12
 
54
13
  /**
55
14
  * Create mock context for testing.
@@ -80,6 +39,12 @@ function createMockContext(
80
39
  }
81
40
 
82
41
  describe("RegisterHandlers", () => {
42
+ beforeEach(() => {
43
+ CodeGenState.reset();
44
+ HandlerTestUtils.setupMockGenerator();
45
+ HandlerTestUtils.setupMockSymbols();
46
+ });
47
+
83
48
  describe("handler registration", () => {
84
49
  it("registers all expected register assignment kinds", () => {
85
50
  const kinds = registerHandlers.map(([kind]) => kind);
@@ -102,12 +67,12 @@ describe("RegisterHandlers", () => {
102
67
  )?.[1];
103
68
 
104
69
  it("generates read-modify-write for read-write register", () => {
105
- const deps = createMockDeps({
70
+ HandlerTestUtils.setupMockGenerator({
106
71
  generateExpression: vi.fn().mockReturnValue("LED_BIT"),
107
72
  });
108
73
  const ctx = createMockContext();
109
74
 
110
- const result = getHandler()!(ctx, deps);
75
+ const result = getHandler()!(ctx);
111
76
 
112
77
  expect(result).toContain("GPIO7_DR_SET");
113
78
  expect(result).toContain("& ~(1 <<");
@@ -115,87 +80,67 @@ describe("RegisterHandlers", () => {
115
80
  });
116
81
 
117
82
  it("generates simple write for write-only register", () => {
118
- const registerMemberAccess = new Map([["GPIO7_DR_SET", "wo"]]);
119
- const deps = createMockDeps({
83
+ HandlerTestUtils.setupMockGenerator({
120
84
  generateExpression: vi.fn().mockReturnValue("LED_BIT"),
121
- symbols: {
122
- structFields: new Map(),
123
- structFieldDimensions: new Map(),
124
- bitmapFields: new Map(),
125
- registerMemberAccess,
126
- registerBaseAddresses: new Map(),
127
- registerMemberOffsets: new Map(),
128
- registerMemberTypes: new Map(),
129
- },
85
+ });
86
+ HandlerTestUtils.setupMockSymbols({
87
+ registerMemberAccess: new Map([["GPIO7_DR_SET", "wo"]]),
130
88
  });
131
89
  const ctx = createMockContext();
132
90
 
133
- const result = getHandler()!(ctx, deps);
91
+ const result = getHandler()!(ctx);
134
92
 
135
93
  expect(result).toBe("GPIO7_DR_SET = (1 << LED_BIT);");
136
94
  });
137
95
 
138
96
  it("throws on write-only register with false value", () => {
139
- const registerMemberAccess = new Map([["GPIO7_DR_SET", "wo"]]);
140
- const deps = createMockDeps({
97
+ HandlerTestUtils.setupMockGenerator({
141
98
  generateExpression: vi.fn().mockReturnValue("LED_BIT"),
142
- symbols: {
143
- structFields: new Map(),
144
- structFieldDimensions: new Map(),
145
- bitmapFields: new Map(),
146
- registerMemberAccess,
147
- registerBaseAddresses: new Map(),
148
- registerMemberOffsets: new Map(),
149
- registerMemberTypes: new Map(),
150
- },
99
+ });
100
+ HandlerTestUtils.setupMockSymbols({
101
+ registerMemberAccess: new Map([["GPIO7_DR_SET", "wo"]]),
151
102
  });
152
103
  const ctx = createMockContext({ generatedValue: "false" });
153
104
 
154
- expect(() => getHandler()!(ctx, deps)).toThrow(
105
+ expect(() => getHandler()!(ctx)).toThrow(
155
106
  "Cannot assign false to write-only register bit",
156
107
  );
157
108
  });
158
109
 
159
110
  it("throws on write-only register with 0 value", () => {
160
- const registerMemberAccess = new Map([["GPIO7_DR_SET", "w1s"]]);
161
- const deps = createMockDeps({
111
+ HandlerTestUtils.setupMockGenerator({
162
112
  generateExpression: vi.fn().mockReturnValue("0"),
163
- symbols: {
164
- structFields: new Map(),
165
- structFieldDimensions: new Map(),
166
- bitmapFields: new Map(),
167
- registerMemberAccess,
168
- registerBaseAddresses: new Map(),
169
- registerMemberOffsets: new Map(),
170
- registerMemberTypes: new Map(),
171
- },
113
+ });
114
+ HandlerTestUtils.setupMockSymbols({
115
+ registerMemberAccess: new Map([["GPIO7_DR_SET", "w1s"]]),
172
116
  });
173
117
  const ctx = createMockContext({ generatedValue: "0" });
174
118
 
175
- expect(() => getHandler()!(ctx, deps)).toThrow(
119
+ expect(() => getHandler()!(ctx)).toThrow(
176
120
  "Cannot assign false to write-only register bit",
177
121
  );
178
122
  });
179
123
 
180
124
  it("throws on compound assignment", () => {
181
- const deps = createMockDeps();
182
125
  const ctx = createMockContext({ isCompound: true, cnextOp: "+<-" });
183
126
 
184
- expect(() => getHandler()!(ctx, deps)).toThrow(
127
+ expect(() => getHandler()!(ctx)).toThrow(
185
128
  "Compound assignment operators not supported for bit field access",
186
129
  );
187
130
  });
188
131
 
189
132
  it("handles scoped register prefix correctly", () => {
190
- const deps = createMockDeps({
133
+ HandlerTestUtils.setupMockGenerator({
191
134
  generateExpression: vi.fn().mockReturnValue("5"),
192
- isKnownScope: vi.fn().mockReturnValue(true),
135
+ });
136
+ HandlerTestUtils.setupMockSymbols({
137
+ knownScopes: new Set(["Motor"]),
193
138
  });
194
139
  const ctx = createMockContext({
195
140
  identifiers: ["Motor", "GPIO7", "DR_SET"],
196
141
  });
197
142
 
198
- const result = getHandler()!(ctx, deps);
143
+ const result = getHandler()!(ctx);
199
144
 
200
145
  expect(result).toContain("Motor_GPIO7_DR_SET");
201
146
  });
@@ -208,7 +153,7 @@ describe("RegisterHandlers", () => {
208
153
  )?.[1];
209
154
 
210
155
  it("generates read-modify-write for bit range", () => {
211
- const deps = createMockDeps({
156
+ HandlerTestUtils.setupMockGenerator({
212
157
  generateExpression: vi
213
158
  .fn()
214
159
  .mockReturnValueOnce("0")
@@ -219,7 +164,7 @@ describe("RegisterHandlers", () => {
219
164
  generatedValue: "value",
220
165
  });
221
166
 
222
- const result = getHandler()!(ctx, deps);
167
+ const result = getHandler()!(ctx);
223
168
 
224
169
  expect(result).toContain("GPIO7_DR_SET");
225
170
  expect(result).toContain("& ~(");
@@ -227,28 +172,21 @@ describe("RegisterHandlers", () => {
227
172
  });
228
173
 
229
174
  it("generates simple write for write-only bit range", () => {
230
- const registerMemberAccess = new Map([["GPIO7_DR_SET", "wo"]]);
231
- const deps = createMockDeps({
175
+ HandlerTestUtils.setupMockGenerator({
232
176
  generateExpression: vi
233
177
  .fn()
234
178
  .mockReturnValueOnce("0")
235
179
  .mockReturnValueOnce("8"),
236
- symbols: {
237
- structFields: new Map(),
238
- structFieldDimensions: new Map(),
239
- bitmapFields: new Map(),
240
- registerMemberAccess,
241
- registerBaseAddresses: new Map(),
242
- registerMemberOffsets: new Map(),
243
- registerMemberTypes: new Map(),
244
- },
180
+ });
181
+ HandlerTestUtils.setupMockSymbols({
182
+ registerMemberAccess: new Map([["GPIO7_DR_SET", "wo"]]),
245
183
  });
246
184
  const ctx = createMockContext({
247
185
  subscripts: [{ mockValue: "0" } as never, { mockValue: "8" } as never],
248
186
  generatedValue: "value",
249
187
  });
250
188
 
251
- const result = getHandler()!(ctx, deps);
189
+ const result = getHandler()!(ctx);
252
190
 
253
191
  expect(result).toContain("GPIO7_DR_SET =");
254
192
  expect(result).toContain("value");
@@ -256,38 +194,27 @@ describe("RegisterHandlers", () => {
256
194
  });
257
195
 
258
196
  it("throws on write-only bit range with 0 value", () => {
259
- const registerMemberAccess = new Map([["GPIO7_DR_SET", "w1c"]]);
260
- const deps = createMockDeps({
197
+ HandlerTestUtils.setupMockGenerator({
261
198
  generateExpression: vi
262
199
  .fn()
263
200
  .mockReturnValueOnce("0")
264
201
  .mockReturnValueOnce("8"),
265
- symbols: {
266
- structFields: new Map(),
267
- structFieldDimensions: new Map(),
268
- bitmapFields: new Map(),
269
- registerMemberAccess,
270
- registerBaseAddresses: new Map(),
271
- registerMemberOffsets: new Map(),
272
- registerMemberTypes: new Map(),
273
- },
202
+ });
203
+ HandlerTestUtils.setupMockSymbols({
204
+ registerMemberAccess: new Map([["GPIO7_DR_SET", "w1c"]]),
274
205
  });
275
206
  const ctx = createMockContext({
276
207
  subscripts: [{ mockValue: "0" } as never, { mockValue: "8" } as never],
277
208
  generatedValue: "0",
278
209
  });
279
210
 
280
- expect(() => getHandler()!(ctx, deps)).toThrow(
211
+ expect(() => getHandler()!(ctx)).toThrow(
281
212
  "Cannot assign 0 to write-only register bits",
282
213
  );
283
214
  });
284
215
 
285
216
  it("generates MMIO optimization for byte-aligned access", () => {
286
- const registerMemberAccess = new Map([["GPIO7_DR_SET", "wo"]]);
287
- const registerBaseAddresses = new Map([["GPIO7", "0x40000000"]]);
288
- const registerMemberOffsets = new Map([["GPIO7_DR_SET", "0x04"]]);
289
-
290
- const deps = createMockDeps({
217
+ HandlerTestUtils.setupMockGenerator({
291
218
  generateExpression: vi
292
219
  .fn()
293
220
  .mockReturnValueOnce("0")
@@ -296,22 +223,18 @@ describe("RegisterHandlers", () => {
296
223
  .fn()
297
224
  .mockReturnValueOnce(0)
298
225
  .mockReturnValueOnce(8),
299
- symbols: {
300
- structFields: new Map(),
301
- structFieldDimensions: new Map(),
302
- bitmapFields: new Map(),
303
- registerMemberAccess,
304
- registerBaseAddresses,
305
- registerMemberOffsets,
306
- registerMemberTypes: new Map(),
307
- },
226
+ });
227
+ HandlerTestUtils.setupMockSymbols({
228
+ registerMemberAccess: new Map([["GPIO7_DR_SET", "wo"]]),
229
+ registerBaseAddresses: new Map([["GPIO7", "0x40000000"]]),
230
+ registerMemberOffsets: new Map([["GPIO7_DR_SET", "0x04"]]),
308
231
  });
309
232
  const ctx = createMockContext({
310
233
  subscripts: [{ mockValue: "0" } as never, { mockValue: "8" } as never],
311
234
  generatedValue: "value",
312
235
  });
313
236
 
314
- const result = getHandler()!(ctx, deps);
237
+ const result = getHandler()!(ctx);
315
238
 
316
239
  expect(result).toContain("volatile uint8_t*");
317
240
  expect(result).toContain("0x40000000");
@@ -319,11 +242,7 @@ describe("RegisterHandlers", () => {
319
242
  });
320
243
 
321
244
  it("generates MMIO with byte offset for non-zero start", () => {
322
- const registerMemberAccess = new Map([["GPIO7_DR_SET", "wo"]]);
323
- const registerBaseAddresses = new Map([["GPIO7", "0x40000000"]]);
324
- const registerMemberOffsets = new Map([["GPIO7_DR_SET", "0x04"]]);
325
-
326
- const deps = createMockDeps({
245
+ HandlerTestUtils.setupMockGenerator({
327
246
  generateExpression: vi
328
247
  .fn()
329
248
  .mockReturnValueOnce("8")
@@ -332,36 +251,31 @@ describe("RegisterHandlers", () => {
332
251
  .fn()
333
252
  .mockReturnValueOnce(8)
334
253
  .mockReturnValueOnce(16),
335
- symbols: {
336
- structFields: new Map(),
337
- structFieldDimensions: new Map(),
338
- bitmapFields: new Map(),
339
- registerMemberAccess,
340
- registerBaseAddresses,
341
- registerMemberOffsets,
342
- registerMemberTypes: new Map(),
343
- },
254
+ });
255
+ HandlerTestUtils.setupMockSymbols({
256
+ registerMemberAccess: new Map([["GPIO7_DR_SET", "wo"]]),
257
+ registerBaseAddresses: new Map([["GPIO7", "0x40000000"]]),
258
+ registerMemberOffsets: new Map([["GPIO7_DR_SET", "0x04"]]),
344
259
  });
345
260
  const ctx = createMockContext({
346
261
  subscripts: [{ mockValue: "8" } as never, { mockValue: "16" } as never],
347
262
  generatedValue: "value",
348
263
  });
349
264
 
350
- const result = getHandler()!(ctx, deps);
265
+ const result = getHandler()!(ctx);
351
266
 
352
267
  expect(result).toContain("volatile uint16_t*");
353
268
  expect(result).toContain("0x04 + 1");
354
269
  });
355
270
 
356
271
  it("throws on compound assignment", () => {
357
- const deps = createMockDeps();
358
272
  const ctx = createMockContext({
359
273
  isCompound: true,
360
274
  cnextOp: "+<-",
361
275
  subscripts: [{ mockValue: "0" } as never, { mockValue: "8" } as never],
362
276
  });
363
277
 
364
- expect(() => getHandler()!(ctx, deps)).toThrow(
278
+ expect(() => getHandler()!(ctx)).toThrow(
365
279
  "Compound assignment operators not supported for bit field access",
366
280
  );
367
281
  });
@@ -374,8 +288,8 @@ describe("RegisterHandlers", () => {
374
288
  )?.[1];
375
289
 
376
290
  it("generates read-modify-write for scoped register bit", () => {
377
- const deps = createMockDeps({
378
- currentScope: "Motor",
291
+ CodeGenState.currentScope = "Motor";
292
+ HandlerTestUtils.setupMockGenerator({
379
293
  generateExpression: vi.fn().mockReturnValue("LED_BIT"),
380
294
  });
381
295
  const ctx = createMockContext({
@@ -383,69 +297,55 @@ describe("RegisterHandlers", () => {
383
297
  hasThis: true,
384
298
  });
385
299
 
386
- const result = getHandler()!(ctx, deps);
300
+ const result = getHandler()!(ctx);
387
301
 
388
302
  expect(result).toContain("Motor_GPIO7_DR_SET");
389
303
  expect(result).toContain("& ~(1 <<");
390
304
  });
391
305
 
392
306
  it("generates simple write for write-only scoped register", () => {
393
- const registerMemberAccess = new Map([["Motor_GPIO7_DR_SET", "wo"]]);
394
- const deps = createMockDeps({
395
- currentScope: "Motor",
307
+ CodeGenState.currentScope = "Motor";
308
+ HandlerTestUtils.setupMockGenerator({
396
309
  generateExpression: vi.fn().mockReturnValue("LED_BIT"),
397
- symbols: {
398
- structFields: new Map(),
399
- structFieldDimensions: new Map(),
400
- bitmapFields: new Map(),
401
- registerMemberAccess,
402
- registerBaseAddresses: new Map(),
403
- registerMemberOffsets: new Map(),
404
- registerMemberTypes: new Map(),
405
- },
310
+ });
311
+ HandlerTestUtils.setupMockSymbols({
312
+ registerMemberAccess: new Map([["Motor_GPIO7_DR_SET", "wo"]]),
406
313
  });
407
314
  const ctx = createMockContext({
408
315
  identifiers: ["GPIO7", "DR_SET"],
409
316
  hasThis: true,
410
317
  });
411
318
 
412
- const result = getHandler()!(ctx, deps);
319
+ const result = getHandler()!(ctx);
413
320
 
414
321
  expect(result).toBe("Motor_GPIO7_DR_SET = (1 << LED_BIT);");
415
322
  });
416
323
 
417
324
  it("throws when used outside scope", () => {
418
- const deps = createMockDeps({ currentScope: null });
325
+ CodeGenState.currentScope = null;
419
326
  const ctx = createMockContext({ hasThis: true });
420
327
 
421
- expect(() => getHandler()!(ctx, deps)).toThrow(
328
+ expect(() => getHandler()!(ctx)).toThrow(
422
329
  "'this' can only be used inside a scope",
423
330
  );
424
331
  });
425
332
 
426
333
  it("throws on compound assignment", () => {
427
- const deps = createMockDeps({ currentScope: "Motor" });
334
+ CodeGenState.currentScope = "Motor";
428
335
  const ctx = createMockContext({ isCompound: true, cnextOp: "+<-" });
429
336
 
430
- expect(() => getHandler()!(ctx, deps)).toThrow(
337
+ expect(() => getHandler()!(ctx)).toThrow(
431
338
  "Compound assignment operators not supported for bit field access",
432
339
  );
433
340
  });
434
341
 
435
342
  it("throws on write-only register with false value", () => {
436
- const registerMemberAccess = new Map([["Motor_GPIO7_DR_SET", "w1s"]]);
437
- const deps = createMockDeps({
438
- currentScope: "Motor",
343
+ CodeGenState.currentScope = "Motor";
344
+ HandlerTestUtils.setupMockGenerator({
439
345
  generateExpression: vi.fn().mockReturnValue("LED_BIT"),
440
- symbols: {
441
- structFields: new Map(),
442
- structFieldDimensions: new Map(),
443
- bitmapFields: new Map(),
444
- registerMemberAccess,
445
- registerBaseAddresses: new Map(),
446
- registerMemberOffsets: new Map(),
447
- registerMemberTypes: new Map(),
448
- },
346
+ });
347
+ HandlerTestUtils.setupMockSymbols({
348
+ registerMemberAccess: new Map([["Motor_GPIO7_DR_SET", "w1s"]]),
449
349
  });
450
350
  const ctx = createMockContext({
451
351
  identifiers: ["GPIO7", "DR_SET"],
@@ -453,7 +353,7 @@ describe("RegisterHandlers", () => {
453
353
  generatedValue: "false",
454
354
  });
455
355
 
456
- expect(() => getHandler()!(ctx, deps)).toThrow(
356
+ expect(() => getHandler()!(ctx)).toThrow(
457
357
  "Cannot assign false to write-only register bit",
458
358
  );
459
359
  });
@@ -466,8 +366,8 @@ describe("RegisterHandlers", () => {
466
366
  )?.[1];
467
367
 
468
368
  it("generates read-modify-write for scoped register bit range", () => {
469
- const deps = createMockDeps({
470
- currentScope: "Motor",
369
+ CodeGenState.currentScope = "Motor";
370
+ HandlerTestUtils.setupMockGenerator({
471
371
  generateExpression: vi
472
372
  .fn()
473
373
  .mockReturnValueOnce("6")
@@ -480,7 +380,7 @@ describe("RegisterHandlers", () => {
480
380
  generatedValue: "value",
481
381
  });
482
382
 
483
- const result = getHandler()!(ctx, deps);
383
+ const result = getHandler()!(ctx);
484
384
 
485
385
  expect(result).toContain("Motor_GPIO7_ICR1");
486
386
  expect(result).toContain("& ~(");
@@ -488,22 +388,15 @@ describe("RegisterHandlers", () => {
488
388
  });
489
389
 
490
390
  it("generates simple write for write-only scoped register bit range", () => {
491
- const registerMemberAccess = new Map([["Motor_GPIO7_ICR1", "wo"]]);
492
- const deps = createMockDeps({
493
- currentScope: "Motor",
391
+ CodeGenState.currentScope = "Motor";
392
+ HandlerTestUtils.setupMockGenerator({
494
393
  generateExpression: vi
495
394
  .fn()
496
395
  .mockReturnValueOnce("6")
497
396
  .mockReturnValueOnce("2"),
498
- symbols: {
499
- structFields: new Map(),
500
- structFieldDimensions: new Map(),
501
- bitmapFields: new Map(),
502
- registerMemberAccess,
503
- registerBaseAddresses: new Map(),
504
- registerMemberOffsets: new Map(),
505
- registerMemberTypes: new Map(),
506
- },
397
+ });
398
+ HandlerTestUtils.setupMockSymbols({
399
+ registerMemberAccess: new Map([["Motor_GPIO7_ICR1", "wo"]]),
507
400
  });
508
401
  const ctx = createMockContext({
509
402
  identifiers: ["GPIO7", "ICR1"],
@@ -512,19 +405,15 @@ describe("RegisterHandlers", () => {
512
405
  generatedValue: "value",
513
406
  });
514
407
 
515
- const result = getHandler()!(ctx, deps);
408
+ const result = getHandler()!(ctx);
516
409
 
517
410
  expect(result).toContain("Motor_GPIO7_ICR1 =");
518
411
  expect(result).not.toContain("& ~");
519
412
  });
520
413
 
521
414
  it("generates MMIO optimization for byte-aligned scoped access", () => {
522
- const registerMemberAccess = new Map([["Motor_GPIO7_ICR1", "wo"]]);
523
- const registerBaseAddresses = new Map([["Motor_GPIO7", "0x40000000"]]);
524
- const registerMemberOffsets = new Map([["Motor_GPIO7_ICR1", "0x08"]]);
525
-
526
- const deps = createMockDeps({
527
- currentScope: "Motor",
415
+ CodeGenState.currentScope = "Motor";
416
+ HandlerTestUtils.setupMockGenerator({
528
417
  generateExpression: vi
529
418
  .fn()
530
419
  .mockReturnValueOnce("0")
@@ -533,15 +422,11 @@ describe("RegisterHandlers", () => {
533
422
  .fn()
534
423
  .mockReturnValueOnce(0)
535
424
  .mockReturnValueOnce(32),
536
- symbols: {
537
- structFields: new Map(),
538
- structFieldDimensions: new Map(),
539
- bitmapFields: new Map(),
540
- registerMemberAccess,
541
- registerBaseAddresses,
542
- registerMemberOffsets,
543
- registerMemberTypes: new Map(),
544
- },
425
+ });
426
+ HandlerTestUtils.setupMockSymbols({
427
+ registerMemberAccess: new Map([["Motor_GPIO7_ICR1", "wo"]]),
428
+ registerBaseAddresses: new Map([["Motor_GPIO7", "0x40000000"]]),
429
+ registerMemberOffsets: new Map([["Motor_GPIO7_ICR1", "0x08"]]),
545
430
  });
546
431
  const ctx = createMockContext({
547
432
  identifiers: ["GPIO7", "ICR1"],
@@ -550,54 +435,47 @@ describe("RegisterHandlers", () => {
550
435
  generatedValue: "value",
551
436
  });
552
437
 
553
- const result = getHandler()!(ctx, deps);
438
+ const result = getHandler()!(ctx);
554
439
 
555
440
  expect(result).toContain("volatile uint32_t*");
556
441
  expect(result).toContain("0x40000000");
557
442
  });
558
443
 
559
444
  it("throws when used outside scope", () => {
560
- const deps = createMockDeps({ currentScope: null });
445
+ CodeGenState.currentScope = null;
561
446
  const ctx = createMockContext({
562
447
  subscripts: [{ mockValue: "6" } as never, { mockValue: "2" } as never],
563
448
  hasThis: true,
564
449
  });
565
450
 
566
- expect(() => getHandler()!(ctx, deps)).toThrow(
451
+ expect(() => getHandler()!(ctx)).toThrow(
567
452
  "'this' can only be used inside a scope",
568
453
  );
569
454
  });
570
455
 
571
456
  it("throws on compound assignment", () => {
572
- const deps = createMockDeps({ currentScope: "Motor" });
457
+ CodeGenState.currentScope = "Motor";
573
458
  const ctx = createMockContext({
574
459
  isCompound: true,
575
460
  cnextOp: "+<-",
576
461
  subscripts: [{ mockValue: "6" } as never, { mockValue: "2" } as never],
577
462
  });
578
463
 
579
- expect(() => getHandler()!(ctx, deps)).toThrow(
464
+ expect(() => getHandler()!(ctx)).toThrow(
580
465
  "Compound assignment operators not supported for bit field access",
581
466
  );
582
467
  });
583
468
 
584
469
  it("throws on write-only bit range with 0 value", () => {
585
- const registerMemberAccess = new Map([["Motor_GPIO7_ICR1", "w1c"]]);
586
- const deps = createMockDeps({
587
- currentScope: "Motor",
470
+ CodeGenState.currentScope = "Motor";
471
+ HandlerTestUtils.setupMockGenerator({
588
472
  generateExpression: vi
589
473
  .fn()
590
474
  .mockReturnValueOnce("6")
591
475
  .mockReturnValueOnce("2"),
592
- symbols: {
593
- structFields: new Map(),
594
- structFieldDimensions: new Map(),
595
- bitmapFields: new Map(),
596
- registerMemberAccess,
597
- registerBaseAddresses: new Map(),
598
- registerMemberOffsets: new Map(),
599
- registerMemberTypes: new Map(),
600
- },
476
+ });
477
+ HandlerTestUtils.setupMockSymbols({
478
+ registerMemberAccess: new Map([["Motor_GPIO7_ICR1", "w1c"]]),
601
479
  });
602
480
  const ctx = createMockContext({
603
481
  identifiers: ["GPIO7", "ICR1"],
@@ -606,7 +484,7 @@ describe("RegisterHandlers", () => {
606
484
  generatedValue: "0",
607
485
  });
608
486
 
609
- expect(() => getHandler()!(ctx, deps)).toThrow(
487
+ expect(() => getHandler()!(ctx)).toThrow(
610
488
  "Cannot assign 0 to write-only register bits",
611
489
  );
612
490
  });