c-next 0.1.69 → 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 (54) 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 +35 -607
  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 +5 -5
  15. package/src/transpiler/output/codegen/__tests__/TypeRegistrationUtils.test.ts +36 -51
  16. package/src/transpiler/output/codegen/__tests__/TypeResolver.test.ts +20 -17
  17. package/src/transpiler/output/codegen/__tests__/TypeValidator.resolution.test.ts +3 -3
  18. package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +1 -1
  19. package/src/transpiler/output/codegen/analysis/MemberChainAnalyzer.ts +1 -1
  20. package/src/transpiler/output/codegen/analysis/StringLengthCounter.ts +1 -1
  21. package/src/transpiler/output/codegen/analysis/__tests__/MemberChainAnalyzer.test.ts +9 -9
  22. package/src/transpiler/output/codegen/analysis/__tests__/StringLengthCounter.test.ts +12 -12
  23. package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +11 -11
  24. package/src/transpiler/output/codegen/assignment/__tests__/AssignmentClassifier.test.ts +23 -17
  25. package/src/transpiler/output/codegen/assignment/handlers/ArrayHandlers.ts +2 -2
  26. package/src/transpiler/output/codegen/assignment/handlers/BitAccessHandlers.ts +3 -3
  27. package/src/transpiler/output/codegen/assignment/handlers/BitmapHandlers.ts +3 -3
  28. package/src/transpiler/output/codegen/assignment/handlers/SpecialHandlers.ts +4 -4
  29. package/src/transpiler/output/codegen/assignment/handlers/StringHandlers.ts +5 -5
  30. package/src/transpiler/output/codegen/assignment/handlers/__tests__/ArrayHandlers.test.ts +23 -25
  31. package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitAccessHandlers.test.ts +20 -36
  32. package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitmapHandlers.test.ts +18 -18
  33. package/src/transpiler/output/codegen/assignment/handlers/__tests__/SpecialHandlers.test.ts +42 -32
  34. package/src/transpiler/output/codegen/assignment/handlers/__tests__/handlerTestUtils.ts +5 -4
  35. package/src/transpiler/output/codegen/generators/expressions/CallExprGenerator.ts +14 -6
  36. package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +19 -16
  37. package/src/transpiler/output/codegen/generators/expressions/__tests__/CallExprGenerator.test.ts +21 -4
  38. package/src/transpiler/output/codegen/generators/expressions/__tests__/PostfixExpressionGenerator.test.ts +15 -2
  39. package/src/transpiler/output/codegen/helpers/ArrayInitHelper.ts +2 -1
  40. package/src/transpiler/output/codegen/helpers/AssignmentExpectedTypeResolver.ts +2 -2
  41. package/src/transpiler/output/codegen/helpers/AssignmentValidator.ts +3 -3
  42. package/src/transpiler/output/codegen/helpers/EnumAssignmentValidator.ts +1 -1
  43. package/src/transpiler/output/codegen/helpers/StringDeclHelper.ts +2 -2
  44. package/src/transpiler/output/codegen/helpers/__tests__/ArrayInitHelper.test.ts +1 -1
  45. package/src/transpiler/output/codegen/helpers/__tests__/AssignmentExpectedTypeResolver.test.ts +7 -7
  46. package/src/transpiler/output/codegen/helpers/__tests__/AssignmentValidator.test.ts +7 -7
  47. package/src/transpiler/output/codegen/helpers/__tests__/EnumAssignmentValidator.test.ts +2 -2
  48. package/src/transpiler/output/codegen/helpers/__tests__/StringDeclHelper.test.ts +4 -4
  49. package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +2 -2
  50. package/src/transpiler/output/codegen/resolution/__tests__/EnumTypeResolver.test.ts +5 -5
  51. package/src/transpiler/state/CodeGenState.ts +122 -4
  52. package/src/transpiler/state/__tests__/CodeGenState.test.ts +269 -1
  53. /package/src/transpiler/{output/codegen → logic/analysis}/helpers/TransitiveModificationPropagator.ts +0 -0
  54. /package/src/transpiler/{output/codegen → logic/analysis}/helpers/__tests__/TransitiveModificationPropagator.test.ts +0 -0
