c-next 0.1.61 → 0.1.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.md +86 -63
  2. package/grammar/CNext.g4 +3 -17
  3. package/package.json +1 -1
  4. package/src/cli/serve/ServeCommand.ts +57 -45
  5. package/src/lib/__tests__/parseCHeader.mocked.test.ts +145 -0
  6. package/src/transpiler/Transpiler.ts +603 -613
  7. package/src/transpiler/__tests__/DualCodePaths.test.ts +5 -1
  8. package/src/transpiler/__tests__/Transpiler.coverage.test.ts +2 -99
  9. package/src/transpiler/__tests__/Transpiler.test.ts +3 -26
  10. package/src/transpiler/data/IncludeTreeWalker.ts +1 -1
  11. package/src/transpiler/logic/analysis/InitializationAnalyzer.ts +23 -52
  12. package/src/transpiler/logic/parser/grammar/CNext.interp +1 -3
  13. package/src/transpiler/logic/parser/grammar/CNextListener.ts +0 -22
  14. package/src/transpiler/logic/parser/grammar/CNextParser.ts +665 -1084
  15. package/src/transpiler/logic/parser/grammar/CNextVisitor.ts +0 -14
  16. package/src/transpiler/logic/symbols/CppSymbolCollector.ts +67 -43
  17. package/src/transpiler/logic/symbols/cnext/collectors/StructCollector.ts +156 -70
  18. package/src/transpiler/logic/symbols/cnext/collectors/VariableCollector.ts +31 -6
  19. package/src/transpiler/logic/symbols/cnext/utils/TypeUtils.ts +43 -11
  20. package/src/transpiler/output/codegen/CodeGenState.ts +811 -0
  21. package/src/transpiler/output/codegen/CodeGenerator.ts +1410 -2587
  22. package/src/transpiler/output/codegen/TypeResolver.ts +193 -149
  23. package/src/transpiler/output/codegen/TypeValidator.ts +148 -370
  24. package/src/transpiler/output/codegen/__tests__/CodeGenState.test.ts +446 -0
  25. package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +2082 -52
  26. package/src/transpiler/output/codegen/__tests__/TrackVariableTypeHelpers.test.ts +1 -1
  27. package/src/transpiler/output/codegen/__tests__/TypeResolver.test.ts +435 -196
  28. package/src/transpiler/output/codegen/__tests__/TypeValidator.resolution.test.ts +51 -67
  29. package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +495 -471
  30. package/src/transpiler/output/codegen/analysis/MemberChainAnalyzer.ts +227 -66
  31. package/src/transpiler/output/codegen/analysis/StringLengthCounter.ts +55 -58
  32. package/src/transpiler/output/codegen/analysis/__tests__/MemberChainAnalyzer.test.ts +288 -275
  33. package/src/transpiler/output/codegen/analysis/__tests__/StringLengthCounter.test.ts +101 -144
  34. package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +195 -133
  35. package/src/transpiler/output/codegen/assignment/AssignmentContextBuilder.ts +24 -74
  36. package/src/transpiler/output/codegen/assignment/AssignmentKind.ts +3 -0
  37. package/src/transpiler/output/codegen/assignment/IAssignmentContext.ts +3 -0
  38. package/src/transpiler/output/codegen/assignment/__tests__/AssignmentClassifier.test.ts +290 -320
  39. package/src/transpiler/output/codegen/assignment/handlers/BitAccessHandlers.ts +42 -0
  40. package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitAccessHandlers.test.ts +76 -2
  41. package/src/transpiler/output/codegen/generators/GeneratorRegistry.ts +12 -0
  42. package/src/transpiler/output/codegen/generators/IOrchestrator.ts +5 -1
  43. package/src/transpiler/output/codegen/generators/__tests__/GeneratorRegistry.test.ts +28 -1
  44. package/src/transpiler/output/codegen/generators/declarationGenerators/ArrayDimensionUtils.ts +67 -0
  45. package/src/transpiler/output/codegen/generators/declarationGenerators/RegisterGenerator.ts +11 -24
  46. package/src/transpiler/output/codegen/generators/declarationGenerators/RegisterMacroGenerator.ts +64 -0
  47. package/src/transpiler/output/codegen/generators/declarationGenerators/ScopeGenerator.ts +137 -61
  48. package/src/transpiler/output/codegen/generators/declarationGenerators/ScopedRegisterGenerator.ts +18 -27
  49. package/src/transpiler/output/codegen/generators/declarationGenerators/StructGenerator.ts +100 -23
  50. package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ArrayDimensionUtils.test.ts +125 -0
  51. package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ScopeGenerator.test.ts +157 -4
  52. package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +5 -1
  53. package/src/transpiler/output/codegen/generators/statements/ControlFlowGenerator.ts +1 -17
  54. package/src/transpiler/output/codegen/generators/support/HelperGenerator.ts +23 -22
  55. package/src/transpiler/output/codegen/helpers/ArrayAccessHelper.ts +129 -0
  56. package/src/transpiler/output/codegen/helpers/ArrayInitHelper.ts +54 -61
  57. package/src/transpiler/output/codegen/helpers/AssignmentExpectedTypeResolver.ts +40 -44
  58. package/src/transpiler/output/codegen/helpers/AssignmentTargetExtractor.ts +17 -45
  59. package/src/transpiler/output/codegen/helpers/AssignmentValidator.ts +83 -78
  60. package/src/transpiler/output/codegen/helpers/CppModeHelper.ts +22 -30
  61. package/src/transpiler/output/codegen/helpers/EnumAssignmentValidator.ts +108 -50
  62. package/src/transpiler/output/codegen/helpers/FloatBitHelper.ts +16 -31
  63. package/src/transpiler/output/codegen/helpers/MemberSeparatorResolver.ts +10 -3
  64. package/src/transpiler/output/codegen/helpers/StringDeclHelper.ts +103 -96
  65. package/src/transpiler/output/codegen/helpers/SymbolLookupHelper.ts +44 -0
  66. package/src/transpiler/output/codegen/helpers/TypeGenerationHelper.ts +9 -0
  67. package/src/transpiler/output/codegen/helpers/__tests__/ArrayAccessHelper.test.ts +479 -0
  68. package/src/transpiler/output/codegen/helpers/__tests__/ArrayInitHelper.test.ts +58 -103
  69. package/src/transpiler/output/codegen/helpers/__tests__/AssignmentExpectedTypeResolver.test.ts +97 -40
  70. package/src/transpiler/output/codegen/helpers/__tests__/AssignmentValidator.test.ts +223 -128
  71. package/src/transpiler/output/codegen/helpers/__tests__/CppModeHelper.test.ts +68 -41
  72. package/src/transpiler/output/codegen/helpers/__tests__/EnumAssignmentValidator.test.ts +198 -47
  73. package/src/transpiler/output/codegen/helpers/__tests__/FloatBitHelper.test.ts +39 -37
  74. package/src/transpiler/output/codegen/helpers/__tests__/MemberSeparatorResolver.test.ts +1 -0
  75. package/src/transpiler/output/codegen/helpers/__tests__/StringDeclHelper.test.ts +191 -453
  76. package/src/transpiler/output/codegen/helpers/__tests__/SymbolLookupHelper.test.ts +201 -0
  77. package/src/transpiler/output/codegen/helpers/__tests__/TypeGenerationHelper.test.ts +50 -0
  78. package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +229 -0
  79. package/src/transpiler/output/codegen/resolution/ScopeResolver.ts +60 -0
  80. package/src/transpiler/output/codegen/resolution/SizeofResolver.ts +177 -0
  81. package/src/transpiler/output/codegen/resolution/__tests__/EnumTypeResolver.test.ts +336 -0
  82. package/src/transpiler/output/codegen/resolution/__tests__/SizeofResolver.test.ts +201 -0
  83. package/src/transpiler/output/codegen/types/IArrayAccessDeps.ts +23 -0
  84. package/src/transpiler/output/codegen/types/IArrayAccessInfo.ts +26 -0
  85. package/src/transpiler/output/codegen/types/IMemberSeparatorDeps.ts +7 -0
  86. package/src/transpiler/output/codegen/utils/CodegenParserUtils.ts +98 -0
  87. package/src/transpiler/output/codegen/utils/ExpressionUnwrapper.ts +22 -22
  88. package/src/transpiler/output/codegen/utils/__tests__/CodegenParserUtils.test.ts +228 -0
  89. package/src/transpiler/types/IFileResult.ts +0 -4
  90. package/src/transpiler/types/IPipelineFile.ts +27 -0
  91. package/src/transpiler/types/IPipelineInput.ts +23 -0
  92. package/src/transpiler/types/TranspilerState.ts +1 -1
  93. package/src/utils/FormatUtils.ts +28 -2
  94. package/src/utils/MapUtils.ts +25 -0
  95. package/src/utils/PostfixAnalysisUtils.ts +48 -0
  96. package/src/utils/__tests__/FormatUtils.test.ts +42 -0
  97. package/src/utils/__tests__/MapUtils.test.ts +85 -0
  98. package/src/utils/constants/OperatorMappings.ts +19 -0
  99. package/src/transpiler/logic/StandaloneContextBuilder.ts +0 -150
  100. package/src/transpiler/logic/__tests__/StandaloneContextBuilder.test.ts +0 -647
  101. package/src/transpiler/output/codegen/types/ITypeResolverDeps.ts +0 -23
  102. package/src/transpiler/output/codegen/types/ITypeValidatorDeps.ts +0 -53
  103. package/src/transpiler/types/ITranspileContext.ts +0 -49
  104. package/src/transpiler/types/ITranspileContribution.ts +0 -32
