c-next 0.1.64 → 0.1.66
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.
- package/grammar/CNext.g4 +9 -2
- package/package.json +5 -1
- package/src/transpiler/logic/parser/grammar/CNext.interp +2 -1
- package/src/transpiler/logic/parser/grammar/CNextListener.ts +11 -0
- package/src/transpiler/logic/parser/grammar/CNextParser.ts +992 -870
- package/src/transpiler/logic/parser/grammar/CNextVisitor.ts +7 -0
- package/src/transpiler/logic/symbols/cnext/__tests__/FunctionCollector.test.ts +6 -6
- package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolAdapter.test.ts +179 -0
- package/src/transpiler/logic/symbols/cnext/__tests__/VariableCollector.test.ts +55 -0
- package/src/transpiler/logic/symbols/cnext/adapters/TSymbolAdapter.ts +76 -8
- package/src/transpiler/logic/symbols/cnext/collectors/FunctionCollector.ts +9 -10
- package/src/transpiler/logic/symbols/cnext/collectors/StructCollector.ts +7 -1
- package/src/transpiler/logic/symbols/cnext/collectors/VariableCollector.ts +33 -14
- package/src/transpiler/output/codegen/CodeGenerator.ts +243 -166
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.coverage.test.ts +1086 -0
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +254 -22
- package/src/transpiler/output/codegen/generators/declarationGenerators/ArrayDimensionUtils.ts +17 -9
- package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ArrayDimensionUtils.test.ts +5 -3
- package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ScopeGenerator.test.ts +12 -7
- package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +624 -12
- package/src/transpiler/output/codegen/generators/expressions/__tests__/PostfixExpressionGenerator.test.ts +819 -0
- package/src/transpiler/output/codegen/helpers/ParameterInputAdapter.ts +337 -0
- package/src/transpiler/output/codegen/helpers/ParameterSignatureBuilder.ts +135 -0
- package/src/transpiler/output/codegen/helpers/TypeGenerationHelper.ts +4 -0
- package/src/transpiler/output/codegen/helpers/VariableDeclarationFormatter.ts +118 -0
- package/src/transpiler/output/codegen/helpers/__tests__/ParameterInputAdapter.test.ts +426 -0
- package/src/transpiler/output/codegen/helpers/__tests__/ParameterSignatureBuilder.test.ts +315 -0
- package/src/transpiler/output/codegen/helpers/__tests__/VariableDeclarationFormatter.test.ts +333 -0
- package/src/transpiler/output/codegen/types/IParameterInput.ts +58 -0
- package/src/transpiler/output/codegen/types/IVariableFormatInput.ts +51 -0
- package/src/transpiler/output/headers/BaseHeaderGenerator.ts +20 -35
- package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +21 -48
- package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +0 -64
|
@@ -1568,7 +1568,7 @@ describe("CodeGenerator", () => {
|
|
|
1568
1568
|
|
|
1569
1569
|
it("should generate array parameter", () => {
|
|
1570
1570
|
const source = `
|
|
1571
|
-
void process(u32
|
|
1571
|
+
void process(u32[10] arr) { }
|
|
1572
1572
|
`;
|
|
1573
1573
|
const { tree, tokenStream } = CNextSourceParser.parse(source);
|
|
1574
1574
|
const generator = new CodeGenerator();
|
|
@@ -5284,7 +5284,7 @@ describe("CodeGenerator", () => {
|
|
|
5284
5284
|
describe("Array passed to function", () => {
|
|
5285
5285
|
it("should pass array without address-of operator", () => {
|
|
5286
5286
|
const source = `
|
|
5287
|
-
void processData(u32 data
|
|
5287
|
+
void processData(u32[5] data) { }
|
|
5288
5288
|
u32[5] myData;
|
|
5289
5289
|
void main() {
|
|
5290
5290
|
processData(myData);
|
|
@@ -5942,7 +5942,7 @@ describe("CodeGenerator", () => {
|
|
|
5942
5942
|
describe("Function with array return type simulation", () => {
|
|
5943
5943
|
it("should handle function returning via output parameter", () => {
|
|
5944
5944
|
const source = `
|
|
5945
|
-
void getData(u8 output
|
|
5945
|
+
void getData(u8[2] output) {
|
|
5946
5946
|
output[0] <- 1;
|
|
5947
5947
|
output[1] <- 2;
|
|
5948
5948
|
}
|
|
@@ -6285,7 +6285,7 @@ describe("CodeGenerator", () => {
|
|
|
6285
6285
|
describe("Array parameter bounds", () => {
|
|
6286
6286
|
it("should handle sized array parameter", () => {
|
|
6287
6287
|
const source = `
|
|
6288
|
-
void process(u32
|
|
6288
|
+
void process(u32[10] arr) {
|
|
6289
6289
|
arr[0] <- 1;
|
|
6290
6290
|
}
|
|
6291
6291
|
`;
|
|
@@ -6813,7 +6813,7 @@ describe("CodeGenerator", () => {
|
|
|
6813
6813
|
describe("Local array tracking", () => {
|
|
6814
6814
|
it("should track local arrays for function arguments", () => {
|
|
6815
6815
|
const source = `
|
|
6816
|
-
void process(u8 arr
|
|
6816
|
+
void process(u8[10] arr) { }
|
|
6817
6817
|
void main() {
|
|
6818
6818
|
u8[10] local;
|
|
6819
6819
|
process(local);
|
|
@@ -8067,7 +8067,7 @@ describe("CodeGenerator", () => {
|
|
|
8067
8067
|
|
|
8068
8068
|
it("should handle identifier argument (array)", () => {
|
|
8069
8069
|
const source = `
|
|
8070
|
-
void callee(u32
|
|
8070
|
+
void callee(u32[10] arr) { }
|
|
8071
8071
|
void test() {
|
|
8072
8072
|
u32[10] data;
|
|
8073
8073
|
callee(data);
|
|
@@ -8181,7 +8181,7 @@ describe("CodeGenerator", () => {
|
|
|
8181
8181
|
it("should handle struct field array argument", () => {
|
|
8182
8182
|
const source = `
|
|
8183
8183
|
struct Data { u32 values[10]; }
|
|
8184
|
-
void callee(u32
|
|
8184
|
+
void callee(u32[10] arr) { }
|
|
8185
8185
|
void test(Data d) {
|
|
8186
8186
|
callee(d.values);
|
|
8187
8187
|
}
|
|
@@ -8246,7 +8246,7 @@ describe("CodeGenerator", () => {
|
|
|
8246
8246
|
it("should handle struct member array as argument (array decay)", () => {
|
|
8247
8247
|
const source = `
|
|
8248
8248
|
struct Config { u8 data[16]; }
|
|
8249
|
-
void processData(u8
|
|
8249
|
+
void processData(u8[16] buffer) { }
|
|
8250
8250
|
void test() {
|
|
8251
8251
|
Config cfg;
|
|
8252
8252
|
processData(cfg.data);
|
|
@@ -8377,7 +8377,7 @@ describe("CodeGenerator", () => {
|
|
|
8377
8377
|
|
|
8378
8378
|
it("should process array parameter type", () => {
|
|
8379
8379
|
const source = `
|
|
8380
|
-
void test(u32
|
|
8380
|
+
void test(u32[10] arr) {
|
|
8381
8381
|
u32 x <- arr[0];
|
|
8382
8382
|
}
|
|
8383
8383
|
`;
|
|
@@ -8583,7 +8583,7 @@ describe("CodeGenerator", () => {
|
|
|
8583
8583
|
|
|
8584
8584
|
it("should error on sizeof of array parameter", () => {
|
|
8585
8585
|
const source = `
|
|
8586
|
-
void test(u32
|
|
8586
|
+
void test(u32[10] arr) {
|
|
8587
8587
|
u32 size <- sizeof(arr);
|
|
8588
8588
|
}
|
|
8589
8589
|
`;
|
|
@@ -8670,7 +8670,7 @@ describe("CodeGenerator", () => {
|
|
|
8670
8670
|
|
|
8671
8671
|
it("should handle parameter array access", () => {
|
|
8672
8672
|
const source = `
|
|
8673
|
-
void test(u32
|
|
8673
|
+
void test(u32[10] arr) {
|
|
8674
8674
|
u32 val <- arr[0];
|
|
8675
8675
|
}
|
|
8676
8676
|
`;
|
|
@@ -10032,7 +10032,7 @@ describe("CodeGenerator", () => {
|
|
|
10032
10032
|
|
|
10033
10033
|
it("should resolve array parameter", () => {
|
|
10034
10034
|
const source = `
|
|
10035
|
-
void test(u32
|
|
10035
|
+
void test(u32[10] arr) {
|
|
10036
10036
|
arr[0] <- 1;
|
|
10037
10037
|
}
|
|
10038
10038
|
`;
|
|
@@ -11078,7 +11078,7 @@ describe("CodeGenerator", () => {
|
|
|
11078
11078
|
|
|
11079
11079
|
it("should not dereference array parameter for index access", () => {
|
|
11080
11080
|
const source = `
|
|
11081
|
-
u32 getElement(u32
|
|
11081
|
+
u32 getElement(u32[10] arr) {
|
|
11082
11082
|
return arr[5];
|
|
11083
11083
|
}
|
|
11084
11084
|
`;
|
|
@@ -11263,7 +11263,7 @@ describe("CodeGenerator", () => {
|
|
|
11263
11263
|
describe("function call argument generation", () => {
|
|
11264
11264
|
it("should handle array argument passed to function", () => {
|
|
11265
11265
|
const source = `
|
|
11266
|
-
void process(u32
|
|
11266
|
+
void process(u32[10] data) {
|
|
11267
11267
|
data[0] <- 1;
|
|
11268
11268
|
}
|
|
11269
11269
|
void test() {
|
|
@@ -12301,7 +12301,7 @@ describe("CodeGenerator", () => {
|
|
|
12301
12301
|
describe("array parameter dimensions", () => {
|
|
12302
12302
|
it("should handle multi-dimensional array parameter", () => {
|
|
12303
12303
|
const source = `
|
|
12304
|
-
void processMatrix(u32
|
|
12304
|
+
void processMatrix(u32[3][3] matrix) {
|
|
12305
12305
|
matrix[0][0] <- 1;
|
|
12306
12306
|
}
|
|
12307
12307
|
`;
|
|
@@ -12318,10 +12318,52 @@ describe("CodeGenerator", () => {
|
|
|
12318
12318
|
|
|
12319
12319
|
expect(code).toContain("uint32_t matrix[3][3]");
|
|
12320
12320
|
});
|
|
12321
|
+
});
|
|
12322
|
+
|
|
12323
|
+
describe("C-style array parameter rejection", () => {
|
|
12324
|
+
it("should reject C-style array parameter with single dimension", () => {
|
|
12325
|
+
const source = `
|
|
12326
|
+
void process(u8 data[8]) {
|
|
12327
|
+
data[0] <- 0xFF;
|
|
12328
|
+
}
|
|
12329
|
+
`;
|
|
12330
|
+
const { tree, tokenStream } = CNextSourceParser.parse(source);
|
|
12331
|
+
const generator = new CodeGenerator();
|
|
12332
|
+
const symbolTable = new SymbolTable();
|
|
12333
|
+
const tSymbols = CNextResolver.resolve(tree, "test.cnx");
|
|
12334
|
+
const symbols = TSymbolInfoAdapter.convert(tSymbols);
|
|
12335
|
+
|
|
12336
|
+
expect(() => {
|
|
12337
|
+
generator.generate(tree, symbolTable, tokenStream, {
|
|
12338
|
+
symbolInfo: symbols,
|
|
12339
|
+
sourcePath: "test.cnx",
|
|
12340
|
+
});
|
|
12341
|
+
}).toThrow(/C-style array parameter is not allowed/);
|
|
12342
|
+
});
|
|
12343
|
+
|
|
12344
|
+
it("should reject C-style array parameter with multiple dimensions", () => {
|
|
12345
|
+
const source = `
|
|
12346
|
+
void process(u32 matrix[3][3]) {
|
|
12347
|
+
matrix[0][0] <- 1;
|
|
12348
|
+
}
|
|
12349
|
+
`;
|
|
12350
|
+
const { tree, tokenStream } = CNextSourceParser.parse(source);
|
|
12351
|
+
const generator = new CodeGenerator();
|
|
12352
|
+
const symbolTable = new SymbolTable();
|
|
12353
|
+
const tSymbols = CNextResolver.resolve(tree, "test.cnx");
|
|
12354
|
+
const symbols = TSymbolInfoAdapter.convert(tSymbols);
|
|
12355
|
+
|
|
12356
|
+
expect(() => {
|
|
12357
|
+
generator.generate(tree, symbolTable, tokenStream, {
|
|
12358
|
+
symbolInfo: symbols,
|
|
12359
|
+
sourcePath: "test.cnx",
|
|
12360
|
+
});
|
|
12361
|
+
}).toThrow(/C-style array parameter is not allowed/);
|
|
12362
|
+
});
|
|
12321
12363
|
|
|
12322
|
-
it("should
|
|
12364
|
+
it("should reject C-style unsized array parameter", () => {
|
|
12323
12365
|
const source = `
|
|
12324
|
-
void
|
|
12366
|
+
void process(u8 data[]) {
|
|
12325
12367
|
data[0] <- 0xFF;
|
|
12326
12368
|
}
|
|
12327
12369
|
`;
|
|
@@ -12331,12 +12373,202 @@ describe("CodeGenerator", () => {
|
|
|
12331
12373
|
const tSymbols = CNextResolver.resolve(tree, "test.cnx");
|
|
12332
12374
|
const symbols = TSymbolInfoAdapter.convert(tSymbols);
|
|
12333
12375
|
|
|
12376
|
+
expect(() => {
|
|
12377
|
+
generator.generate(tree, symbolTable, tokenStream, {
|
|
12378
|
+
symbolInfo: symbols,
|
|
12379
|
+
sourcePath: "test.cnx",
|
|
12380
|
+
});
|
|
12381
|
+
}).toThrow(/C-style array parameter is not allowed/);
|
|
12382
|
+
});
|
|
12383
|
+
|
|
12384
|
+
it("should suggest correct C-Next style syntax in error message", () => {
|
|
12385
|
+
const source = `
|
|
12386
|
+
void process(i32 values[10]) {
|
|
12387
|
+
values[0] <- 1;
|
|
12388
|
+
}
|
|
12389
|
+
`;
|
|
12390
|
+
const { tree, tokenStream } = CNextSourceParser.parse(source);
|
|
12391
|
+
const generator = new CodeGenerator();
|
|
12392
|
+
const symbolTable = new SymbolTable();
|
|
12393
|
+
const tSymbols = CNextResolver.resolve(tree, "test.cnx");
|
|
12394
|
+
const symbols = TSymbolInfoAdapter.convert(tSymbols);
|
|
12395
|
+
|
|
12396
|
+
expect(() => {
|
|
12397
|
+
generator.generate(tree, symbolTable, tokenStream, {
|
|
12398
|
+
symbolInfo: symbols,
|
|
12399
|
+
sourcePath: "test.cnx",
|
|
12400
|
+
});
|
|
12401
|
+
}).toThrow(/Use 'i32\[10\] values' instead of 'i32 values\[10\]'/);
|
|
12402
|
+
});
|
|
12403
|
+
});
|
|
12404
|
+
|
|
12405
|
+
describe("user type array parameters", () => {
|
|
12406
|
+
it("should handle struct array parameter with C-Next style", () => {
|
|
12407
|
+
const source = `
|
|
12408
|
+
struct Point { i32 x; i32 y; }
|
|
12409
|
+
void processPoints(Point[4] points) {
|
|
12410
|
+
points[0].x <- 10;
|
|
12411
|
+
}
|
|
12412
|
+
`;
|
|
12413
|
+
const { tree, tokenStream } = CNextSourceParser.parse(source);
|
|
12414
|
+
const generator = new CodeGenerator();
|
|
12415
|
+
const symbolTable = new SymbolTable();
|
|
12416
|
+
const tSymbols = CNextResolver.resolve(tree, "test.cnx");
|
|
12417
|
+
const symbols = TSymbolInfoAdapter.convert(tSymbols);
|
|
12418
|
+
|
|
12334
12419
|
const code = generator.generate(tree, symbolTable, tokenStream, {
|
|
12335
12420
|
symbolInfo: symbols,
|
|
12336
12421
|
sourcePath: "test.cnx",
|
|
12337
12422
|
});
|
|
12338
12423
|
|
|
12339
|
-
expect(code).toContain("
|
|
12424
|
+
expect(code).toContain("Point points[4]");
|
|
12425
|
+
});
|
|
12426
|
+
|
|
12427
|
+
it("should detect struct type in arrayType for parameter", () => {
|
|
12428
|
+
const source = `
|
|
12429
|
+
struct Data { u32 value; }
|
|
12430
|
+
void process(Data[8] items) {
|
|
12431
|
+
items[0].value <- 42;
|
|
12432
|
+
}
|
|
12433
|
+
`;
|
|
12434
|
+
const { tree, tokenStream } = CNextSourceParser.parse(source);
|
|
12435
|
+
const generator = new CodeGenerator();
|
|
12436
|
+
const symbolTable = new SymbolTable();
|
|
12437
|
+
const tSymbols = CNextResolver.resolve(tree, "test.cnx");
|
|
12438
|
+
const symbols = TSymbolInfoAdapter.convert(tSymbols);
|
|
12439
|
+
|
|
12440
|
+
const code = generator.generate(tree, symbolTable, tokenStream, {
|
|
12441
|
+
symbolInfo: symbols,
|
|
12442
|
+
sourcePath: "test.cnx",
|
|
12443
|
+
});
|
|
12444
|
+
|
|
12445
|
+
expect(code).toContain("Data items[8]");
|
|
12446
|
+
expect(code).toContain("items[0].value = 42");
|
|
12447
|
+
});
|
|
12448
|
+
});
|
|
12449
|
+
|
|
12450
|
+
describe("multi-dimensional C-Next style array parameters", () => {
|
|
12451
|
+
it("should handle 2D array parameter", () => {
|
|
12452
|
+
const source = `
|
|
12453
|
+
void processMatrix(i32[4][4] matrix) {
|
|
12454
|
+
matrix[0][0] <- 1;
|
|
12455
|
+
}
|
|
12456
|
+
`;
|
|
12457
|
+
const { tree, tokenStream } = CNextSourceParser.parse(source);
|
|
12458
|
+
const generator = new CodeGenerator();
|
|
12459
|
+
const symbolTable = new SymbolTable();
|
|
12460
|
+
const tSymbols = CNextResolver.resolve(tree, "test.cnx");
|
|
12461
|
+
const symbols = TSymbolInfoAdapter.convert(tSymbols);
|
|
12462
|
+
|
|
12463
|
+
const code = generator.generate(tree, symbolTable, tokenStream, {
|
|
12464
|
+
symbolInfo: symbols,
|
|
12465
|
+
sourcePath: "test.cnx",
|
|
12466
|
+
});
|
|
12467
|
+
|
|
12468
|
+
expect(code).toContain("int32_t matrix[4][4]");
|
|
12469
|
+
});
|
|
12470
|
+
|
|
12471
|
+
it("should handle 3D array parameter", () => {
|
|
12472
|
+
const source = `
|
|
12473
|
+
void processCube(u8[2][3][4] cube) {
|
|
12474
|
+
cube[0][0][0] <- 0xFF;
|
|
12475
|
+
}
|
|
12476
|
+
`;
|
|
12477
|
+
const { tree, tokenStream } = CNextSourceParser.parse(source);
|
|
12478
|
+
const generator = new CodeGenerator();
|
|
12479
|
+
const symbolTable = new SymbolTable();
|
|
12480
|
+
const tSymbols = CNextResolver.resolve(tree, "test.cnx");
|
|
12481
|
+
const symbols = TSymbolInfoAdapter.convert(tSymbols);
|
|
12482
|
+
|
|
12483
|
+
const code = generator.generate(tree, symbolTable, tokenStream, {
|
|
12484
|
+
symbolInfo: symbols,
|
|
12485
|
+
sourcePath: "test.cnx",
|
|
12486
|
+
});
|
|
12487
|
+
|
|
12488
|
+
expect(code).toContain("uint8_t cube[2][3][4]");
|
|
12489
|
+
});
|
|
12490
|
+
|
|
12491
|
+
it("should reject unbounded array parameter for memory safety", () => {
|
|
12492
|
+
const source = `
|
|
12493
|
+
void processRows(u32[][4] rows, u32 count) {
|
|
12494
|
+
rows[0][0] <- 1;
|
|
12495
|
+
}
|
|
12496
|
+
`;
|
|
12497
|
+
const { tree, tokenStream } = CNextSourceParser.parse(source);
|
|
12498
|
+
const generator = new CodeGenerator();
|
|
12499
|
+
const symbolTable = new SymbolTable();
|
|
12500
|
+
const tSymbols = CNextResolver.resolve(tree, "test.cnx");
|
|
12501
|
+
const symbols = TSymbolInfoAdapter.convert(tSymbols);
|
|
12502
|
+
|
|
12503
|
+
expect(() => {
|
|
12504
|
+
generator.generate(tree, symbolTable, tokenStream, {
|
|
12505
|
+
symbolInfo: symbols,
|
|
12506
|
+
sourcePath: "test.cnx",
|
|
12507
|
+
});
|
|
12508
|
+
}).toThrow(/Unbounded array parameters are not allowed/);
|
|
12509
|
+
});
|
|
12510
|
+
|
|
12511
|
+
it("should reject simple unbounded array parameter", () => {
|
|
12512
|
+
const source = `
|
|
12513
|
+
void process(u8[] data) {
|
|
12514
|
+
data[0] <- 0xFF;
|
|
12515
|
+
}
|
|
12516
|
+
`;
|
|
12517
|
+
const { tree, tokenStream } = CNextSourceParser.parse(source);
|
|
12518
|
+
const generator = new CodeGenerator();
|
|
12519
|
+
const symbolTable = new SymbolTable();
|
|
12520
|
+
const tSymbols = CNextResolver.resolve(tree, "test.cnx");
|
|
12521
|
+
const symbols = TSymbolInfoAdapter.convert(tSymbols);
|
|
12522
|
+
|
|
12523
|
+
expect(() => {
|
|
12524
|
+
generator.generate(tree, symbolTable, tokenStream, {
|
|
12525
|
+
symbolInfo: symbols,
|
|
12526
|
+
sourcePath: "test.cnx",
|
|
12527
|
+
});
|
|
12528
|
+
}).toThrow(/Unbounded array parameters are not allowed/);
|
|
12529
|
+
});
|
|
12530
|
+
});
|
|
12531
|
+
|
|
12532
|
+
describe("string array parameter capacity", () => {
|
|
12533
|
+
it("should add capacity dimension for string array parameter", () => {
|
|
12534
|
+
const source = `
|
|
12535
|
+
void processNames(string<16>[5] names) {
|
|
12536
|
+
names[0] <- "test";
|
|
12537
|
+
}
|
|
12538
|
+
`;
|
|
12539
|
+
const { tree, tokenStream } = CNextSourceParser.parse(source);
|
|
12540
|
+
const generator = new CodeGenerator();
|
|
12541
|
+
const symbolTable = new SymbolTable();
|
|
12542
|
+
const tSymbols = CNextResolver.resolve(tree, "test.cnx");
|
|
12543
|
+
const symbols = TSymbolInfoAdapter.convert(tSymbols);
|
|
12544
|
+
|
|
12545
|
+
const code = generator.generate(tree, symbolTable, tokenStream, {
|
|
12546
|
+
symbolInfo: symbols,
|
|
12547
|
+
sourcePath: "test.cnx",
|
|
12548
|
+
});
|
|
12549
|
+
|
|
12550
|
+
// string<16>[5] -> char[5][17] (capacity + 1 for null terminator)
|
|
12551
|
+
expect(code).toContain("char names[5][17]");
|
|
12552
|
+
});
|
|
12553
|
+
|
|
12554
|
+
it("should handle string array with larger capacity", () => {
|
|
12555
|
+
const source = `
|
|
12556
|
+
void logMessages(string<128>[10] messages) {
|
|
12557
|
+
messages[0] <- "hello";
|
|
12558
|
+
}
|
|
12559
|
+
`;
|
|
12560
|
+
const { tree, tokenStream } = CNextSourceParser.parse(source);
|
|
12561
|
+
const generator = new CodeGenerator();
|
|
12562
|
+
const symbolTable = new SymbolTable();
|
|
12563
|
+
const tSymbols = CNextResolver.resolve(tree, "test.cnx");
|
|
12564
|
+
const symbols = TSymbolInfoAdapter.convert(tSymbols);
|
|
12565
|
+
|
|
12566
|
+
const code = generator.generate(tree, symbolTable, tokenStream, {
|
|
12567
|
+
symbolInfo: symbols,
|
|
12568
|
+
sourcePath: "test.cnx",
|
|
12569
|
+
});
|
|
12570
|
+
|
|
12571
|
+
expect(code).toContain("char messages[10][129]");
|
|
12340
12572
|
});
|
|
12341
12573
|
});
|
|
12342
12574
|
|
|
@@ -12633,7 +12865,7 @@ describe("CodeGenerator", () => {
|
|
|
12633
12865
|
describe("string array parameters", () => {
|
|
12634
12866
|
it("should handle string array parameter with capacity", () => {
|
|
12635
12867
|
const source = `
|
|
12636
|
-
void processNames(string<32>
|
|
12868
|
+
void processNames(string<32>[10] names) {
|
|
12637
12869
|
string<32> first <- names[0];
|
|
12638
12870
|
}
|
|
12639
12871
|
`;
|
|
@@ -13499,7 +13731,7 @@ describe("CodeGenerator", () => {
|
|
|
13499
13731
|
|
|
13500
13732
|
it("should handle array parameters", () => {
|
|
13501
13733
|
const source = `
|
|
13502
|
-
void sum(u32
|
|
13734
|
+
void sum(u32[10] values) {
|
|
13503
13735
|
u32 total <- 0;
|
|
13504
13736
|
}
|
|
13505
13737
|
`;
|
|
@@ -13515,7 +13747,7 @@ describe("CodeGenerator", () => {
|
|
|
13515
13747
|
});
|
|
13516
13748
|
|
|
13517
13749
|
expect(code).toContain("values");
|
|
13518
|
-
expect(code).toContain("
|
|
13750
|
+
expect(code).toContain("uint32_t values[10]");
|
|
13519
13751
|
});
|
|
13520
13752
|
});
|
|
13521
13753
|
|
|
@@ -15254,7 +15486,7 @@ describe("CodeGenerator", () => {
|
|
|
15254
15486
|
|
|
15255
15487
|
it("should generate function with array parameter", () => {
|
|
15256
15488
|
const source = `
|
|
15257
|
-
void process(u32
|
|
15489
|
+
void process(u32[10] arr) {
|
|
15258
15490
|
u32 val <- arr[0];
|
|
15259
15491
|
}
|
|
15260
15492
|
`;
|
package/src/transpiler/output/codegen/generators/declarationGenerators/ArrayDimensionUtils.ts
CHANGED
|
@@ -23,18 +23,26 @@ function generateArrayTypeDimension(
|
|
|
23
23
|
return "";
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
// Handle all dimensions from arrayType (supports u8[4][4], u8[], etc.)
|
|
27
|
+
const dims = arrayTypeCtx.arrayTypeDimension();
|
|
28
|
+
let result = "";
|
|
29
|
+
for (const dim of dims) {
|
|
30
|
+
const sizeExpr = dim.expression();
|
|
31
|
+
if (!sizeExpr) {
|
|
32
|
+
result += "[]";
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
30
35
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
const constValue = orchestrator.tryEvaluateConstant(sizeExpr);
|
|
37
|
+
if (constValue === undefined) {
|
|
38
|
+
// Fall back to expression generation for macros, enums, etc.
|
|
39
|
+
result += `[${orchestrator.generateExpression(sizeExpr)}]`;
|
|
40
|
+
} else {
|
|
41
|
+
result += `[${constValue}]`;
|
|
42
|
+
}
|
|
35
43
|
}
|
|
36
44
|
|
|
37
|
-
return
|
|
45
|
+
return result;
|
|
38
46
|
}
|
|
39
47
|
|
|
40
48
|
/**
|
|
@@ -26,7 +26,7 @@ describe("ArrayDimensionUtils", () => {
|
|
|
26
26
|
it("returns [] for context with no expression", () => {
|
|
27
27
|
const orchestrator = createMockOrchestrator();
|
|
28
28
|
const ctx = {
|
|
29
|
-
expression: () => null,
|
|
29
|
+
arrayTypeDimension: () => [{ expression: () => null }],
|
|
30
30
|
};
|
|
31
31
|
const result = ArrayDimensionUtils.generateArrayTypeDimension(
|
|
32
32
|
ctx as never,
|
|
@@ -38,7 +38,9 @@ describe("ArrayDimensionUtils", () => {
|
|
|
38
38
|
it("returns constant dimension when evaluable", () => {
|
|
39
39
|
const orchestrator = createMockOrchestrator(16);
|
|
40
40
|
const ctx = {
|
|
41
|
-
|
|
41
|
+
arrayTypeDimension: () => [
|
|
42
|
+
{ expression: () => ({ getText: () => "16" }) },
|
|
43
|
+
],
|
|
42
44
|
};
|
|
43
45
|
const result = ArrayDimensionUtils.generateArrayTypeDimension(
|
|
44
46
|
ctx as never,
|
|
@@ -52,7 +54,7 @@ describe("ArrayDimensionUtils", () => {
|
|
|
52
54
|
const orchestrator = createMockOrchestrator(undefined, "BUFFER_SIZE");
|
|
53
55
|
const mockExpr = { getText: () => "BUFFER_SIZE" };
|
|
54
56
|
const ctx = {
|
|
55
|
-
expression: () => mockExpr,
|
|
57
|
+
arrayTypeDimension: () => [{ expression: () => mockExpr }],
|
|
56
58
|
};
|
|
57
59
|
const result = ArrayDimensionUtils.generateArrayTypeDimension(
|
|
58
60
|
ctx as never,
|
|
@@ -44,15 +44,11 @@ function createMockConstModifier(
|
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
46
|
* Create a mock array type context.
|
|
47
|
+
* Updated for new grammar: arrayType has arrayTypeDimension() which returns dimensions
|
|
47
48
|
*/
|
|
48
49
|
function createMockArrayType(sizeExpr?: string | null) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return {
|
|
52
|
-
expression: () => null,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
return {
|
|
50
|
+
// Create a single dimension with optional expression
|
|
51
|
+
const mockDimension = {
|
|
56
52
|
expression: () =>
|
|
57
53
|
sizeExpr
|
|
58
54
|
? {
|
|
@@ -61,6 +57,15 @@ function createMockArrayType(sizeExpr?: string | null) {
|
|
|
61
57
|
}
|
|
62
58
|
: null,
|
|
63
59
|
};
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
// New grammar: arrayTypeDimension() returns array of dimensions
|
|
63
|
+
arrayTypeDimension: () => [mockDimension],
|
|
64
|
+
// Keep primitiveType for base type extraction
|
|
65
|
+
primitiveType: () => null,
|
|
66
|
+
userType: () => null,
|
|
67
|
+
stringType: () => null,
|
|
68
|
+
};
|
|
64
69
|
}
|
|
65
70
|
|
|
66
71
|
/**
|