@@ -6,7 +6,7 @@
6
6
  * qualifiedType, userType) that each had identical enum/bitmap handling.
7
7
  */
8
8
 
9
- import TTypeInfo from "./types/TTypeInfo";
9
+ import CodeGenState from "../../state/CodeGenState";
10
10
  import TOverflowBehavior from "./types/TOverflowBehavior";
11
11
 
12
12
  /**
@@ -40,7 +40,6 @@ class TypeRegistrationUtils {
40
40
  * Returns true if the type was a known enum and was registered.
41
41
  */
42
42
  static tryRegisterEnumType(
43
- typeRegistry: Map<string, TTypeInfo>,
44
43
  symbols: ITypeSymbols,
45
44
  options: ITypeRegistrationOptions,
46
45
  ): boolean {
@@ -48,7 +47,7 @@ class TypeRegistrationUtils {
48
47
  return false;
49
48
  }
50
49
 
51
- typeRegistry.set(options.name, {
50
+ CodeGenState.setVariableTypeInfo(options.name, {
52
51
  baseType: options.baseType,
53
52
  bitWidth: 0,
54
53
  isArray: false,
@@ -69,7 +68,6 @@ class TypeRegistrationUtils {
69
68
  * Handles both array and non-array bitmap types.
70
69
  */
71
70
  static tryRegisterBitmapType(
72
- typeRegistry: Map<string, TTypeInfo>,
73
71
  symbols: ITypeSymbols,
74
72
  options: ITypeRegistrationOptions,
75
73
  arrayDimensions: number[] | undefined,
@@ -82,7 +80,7 @@ class TypeRegistrationUtils {
82
80
 
83
81
  if (arrayDimensions && arrayDimensions.length > 0) {
84
82
  // Bitmap array
85
- typeRegistry.set(options.name, {
83
+ CodeGenState.setVariableTypeInfo(options.name, {
86
84
  baseType: options.baseType,
87
85
  bitWidth,
88
86
  isArray: true,
@@ -95,7 +93,7 @@ class TypeRegistrationUtils {
95
93
  });
96
94
  } else {
97
95
  // Non-array bitmap
98
- typeRegistry.set(options.name, {
96
+ CodeGenState.setVariableTypeInfo(options.name, {
99
97
  baseType: options.baseType,
100
98
  bitWidth,
101
99
  isArray: false,
@@ -303,7 +303,7 @@ class TypeResolver {
303
303
  * Look up a variable name in the type registry and return a SuffixResult.
304
304
  */
305
305
  private static resolveRegistryLookup(name: string): SuffixResult {
306
- const typeInfo = CodeGenState.typeRegistry.get(name);
306
+ const typeInfo = CodeGenState.getVariableTypeInfo(name);
307
307
  if (typeInfo) {
308
308
  return {
309
309
  stop: false,
@@ -356,7 +356,7 @@ class TypeResolver {
356
356
  if (id) {
357
357
  const name = id.getText();
358
358
  const scopedName = CodeGenState.resolveIdentifier(name);
359
- const typeInfo = CodeGenState.typeRegistry.get(scopedName);
359
+ const typeInfo = CodeGenState.getVariableTypeInfo(scopedName);
360
360
  if (typeInfo) {
361
361
  return { baseType: typeInfo.baseType, isArray: typeInfo.isArray };
362
362
  }
@@ -291,7 +291,7 @@ class TypeValidator {
291
291
 
292
292
  const scopedName = CodeGenState.resolveIdentifier(identifier);
293
293
 
294
- const typeInfo = CodeGenState.typeRegistry.get(scopedName);
294
+ const typeInfo = CodeGenState.getVariableTypeInfo(scopedName);
295
295
  if (typeInfo?.isConst) {
296
296
  return `cannot assign to const variable '${identifier}'`;
297
297
  }
@@ -305,7 +305,7 @@ class TypeValidator {
305
305
  return true;
306
306
  }
307
307
 
308
- const typeInfo = CodeGenState.typeRegistry.get(identifier);
308
+ const typeInfo = CodeGenState.getVariableTypeInfo(identifier);
309
309
  if (typeInfo?.isConst) {
310
310
  return true;
311
311
  }
@@ -366,7 +366,7 @@ class TypeValidator {
366
366
  );
367
367
  }
368
368
 
369
- const typeInfo = CodeGenState.typeRegistry.get(identifier);
369
+ const typeInfo = CodeGenState.getVariableTypeInfo(identifier);
370
370
  if (typeInfo && !identifier.includes("_")) {
371
371
  throw new Error(
372
372
  `Error: Use 'global.${identifier}' to access global variable '${identifier}' inside scope '${currentScope}'`,
@@ -428,7 +428,7 @@ class TypeValidator {
428
428
  currentScope: string | null,
429
429
  isKnownStruct: (name: string) => boolean,
430
430
  ): boolean {
431
- const typeInfo = CodeGenState.typeRegistry.get(identifier);
431
+ const typeInfo = CodeGenState.getVariableTypeInfo(identifier);
432
432
  if (typeInfo && !identifier.includes("_")) {
433
433
  return true;
434
434
  }
@@ -790,7 +790,7 @@ class TypeValidator {
790
790
  return true;
791
791
  }
792
792
 
793
- const typeInfo = CodeGenState.typeRegistry.get(text);
793
+ const typeInfo = CodeGenState.getVariableTypeInfo(text);
794
794
  if (typeInfo?.baseType === "bool") {
795
795
  return true;
796
796
  }
@@ -3,9 +3,9 @@
3
3
  * Tests the extracted enum/bitmap type registration helpers.
4
4
  */
5
5
 
6
- import { describe, expect, it } from "vitest";
6
+ import { beforeEach, describe, expect, it } from "vitest";
7
7
  import TypeRegistrationUtils from "../TypeRegistrationUtils";
8
- import TTypeInfo from "../types/TTypeInfo";
8
+ import CodeGenState from "../../../state/CodeGenState";
9
9
 
10
10
  /**
11
11
  * Create mock symbols for testing
@@ -20,49 +20,43 @@ function createMockSymbols(overrides: Record<string, unknown> = {}) {
20
20
  }
21
21
 
22
22
  describe("TypeRegistrationUtils", () => {
23
+ beforeEach(() => {
24
+ CodeGenState.reset();
25
+ });
26
+
23
27
  describe("tryRegisterEnumType", () => {
24
28
  it("returns false if type is not a known enum", () => {
25
- const typeRegistry = new Map<string, TTypeInfo>();
26
29
  const symbols = createMockSymbols();
27
30
 
28
- const result = TypeRegistrationUtils.tryRegisterEnumType(
29
- typeRegistry,
30
- symbols,
31
- {
32
- name: "myVar",
33
- baseType: "UnknownType",
34
- isConst: false,
35
- overflowBehavior: "clamp",
36
- isAtomic: false,
37
- },
38
- );
31
+ const result = TypeRegistrationUtils.tryRegisterEnumType(symbols, {
32
+ name: "myVar",
33
+ baseType: "UnknownType",
34
+ isConst: false,
35
+ overflowBehavior: "clamp",
36
+ isAtomic: false,
37
+ });
39
38
 
40
39
  expect(result).toBe(false);
41
- expect(typeRegistry.size).toBe(0);
40
+ expect(CodeGenState.getVariableTypeInfo("myVar")).toBeUndefined();
42
41
  });
43
42
 
44
43
  it("registers enum type and returns true", () => {
45
- const typeRegistry = new Map<string, TTypeInfo>();
46
44
  const symbols = createMockSymbols({
47
45
  knownEnums: new Set(["MyEnum"]),
48
46
  });
49
47
 
50
- const result = TypeRegistrationUtils.tryRegisterEnumType(
51
- typeRegistry,
52
- symbols,
53
- {
54
- name: "myVar",
55
- baseType: "MyEnum",
56
- isConst: false,
57
- overflowBehavior: "clamp",
58
- isAtomic: false,
59
- },
60
- );
48
+ const result = TypeRegistrationUtils.tryRegisterEnumType(symbols, {
49
+ name: "myVar",
50
+ baseType: "MyEnum",
51
+ isConst: false,
52
+ overflowBehavior: "clamp",
53
+ isAtomic: false,
54
+ });
61
55
 
62
56
  expect(result).toBe(true);
63
- expect(typeRegistry.has("myVar")).toBe(true);
57
+ expect(CodeGenState.hasVariableTypeInfo("myVar")).toBe(true);
64
58
 
65
- const info = typeRegistry.get("myVar")!;
59
+ const info = CodeGenState.getVariableTypeInfo("myVar")!;
66
60
  expect(info.baseType).toBe("MyEnum");
67
61
  expect(info.isEnum).toBe(true);
68
62
  expect(info.enumTypeName).toBe("MyEnum");
@@ -70,12 +64,11 @@ describe("TypeRegistrationUtils", () => {
70
64
  });
71
65
 
72
66
  it("respects isConst flag", () => {
73
- const typeRegistry = new Map<string, TTypeInfo>();
74
67
  const symbols = createMockSymbols({
75
68
  knownEnums: new Set(["MyEnum"]),
76
69
  });
77
70
 
78
- TypeRegistrationUtils.tryRegisterEnumType(typeRegistry, symbols, {
71
+ TypeRegistrationUtils.tryRegisterEnumType(symbols, {
79
72
  name: "myVar",
80
73
  baseType: "MyEnum",
81
74
  isConst: true,
@@ -83,16 +76,15 @@ describe("TypeRegistrationUtils", () => {
83
76
  isAtomic: false,
84
77
  });
85
78
 
86
- expect(typeRegistry.get("myVar")!.isConst).toBe(true);
79
+ expect(CodeGenState.getVariableTypeInfo("myVar")!.isConst).toBe(true);
87
80
  });
88
81
 
89
82
  it("respects overflowBehavior", () => {
90
- const typeRegistry = new Map<string, TTypeInfo>();
91
83
  const symbols = createMockSymbols({
92
84
  knownEnums: new Set(["MyEnum"]),
93
85
  });
94
86
 
95
- TypeRegistrationUtils.tryRegisterEnumType(typeRegistry, symbols, {
87
+ TypeRegistrationUtils.tryRegisterEnumType(symbols, {
96
88
  name: "myVar",
97
89
  baseType: "MyEnum",
98
90
  isConst: false,
@@ -100,16 +92,17 @@ describe("TypeRegistrationUtils", () => {
100
92
  isAtomic: false,
101
93
  });
102
94
 
103
- expect(typeRegistry.get("myVar")!.overflowBehavior).toBe("wrap");
95
+ expect(CodeGenState.getVariableTypeInfo("myVar")!.overflowBehavior).toBe(
96
+ "wrap",
97
+ );
104
98
  });
105
99
 
106
100
  it("respects isAtomic flag", () => {
107
- const typeRegistry = new Map<string, TTypeInfo>();
108
101
  const symbols = createMockSymbols({
109
102
  knownEnums: new Set(["MyEnum"]),
110
103
  });
111
104
 
112
- TypeRegistrationUtils.tryRegisterEnumType(typeRegistry, symbols, {
105
+ TypeRegistrationUtils.tryRegisterEnumType(symbols, {
113
106
  name: "myVar",
114
107
  baseType: "MyEnum",
115
108
  isConst: false,
@@ -117,17 +110,15 @@ describe("TypeRegistrationUtils", () => {
117
110
  isAtomic: true,
118
111
  });
119
112
 
120
- expect(typeRegistry.get("myVar")!.isAtomic).toBe(true);
113
+ expect(CodeGenState.getVariableTypeInfo("myVar")!.isAtomic).toBe(true);
121
114
  });
122
115
  });
123
116
 
124
117
  describe("tryRegisterBitmapType", () => {
125
118
  it("returns false if type is not a known bitmap", () => {
126
- const typeRegistry = new Map<string, TTypeInfo>();
127
119
  const symbols = createMockSymbols();
128
120
 
129
121
  const result = TypeRegistrationUtils.tryRegisterBitmapType(
130
- typeRegistry,
131
122
  symbols,
132
123
  {
133
124
  name: "myVar",
@@ -140,18 +131,16 @@ describe("TypeRegistrationUtils", () => {
140
131
  );
141
132
 
142
133
  expect(result).toBe(false);
143
- expect(typeRegistry.size).toBe(0);
134
+ expect(CodeGenState.getVariableTypeInfo("myVar")).toBeUndefined();
144
135
  });
145
136
 
146
137
  it("registers non-array bitmap type", () => {
147
- const typeRegistry = new Map<string, TTypeInfo>();
148
138
  const symbols = createMockSymbols({
149
139
  knownBitmaps: new Set(["MyFlags"]),
150
140
  bitmapBitWidth: new Map([["MyFlags", 8]]),
151
141
  });
152
142
 
153
143
  const result = TypeRegistrationUtils.tryRegisterBitmapType(
154
- typeRegistry,
155
144
  symbols,
156
145
  {
157
146
  name: "flags",
@@ -164,9 +153,9 @@ describe("TypeRegistrationUtils", () => {
164
153
  );
165
154
 
166
155
  expect(result).toBe(true);
167
- expect(typeRegistry.has("flags")).toBe(true);
156
+ expect(CodeGenState.hasVariableTypeInfo("flags")).toBe(true);
168
157
 
169
- const info = typeRegistry.get("flags")!;
158
+ const info = CodeGenState.getVariableTypeInfo("flags")!;
170
159
  expect(info.baseType).toBe("MyFlags");
171
160
  expect(info.isBitmap).toBe(true);
172
161
  expect(info.bitmapTypeName).toBe("MyFlags");
@@ -175,14 +164,12 @@ describe("TypeRegistrationUtils", () => {
175
164
  });
176
165
 
177
166
  it("registers bitmap array type with dimensions", () => {
178
- const typeRegistry = new Map<string, TTypeInfo>();
179
167
  const symbols = createMockSymbols({
180
168
  knownBitmaps: new Set(["MyFlags"]),
181
169
  bitmapBitWidth: new Map([["MyFlags", 16]]),
182
170
  });
183
171
 
184
172
  const result = TypeRegistrationUtils.tryRegisterBitmapType(
185
- typeRegistry,
186
173
  symbols,
187
174
  {
188
175
  name: "flagsArray",
@@ -196,21 +183,19 @@ describe("TypeRegistrationUtils", () => {
196
183
 
197
184
  expect(result).toBe(true);
198
185
 
199
- const info = typeRegistry.get("flagsArray")!;
186
+ const info = CodeGenState.getVariableTypeInfo("flagsArray")!;
200
187
  expect(info.isArray).toBe(true);
201
188
  expect(info.arrayDimensions).toEqual([10, 5]);
202
189
  expect(info.bitWidth).toBe(16);
203
190
  });
204
191
 
205
192
  it("defaults bitWidth to 0 if not found", () => {
206
- const typeRegistry = new Map<string, TTypeInfo>();
207
193
  const symbols = createMockSymbols({
208
194
  knownBitmaps: new Set(["MyFlags"]),
209
195
  // No bitWidth entry
210
196
  });
211
197
 
212
198
  TypeRegistrationUtils.tryRegisterBitmapType(
213
- typeRegistry,
214
199
  symbols,
215
200
  {
216
201
  name: "flags",
@@ -222,7 +207,7 @@ describe("TypeRegistrationUtils", () => {
222
207
  undefined,
223
208
  );
224
209
 
225
- expect(typeRegistry.get("flags")!.bitWidth).toBe(0);
210
+ expect(CodeGenState.getVariableTypeInfo("flags")!.bitWidth).toBe(0);
226
211
  });
227
212
  });
228
213
  });
@@ -10,15 +10,18 @@ import TTypeInfo from "../types/TTypeInfo";
10
10
 
11
11
  describe("TypeResolver", () => {
12
12
  let symbolTable: SymbolTable;
13
- let typeRegistry: Map<string, TTypeInfo>;
14
13
 
15
14
  beforeEach(() => {
16
15
  CodeGenState.reset();
17
16
  symbolTable = new SymbolTable();
18
- typeRegistry = CodeGenState.typeRegistry;
19
17
  CodeGenState.symbolTable = symbolTable;
20
18
  });
21
19
 
20
+ /** Helper function to set type info in the registry */
21
+ function setTypeInfo(name: string, info: TTypeInfo): void {
22
+ CodeGenState.setVariableTypeInfo(name, info);
23
+ }
24
+
22
25
  // ========================================================================
23
26
  // Type Classification Methods
24
27
  // ========================================================================
@@ -400,7 +403,7 @@ describe("TypeResolver", () => {
400
403
  };
401
404
 
402
405
  it("should return type for identifier in registry", () => {
403
- typeRegistry.set("myVar", {
406
+ setTypeInfo("myVar", {
404
407
  baseType: "u32",
405
408
  bitWidth: 32,
406
409
  isArray: false,
@@ -612,7 +615,7 @@ describe("TypeResolver", () => {
612
615
  });
613
616
 
614
617
  it("should return type from simple identifier", () => {
615
- typeRegistry.set("counter", {
618
+ setTypeInfo("counter", {
616
619
  baseType: "u32",
617
620
  bitWidth: 32,
618
621
  isArray: false,
@@ -651,7 +654,7 @@ describe("TypeResolver", () => {
651
654
  });
652
655
 
653
656
  it("should return member type for struct member access", () => {
654
- typeRegistry.set("point", {
657
+ setTypeInfo("point", {
655
658
  baseType: "Point",
656
659
  bitWidth: 0,
657
660
  isArray: false,
@@ -675,7 +678,7 @@ describe("TypeResolver", () => {
675
678
  });
676
679
 
677
680
  it("should return null for unknown member", () => {
678
- typeRegistry.set("point", {
681
+ setTypeInfo("point", {
679
682
  baseType: "Point",
680
683
  bitWidth: 0,
681
684
  isArray: false,
@@ -699,7 +702,7 @@ describe("TypeResolver", () => {
699
702
  });
700
703
 
701
704
  it("should return null for range bit indexing", () => {
702
- typeRegistry.set("flags", {
705
+ setTypeInfo("flags", {
703
706
  baseType: "u32",
704
707
  bitWidth: 32,
705
708
  isArray: false,
@@ -722,7 +725,7 @@ describe("TypeResolver", () => {
722
725
  });
723
726
 
724
727
  it("should return bool for single bit indexing on integer", () => {
725
- typeRegistry.set("flags", {
728
+ setTypeInfo("flags", {
726
729
  baseType: "u32",
727
730
  bitWidth: 32,
728
731
  isArray: false,
@@ -745,7 +748,7 @@ describe("TypeResolver", () => {
745
748
  });
746
749
 
747
750
  it("should return element type for struct array member indexing", () => {
748
- typeRegistry.set("data", {
751
+ setTypeInfo("data", {
749
752
  baseType: "Data",
750
753
  bitWidth: 0,
751
754
  isArray: false,
@@ -774,7 +777,7 @@ describe("TypeResolver", () => {
774
777
  });
775
778
 
776
779
  it("should return element type for direct array variable indexing", () => {
777
- typeRegistry.set("arr", {
780
+ setTypeInfo("arr", {
778
781
  baseType: "u8",
779
782
  bitWidth: 8,
780
783
  isArray: true,
@@ -798,7 +801,7 @@ describe("TypeResolver", () => {
798
801
  });
799
802
 
800
803
  it("should return bool for bit indexing on plain integer variable", () => {
801
- typeRegistry.set("val", {
804
+ setTypeInfo("val", {
802
805
  baseType: "u8",
803
806
  bitWidth: 8,
804
807
  isArray: false,
@@ -828,7 +831,7 @@ describe("TypeResolver", () => {
828
831
 
829
832
  describe("getPostfixExpressionType with global/this", () => {
830
833
  it("should resolve global.structVar.field type", () => {
831
- typeRegistry.set("config", {
834
+ setTypeInfo("config", {
832
835
  baseType: "TConfig",
833
836
  bitWidth: 0,
834
837
  isArray: false,
@@ -858,7 +861,7 @@ describe("TypeResolver", () => {
858
861
  });
859
862
 
860
863
  it("should resolve global.arrayVar[0] element type", () => {
861
- typeRegistry.set("inputs", {
864
+ setTypeInfo("inputs", {
862
865
  baseType: "TInput",
863
866
  bitWidth: 0,
864
867
  isArray: true,
@@ -888,7 +891,7 @@ describe("TypeResolver", () => {
888
891
 
889
892
  it("should resolve this.scopeVar type", () => {
890
893
  CodeGenState.currentScope = "Motor";
891
- typeRegistry.set("Motor_speed", {
894
+ setTypeInfo("Motor_speed", {
892
895
  baseType: "u32",
893
896
  bitWidth: 32,
894
897
  isArray: false,
@@ -951,7 +954,7 @@ describe("TypeResolver", () => {
951
954
  });
952
955
 
953
956
  it("should resolve global.struct.enumField for enum type", () => {
954
- typeRegistry.set("input", {
957
+ setTypeInfo("input", {
955
958
  baseType: "TInput",
956
959
  bitWidth: 0,
957
960
  isArray: false,
@@ -987,7 +990,7 @@ describe("TypeResolver", () => {
987
990
 
988
991
  describe("getUnaryExpressionType", () => {
989
992
  it("should return type from postfix expression", () => {
990
- typeRegistry.set("value", {
993
+ setTypeInfo("value", {
991
994
  baseType: "i32",
992
995
  bitWidth: 32,
993
996
  isArray: false,
@@ -1020,7 +1023,7 @@ describe("TypeResolver", () => {
1020
1023
  });
1021
1024
 
1022
1025
  it("should recurse through unary expression chain", () => {
1023
- typeRegistry.set("x", {
1026
+ setTypeInfo("x", {
1024
1027
  baseType: "i32",
1025
1028
  bitWidth: 32,
1026
1029
  isArray: false,
@@ -39,13 +39,13 @@ describe("TypeValidator.resolveBareIdentifier", () => {
39
39
  beforeEach(() => {
40
40
  CodeGenState.reset();
41
41
  CodeGenState.setScopeMembers("Motor", new Set(["speed", "maxSpeed"]));
42
- CodeGenState.typeRegistry.set("globalCounter", {
42
+ CodeGenState.setVariableTypeInfo("globalCounter", {
43
43
  baseType: "u32",
44
44
  bitWidth: 32,
45
45
  isArray: false,
46
46
  isConst: false,
47
47
  });
48
- CodeGenState.typeRegistry.set("Motor_speed", {
48
+ CodeGenState.setVariableTypeInfo("Motor_speed", {
49
49
  baseType: "u32",
50
50
  bitWidth: 32,
51
51
  isArray: false,
@@ -146,7 +146,7 @@ describe("TypeValidator.resolveBareIdentifier", () => {
146
146
  describe("resolveForMemberAccess", () => {
147
147
  it("prefers scope name over global variable for member access", () => {
148
148
  // Setup: global variable 'LED' exists AND scope 'LED' exists
149
- CodeGenState.typeRegistry.set("LED", {
149
+ CodeGenState.setVariableTypeInfo("LED", {
150
150
  baseType: "u8",
151
151
  bitWidth: 8,
152
152
  isArray: false,
@@ -74,7 +74,7 @@ function setupState(options: SetupStateOptions = {}): void {
74
74
  }
75
75
  if (options.typeRegistry) {
76
76
  for (const [k, v] of options.typeRegistry) {
77
- CodeGenState.typeRegistry.set(k, v);
77
+ CodeGenState.setVariableTypeInfo(k, v);
78
78
  }
79
79
  }
80
80
  if (options.callbackTypes) {
@@ -127,7 +127,7 @@ class MemberChainAnalyzer {
127
127
  ops: Parser.PostfixTargetOpContext[],
128
128
  _subscriptsSoFar: number,
129
129
  ): { type: string; isArray: boolean } | undefined {
130
- const baseTypeInfo = CodeGenState.typeRegistry.get(baseId);
130
+ const baseTypeInfo = CodeGenState.getVariableTypeInfo(baseId);
131
131
  if (!baseTypeInfo) {
132
132
  return undefined;
133
133
  }
@@ -193,7 +193,7 @@ class StringLengthCounter {
193
193
  const memberName = op.IDENTIFIER()?.getText();
194
194
  if (memberName === "length") {
195
195
  // Check if this is a string type
196
- const typeInfo = CodeGenState.typeRegistry.get(primaryId);
196
+ const typeInfo = CodeGenState.getVariableTypeInfo(primaryId);
197
197
  if (typeInfo?.isString) {
198
198
  const currentCount = counts.get(primaryId) || 0;
199
199
  counts.set(primaryId, currentCount + 1);
@@ -139,7 +139,7 @@ describe("MemberChainAnalyzer", () => {
139
139
 
140
140
  it("returns isBitAccess false when last op is member access", () => {
141
141
  // point.flags (no subscript at end)
142
- CodeGenState.typeRegistry.set("point", {
142
+ CodeGenState.setVariableTypeInfo("point", {
143
143
  baseType: "Point",
144
144
  bitWidth: 0,
145
145
  isArray: false,
@@ -159,7 +159,7 @@ describe("MemberChainAnalyzer", () => {
159
159
 
160
160
  it("returns isBitAccess false when last subscript has 2 expressions (bit range)", () => {
161
161
  // flags[0, 8] - bit range, not single bit access
162
- CodeGenState.typeRegistry.set("flags", {
162
+ CodeGenState.setVariableTypeInfo("flags", {
163
163
  baseType: "u32",
164
164
  bitWidth: 32,
165
165
  isArray: false,
@@ -180,7 +180,7 @@ describe("MemberChainAnalyzer", () => {
180
180
  pointFields.set("flags", "u8");
181
181
  setupStructFields("Point", pointFields);
182
182
 
183
- CodeGenState.typeRegistry.set("point", {
183
+ CodeGenState.setVariableTypeInfo("point", {
184
184
  baseType: "Point",
185
185
  bitWidth: 0,
186
186
  isArray: false,
@@ -209,7 +209,7 @@ describe("MemberChainAnalyzer", () => {
209
209
  gridFields.set("items", "u8");
210
210
  setupStructFields("Grid", gridFields, new Set(["items"]));
211
211
 
212
- CodeGenState.typeRegistry.set("grid", {
212
+ CodeGenState.setVariableTypeInfo("grid", {
213
213
  baseType: "Grid",
214
214
  bitWidth: 0,
215
215
  isArray: false,
@@ -236,7 +236,7 @@ describe("MemberChainAnalyzer", () => {
236
236
  pointFields.set("name", "string");
237
237
  setupStructFields("Point", pointFields);
238
238
 
239
- CodeGenState.typeRegistry.set("point", {
239
+ CodeGenState.setVariableTypeInfo("point", {
240
240
  baseType: "Point",
241
241
  bitWidth: 0,
242
242
  isArray: false,
@@ -263,7 +263,7 @@ describe("MemberChainAnalyzer", () => {
263
263
  deviceFields.set("flags", "u8");
264
264
  setupStructFields("Device", deviceFields);
265
265
 
266
- CodeGenState.typeRegistry.set("devices", {
266
+ CodeGenState.setVariableTypeInfo("devices", {
267
267
  baseType: "Device",
268
268
  bitWidth: 0,
269
269
  isArray: true,
@@ -290,7 +290,7 @@ describe("MemberChainAnalyzer", () => {
290
290
 
291
291
  it("returns false for 2D array element: matrix[0][1]", () => {
292
292
  // matrix[0][1] is array access, not bit access
293
- CodeGenState.typeRegistry.set("matrix", {
293
+ CodeGenState.setVariableTypeInfo("matrix", {
294
294
  baseType: "u8",
295
295
  bitWidth: 8,
296
296
  isArray: true,
@@ -315,7 +315,7 @@ describe("MemberChainAnalyzer", () => {
315
315
  it("detects bit access on 2D array element: matrix[0][1][3]", () => {
316
316
  // matrix[0][1][3] where matrix is u8[4][4]
317
317
  // The third subscript [3] is bit access on the u8 element
318
- CodeGenState.typeRegistry.set("matrix", {
318
+ CodeGenState.setVariableTypeInfo("matrix", {
319
319
  baseType: "u8",
320
320
  bitWidth: 8,
321
321
  isArray: true,
@@ -357,7 +357,7 @@ describe("MemberChainAnalyzer", () => {
357
357
 
358
358
  it("returns false for member access on non-struct", () => {
359
359
  // x.field[0] where x is a primitive
360
- CodeGenState.typeRegistry.set("x", {
360
+ CodeGenState.setVariableTypeInfo("x", {
361
361
  baseType: "u32",
362
362
  bitWidth: 32,
363
363
  isArray: false,