c-next 0.1.62 → 0.1.64

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 (55) hide show
  1. package/README.md +86 -63
  2. package/package.json +1 -1
  3. package/src/transpiler/Transpiler.ts +3 -2
  4. package/src/transpiler/__tests__/DualCodePaths.test.ts +1 -1
  5. package/src/transpiler/__tests__/Transpiler.coverage.test.ts +1 -1
  6. package/src/transpiler/__tests__/Transpiler.test.ts +0 -23
  7. package/src/transpiler/logic/symbols/cnext/collectors/StructCollector.ts +156 -70
  8. package/src/transpiler/logic/symbols/cnext/collectors/VariableCollector.ts +31 -6
  9. package/src/transpiler/logic/symbols/cnext/utils/TypeUtils.ts +43 -11
  10. package/src/transpiler/output/codegen/CodeGenState.ts +811 -0
  11. package/src/transpiler/output/codegen/CodeGenerator.ts +848 -1382
  12. package/src/transpiler/output/codegen/TypeResolver.ts +193 -149
  13. package/src/transpiler/output/codegen/TypeValidator.ts +148 -370
  14. package/src/transpiler/output/codegen/__tests__/CodeGenState.test.ts +446 -0
  15. package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +462 -60
  16. package/src/transpiler/output/codegen/__tests__/TrackVariableTypeHelpers.test.ts +1 -1
  17. package/src/transpiler/output/codegen/__tests__/TypeResolver.test.ts +435 -196
  18. package/src/transpiler/output/codegen/__tests__/TypeValidator.resolution.test.ts +51 -67
  19. package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +495 -471
  20. package/src/transpiler/output/codegen/analysis/MemberChainAnalyzer.ts +39 -43
  21. package/src/transpiler/output/codegen/analysis/StringLengthCounter.ts +52 -55
  22. package/src/transpiler/output/codegen/analysis/__tests__/MemberChainAnalyzer.test.ts +122 -62
  23. package/src/transpiler/output/codegen/analysis/__tests__/StringLengthCounter.test.ts +101 -144
  24. package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +143 -126
  25. package/src/transpiler/output/codegen/assignment/__tests__/AssignmentClassifier.test.ts +287 -320
  26. package/src/transpiler/output/codegen/generators/GeneratorRegistry.ts +12 -0
  27. package/src/transpiler/output/codegen/generators/__tests__/GeneratorRegistry.test.ts +28 -1
  28. package/src/transpiler/output/codegen/generators/declarationGenerators/ArrayDimensionUtils.ts +67 -0
  29. package/src/transpiler/output/codegen/generators/declarationGenerators/ScopeGenerator.ts +121 -51
  30. package/src/transpiler/output/codegen/generators/declarationGenerators/StructGenerator.ts +100 -23
  31. package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ArrayDimensionUtils.test.ts +125 -0
  32. package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ScopeGenerator.test.ts +157 -4
  33. package/src/transpiler/output/codegen/generators/support/HelperGenerator.ts +23 -22
  34. package/src/transpiler/output/codegen/helpers/ArrayInitHelper.ts +54 -61
  35. package/src/transpiler/output/codegen/helpers/AssignmentExpectedTypeResolver.ts +21 -30
  36. package/src/transpiler/output/codegen/helpers/AssignmentValidator.ts +56 -53
  37. package/src/transpiler/output/codegen/helpers/CppModeHelper.ts +22 -30
  38. package/src/transpiler/output/codegen/helpers/EnumAssignmentValidator.ts +108 -50
  39. package/src/transpiler/output/codegen/helpers/FloatBitHelper.ts +16 -31
  40. package/src/transpiler/output/codegen/helpers/StringDeclHelper.ts +103 -96
  41. package/src/transpiler/output/codegen/helpers/TypeGenerationHelper.ts +9 -0
  42. package/src/transpiler/output/codegen/helpers/__tests__/ArrayInitHelper.test.ts +58 -103
  43. package/src/transpiler/output/codegen/helpers/__tests__/AssignmentExpectedTypeResolver.test.ts +97 -40
  44. package/src/transpiler/output/codegen/helpers/__tests__/AssignmentValidator.test.ts +223 -128
  45. package/src/transpiler/output/codegen/helpers/__tests__/CppModeHelper.test.ts +68 -41
  46. package/src/transpiler/output/codegen/helpers/__tests__/EnumAssignmentValidator.test.ts +198 -47
  47. package/src/transpiler/output/codegen/helpers/__tests__/FloatBitHelper.test.ts +39 -37
  48. package/src/transpiler/output/codegen/helpers/__tests__/StringDeclHelper.test.ts +191 -453
  49. package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +229 -0
  50. package/src/transpiler/output/codegen/resolution/ScopeResolver.ts +60 -0
  51. package/src/transpiler/output/codegen/resolution/SizeofResolver.ts +177 -0
  52. package/src/transpiler/output/codegen/resolution/__tests__/EnumTypeResolver.test.ts +336 -0
  53. package/src/transpiler/output/codegen/resolution/__tests__/SizeofResolver.test.ts +201 -0
  54. package/src/transpiler/output/codegen/types/ITypeResolverDeps.ts +0 -23
  55. package/src/transpiler/output/codegen/types/ITypeValidatorDeps.ts +0 -53
