c-next 0.1.68 → 0.1.70

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 (62) hide show
  1. package/package.json +1 -1
  2. package/src/transpiler/logic/analysis/FunctionCallAnalyzer.ts +240 -204
  3. package/src/transpiler/logic/analysis/PassByValueAnalyzer.ts +693 -0
  4. package/src/transpiler/logic/analysis/__tests__/FunctionCallAnalyzer.test.ts +86 -5
  5. package/src/transpiler/{output/codegen → logic/analysis}/helpers/AssignmentTargetExtractor.ts +1 -1
  6. package/src/transpiler/{output/codegen → logic/analysis}/helpers/ChildStatementCollector.ts +1 -1
  7. package/src/transpiler/{output/codegen → logic/analysis}/helpers/StatementExpressionCollector.ts +1 -1
  8. package/src/transpiler/{output/codegen → logic/analysis}/helpers/__tests__/AssignmentTargetExtractor.test.ts +2 -2
  9. package/src/transpiler/{output/codegen → logic/analysis}/helpers/__tests__/ChildStatementCollector.test.ts +2 -2
  10. package/src/transpiler/{output/codegen → logic/analysis}/helpers/__tests__/StatementExpressionCollector.test.ts +2 -2
  11. package/src/transpiler/output/codegen/CodeGenerator.ts +160 -742
  12. package/src/transpiler/output/codegen/TypeRegistrationUtils.ts +4 -6
  13. package/src/transpiler/output/codegen/TypeResolver.ts +2 -2
  14. package/src/transpiler/output/codegen/TypeValidator.ts +7 -7
  15. package/src/transpiler/output/codegen/__tests__/CodeGenerator.coverage.test.ts +2 -2
  16. package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +29 -1
  17. package/src/transpiler/output/codegen/__tests__/TypeRegistrationUtils.test.ts +36 -51
  18. package/src/transpiler/output/codegen/__tests__/TypeResolver.test.ts +20 -17
  19. package/src/transpiler/output/codegen/__tests__/TypeValidator.resolution.test.ts +4 -6
  20. package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +4 -2
  21. package/src/transpiler/output/codegen/analysis/MemberChainAnalyzer.ts +1 -1
  22. package/src/transpiler/output/codegen/analysis/StringLengthCounter.ts +1 -1
  23. package/src/transpiler/output/codegen/analysis/__tests__/MemberChainAnalyzer.test.ts +9 -9
  24. package/src/transpiler/output/codegen/analysis/__tests__/StringLengthCounter.test.ts +12 -12
  25. package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +11 -11
  26. package/src/transpiler/output/codegen/assignment/AssignmentContextBuilder.ts +49 -0
  27. package/src/transpiler/output/codegen/assignment/IAssignmentContext.ts +15 -0
  28. package/src/transpiler/output/codegen/assignment/__tests__/AssignmentClassifier.test.ts +30 -17
  29. package/src/transpiler/output/codegen/assignment/handlers/ArrayHandlers.ts +25 -18
  30. package/src/transpiler/output/codegen/assignment/handlers/BitAccessHandlers.ts +19 -8
  31. package/src/transpiler/output/codegen/assignment/handlers/BitmapHandlers.ts +3 -3
  32. package/src/transpiler/output/codegen/assignment/handlers/SpecialHandlers.ts +4 -4
  33. package/src/transpiler/output/codegen/assignment/handlers/StringHandlers.ts +5 -5
  34. package/src/transpiler/output/codegen/assignment/handlers/__tests__/AccessPatternHandlers.test.ts +9 -1
  35. package/src/transpiler/output/codegen/assignment/handlers/__tests__/ArrayHandlers.test.ts +41 -26
  36. package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitAccessHandlers.test.ts +29 -37
  37. package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitmapHandlers.test.ts +27 -19
  38. package/src/transpiler/output/codegen/assignment/handlers/__tests__/RegisterHandlers.test.ts +10 -1
  39. package/src/transpiler/output/codegen/assignment/handlers/__tests__/SpecialHandlers.test.ts +51 -33
  40. package/src/transpiler/output/codegen/assignment/handlers/__tests__/StringHandlers.test.ts +9 -1
  41. package/src/transpiler/output/codegen/assignment/handlers/__tests__/handlerTestUtils.ts +5 -4
  42. package/src/transpiler/output/codegen/generators/expressions/CallExprGenerator.ts +14 -6
  43. package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +19 -16
  44. package/src/transpiler/output/codegen/generators/expressions/__tests__/CallExprGenerator.test.ts +21 -4
  45. package/src/transpiler/output/codegen/generators/expressions/__tests__/PostfixExpressionGenerator.test.ts +15 -2
  46. package/src/transpiler/output/codegen/helpers/ArrayInitHelper.ts +2 -1
  47. package/src/transpiler/output/codegen/helpers/AssignmentExpectedTypeResolver.ts +2 -2
  48. package/src/transpiler/output/codegen/helpers/AssignmentValidator.ts +3 -3
  49. package/src/transpiler/output/codegen/helpers/EnumAssignmentValidator.ts +1 -1
  50. package/src/transpiler/output/codegen/helpers/MemberSeparatorResolver.ts +6 -1
  51. package/src/transpiler/output/codegen/helpers/StringDeclHelper.ts +2 -2
  52. package/src/transpiler/output/codegen/helpers/__tests__/ArrayInitHelper.test.ts +1 -1
  53. package/src/transpiler/output/codegen/helpers/__tests__/AssignmentExpectedTypeResolver.test.ts +7 -7
  54. package/src/transpiler/output/codegen/helpers/__tests__/AssignmentValidator.test.ts +7 -7
  55. package/src/transpiler/output/codegen/helpers/__tests__/EnumAssignmentValidator.test.ts +2 -2
  56. package/src/transpiler/output/codegen/helpers/__tests__/StringDeclHelper.test.ts +4 -4
  57. package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +2 -2
  58. package/src/transpiler/output/codegen/resolution/__tests__/EnumTypeResolver.test.ts +5 -5
  59. package/src/transpiler/state/CodeGenState.ts +157 -5
  60. package/src/transpiler/state/__tests__/CodeGenState.test.ts +274 -6
  61. /package/src/transpiler/{output/codegen → logic/analysis}/helpers/TransitiveModificationPropagator.ts +0 -0
  62. /package/src/transpiler/{output/codegen → logic/analysis}/helpers/__tests__/TransitiveModificationPropagator.test.ts +0 -0