@@ -3,10 +3,10 @@
3
3
  * Issue #644: strlen caching optimization
4
4
  */
5
5
 
6
- import { describe, it, expect, vi } from "vitest";
6
+ import { describe, it, expect, beforeEach } from "vitest";
7
7
  import StringLengthCounter from "../StringLengthCounter";
8
8
  import CNextSourceParser from "../../../../logic/parser/CNextSourceParser";
9
- import TTypeInfo from "../../types/TTypeInfo";
9
+ import CodeGenState from "../../CodeGenState";
10
10
 
11
11
  /**
12
12
  * Parse a C-Next expression and return the expression context.
@@ -32,122 +32,102 @@ function parseBlock(statements: string) {
32
32
  }
33
33
 
34
34
  describe("StringLengthCounter", () => {
35
+ beforeEach(() => {
36
+ CodeGenState.reset();
37
+ });
38
+
35
39
  describe("countExpression", () => {
36
40
  it("counts single .length access on string variable", () => {
37
- const typeRegistry = vi.fn((name: string): TTypeInfo | undefined => {
38
- if (name === "myStr") {
39
- return {
40
- baseType: "char",
41
- bitWidth: 8,
42
- isArray: false,
43
- isConst: false,
44
- isString: true,
45
- stringCapacity: 64,
46
- };
47
- }
48
- return undefined;
41
+ CodeGenState.typeRegistry.set("myStr", {
42
+ baseType: "char",
43
+ bitWidth: 8,
44
+ isArray: false,
45
+ isConst: false,
46
+ isString: true,
47
+ stringCapacity: 64,
49
48
  });
50
49
 
51
- const counter = new StringLengthCounter(typeRegistry);
52
50
  const expr = parseExpression("myStr.length");
53
- const counts = counter.countExpression(expr);
51
+ const counts = StringLengthCounter.countExpression(expr);
54
52
 
55
53
  expect(counts.get("myStr")).toBe(1);
56
54
  });
57
55
 
58
56
  it("counts multiple .length accesses on same variable", () => {
59
- const typeRegistry = vi.fn((name: string): TTypeInfo | undefined => {
60
- if (name === "str") {
61
- return {
62
- baseType: "char",
63
- bitWidth: 8,
64
- isArray: false,
65
- isConst: false,
66
- isString: true,
67
- stringCapacity: 32,
68
- };
69
- }
70
- return undefined;
57
+ CodeGenState.typeRegistry.set("str", {
58
+ baseType: "char",
59
+ bitWidth: 8,
60
+ isArray: false,
61
+ isConst: false,
62
+ isString: true,
63
+ stringCapacity: 32,
71
64
  });
72
65
 
73
- const counter = new StringLengthCounter(typeRegistry);
74
66
  // Expression: str.length + str.length
75
67
  const expr = parseExpression("str.length + str.length");
76
- const counts = counter.countExpression(expr);
68
+ const counts = StringLengthCounter.countExpression(expr);
77
69
 
78
70
  expect(counts.get("str")).toBe(2);
79
71
  });
80
72
 
81
73
  it("counts .length accesses on different string variables", () => {
82
- const typeRegistry = vi.fn((name: string): TTypeInfo | undefined => {
83
- if (name === "a" || name === "b") {
84
- return {
85
- baseType: "char",
86
- bitWidth: 8,
87
- isArray: false,
88
- isConst: false,
89
- isString: true,
90
- stringCapacity: 16,
91
- };
92
- }
93
- return undefined;
74
+ CodeGenState.typeRegistry.set("a", {
75
+ baseType: "char",
76
+ bitWidth: 8,
77
+ isArray: false,
78
+ isConst: false,
79
+ isString: true,
80
+ stringCapacity: 16,
81
+ });
82
+ CodeGenState.typeRegistry.set("b", {
83
+ baseType: "char",
84
+ bitWidth: 8,
85
+ isArray: false,
86
+ isConst: false,
87
+ isString: true,
88
+ stringCapacity: 16,
94
89
  });
95
90
 
96
- const counter = new StringLengthCounter(typeRegistry);
97
91
  const expr = parseExpression("a.length + b.length");
98
- const counts = counter.countExpression(expr);
92
+ const counts = StringLengthCounter.countExpression(expr);
99
93
 
100
94
  expect(counts.get("a")).toBe(1);
101
95
  expect(counts.get("b")).toBe(1);
102
96
  });
103
97
 
104
98
  it("ignores .length on non-string variables", () => {
105
- const typeRegistry = vi.fn((name: string): TTypeInfo | undefined => {
106
- if (name === "arr") {
107
- return {
108
- baseType: "u8",
109
- bitWidth: 8,
110
- isArray: true,
111
- isConst: false,
112
- arrayDimensions: [10],
113
- };
114
- }
115
- return undefined;
99
+ CodeGenState.typeRegistry.set("arr", {
100
+ baseType: "u8",
101
+ bitWidth: 8,
102
+ isArray: true,
103
+ isConst: false,
104
+ arrayDimensions: [10],
116
105
  });
117
106
 
118
- const counter = new StringLengthCounter(typeRegistry);
119
107
  const expr = parseExpression("arr.length");
120
- const counts = counter.countExpression(expr);
108
+ const counts = StringLengthCounter.countExpression(expr);
121
109
 
122
110
  expect(counts.get("arr")).toBeUndefined();
123
111
  });
124
112
 
125
113
  it("ignores other member accesses", () => {
126
- const typeRegistry = vi.fn((name: string): TTypeInfo | undefined => {
127
- if (name === "obj") {
128
- return {
129
- baseType: "MyStruct",
130
- bitWidth: 32,
131
- isArray: false,
132
- isConst: false,
133
- };
134
- }
135
- return undefined;
114
+ CodeGenState.typeRegistry.set("obj", {
115
+ baseType: "MyStruct",
116
+ bitWidth: 32,
117
+ isArray: false,
118
+ isConst: false,
136
119
  });
137
120
 
138
- const counter = new StringLengthCounter(typeRegistry);
139
121
  const expr = parseExpression("obj.value");
140
- const counts = counter.countExpression(expr);
122
+ const counts = StringLengthCounter.countExpression(expr);
141
123
 
142
124
  expect(counts.size).toBe(0);
143
125
  });
144
126
 
145
127
  it("handles unknown variables gracefully", () => {
146
- const typeRegistry = vi.fn((): TTypeInfo | undefined => undefined);
147
-
148
- const counter = new StringLengthCounter(typeRegistry);
128
+ // No type registered for "unknown"
149
129
  const expr = parseExpression("unknown.length");
150
- const counts = counter.countExpression(expr);
130
+ const counts = StringLengthCounter.countExpression(expr);
151
131
 
152
132
  expect(counts.size).toBe(0);
153
133
  });
@@ -155,51 +135,39 @@ describe("StringLengthCounter", () => {
155
135
 
156
136
  describe("countBlock", () => {
157
137
  it("counts .length accesses across multiple statements", () => {
158
- const typeRegistry = vi.fn((name: string): TTypeInfo | undefined => {
159
- if (name === "msg") {
160
- return {
161
- baseType: "char",
162
- bitWidth: 8,
163
- isArray: false,
164
- isConst: false,
165
- isString: true,
166
- stringCapacity: 128,
167
- };
168
- }
169
- return undefined;
138
+ CodeGenState.typeRegistry.set("msg", {
139
+ baseType: "char",
140
+ bitWidth: 8,
141
+ isArray: false,
142
+ isConst: false,
143
+ isString: true,
144
+ stringCapacity: 128,
170
145
  });
171
146
 
172
- const counter = new StringLengthCounter(typeRegistry);
173
147
  const block = parseBlock(`
174
148
  u32 len <- msg.length;
175
149
  u32 doubled <- msg.length * 2;
176
150
  `);
177
- const counts = counter.countBlock(block);
151
+ const counts = StringLengthCounter.countBlock(block);
178
152
 
179
153
  expect(counts.get("msg")).toBe(2);
180
154
  });
181
155
 
182
156
  it("counts .length in assignment statements", () => {
183
- const typeRegistry = vi.fn((name: string): TTypeInfo | undefined => {
184
- if (name === "text") {
185
- return {
186
- baseType: "char",
187
- bitWidth: 8,
188
- isArray: false,
189
- isConst: false,
190
- isString: true,
191
- stringCapacity: 64,
192
- };
193
- }
194
- return undefined;
157
+ CodeGenState.typeRegistry.set("text", {
158
+ baseType: "char",
159
+ bitWidth: 8,
160
+ isArray: false,
161
+ isConst: false,
162
+ isString: true,
163
+ stringCapacity: 64,
195
164
  });
196
165
 
197
- const counter = new StringLengthCounter(typeRegistry);
198
166
  const block = parseBlock(`
199
167
  u32 x;
200
168
  x <- text.length;
201
169
  `);
202
- const counts = counter.countBlock(block);
170
+ const counts = StringLengthCounter.countBlock(block);
203
171
 
204
172
  expect(counts.get("text")).toBe(1);
205
173
  });
@@ -207,21 +175,22 @@ describe("StringLengthCounter", () => {
207
175
 
208
176
  describe("countBlockInto", () => {
209
177
  it("adds counts to existing map", () => {
210
- const typeRegistry = vi.fn((name: string): TTypeInfo | undefined => {
211
- if (name === "s1" || name === "s2") {
212
- return {
213
- baseType: "char",
214
- bitWidth: 8,
215
- isArray: false,
216
- isConst: false,
217
- isString: true,
218
- stringCapacity: 32,
219
- };
220
- }
221
- return undefined;
178
+ CodeGenState.typeRegistry.set("s1", {
179
+ baseType: "char",
180
+ bitWidth: 8,
181
+ isArray: false,
182
+ isConst: false,
183
+ isString: true,
184
+ stringCapacity: 32,
185
+ });
186
+ CodeGenState.typeRegistry.set("s2", {
187
+ baseType: "char",
188
+ bitWidth: 8,
189
+ isArray: false,
190
+ isConst: false,
191
+ isString: true,
192
+ stringCapacity: 32,
222
193
  });
223
-
224
- const counter = new StringLengthCounter(typeRegistry);
225
194
 
226
195
  // Pre-populate counts
227
196
  const counts = new Map<string, number>();
@@ -231,7 +200,7 @@ describe("StringLengthCounter", () => {
231
200
  u32 a <- s1.length;
232
201
  u32 b <- s2.length;
233
202
  `);
234
- counter.countBlockInto(block, counts);
203
+ StringLengthCounter.countBlockInto(block, counts);
235
204
 
236
205
  expect(counts.get("s1")).toBe(2); // 1 existing + 1 new
237
206
  expect(counts.get("s2")).toBe(1);
@@ -240,45 +209,33 @@ describe("StringLengthCounter", () => {
240
209
 
241
210
  describe("nested expressions", () => {
242
211
  it("counts .length in ternary expressions", () => {
243
- const typeRegistry = vi.fn((name: string): TTypeInfo | undefined => {
244
- if (name === "str") {
245
- return {
246
- baseType: "char",
247
- bitWidth: 8,
248
- isArray: false,
249
- isConst: false,
250
- isString: true,
251
- stringCapacity: 64,
252
- };
253
- }
254
- return undefined;
212
+ CodeGenState.typeRegistry.set("str", {
213
+ baseType: "char",
214
+ bitWidth: 8,
215
+ isArray: false,
216
+ isConst: false,
217
+ isString: true,
218
+ stringCapacity: 64,
255
219
  });
256
220
 
257
- const counter = new StringLengthCounter(typeRegistry);
258
221
  const expr = parseExpression("(str.length > 0) ? str.length : 0");
259
- const counts = counter.countExpression(expr);
222
+ const counts = StringLengthCounter.countExpression(expr);
260
223
 
261
224
  expect(counts.get("str")).toBe(2);
262
225
  });
263
226
 
264
227
  it("counts .length in comparison expressions", () => {
265
- const typeRegistry = vi.fn((name: string): TTypeInfo | undefined => {
266
- if (name === "name") {
267
- return {
268
- baseType: "char",
269
- bitWidth: 8,
270
- isArray: false,
271
- isConst: false,
272
- isString: true,
273
- stringCapacity: 50,
274
- };
275
- }
276
- return undefined;
228
+ CodeGenState.typeRegistry.set("name", {
229
+ baseType: "char",
230
+ bitWidth: 8,
231
+ isArray: false,
232
+ isConst: false,
233
+ isString: true,
234
+ stringCapacity: 50,
277
235
  });
278
236
 
279
- const counter = new StringLengthCounter(typeRegistry);
280
237
  const expr = parseExpression("name.length = 10");
281
- const counts = counter.countExpression(expr);
238
+ const counts = StringLengthCounter.countExpression(expr);
282
239
 
283
240
  expect(counts.get("name")).toBe(1);
284
241
  });