@@ -1466,7 +1466,7 @@ describe("CodeGenerator", () => {
1466
1466
  describe("Array declarations", () => {
1467
1467
  it("should generate array declaration", () => {
1468
1468
  const source = `
1469
- u32 arr[10];
1469
+ u32[10] arr;
1470
1470
  void main() { }
1471
1471
  `;
1472
1472
  const { tree, tokenStream } = CNextSourceParser.parse(source);
@@ -1485,7 +1485,7 @@ describe("CodeGenerator", () => {
1485
1485
 
1486
1486
  it("should generate array with initializer", () => {
1487
1487
  const source = `
1488
- u32 arr[3] <- [1, 2, 3];
1488
+ u32[3] arr <- [1, 2, 3];
1489
1489
  void main() { }
1490
1490
  `;
1491
1491
  const { tree, tokenStream } = CNextSourceParser.parse(source);
@@ -1505,7 +1505,7 @@ describe("CodeGenerator", () => {
1505
1505
 
1506
1506
  it("should generate multi-dimensional array", () => {
1507
1507
  const source = `
1508
- u32 matrix[3][3];
1508
+ u32[3] matrix[3];
1509
1509
  void main() { }
1510
1510
  `;
1511
1511
  const { tree, tokenStream } = CNextSourceParser.parse(source);
@@ -2586,7 +2586,7 @@ describe("CodeGenerator", () => {
2586
2586
  describe("Array element assignment", () => {
2587
2587
  it("should generate array element assignment", () => {
2588
2588
  const source = `
2589
- wrap u32 arr[10];
2589
+ wrap u32[10] arr;
2590
2590
  void main() {
2591
2591
  arr[0] <- 42;
2592
2592
  arr[5] <- 100;
@@ -2734,7 +2734,7 @@ describe("CodeGenerator", () => {
2734
2734
  it("should generate struct with array field", () => {
2735
2735
  const source = `
2736
2736
  struct Buffer {
2737
- u8 data[64];
2737
+ u8[64] data;
2738
2738
  u32 length;
2739
2739
  }
2740
2740
  `;
@@ -3297,7 +3297,7 @@ describe("CodeGenerator", () => {
3297
3297
  it("should generate struct with array member access", () => {
3298
3298
  const source = `
3299
3299
  struct Buffer {
3300
- u8 data[64];
3300
+ u8[64] data;
3301
3301
  }
3302
3302
  Buffer buf;
3303
3303
  void main() {
@@ -3427,7 +3427,7 @@ describe("CodeGenerator", () => {
3427
3427
  describe("Const array", () => {
3428
3428
  it("should generate const array", () => {
3429
3429
  const source = `
3430
- const u32 LOOKUP[4] <- [10, 20, 30, 40];
3430
+ const u32[4] LOOKUP <- [10, 20, 30, 40];
3431
3431
  void main() { }
3432
3432
  `;
3433
3433
  const { tree, tokenStream } = CNextSourceParser.parse(source);
@@ -3853,7 +3853,7 @@ describe("CodeGenerator", () => {
3853
3853
  describe("Array fill-all syntax", () => {
3854
3854
  it("should generate fill-all array [0*]", () => {
3855
3855
  const source = `
3856
- u32 data[10] <- [0*];
3856
+ u32[10] data <- [0*];
3857
3857
  `;
3858
3858
  const { tree, tokenStream } = CNextSourceParser.parse(source);
3859
3859
  const generator = new CodeGenerator();
@@ -3872,7 +3872,7 @@ describe("CodeGenerator", () => {
3872
3872
 
3873
3873
  it("should generate fill-all array with non-zero value", () => {
3874
3874
  const source = `
3875
- u8 buffer[4] <- [255*];
3875
+ u8[4] buffer <- [255*];
3876
3876
  `;
3877
3877
  const { tree, tokenStream } = CNextSourceParser.parse(source);
3878
3878
  const generator = new CodeGenerator();
@@ -3893,7 +3893,7 @@ describe("CodeGenerator", () => {
3893
3893
  describe("Nested array initializers", () => {
3894
3894
  it("should generate 2D array initializer", () => {
3895
3895
  const source = `
3896
- u32 matrix[2][3] <- [[1, 2, 3], [4, 5, 6]];
3896
+ u32[2] matrix[3] <- [[1, 2, 3], [4, 5, 6]];
3897
3897
  `;
3898
3898
  const { tree, tokenStream } = CNextSourceParser.parse(source);
3899
3899
  const generator = new CodeGenerator();
@@ -3914,7 +3914,7 @@ describe("CodeGenerator", () => {
3914
3914
  it("should generate array of struct initializers", () => {
3915
3915
  const source = `
3916
3916
  struct Point { i32 x; i32 y; }
3917
- Point points[2] <- [{x: 1, y: 2}, {x: 3, y: 4}];
3917
+ Point[2] points <- [{x: 1, y: 2}, {x: 3, y: 4}];
3918
3918
  `;
3919
3919
  const { tree, tokenStream } = CNextSourceParser.parse(source);
3920
3920
  const generator = new CodeGenerator();
@@ -4184,7 +4184,7 @@ describe("CodeGenerator", () => {
4184
4184
  it("should resolve const as array dimension at file scope", () => {
4185
4185
  const source = `
4186
4186
  const u32 SIZE <- 10;
4187
- u32 data[SIZE];
4187
+ u32[SIZE] data;
4188
4188
  `;
4189
4189
  const { tree, tokenStream } = CNextSourceParser.parse(source);
4190
4190
  const generator = new CodeGenerator();
@@ -4205,7 +4205,7 @@ describe("CodeGenerator", () => {
4205
4205
  describe("Multi-dimensional array", () => {
4206
4206
  it("should generate 3D array declaration", () => {
4207
4207
  const source = `
4208
- u8 cube[2][3][4];
4208
+ u8[2] cube[3][4];
4209
4209
  `;
4210
4210
  const { tree, tokenStream } = CNextSourceParser.parse(source);
4211
4211
  const generator = new CodeGenerator();
@@ -4686,7 +4686,7 @@ describe("CodeGenerator", () => {
4686
4686
  describe("Array indexing with expressions", () => {
4687
4687
  it("should generate array index with arithmetic", () => {
4688
4688
  const source = `
4689
- u32 data[10];
4689
+ u32[10] data;
4690
4690
  wrap u32 i <- 2;
4691
4691
  void main() {
4692
4692
  data[i * 2 + 1] <- 42;
@@ -4877,7 +4877,7 @@ describe("CodeGenerator", () => {
4877
4877
  describe("Array length", () => {
4878
4878
  it("should generate array length using sizeof", () => {
4879
4879
  const source = `
4880
- u32 data[10];
4880
+ u32[10] data;
4881
4881
  u32 len <- data.length;
4882
4882
  `;
4883
4883
  const { tree, tokenStream } = CNextSourceParser.parse(source);
@@ -5285,7 +5285,7 @@ describe("CodeGenerator", () => {
5285
5285
  it("should pass array without address-of operator", () => {
5286
5286
  const source = `
5287
5287
  void processData(u32 data[]) { }
5288
- u32 myData[5];
5288
+ u32[5] myData;
5289
5289
  void main() {
5290
5290
  processData(myData);
5291
5291
  }
@@ -5310,7 +5310,7 @@ describe("CodeGenerator", () => {
5310
5310
  it("should generate struct with array field", () => {
5311
5311
  const source = `
5312
5312
  struct Buffer {
5313
- u8 data[64];
5313
+ u8[64] data;
5314
5314
  u32 length;
5315
5315
  }
5316
5316
  `;
@@ -5694,7 +5694,7 @@ describe("CodeGenerator", () => {
5694
5694
  describe("Array bounds checking", () => {
5695
5695
  it("should throw error for out-of-bounds constant index", () => {
5696
5696
  const source = `
5697
- u32 data[5];
5697
+ u32[5] data;
5698
5698
  void main() {
5699
5699
  data[10] <- 1;
5700
5700
  }
@@ -5899,7 +5899,7 @@ describe("CodeGenerator", () => {
5899
5899
  describe("Sizeof variable", () => {
5900
5900
  it("should generate sizeof for variable", () => {
5901
5901
  const source = `
5902
- u32 arr[10];
5902
+ u32[10] arr;
5903
5903
  u32 size <- sizeof(arr);
5904
5904
  `;
5905
5905
  const { tree, tokenStream } = CNextSourceParser.parse(source);
@@ -5921,7 +5921,7 @@ describe("CodeGenerator", () => {
5921
5921
  it("should resolve const to literal for file-scope array", () => {
5922
5922
  const source = `
5923
5923
  const u32 BUFFER_SIZE <- 256;
5924
- u8 buffer[BUFFER_SIZE];
5924
+ u8[BUFFER_SIZE] buffer;
5925
5925
  `;
5926
5926
  const { tree, tokenStream } = CNextSourceParser.parse(source);
5927
5927
  const generator = new CodeGenerator();
@@ -6056,7 +6056,7 @@ describe("CodeGenerator", () => {
6056
6056
  it("should generate struct with array field access", () => {
6057
6057
  const source = `
6058
6058
  struct Message {
6059
- u8 data[8];
6059
+ u8[8] data;
6060
6060
  u8 length;
6061
6061
  }
6062
6062
  Message msg;
@@ -6166,7 +6166,7 @@ describe("CodeGenerator", () => {
6166
6166
  const source = `
6167
6167
  void setup() {
6168
6168
  const u32 SIZE <- 5;
6169
- u32 data[SIZE];
6169
+ u32[SIZE] data;
6170
6170
  }
6171
6171
  `;
6172
6172
  const { tree, tokenStream } = CNextSourceParser.parse(source);
@@ -6181,7 +6181,8 @@ describe("CodeGenerator", () => {
6181
6181
  });
6182
6182
 
6183
6183
  expect(code).toContain("SIZE");
6184
- expect(code).toContain("[SIZE]");
6184
+ // Const value is evaluated at compile time
6185
+ expect(code).toContain("data[5]");
6185
6186
  });
6186
6187
  });
6187
6188
 
@@ -6666,7 +6667,7 @@ describe("CodeGenerator", () => {
6666
6667
 
6667
6668
  describe("Array with literal size", () => {
6668
6669
  it("should generate array with integer literal size", () => {
6669
- const source = `u32 buffer[100];`;
6670
+ const source = `u32[100] buffer;`;
6670
6671
  const { tree, tokenStream } = CNextSourceParser.parse(source);
6671
6672
  const generator = new CodeGenerator();
6672
6673
  const symbolTable = new SymbolTable();
@@ -6793,7 +6794,7 @@ describe("CodeGenerator", () => {
6793
6794
 
6794
6795
  describe("Array initialization with values", () => {
6795
6796
  it("should generate array with initialization list", () => {
6796
- const source = `u8 data[4] <- [1, 2, 3, 4];`;
6797
+ const source = `u8[4] data <- [1, 2, 3, 4];`;
6797
6798
  const { tree, tokenStream } = CNextSourceParser.parse(source);
6798
6799
  const generator = new CodeGenerator();
6799
6800
  const symbolTable = new SymbolTable();
@@ -6814,7 +6815,7 @@ describe("CodeGenerator", () => {
6814
6815
  const source = `
6815
6816
  void process(u8 arr[]) { }
6816
6817
  void main() {
6817
- u8 local[10];
6818
+ u8[10] local;
6818
6819
  process(local);
6819
6820
  }
6820
6821
  `;
@@ -7081,7 +7082,7 @@ describe("CodeGenerator", () => {
7081
7082
  it("should initialize POD arrays to {0}", () => {
7082
7083
  const source = `
7083
7084
  void main() {
7084
- u32 values[10];
7085
+ u32[10] values;
7085
7086
  }
7086
7087
  `;
7087
7088
  const { tree, tokenStream } = CNextSourceParser.parse(source);
@@ -7102,7 +7103,7 @@ describe("CodeGenerator", () => {
7102
7103
  const source = `
7103
7104
  struct Point { i32 x; i32 y; }
7104
7105
  void main() {
7105
- Point points[5];
7106
+ Point[5] points;
7106
7107
  }
7107
7108
  `;
7108
7109
  const { tree, tokenStream } = CNextSourceParser.parse(source);
@@ -7168,6 +7169,142 @@ describe("CodeGenerator", () => {
7168
7169
 
7169
7170
  // Note: Template type tests skipped - template argument transformation
7170
7171
  // (i32 -> int32_t) is a separate issue to be addressed in another PR
7172
+
7173
+ it("should generate C-Next style array params with dimensions in C++ mode", () => {
7174
+ const source = `
7175
+ void fill(u8[8] buf) {
7176
+ buf[0] <- 0xFF;
7177
+ }
7178
+ `;
7179
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
7180
+ const generator = new CodeGenerator();
7181
+ const symbolTable = new SymbolTable();
7182
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
7183
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
7184
+
7185
+ const code = generator.generate(tree, symbolTable, tokenStream, {
7186
+ symbolInfo: symbols,
7187
+ sourcePath: "test.cnx",
7188
+ cppMode: true,
7189
+ });
7190
+
7191
+ // C-Next style u8[8] param should generate uint8_t buf[8], not uint8_t& buf
7192
+ expect(code).toContain("uint8_t buf[8]");
7193
+ expect(code).not.toContain("uint8_t& buf");
7194
+ expect(code).not.toContain("uint8_t& buf");
7195
+ });
7196
+
7197
+ it("should generate const C-Next style array params in C++ mode", () => {
7198
+ const source = `
7199
+ u8 read(const u8[4] data) {
7200
+ return data[0];
7201
+ }
7202
+ `;
7203
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
7204
+ const generator = new CodeGenerator();
7205
+ const symbolTable = new SymbolTable();
7206
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
7207
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
7208
+
7209
+ const code = generator.generate(tree, symbolTable, tokenStream, {
7210
+ symbolInfo: symbols,
7211
+ sourcePath: "test.cnx",
7212
+ cppMode: true,
7213
+ });
7214
+
7215
+ // Const C-Next style array param should retain dimension
7216
+ expect(code).toContain("const uint8_t data[4]");
7217
+ expect(code).not.toContain("const uint8_t& data");
7218
+ });
7219
+
7220
+ it("should generate C-Next style array params in C mode too", () => {
7221
+ const source = `
7222
+ void fill(u8[8] buf) {
7223
+ buf[0] <- 0xFF;
7224
+ }
7225
+ `;
7226
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
7227
+ const generator = new CodeGenerator();
7228
+ const symbolTable = new SymbolTable();
7229
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
7230
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
7231
+
7232
+ const code = generator.generate(tree, symbolTable, tokenStream, {
7233
+ symbolInfo: symbols,
7234
+ sourcePath: "test.cnx",
7235
+ });
7236
+
7237
+ // C mode should also generate uint8_t buf[8]
7238
+ expect(code).toContain("uint8_t buf[8]");
7239
+ expect(code).not.toContain("uint8_t* buf");
7240
+ });
7241
+
7242
+ it("should generate primitive C-Next style arrays with {0} in C++ mode", () => {
7243
+ const source = `
7244
+ void main() {
7245
+ u32[8] counters;
7246
+ }
7247
+ `;
7248
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
7249
+ const generator = new CodeGenerator();
7250
+ const symbolTable = new SymbolTable();
7251
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
7252
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
7253
+
7254
+ const code = generator.generate(tree, symbolTable, tokenStream, {
7255
+ symbolInfo: symbols,
7256
+ sourcePath: "test.cnx",
7257
+ cppMode: true,
7258
+ });
7259
+
7260
+ // Primitive type arrays should still use {0}
7261
+ expect(code).toContain("uint32_t counters[8] = {0}");
7262
+ });
7263
+
7264
+ it("should generate unknown user type C-Next style arrays with {} in C++ mode", () => {
7265
+ const source = `
7266
+ void main() {
7267
+ UnknownType[4] items;
7268
+ }
7269
+ `;
7270
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
7271
+ const generator = new CodeGenerator();
7272
+ const symbolTable = new SymbolTable();
7273
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
7274
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
7275
+
7276
+ const code = generator.generate(tree, symbolTable, tokenStream, {
7277
+ symbolInfo: symbols,
7278
+ sourcePath: "test.cnx",
7279
+ cppMode: true,
7280
+ });
7281
+
7282
+ // Unknown types in C++ mode use {} (may have non-trivial constructors)
7283
+ expect(code).toContain("UnknownType items[4] = {}");
7284
+ });
7285
+
7286
+ it("should generate known C-Next struct arrays with {0} in C++ mode", () => {
7287
+ const source = `
7288
+ struct Point { i32 x; i32 y; }
7289
+ void main() {
7290
+ Point[3] pts;
7291
+ }
7292
+ `;
7293
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
7294
+ const generator = new CodeGenerator();
7295
+ const symbolTable = new SymbolTable();
7296
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
7297
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
7298
+
7299
+ const code = generator.generate(tree, symbolTable, tokenStream, {
7300
+ symbolInfo: symbols,
7301
+ sourcePath: "test.cnx",
7302
+ cppMode: true,
7303
+ });
7304
+
7305
+ // Known C-Next structs are POD types, {0} is correct
7306
+ expect(code).toContain("Point pts[3] = {0}");
7307
+ });
7171
7308
  });
7172
7309
  });
7173
7310
 
@@ -7347,7 +7484,7 @@ describe("CodeGenerator", () => {
7347
7484
  it("should generate struct array member write", () => {
7348
7485
  const source = `
7349
7486
  struct Item { u32 value; }
7350
- Item items[3];
7487
+ Item[3] items;
7351
7488
  void main() {
7352
7489
  items[0].value <- 42;
7353
7490
  }
@@ -7932,7 +8069,7 @@ describe("CodeGenerator", () => {
7932
8069
  const source = `
7933
8070
  void callee(u32 arr[10]) { }
7934
8071
  void test() {
7935
- u32 data[10];
8072
+ u32[10] data;
7936
8073
  callee(data);
7937
8074
  }
7938
8075
  `;
@@ -7976,7 +8113,7 @@ describe("CodeGenerator", () => {
7976
8113
  const source = `
7977
8114
  void callee(u32 val) { }
7978
8115
  void test() {
7979
- u32 arr[10];
8116
+ u32[10] arr;
7980
8117
  callee(arr[0]);
7981
8118
  }
7982
8119
  `;
@@ -8426,7 +8563,7 @@ describe("CodeGenerator", () => {
8426
8563
  it("should handle sizeof on variable", () => {
8427
8564
  const source = `
8428
8565
  void test() {
8429
- u32 arr[10];
8566
+ u32[10] arr;
8430
8567
  u32 size <- sizeof(arr);
8431
8568
  }
8432
8569
  `;
@@ -8491,7 +8628,7 @@ describe("CodeGenerator", () => {
8491
8628
  it("should handle single index array access", () => {
8492
8629
  const source = `
8493
8630
  void test() {
8494
- u32 arr[10];
8631
+ u32[10] arr;
8495
8632
  u32 val <- arr[5];
8496
8633
  }
8497
8634
  `;
@@ -8575,7 +8712,7 @@ describe("CodeGenerator", () => {
8575
8712
  it("should handle C++ mode array access", () => {
8576
8713
  const source = `
8577
8714
  void test() {
8578
- u32 arr[10];
8715
+ u32[10] arr;
8579
8716
  u32 val <- arr[5];
8580
8717
  }
8581
8718
  `;
@@ -8597,7 +8734,7 @@ describe("CodeGenerator", () => {
8597
8734
  it("should handle multi-dimensional array access", () => {
8598
8735
  const source = `
8599
8736
  void test() {
8600
- u32 matrix[3][3];
8737
+ u32[3] matrix[3];
8601
8738
  u32 val <- matrix[1][2];
8602
8739
  }
8603
8740
  `;
@@ -8778,7 +8915,7 @@ describe("CodeGenerator", () => {
8778
8915
  const source = `
8779
8916
  struct Point { u32 x; u32 y; }
8780
8917
  void test() {
8781
- Point points[10];
8918
+ Point[10] points;
8782
8919
  u32 x <- points[0].x;
8783
8920
  }
8784
8921
  `;
@@ -9141,7 +9278,7 @@ describe("CodeGenerator", () => {
9141
9278
  it("should resolve const values in expressions", () => {
9142
9279
  const source = `
9143
9280
  const u32 MAX_SIZE <- 100;
9144
- u32 buffer[MAX_SIZE];
9281
+ u32[MAX_SIZE] buffer;
9145
9282
  `;
9146
9283
  const { tree, tokenStream } = CNextSourceParser.parse(source);
9147
9284
  const generator = new CodeGenerator();
@@ -9210,7 +9347,7 @@ describe("CodeGenerator", () => {
9210
9347
  it("should handle array access in assignment target", () => {
9211
9348
  const source = `
9212
9349
  void test() {
9213
- u32 arr[10];
9350
+ u32[10] arr;
9214
9351
  arr[5] <- 42;
9215
9352
  }
9216
9353
  `;
@@ -9716,7 +9853,7 @@ describe("CodeGenerator", () => {
9716
9853
  it("should generate struct with array member", () => {
9717
9854
  const source = `
9718
9855
  struct Buffer {
9719
- u8 data[64];
9856
+ u8[64] data;
9720
9857
  u32 size;
9721
9858
  }
9722
9859
  Buffer buf;
@@ -9833,7 +9970,7 @@ describe("CodeGenerator", () => {
9833
9970
  it("should generate array with initializer list", () => {
9834
9971
  const source = `
9835
9972
  void test() {
9836
- u32 arr[5] <- [1, 2, 3, 4, 5];
9973
+ u32[5] arr <- [1, 2, 3, 4, 5];
9837
9974
  }
9838
9975
  `;
9839
9976
  const { tree, tokenStream } = CNextSourceParser.parse(source);
@@ -11130,7 +11267,7 @@ describe("CodeGenerator", () => {
11130
11267
  data[0] <- 1;
11131
11268
  }
11132
11269
  void test() {
11133
- u32 arr[10];
11270
+ u32[10] arr;
11134
11271
  process(arr);
11135
11272
  }
11136
11273
  `;
@@ -11436,7 +11573,7 @@ describe("CodeGenerator", () => {
11436
11573
  it("should handle array with size in declaration", () => {
11437
11574
  const source = `
11438
11575
  void test() {
11439
- u8 buffer[10];
11576
+ u8[10] buffer;
11440
11577
  buffer[0] <- 0xFF;
11441
11578
  }
11442
11579
  `;
@@ -11458,7 +11595,7 @@ describe("CodeGenerator", () => {
11458
11595
  const source = `
11459
11596
  const u32 BUFFER_SIZE <- 64;
11460
11597
  void test() {
11461
- u8 buffer[BUFFER_SIZE];
11598
+ u8[BUFFER_SIZE] buffer;
11462
11599
  buffer[0] <- 0;
11463
11600
  }
11464
11601
  `;
@@ -11475,6 +11612,90 @@ describe("CodeGenerator", () => {
11475
11612
 
11476
11613
  expect(code).toContain("BUFFER_SIZE");
11477
11614
  });
11615
+
11616
+ it("should reject C-style array declaration for primitive types", () => {
11617
+ const source = `
11618
+ void test() {
11619
+ u8 buffer[10];
11620
+ }
11621
+ `;
11622
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
11623
+ const generator = new CodeGenerator();
11624
+ const symbolTable = new SymbolTable();
11625
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
11626
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
11627
+
11628
+ expect(() => {
11629
+ generator.generate(tree, symbolTable, tokenStream, {
11630
+ symbolInfo: symbols,
11631
+ sourcePath: "test.cnx",
11632
+ });
11633
+ }).toThrow(/C-style array declaration is not allowed/);
11634
+ });
11635
+
11636
+ it("should reject C-style array declaration for user types", () => {
11637
+ const source = `
11638
+ struct Data {
11639
+ u32 value;
11640
+ }
11641
+ void test() {
11642
+ Data items[5];
11643
+ }
11644
+ `;
11645
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
11646
+ const generator = new CodeGenerator();
11647
+ const symbolTable = new SymbolTable();
11648
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
11649
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
11650
+
11651
+ expect(() => {
11652
+ generator.generate(tree, symbolTable, tokenStream, {
11653
+ symbolInfo: symbols,
11654
+ sourcePath: "test.cnx",
11655
+ });
11656
+ }).toThrow(/C-style array declaration is not allowed/);
11657
+ });
11658
+
11659
+ it("should allow empty brackets for size inference", () => {
11660
+ const source = `
11661
+ void test() {
11662
+ u8 data[] <- [1, 2, 3];
11663
+ }
11664
+ `;
11665
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
11666
+ const generator = new CodeGenerator();
11667
+ const symbolTable = new SymbolTable();
11668
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
11669
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
11670
+
11671
+ const code = generator.generate(tree, symbolTable, tokenStream, {
11672
+ symbolInfo: symbols,
11673
+ sourcePath: "test.cnx",
11674
+ });
11675
+
11676
+ expect(code).toContain("uint8_t data[3]");
11677
+ });
11678
+
11679
+ it("should allow multi-dimensional C-style arrays", () => {
11680
+ const source = `
11681
+ void test() {
11682
+ u8 matrix[4][4];
11683
+ matrix[0][0] <- 0;
11684
+ }
11685
+ `;
11686
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
11687
+ const generator = new CodeGenerator();
11688
+ const symbolTable = new SymbolTable();
11689
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
11690
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
11691
+
11692
+ const code = generator.generate(tree, symbolTable, tokenStream, {
11693
+ symbolInfo: symbols,
11694
+ sourcePath: "test.cnx",
11695
+ });
11696
+
11697
+ expect(code).toContain("uint8_t matrix[4][4]");
11698
+ });
11478
11699
  });
11479
11700
 
11480
11701
  describe("string expression type checking", () => {
@@ -12208,7 +12429,7 @@ describe("CodeGenerator", () => {
12208
12429
  it("should handle sizeof on local array", () => {
12209
12430
  const source = `
12210
12431
  void test() {
12211
- u8 buffer[16];
12432
+ u8[16] buffer;
12212
12433
  u32 size <- sizeof(buffer);
12213
12434
  }
12214
12435
  `;
@@ -12368,7 +12589,7 @@ describe("CodeGenerator", () => {
12368
12589
  it("should resolve array element access in expression", () => {
12369
12590
  const source = `
12370
12591
  void test() {
12371
- u32 arr[10];
12592
+ u32[10] arr;
12372
12593
  u32 val <- arr[5];
12373
12594
  }
12374
12595
  `;
@@ -12389,7 +12610,7 @@ describe("CodeGenerator", () => {
12389
12610
  it("should resolve array element with variable index", () => {
12390
12611
  const source = `
12391
12612
  void test() {
12392
- u32 arr[10];
12613
+ u32[10] arr;
12393
12614
  u32 i <- 3;
12394
12615
  u32 val <- arr[i];
12395
12616
  }
@@ -12802,7 +13023,7 @@ describe("CodeGenerator", () => {
12802
13023
  const source = `
12803
13024
  struct Item { u32 id; }
12804
13025
  void test() {
12805
- Item items[10];
13026
+ Item[10] items;
12806
13027
  items[0].id <- 42;
12807
13028
  }
12808
13029
  `;
@@ -13071,7 +13292,7 @@ describe("CodeGenerator", () => {
13071
13292
  it("should handle array type with user-defined struct", () => {
13072
13293
  const source = `
13073
13294
  struct Point { i32 x; i32 y; }
13074
- Point points[10];
13295
+ Point[10] points;
13075
13296
  `;
13076
13297
  const { tree, tokenStream } = CNextSourceParser.parse(source);
13077
13298
  const generator = new CodeGenerator();
@@ -13089,8 +13310,8 @@ describe("CodeGenerator", () => {
13089
13310
 
13090
13311
  it("should handle array type with primitive types", () => {
13091
13312
  const source = `
13092
- u8 buffer[256];
13093
- i32 numbers[10];
13313
+ u8[256] buffer;
13314
+ i32[10] numbers;
13094
13315
  `;
13095
13316
  const { tree, tokenStream } = CNextSourceParser.parse(source);
13096
13317
  const generator = new CodeGenerator();
@@ -13590,7 +13811,7 @@ describe("CodeGenerator", () => {
13590
13811
  describe("array access resolution helpers", () => {
13591
13812
  it("should resolve simple array access", () => {
13592
13813
  const source = `
13593
- u8 buffer[10];
13814
+ u8[10] buffer;
13594
13815
  void test() {
13595
13816
  u8 val <- buffer[5];
13596
13817
  }
@@ -13611,7 +13832,7 @@ describe("CodeGenerator", () => {
13611
13832
 
13612
13833
  it("should handle array access with variable index", () => {
13613
13834
  const source = `
13614
- u8 data[20];
13835
+ u8[20] data;
13615
13836
  void test() {
13616
13837
  u32 idx <- 3;
13617
13838
  u8 val <- data[idx];
@@ -14098,7 +14319,7 @@ describe("CodeGenerator", () => {
14098
14319
  it("should register array type correctly", () => {
14099
14320
  const source = `
14100
14321
  void test() {
14101
- u8 buffer[10];
14322
+ u8[10] buffer;
14102
14323
  buffer[0] <- 0xFF;
14103
14324
  }
14104
14325
  `;
@@ -14119,7 +14340,7 @@ describe("CodeGenerator", () => {
14119
14340
  it("should register multi-dimensional array", () => {
14120
14341
  const source = `
14121
14342
  void test() {
14122
- u8 matrix[10][20];
14343
+ u8[10] matrix[20];
14123
14344
  matrix[0][0] <- 0;
14124
14345
  }
14125
14346
  `;
@@ -14140,7 +14361,7 @@ describe("CodeGenerator", () => {
14140
14361
  it("should handle i32 array type", () => {
14141
14362
  const source = `
14142
14363
  void test() {
14143
- i32 values[5];
14364
+ i32[5] values;
14144
14365
  values[0] <- 100;
14145
14366
  }
14146
14367
  `;
@@ -14161,7 +14382,7 @@ describe("CodeGenerator", () => {
14161
14382
  it("should handle const array type", () => {
14162
14383
  const source = `
14163
14384
  void test() {
14164
- const u8 data[4] <- [1, 2, 3, 4];
14385
+ const u8[4] data <- [1, 2, 3, 4];
14165
14386
  }
14166
14387
  `;
14167
14388
  const { tree, tokenStream } = CNextSourceParser.parse(source);
@@ -14177,6 +14398,111 @@ describe("CodeGenerator", () => {
14177
14398
 
14178
14399
  expect(code).toContain("const uint8_t data[4]");
14179
14400
  });
14401
+
14402
+ it("should handle struct array with C-Next syntax", () => {
14403
+ const source = `
14404
+ struct Point {
14405
+ i32 x;
14406
+ i32 y;
14407
+ }
14408
+ void test() {
14409
+ Point[3] points;
14410
+ points[0].x <- 10;
14411
+ }
14412
+ `;
14413
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
14414
+ const generator = new CodeGenerator();
14415
+ const symbolTable = new SymbolTable();
14416
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
14417
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
14418
+
14419
+ const code = generator.generate(tree, symbolTable, tokenStream, {
14420
+ symbolInfo: symbols,
14421
+ sourcePath: "test.cnx",
14422
+ });
14423
+
14424
+ expect(code).toContain("Point points[3]");
14425
+ expect(code).toContain("points[0].x = 10");
14426
+ });
14427
+
14428
+ it("should handle bitmap array with C-Next syntax", () => {
14429
+ const source = `
14430
+ bitmap8 Flags {
14431
+ active,
14432
+ ready,
14433
+ error,
14434
+ mode[3],
14435
+ priority[2]
14436
+ }
14437
+ void test() {
14438
+ Flags[4] flags;
14439
+ flags[0].active <- true;
14440
+ }
14441
+ `;
14442
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
14443
+ const generator = new CodeGenerator();
14444
+ const symbolTable = new SymbolTable();
14445
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
14446
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
14447
+
14448
+ const code = generator.generate(tree, symbolTable, tokenStream, {
14449
+ symbolInfo: symbols,
14450
+ sourcePath: "test.cnx",
14451
+ });
14452
+
14453
+ expect(code).toContain("Flags flags[4]");
14454
+ // Bitmap field access should generate bit manipulation
14455
+ expect(code).toContain("flags[0]");
14456
+ });
14457
+
14458
+ it("should handle enum array with C-Next syntax", () => {
14459
+ const source = `
14460
+ enum Color {
14461
+ RED,
14462
+ GREEN,
14463
+ BLUE
14464
+ }
14465
+ void test() {
14466
+ Color[3] colors;
14467
+ colors[0] <- RED;
14468
+ }
14469
+ `;
14470
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
14471
+ const generator = new CodeGenerator();
14472
+ const symbolTable = new SymbolTable();
14473
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
14474
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
14475
+
14476
+ const code = generator.generate(tree, symbolTable, tokenStream, {
14477
+ symbolInfo: symbols,
14478
+ sourcePath: "test.cnx",
14479
+ });
14480
+
14481
+ expect(code).toContain("Color colors[3]");
14482
+ expect(code).toContain("colors[0] = Color_RED");
14483
+ });
14484
+
14485
+ it("should handle struct array initializer with C-Next syntax", () => {
14486
+ const source = `
14487
+ struct Item {
14488
+ u8 id;
14489
+ }
14490
+ const Item[2] items <- [{id: 1}, {id: 2}];
14491
+ `;
14492
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
14493
+ const generator = new CodeGenerator();
14494
+ const symbolTable = new SymbolTable();
14495
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
14496
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
14497
+
14498
+ const code = generator.generate(tree, symbolTable, tokenStream, {
14499
+ symbolInfo: symbols,
14500
+ sourcePath: "test.cnx",
14501
+ });
14502
+
14503
+ expect(code).toContain("const Item items[2]");
14504
+ expect(code).toContain(".id = 1");
14505
+ });
14180
14506
  });
14181
14507
 
14182
14508
  describe("C++ mode member conversion", () => {
@@ -14211,7 +14537,7 @@ describe("CodeGenerator", () => {
14211
14537
  u32 id;
14212
14538
  }
14213
14539
  void process() {
14214
- Item items[3];
14540
+ Item[3] items;
14215
14541
  u32 first <- items[0].id;
14216
14542
  }
14217
14543
  `;
@@ -14610,7 +14936,7 @@ describe("CodeGenerator", () => {
14610
14936
  it("should generate array element write", () => {
14611
14937
  const source = `
14612
14938
  void test() {
14613
- u32 arr[10];
14939
+ u32[10] arr;
14614
14940
  arr[5] <- 42;
14615
14941
  }
14616
14942
  `;
@@ -15384,7 +15710,7 @@ describe("CodeGenerator", () => {
15384
15710
  describe("array access via ArrayAccessHelper", () => {
15385
15711
  it("should generate single-index array access", () => {
15386
15712
  const source = `
15387
- u32 arr[10];
15713
+ u32[10] arr;
15388
15714
  void test() {
15389
15715
  u32 val <- arr[5];
15390
15716
  }
@@ -15405,7 +15731,7 @@ describe("CodeGenerator", () => {
15405
15731
 
15406
15732
  it("should generate array access with variable index", () => {
15407
15733
  const source = `
15408
- u8 data[100];
15734
+ u8[100] data;
15409
15735
  void test(u32 idx) {
15410
15736
  u8 val <- data[idx];
15411
15737
  }
@@ -15546,4 +15872,80 @@ describe("CodeGenerator", () => {
15546
15872
  expect(code).not.toContain("Bar_OFFSET");
15547
15873
  });
15548
15874
  });
15875
+
15876
+ describe("Generator registration error paths", () => {
15877
+ it("throws error when struct generator is not registered", () => {
15878
+ // First call initializes the registry
15879
+ const initSource = `u8 x;`;
15880
+ const { tree: initTree, tokenStream: initTokenStream } =
15881
+ CNextSourceParser.parse(initSource);
15882
+ const generator = new CodeGenerator();
15883
+ const initSymbolTable = new SymbolTable();
15884
+ const initTSymbols = CNextResolver.resolve(initTree, "init.cnx");
15885
+ const initSymbols = TSymbolInfoAdapter.convert(initTSymbols);
15886
+ generator.generate(initTree, initSymbolTable, initTokenStream, {
15887
+ symbolInfo: initSymbols,
15888
+ sourcePath: "init.cnx",
15889
+ });
15890
+
15891
+ // Unregister the struct generator to test error path
15892
+ const registry = (
15893
+ generator as unknown as {
15894
+ registry: { unregisterDeclaration: (kind: string) => void };
15895
+ }
15896
+ ).registry;
15897
+ registry.unregisterDeclaration("struct");
15898
+
15899
+ // Second call should throw because struct generator is now missing
15900
+ const source = `struct Point { i32 x; i32 y; }`;
15901
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
15902
+ const symbolTable = new SymbolTable();
15903
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
15904
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
15905
+
15906
+ expect(() => {
15907
+ generator.generate(tree, symbolTable, tokenStream, {
15908
+ symbolInfo: symbols,
15909
+ sourcePath: "test.cnx",
15910
+ });
15911
+ }).toThrow("Error: struct generator not registered");
15912
+ });
15913
+
15914
+ it("throws error when enum generator is not registered", () => {
15915
+ // First call initializes the registry
15916
+ const initSource = `u8 x;`;
15917
+ const { tree: initTree, tokenStream: initTokenStream } =
15918
+ CNextSourceParser.parse(initSource);
15919
+ const generator = new CodeGenerator();
15920
+ const initSymbolTable = new SymbolTable();
15921
+ const initTSymbols = CNextResolver.resolve(initTree, "init.cnx");
15922
+ const initSymbols = TSymbolInfoAdapter.convert(initTSymbols);
15923
+ generator.generate(initTree, initSymbolTable, initTokenStream, {
15924
+ symbolInfo: initSymbols,
15925
+ sourcePath: "init.cnx",
15926
+ });
15927
+
15928
+ // Unregister the enum generator to test error path
15929
+ const registry = (
15930
+ generator as unknown as {
15931
+ registry: { unregisterDeclaration: (kind: string) => void };
15932
+ }
15933
+ ).registry;
15934
+ registry.unregisterDeclaration("enum");
15935
+
15936
+ // Second call should throw because enum generator is now missing
15937
+ const source = `enum State { IDLE, RUNNING }`;
15938
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
15939
+ const symbolTable = new SymbolTable();
15940
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
15941
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
15942
+
15943
+ expect(() => {
15944
+ generator.generate(tree, symbolTable, tokenStream, {
15945
+ symbolInfo: symbols,
15946
+ sourcePath: "test.cnx",
15947
+ });
15948
+ }).toThrow("Error: enum generator not registered");
15949
+ });
15950
+ });
15549
15951
  });