@@ -33,13 +33,16 @@ function validateNotCompound(ctx: IAssignmentContext): void {
33
33
  /**
34
34
  * Handle single bit on integer variable: flags[3] <- true
35
35
  * Also handles float bit indexing: f32Var[3] <- true
36
+ * Uses resolvedBaseIdentifier for proper scope prefix support.
36
37
  */
37
38
  function handleIntegerBit(ctx: IAssignmentContext): string {
38
39
  validateNotCompound(ctx);
39
40
 
40
- const name = ctx.identifiers[0];
41
+ // Use resolvedBaseIdentifier for type lookup and code generation
42
+ // e.g., "ArrayBug_flags" instead of "flags"
43
+ const name = ctx.resolvedBaseIdentifier;
41
44
  const bitIndex = gen().generateExpression(ctx.subscripts[0]);
42
- const typeInfo = CodeGenState.typeRegistry.get(name);
45
+ const typeInfo = CodeGenState.getVariableTypeInfo(name);
43
46
 
44
47
  // Check for float bit indexing
45
48
  if (typeInfo) {
@@ -67,14 +70,16 @@ function handleIntegerBit(ctx: IAssignmentContext): string {
67
70
  /**
68
71
  * Handle bit range on integer variable: flags[0, 3] <- 5
69
72
  * Also handles float bit range: f32Var[0, 8] <- 0xFF
73
+ * Uses resolvedBaseIdentifier for proper scope prefix support.
70
74
  */
71
75
  function handleIntegerBitRange(ctx: IAssignmentContext): string {
72
76
  validateNotCompound(ctx);
73
77
 
74
- const name = ctx.identifiers[0];
78
+ // Use resolvedBaseIdentifier for type lookup and code generation
79
+ const name = ctx.resolvedBaseIdentifier;
75
80
  const start = gen().generateExpression(ctx.subscripts[0]);
76
81
  const width = gen().generateExpression(ctx.subscripts[1]);
77
- const typeInfo = CodeGenState.typeRegistry.get(name);
82
+ const typeInfo = CodeGenState.getVariableTypeInfo(name);
78
83
 
79
84
  // Check for float bit indexing
80
85
  if (typeInfo) {
@@ -126,15 +131,19 @@ function handleStructMemberBit(ctx: IAssignmentContext): string {
126
131
 
127
132
  /**
128
133
  * Handle bit on multi-dimensional array element: matrix[i][j][FIELD_BIT] <- false
134
+ * Uses resolvedBaseIdentifier for proper scope prefix support.
129
135
  */
130
136
  function handleArrayElementBit(ctx: IAssignmentContext): string {
131
137
  validateNotCompound(ctx);
132
138
 
133
- const arrayName = ctx.identifiers[0];
134
- const typeInfo = CodeGenState.typeRegistry.get(arrayName);
139
+ // Use resolvedBaseIdentifier for type lookup and code generation
140
+ const arrayName = ctx.resolvedBaseIdentifier;
141
+ const typeInfo = CodeGenState.getVariableTypeInfo(arrayName);
135
142
 
136
143
  if (!typeInfo?.arrayDimensions) {
137
- throw new Error(`Error: ${arrayName} is not an array`);
144
+ // Use raw identifier in error message for clarity
145
+ const rawName = ctx.identifiers[0];
146
+ throw new Error(`Error: ${rawName} is not an array`);
138
147
  }
139
148
 
140
149
  const numDims = typeInfo.arrayDimensions.length;
@@ -160,12 +169,14 @@ function handleArrayElementBit(ctx: IAssignmentContext): string {
160
169
  *
161
170
  * The target is a chain like array[idx].member or struct.field with a
162
171
  * bit range subscript [start, width] at the end.
172
+ * Uses resolvedBaseIdentifier for proper scope prefix support.
163
173
  */
164
174
  function handleStructChainBitRange(ctx: IAssignmentContext): string {
165
175
  validateNotCompound(ctx);
166
176
 
167
177
  // Build the base target from postfixOps, excluding the last one (the bit range)
168
- const baseId = ctx.identifiers[0];
178
+ // Use resolvedBaseIdentifier for the base to include scope prefix
179
+ const baseId = ctx.resolvedBaseIdentifier;
169
180
  const opsBeforeLast = ctx.postfixOps.slice(0, -1);
170
181
 
171
182
  let baseTarget = baseId;
@@ -109,7 +109,7 @@ function generateWriteOnlyBitmapWrite(
109
109
  function handleBitmapFieldSingleBit(ctx: IAssignmentContext): string {
110
110
  const varName = ctx.identifiers[0];
111
111
  const fieldName = ctx.identifiers[1];
112
- const typeInfo = CodeGenState.typeRegistry.get(varName);
112
+ const typeInfo = CodeGenState.getVariableTypeInfo(varName);
113
113
  const bitmapType = typeInfo!.bitmapTypeName!;
114
114
 
115
115
  const fieldInfo = getBitmapFieldInfo(bitmapType, fieldName, ctx);
@@ -130,7 +130,7 @@ function handleBitmapFieldMultiBit(ctx: IAssignmentContext): string {
130
130
  function handleBitmapArrayElementField(ctx: IAssignmentContext): string {
131
131
  const arrayName = ctx.identifiers[0];
132
132
  const fieldName = ctx.identifiers[1];
133
- const typeInfo = CodeGenState.typeRegistry.get(arrayName);
133
+ const typeInfo = CodeGenState.getVariableTypeInfo(arrayName);
134
134
  const bitmapType = typeInfo!.bitmapTypeName!;
135
135
 
136
136
  const fieldInfo = getBitmapFieldInfo(bitmapType, fieldName, ctx);
@@ -148,7 +148,7 @@ function handleStructMemberBitmapField(ctx: IAssignmentContext): string {
148
148
  const memberName = ctx.identifiers[1];
149
149
  const fieldName = ctx.identifiers[2];
150
150
 
151
- const structTypeInfo = CodeGenState.typeRegistry.get(structName);
151
+ const structTypeInfo = CodeGenState.getVariableTypeInfo(structName);
152
152
  const memberInfo = CodeGenState.getMemberTypeInfo(
153
153
  structTypeInfo!.baseType,
154
154
  memberName,
@@ -36,22 +36,22 @@ function getTargetTypeInfo(ctx: IAssignmentContext): {
36
36
 
37
37
  // Simple identifier
38
38
  if (ctx.isSimpleIdentifier) {
39
- return { typeInfo: CodeGenState.typeRegistry.get(id) };
39
+ return { typeInfo: CodeGenState.getVariableTypeInfo(id) };
40
40
  }
41
41
 
42
42
  // this.member: lookup using scoped name
43
43
  if (ctx.isSimpleThisAccess && CodeGenState.currentScope) {
44
44
  const scopedName = `${CodeGenState.currentScope}_${id}`;
45
- return { typeInfo: CodeGenState.typeRegistry.get(scopedName) };
45
+ return { typeInfo: CodeGenState.getVariableTypeInfo(scopedName) };
46
46
  }
47
47
 
48
48
  // global.member: lookup using direct name
49
49
  if (ctx.isSimpleGlobalAccess) {
50
- return { typeInfo: CodeGenState.typeRegistry.get(id) };
50
+ return { typeInfo: CodeGenState.getVariableTypeInfo(id) };
51
51
  }
52
52
 
53
53
  // Fallback to direct lookup
54
- return { typeInfo: CodeGenState.typeRegistry.get(id) };
54
+ return { typeInfo: CodeGenState.getVariableTypeInfo(id) };
55
55
  }
56
56
 
57
57
  /**
@@ -42,7 +42,7 @@ function handleSimpleStringAssignment(ctx: IAssignmentContext): string {
42
42
  validateNotCompound(ctx);
43
43
 
44
44
  const id = ctx.identifiers[0];
45
- const typeInfo = CodeGenState.typeRegistry.get(id);
45
+ const typeInfo = CodeGenState.getVariableTypeInfo(id);
46
46
  const capacity = typeInfo!.stringCapacity!;
47
47
 
48
48
  CodeGenState.needsString = true;
@@ -57,7 +57,7 @@ function handleSimpleStringAssignment(ctx: IAssignmentContext): string {
57
57
  * Shared helper for struct field string handlers.
58
58
  */
59
59
  function getStructFieldType(structName: string, fieldName: string): string {
60
- const structTypeInfo = CodeGenState.typeRegistry.get(structName);
60
+ const structTypeInfo = CodeGenState.getVariableTypeInfo(structName);
61
61
  const structType = structTypeInfo!.baseType;
62
62
  const structFields = CodeGenState.symbols!.structFields.get(structType);
63
63
  return structFields!.get(fieldName)!;
@@ -69,7 +69,7 @@ function getStructFieldType(structName: string, fieldName: string): string {
69
69
  * Shared helper for struct field handlers.
70
70
  */
71
71
  function getStructType(structName: string): string {
72
- const structTypeInfo = CodeGenState.typeRegistry.get(structName);
72
+ const structTypeInfo = CodeGenState.getVariableTypeInfo(structName);
73
73
  return structTypeInfo!.baseType;
74
74
  }
75
75
 
@@ -85,7 +85,7 @@ function handleStringThisMember(ctx: IAssignmentContext): string {
85
85
 
86
86
  const memberName = ctx.identifiers[0];
87
87
  const scopedName = `${CodeGenState.currentScope}_${memberName}`;
88
- const typeInfo = CodeGenState.typeRegistry.get(scopedName);
88
+ const typeInfo = CodeGenState.getVariableTypeInfo(scopedName);
89
89
  const capacity = typeInfo!.stringCapacity!;
90
90
 
91
91
  CodeGenState.needsString = true;
@@ -123,7 +123,7 @@ function handleStringArrayElement(ctx: IAssignmentContext): string {
123
123
  validateNotCompound(ctx);
124
124
 
125
125
  const name = ctx.identifiers[0];
126
- const typeInfo = CodeGenState.typeRegistry.get(name);
126
+ const typeInfo = CodeGenState.getVariableTypeInfo(name);
127
127
  const capacity = typeInfo!.stringCapacity!;
128
128
 
129
129
  CodeGenState.needsString = true;
@@ -16,8 +16,14 @@ import HandlerTestUtils from "./handlerTestUtils";
16
16
  function createMockContext(
17
17
  overrides: Partial<IAssignmentContext> = {},
18
18
  ): IAssignmentContext {
19
+ // Default resolved values based on first identifier
20
+ const identifiers = overrides.identifiers ?? ["Counter", "value"];
21
+ const resolvedTarget = overrides.resolvedTarget ?? `${identifiers.join("_")}`;
22
+ const resolvedBaseIdentifier =
23
+ overrides.resolvedBaseIdentifier ?? identifiers[0];
24
+
19
25
  return {
20
- identifiers: ["Counter", "value"],
26
+ identifiers,
21
27
  subscripts: [],
22
28
  isCompound: false,
23
29
  cnextOp: "<-",
@@ -34,6 +40,8 @@ function createMockContext(
34
40
  isSimpleIdentifier: false,
35
41
  isSimpleThisAccess: false,
36
42
  isSimpleGlobalAccess: false,
43
+ resolvedTarget,
44
+ resolvedBaseIdentifier,
37
45
  ...overrides,
38
46
  } as IAssignmentContext;
39
47
  }
@@ -28,8 +28,14 @@ import HandlerTestUtils from "./handlerTestUtils";
28
28
  function createMockContext(
29
29
  overrides: Partial<IAssignmentContext> = {},
30
30
  ): IAssignmentContext {
31
+ // Default resolved values based on first identifier
32
+ const identifiers = overrides.identifiers ?? ["arr"];
33
+ const resolvedTarget = overrides.resolvedTarget ?? `${identifiers[0]}[i]`;
34
+ const resolvedBaseIdentifier =
35
+ overrides.resolvedBaseIdentifier ?? identifiers[0];
36
+
31
37
  return {
32
- identifiers: ["arr"],
38
+ identifiers,
33
39
  subscripts: [{ mockValue: "i", start: { line: 1 } } as never],
34
40
  isCompound: false,
35
41
  cnextOp: "<-",
@@ -46,6 +52,8 @@ function createMockContext(
46
52
  isSimpleIdentifier: false,
47
53
  isSimpleThisAccess: false,
48
54
  isSimpleGlobalAccess: false,
55
+ resolvedTarget,
56
+ resolvedBaseIdentifier,
49
57
  ...overrides,
50
58
  } as IAssignmentContext;
51
59
  }
@@ -96,6 +104,7 @@ describe("ArrayHandlers", () => {
96
104
  isCompound: true,
97
105
  cnextOp: "+<-",
98
106
  cOp: "+=",
107
+ resolvedTarget: "arr[0]",
99
108
  });
100
109
 
101
110
  const result = getHandler()!(ctx);
@@ -109,6 +118,8 @@ describe("ArrayHandlers", () => {
109
118
  });
110
119
  const ctx = createMockContext({
111
120
  identifiers: ["buffer"],
121
+ resolvedTarget: "buffer[idx]",
122
+ resolvedBaseIdentifier: "buffer",
112
123
  });
113
124
 
114
125
  const result = getHandler()!(ctx);
@@ -137,6 +148,8 @@ describe("ArrayHandlers", () => {
137
148
  { mockValue: "j", start: { line: 1 } } as never,
138
149
  ],
139
150
  subscriptDepth: 2,
151
+ resolvedTarget: "matrix[i][j]",
152
+ resolvedBaseIdentifier: "matrix",
140
153
  });
141
154
 
142
155
  const result = getHandler()!(ctx);
@@ -160,6 +173,8 @@ describe("ArrayHandlers", () => {
160
173
  { mockValue: "z", start: { line: 1 } } as never,
161
174
  ],
162
175
  subscriptDepth: 3,
176
+ resolvedTarget: "cube[x][y][z]",
177
+ resolvedBaseIdentifier: "cube",
163
178
  });
164
179
 
165
180
  const result = getHandler()!(ctx);
@@ -168,9 +183,9 @@ describe("ArrayHandlers", () => {
168
183
  });
169
184
 
170
185
  it("performs bounds checking when type info available", () => {
171
- CodeGenState.typeRegistry = new Map([
186
+ HandlerTestUtils.setupMockTypeRegistry([
172
187
  ["matrix", { arrayDimensions: [10, 10], baseType: "i32" }],
173
- ]) as any;
188
+ ]);
174
189
  mockCheckArrayBounds.mockClear();
175
190
  HandlerTestUtils.setupMockGenerator({
176
191
  generateExpression: vi
@@ -212,6 +227,8 @@ describe("ArrayHandlers", () => {
212
227
  ],
213
228
  isCompound: true,
214
229
  cOp: "-=",
230
+ resolvedTarget: "grid[0][1]",
231
+ resolvedBaseIdentifier: "grid",
215
232
  });
216
233
 
217
234
  const result = getHandler()!(ctx);
@@ -225,9 +242,9 @@ describe("ArrayHandlers", () => {
225
242
  arrayHandlers.find(([kind]) => kind === AssignmentKind.ARRAY_SLICE)?.[1];
226
243
 
227
244
  it("generates memcpy for valid slice assignment", () => {
228
- CodeGenState.typeRegistry = new Map([
245
+ HandlerTestUtils.setupMockTypeRegistry([
229
246
  ["buffer", { arrayDimensions: [100], baseType: "u8" }],
230
- ]) as any;
247
+ ]);
231
248
  HandlerTestUtils.setupMockGenerator({
232
249
  tryEvaluateConstant: vi
233
250
  .fn()
@@ -250,7 +267,7 @@ describe("ArrayHandlers", () => {
250
267
  });
251
268
 
252
269
  it("generates memcpy for string slice", () => {
253
- CodeGenState.typeRegistry = new Map([
270
+ HandlerTestUtils.setupMockTypeRegistry([
254
271
  [
255
272
  "str",
256
273
  {
@@ -260,7 +277,7 @@ describe("ArrayHandlers", () => {
260
277
  baseType: "string",
261
278
  },
262
279
  ],
263
- ]) as any;
280
+ ]);
264
281
  HandlerTestUtils.setupMockGenerator({
265
282
  tryEvaluateConstant: vi
266
283
  .fn()
@@ -282,9 +299,9 @@ describe("ArrayHandlers", () => {
282
299
  });
283
300
 
284
301
  it("throws on compound assignment", () => {
285
- CodeGenState.typeRegistry = new Map([
302
+ HandlerTestUtils.setupMockTypeRegistry([
286
303
  ["buffer", { arrayDimensions: [100], baseType: "u8" }],
287
- ]) as any;
304
+ ]);
288
305
  HandlerTestUtils.setupMockGenerator({
289
306
  tryEvaluateConstant: vi
290
307
  .fn()
@@ -306,9 +323,9 @@ describe("ArrayHandlers", () => {
306
323
  });
307
324
 
308
325
  it("throws on multi-dimensional array", () => {
309
- CodeGenState.typeRegistry = new Map([
326
+ HandlerTestUtils.setupMockTypeRegistry([
310
327
  ["matrix", { arrayDimensions: [10, 10], baseType: "u8" }],
311
- ]) as any;
328
+ ]);
312
329
  const ctx = createMockContext({
313
330
  identifiers: ["matrix"],
314
331
  subscripts: [
@@ -323,9 +340,9 @@ describe("ArrayHandlers", () => {
323
340
  });
324
341
 
325
342
  it("throws on non-constant offset", () => {
326
- CodeGenState.typeRegistry = new Map([
343
+ HandlerTestUtils.setupMockTypeRegistry([
327
344
  ["buffer", { arrayDimensions: [100], baseType: "u8" }],
328
- ]) as any;
345
+ ]);
329
346
  HandlerTestUtils.setupMockGenerator({
330
347
  tryEvaluateConstant: vi.fn().mockReturnValue(undefined),
331
348
  });
@@ -342,9 +359,9 @@ describe("ArrayHandlers", () => {
342
359
  });
343
360
 
344
361
  it("throws on non-constant length", () => {
345
- CodeGenState.typeRegistry = new Map([
362
+ HandlerTestUtils.setupMockTypeRegistry([
346
363
  ["buffer", { arrayDimensions: [100], baseType: "u8" }],
347
- ]) as any;
364
+ ]);
348
365
  HandlerTestUtils.setupMockGenerator({
349
366
  tryEvaluateConstant: vi
350
367
  .fn()
@@ -364,9 +381,9 @@ describe("ArrayHandlers", () => {
364
381
  });
365
382
 
366
383
  it("throws on out of bounds access", () => {
367
- CodeGenState.typeRegistry = new Map([
384
+ HandlerTestUtils.setupMockTypeRegistry([
368
385
  ["buffer", { arrayDimensions: [50], baseType: "u8" }],
369
- ]) as any;
386
+ ]);
370
387
  HandlerTestUtils.setupMockGenerator({
371
388
  tryEvaluateConstant: vi
372
389
  .fn()
@@ -387,9 +404,9 @@ describe("ArrayHandlers", () => {
387
404
  });
388
405
 
389
406
  it("throws on negative offset", () => {
390
- CodeGenState.typeRegistry = new Map([
407
+ HandlerTestUtils.setupMockTypeRegistry([
391
408
  ["buffer", { arrayDimensions: [100], baseType: "u8" }],
392
- ]) as any;
409
+ ]);
393
410
  HandlerTestUtils.setupMockGenerator({
394
411
  tryEvaluateConstant: vi
395
412
  .fn()
@@ -410,9 +427,9 @@ describe("ArrayHandlers", () => {
410
427
  });
411
428
 
412
429
  it("throws on zero length", () => {
413
- CodeGenState.typeRegistry = new Map([
430
+ HandlerTestUtils.setupMockTypeRegistry([
414
431
  ["buffer", { arrayDimensions: [100], baseType: "u8" }],
415
- ]) as any;
432
+ ]);
416
433
  HandlerTestUtils.setupMockGenerator({
417
434
  tryEvaluateConstant: vi
418
435
  .fn()
@@ -433,9 +450,9 @@ describe("ArrayHandlers", () => {
433
450
  });
434
451
 
435
452
  it("throws on negative length", () => {
436
- CodeGenState.typeRegistry = new Map([
453
+ HandlerTestUtils.setupMockTypeRegistry([
437
454
  ["buffer", { arrayDimensions: [100], baseType: "u8" }],
438
- ]) as any;
455
+ ]);
439
456
  HandlerTestUtils.setupMockGenerator({
440
457
  tryEvaluateConstant: vi
441
458
  .fn()
@@ -456,9 +473,7 @@ describe("ArrayHandlers", () => {
456
473
  });
457
474
 
458
475
  it("throws when buffer size cannot be determined", () => {
459
- CodeGenState.typeRegistry = new Map([
460
- ["unknown", { baseType: "u8" }],
461
- ]) as any;
476
+ HandlerTestUtils.setupMockTypeRegistry([["unknown", { baseType: "u8" }]]);
462
477
  HandlerTestUtils.setupMockGenerator({
463
478
  tryEvaluateConstant: vi
464
479
  .fn()
@@ -16,8 +16,14 @@ import HandlerTestUtils from "./handlerTestUtils";
16
16
  function createMockContext(
17
17
  overrides: Partial<IAssignmentContext> = {},
18
18
  ): IAssignmentContext {
19
+ // Default resolved values based on first identifier
20
+ const identifiers = overrides.identifiers ?? ["flags"];
21
+ const resolvedTarget = overrides.resolvedTarget ?? `${identifiers[0]}[3]`;
22
+ const resolvedBaseIdentifier =
23
+ overrides.resolvedBaseIdentifier ?? identifiers[0];
24
+
19
25
  return {
20
- identifiers: ["flags"],
26
+ identifiers,
21
27
  subscripts: [{ mockValue: "3" } as never],
22
28
  isCompound: false,
23
29
  cnextOp: "<-",
@@ -34,6 +40,8 @@ function createMockContext(
34
40
  isSimpleIdentifier: false,
35
41
  isSimpleThisAccess: false,
36
42
  isSimpleGlobalAccess: false,
43
+ resolvedTarget,
44
+ resolvedBaseIdentifier,
37
45
  ...overrides,
38
46
  } as IAssignmentContext;
39
47
  }
@@ -68,9 +76,7 @@ describe("BitAccessHandlers", () => {
68
76
  )?.[1];
69
77
 
70
78
  it("generates single bit read-modify-write", () => {
71
- CodeGenState.typeRegistry = new Map([
72
- ["flags", { baseType: "u32" }],
73
- ]) as any;
79
+ HandlerTestUtils.setupMockTypeRegistry([["flags", { baseType: "u32" }]]);
74
80
  HandlerTestUtils.setupMockGenerator({
75
81
  generateExpression: vi.fn().mockReturnValue("3"),
76
82
  });
@@ -84,9 +90,7 @@ describe("BitAccessHandlers", () => {
84
90
  });
85
91
 
86
92
  it("uses 1ULL for 64-bit types", () => {
87
- CodeGenState.typeRegistry = new Map([
88
- ["flags", { baseType: "u64" }],
89
- ]) as any;
93
+ HandlerTestUtils.setupMockTypeRegistry([["flags", { baseType: "u64" }]]);
90
94
  HandlerTestUtils.setupMockGenerator({
91
95
  generateExpression: vi.fn().mockReturnValue("32"),
92
96
  });
@@ -100,9 +104,7 @@ describe("BitAccessHandlers", () => {
100
104
  });
101
105
 
102
106
  it("uses 1ULL for signed 64-bit types", () => {
103
- CodeGenState.typeRegistry = new Map([
104
- ["flags", { baseType: "i64" }],
105
- ]) as any;
107
+ HandlerTestUtils.setupMockTypeRegistry([["flags", { baseType: "i64" }]]);
106
108
  HandlerTestUtils.setupMockGenerator({
107
109
  generateExpression: vi.fn().mockReturnValue("bit"),
108
110
  });
@@ -115,9 +117,7 @@ describe("BitAccessHandlers", () => {
115
117
  });
116
118
 
117
119
  it("converts true to 1", () => {
118
- CodeGenState.typeRegistry = new Map([
119
- ["flags", { baseType: "u8" }],
120
- ]) as any;
120
+ HandlerTestUtils.setupMockTypeRegistry([["flags", { baseType: "u8" }]]);
121
121
  HandlerTestUtils.setupMockGenerator({
122
122
  generateExpression: vi.fn().mockReturnValue("0"),
123
123
  });
@@ -131,9 +131,7 @@ describe("BitAccessHandlers", () => {
131
131
  });
132
132
 
133
133
  it("converts false to 0", () => {
134
- CodeGenState.typeRegistry = new Map([
135
- ["flags", { baseType: "u8" }],
136
- ]) as any;
134
+ HandlerTestUtils.setupMockTypeRegistry([["flags", { baseType: "u8" }]]);
137
135
  HandlerTestUtils.setupMockGenerator({
138
136
  generateExpression: vi.fn().mockReturnValue("0"),
139
137
  });
@@ -147,7 +145,7 @@ describe("BitAccessHandlers", () => {
147
145
  });
148
146
 
149
147
  it("delegates to float bit write for float types", () => {
150
- CodeGenState.typeRegistry = new Map([["f", { baseType: "f32" }]]) as any;
148
+ HandlerTestUtils.setupMockTypeRegistry([["f", { baseType: "f32" }]]);
151
149
  const generateFloatBitWrite = vi
152
150
  .fn()
153
151
  .mockReturnValue("float_bit_write_result");
@@ -184,9 +182,7 @@ describe("BitAccessHandlers", () => {
184
182
  )?.[1];
185
183
 
186
184
  it("generates bit range read-modify-write", () => {
187
- CodeGenState.typeRegistry = new Map([
188
- ["flags", { baseType: "u32" }],
189
- ]) as any;
185
+ HandlerTestUtils.setupMockTypeRegistry([["flags", { baseType: "u32" }]]);
190
186
  HandlerTestUtils.setupMockGenerator({
191
187
  generateExpression: vi
192
188
  .fn()
@@ -206,9 +202,7 @@ describe("BitAccessHandlers", () => {
206
202
  });
207
203
 
208
204
  it("uses correct mask for bit range", () => {
209
- CodeGenState.typeRegistry = new Map([
210
- ["data", { baseType: "u16" }],
211
- ]) as any;
205
+ HandlerTestUtils.setupMockTypeRegistry([["data", { baseType: "u16" }]]);
212
206
  HandlerTestUtils.setupMockGenerator({
213
207
  generateExpression: vi
214
208
  .fn()
@@ -229,9 +223,7 @@ describe("BitAccessHandlers", () => {
229
223
  });
230
224
 
231
225
  it("uses ULL suffix for 64-bit bit range mask", () => {
232
- CodeGenState.typeRegistry = new Map([
233
- ["flags", { baseType: "u64" }],
234
- ]) as any;
226
+ HandlerTestUtils.setupMockTypeRegistry([["flags", { baseType: "u64" }]]);
235
227
  HandlerTestUtils.setupMockGenerator({
236
228
  generateExpression: vi
237
229
  .fn()
@@ -253,7 +245,7 @@ describe("BitAccessHandlers", () => {
253
245
  });
254
246
 
255
247
  it("delegates to float bit write for float types", () => {
256
- CodeGenState.typeRegistry = new Map([["f", { baseType: "f32" }]]) as any;
248
+ HandlerTestUtils.setupMockTypeRegistry([["f", { baseType: "f32" }]]);
257
249
  const generateFloatBitWrite = vi
258
250
  .fn()
259
251
  .mockReturnValue("float_range_write_result");
@@ -336,9 +328,9 @@ describe("BitAccessHandlers", () => {
336
328
  )?.[1];
337
329
 
338
330
  it("generates array element bit assignment for 1D array", () => {
339
- CodeGenState.typeRegistry = new Map([
331
+ HandlerTestUtils.setupMockTypeRegistry([
340
332
  ["arr", { baseType: "u32", arrayDimensions: [10] }],
341
- ]) as any;
333
+ ]);
342
334
  HandlerTestUtils.setupMockGenerator({
343
335
  generateExpression: vi
344
336
  .fn()
@@ -360,9 +352,9 @@ describe("BitAccessHandlers", () => {
360
352
  });
361
353
 
362
354
  it("generates array element bit assignment for 2D array", () => {
363
- CodeGenState.typeRegistry = new Map([
355
+ HandlerTestUtils.setupMockTypeRegistry([
364
356
  ["matrix", { baseType: "u16", arrayDimensions: [10, 10] }],
365
- ]) as any;
357
+ ]);
366
358
  HandlerTestUtils.setupMockGenerator({
367
359
  generateExpression: vi
368
360
  .fn()
@@ -386,9 +378,9 @@ describe("BitAccessHandlers", () => {
386
378
  });
387
379
 
388
380
  it("uses 1ULL for 64-bit array element", () => {
389
- CodeGenState.typeRegistry = new Map([
381
+ HandlerTestUtils.setupMockTypeRegistry([
390
382
  ["arr", { baseType: "u64", arrayDimensions: [5] }],
391
- ]) as any;
383
+ ]);
392
384
  HandlerTestUtils.setupMockGenerator({
393
385
  generateExpression: vi
394
386
  .fn()
@@ -406,9 +398,9 @@ describe("BitAccessHandlers", () => {
406
398
  });
407
399
 
408
400
  it("throws when variable is not an array", () => {
409
- CodeGenState.typeRegistry = new Map([
401
+ HandlerTestUtils.setupMockTypeRegistry([
410
402
  ["notArray", { baseType: "u32" }],
411
- ]) as any;
403
+ ]);
412
404
  const ctx = createMockContext({
413
405
  identifiers: ["notArray"],
414
406
  });
@@ -417,9 +409,9 @@ describe("BitAccessHandlers", () => {
417
409
  });
418
410
 
419
411
  it("throws on compound assignment", () => {
420
- CodeGenState.typeRegistry = new Map([
412
+ HandlerTestUtils.setupMockTypeRegistry([
421
413
  ["arr", { baseType: "u32", arrayDimensions: [10] }],
422
- ]) as any;
414
+ ]);
423
415
  const ctx = createMockContext({
424
416
  isCompound: true,
425
417
  cnextOp: "+<-",