c-next 0.2.6 → 0.2.7

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 (37) hide show
  1. package/dist/index.js +387 -433
  2. package/dist/index.js.map +4 -4
  3. package/package.json +1 -1
  4. package/src/transpiler/Transpiler.ts +50 -29
  5. package/src/transpiler/__tests__/Transpiler.coverage.test.ts +2 -1
  6. package/src/transpiler/data/PathResolver.ts +10 -6
  7. package/src/transpiler/data/__tests__/PathResolver.test.ts +32 -0
  8. package/src/transpiler/logic/analysis/PassByValueAnalyzer.ts +1 -12
  9. package/src/transpiler/logic/analysis/SignedShiftAnalyzer.ts +239 -0
  10. package/src/transpiler/logic/analysis/__tests__/SignedShiftAnalyzer.test.ts +414 -0
  11. package/src/transpiler/logic/analysis/__tests__/StructFieldAnalyzer.test.ts +15 -75
  12. package/src/transpiler/logic/analysis/__tests__/runAnalyzers.test.ts +3 -15
  13. package/src/transpiler/logic/analysis/runAnalyzers.ts +11 -2
  14. package/src/transpiler/logic/analysis/types/ISignedShiftError.ts +15 -0
  15. package/src/transpiler/logic/symbols/SymbolUtils.ts +4 -1
  16. package/src/transpiler/logic/symbols/__tests__/SymbolUtils.test.ts +10 -11
  17. package/src/transpiler/logic/symbols/c/__tests__/CResolver.integration.test.ts +4 -4
  18. package/src/transpiler/logic/symbols/cpp/__tests__/CppResolver.integration.test.ts +4 -4
  19. package/src/transpiler/output/codegen/CodeGenerator.ts +12 -4
  20. package/src/transpiler/output/codegen/__tests__/CodeGenerator.coverage.test.ts +3 -3
  21. package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +26 -26
  22. package/src/transpiler/output/codegen/analysis/StringLengthCounter.ts +12 -11
  23. package/src/transpiler/output/codegen/analysis/__tests__/StringLengthCounter.test.ts +21 -21
  24. package/src/transpiler/output/codegen/generators/expressions/AccessExprGenerator.ts +7 -326
  25. package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +14 -275
  26. package/src/transpiler/output/codegen/generators/expressions/UnaryExprGenerator.ts +13 -1
  27. package/src/transpiler/output/codegen/generators/expressions/__tests__/AccessExprGenerator.test.ts +0 -573
  28. package/src/transpiler/output/codegen/generators/expressions/__tests__/PostfixExpressionGenerator.test.ts +8 -439
  29. package/src/transpiler/output/codegen/generators/expressions/__tests__/UnaryExprGenerator.test.ts +196 -0
  30. package/src/transpiler/output/codegen/helpers/ParameterInputAdapter.ts +7 -2
  31. package/src/transpiler/output/codegen/helpers/TypedefParamParser.ts +34 -0
  32. package/src/transpiler/output/codegen/helpers/__tests__/ParameterInputAdapter.test.ts +48 -0
  33. package/src/transpiler/output/codegen/helpers/__tests__/TypedefParamParser.test.ts +88 -0
  34. package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +15 -2
  35. package/src/transpiler/output/headers/__tests__/BaseHeaderGenerator.test.ts +87 -0
  36. package/src/utils/ExpressionUtils.ts +51 -0
  37. package/src/utils/types/IParameterSymbol.ts +2 -0
@@ -3,579 +3,6 @@ import accessGenerators from "../AccessExprGenerator";
3
3
  import TTypeInfo from "../../../types/TTypeInfo";
4
4
 
5
5
  describe("AccessExprGenerator", () => {
6
- describe("generateLengthProperty", () => {
7
- // Helper to create a minimal PropertyContext
8
- const createContext = (overrides: Record<string, unknown> = {}) => ({
9
- result: "test",
10
- primaryId: undefined as string | undefined,
11
- currentIdentifier: undefined as string | undefined,
12
- subscriptDepth: 0,
13
- previousStructType: undefined as string | undefined,
14
- previousMemberName: undefined as string | undefined,
15
- typeInfo: undefined as TTypeInfo | undefined,
16
- mainArgsName: undefined as string | undefined,
17
- lengthCache: undefined as ReadonlyMap<string, string> | undefined,
18
- getStructFieldInfo: () =>
19
- undefined as { type: string; dimensions?: number[] } | undefined,
20
- getBitmapBitWidth: undefined as
21
- | ((name: string) => number | undefined)
22
- | undefined,
23
- ...overrides,
24
- });
25
-
26
- describe("main args handling", () => {
27
- it("returns argc for main args.length", () => {
28
- const ctx = createContext({
29
- mainArgsName: "args",
30
- primaryId: "args",
31
- });
32
- const result = accessGenerators.generateLengthProperty(ctx);
33
- expect(result.code).toBe("argc");
34
- expect(result.effects).toHaveLength(0);
35
- });
36
-
37
- it("does not return argc when primaryId does not match mainArgsName", () => {
38
- const ctx = createContext({
39
- mainArgsName: "args",
40
- primaryId: "other",
41
- typeInfo: {
42
- baseType: "u32",
43
- bitWidth: 32,
44
- isArray: false,
45
- isConst: false,
46
- },
47
- });
48
- const result = accessGenerators.generateLengthProperty(ctx);
49
- expect(result.code).not.toBe("argc");
50
- });
51
- });
52
-
53
- describe("struct member .length", () => {
54
- it("returns element count for string array field without subscript", () => {
55
- const ctx = createContext({
56
- previousStructType: "MyStruct",
57
- previousMemberName: "arr",
58
- subscriptDepth: 0,
59
- getStructFieldInfo: (structType: string, fieldName: string) => {
60
- if (structType === "MyStruct" && fieldName === "arr") {
61
- return { type: "string<64>", dimensions: [4, 65] };
62
- }
63
- return undefined;
64
- },
65
- });
66
- const result = accessGenerators.generateLengthProperty(ctx);
67
- expect(result.code).toBe("4");
68
- expect(result.skipContinue).toBe(true);
69
- });
70
-
71
- it("returns strlen for string array field with subscript", () => {
72
- const ctx = createContext({
73
- result: "ts.arr[0]",
74
- previousStructType: "MyStruct",
75
- previousMemberName: "arr",
76
- subscriptDepth: 1,
77
- getStructFieldInfo: () => ({
78
- type: "string<64>",
79
- dimensions: [4, 65],
80
- }),
81
- });
82
- const result = accessGenerators.generateLengthProperty(ctx);
83
- expect(result.code).toBe("strlen(ts.arr[0])");
84
- expect(result.effects).toContainEqual({
85
- type: "include",
86
- header: "string",
87
- });
88
- expect(result.skipContinue).toBe(true);
89
- });
90
-
91
- it("returns strlen for single string field", () => {
92
- const ctx = createContext({
93
- result: "ts.str",
94
- previousStructType: "MyStruct",
95
- previousMemberName: "str",
96
- getStructFieldInfo: () => ({ type: "string<64>", dimensions: [65] }),
97
- });
98
- const result = accessGenerators.generateLengthProperty(ctx);
99
- expect(result.code).toBe("strlen(ts.str)");
100
- expect(result.effects).toContainEqual({
101
- type: "include",
102
- header: "string",
103
- });
104
- expect(result.skipContinue).toBe(true);
105
- });
106
-
107
- it("returns dimension for multi-dim array with partial subscript", () => {
108
- const ctx = createContext({
109
- previousStructType: "MyStruct",
110
- previousMemberName: "matrix",
111
- subscriptDepth: 1,
112
- getStructFieldInfo: () => ({ type: "u32", dimensions: [3, 4, 5] }),
113
- });
114
- const result = accessGenerators.generateLengthProperty(ctx);
115
- expect(result.code).toBe("4");
116
- expect(result.skipContinue).toBe(true);
117
- });
118
-
119
- it("returns bit width for fully subscripted array member", () => {
120
- const ctx = createContext({
121
- previousStructType: "MyStruct",
122
- previousMemberName: "values",
123
- subscriptDepth: 2,
124
- getStructFieldInfo: () => ({ type: "u16", dimensions: [3, 4] }),
125
- });
126
- const result = accessGenerators.generateLengthProperty(ctx);
127
- expect(result.code).toBe("16");
128
- expect(result.skipContinue).toBe(true);
129
- });
130
-
131
- it("returns bit width for non-array member", () => {
132
- const ctx = createContext({
133
- previousStructType: "MyStruct",
134
- previousMemberName: "value",
135
- getStructFieldInfo: () => ({ type: "i32" }),
136
- });
137
- const result = accessGenerators.generateLengthProperty(ctx);
138
- expect(result.code).toBe("32");
139
- expect(result.skipContinue).toBe(true);
140
- });
141
-
142
- it("returns comment for unsupported element type", () => {
143
- const ctx = createContext({
144
- previousStructType: "MyStruct",
145
- previousMemberName: "values",
146
- subscriptDepth: 1,
147
- getStructFieldInfo: () => ({ type: "CustomType", dimensions: [3] }),
148
- });
149
- const result = accessGenerators.generateLengthProperty(ctx);
150
- expect(result.code).toContain("unsupported element type CustomType");
151
- expect(result.code).toContain("0");
152
- expect(result.skipContinue).toBe(true);
153
- });
154
-
155
- it("returns comment for unsupported non-array type", () => {
156
- const ctx = createContext({
157
- previousStructType: "MyStruct",
158
- previousMemberName: "custom",
159
- getStructFieldInfo: () => ({ type: "UnknownType" }),
160
- });
161
- const result = accessGenerators.generateLengthProperty(ctx);
162
- expect(result.code).toContain("unsupported type UnknownType");
163
- expect(result.code).toContain("0");
164
- expect(result.skipContinue).toBe(true);
165
- });
166
- });
167
-
168
- describe("string type handling", () => {
169
- it("returns element count for string array without subscript", () => {
170
- const typeInfo: TTypeInfo = {
171
- baseType: "char",
172
- bitWidth: 8,
173
- isArray: true,
174
- arrayDimensions: [4, 65],
175
- isConst: false,
176
- isString: true,
177
- };
178
- const ctx = createContext({
179
- typeInfo,
180
- subscriptDepth: 0,
181
- });
182
- const result = accessGenerators.generateLengthProperty(ctx);
183
- expect(result.code).toBe("4");
184
- });
185
-
186
- it("returns strlen for string array with subscript", () => {
187
- const typeInfo: TTypeInfo = {
188
- baseType: "char",
189
- bitWidth: 8,
190
- isArray: true,
191
- arrayDimensions: [4, 65],
192
- isConst: false,
193
- isString: true,
194
- };
195
- const ctx = createContext({
196
- result: "strArr[0]",
197
- typeInfo,
198
- subscriptDepth: 1,
199
- });
200
- const result = accessGenerators.generateLengthProperty(ctx);
201
- expect(result.code).toBe("strlen(strArr[0])");
202
- expect(result.effects).toContainEqual({
203
- type: "include",
204
- header: "string",
205
- });
206
- });
207
-
208
- it("uses cached length when available", () => {
209
- const typeInfo: TTypeInfo = {
210
- baseType: "char",
211
- bitWidth: 8,
212
- isArray: false,
213
- isConst: false,
214
- isString: true,
215
- };
216
- const lengthCache = new Map([["myStr", "cached_len"]]);
217
- const ctx = createContext({
218
- typeInfo,
219
- currentIdentifier: "myStr",
220
- lengthCache,
221
- });
222
- const result = accessGenerators.generateLengthProperty(ctx);
223
- expect(result.code).toBe("cached_len");
224
- expect(result.effects).toHaveLength(0);
225
- });
226
-
227
- it("returns strlen for single string", () => {
228
- const typeInfo: TTypeInfo = {
229
- baseType: "char",
230
- bitWidth: 8,
231
- isArray: false,
232
- arrayDimensions: [65],
233
- isConst: false,
234
- isString: true,
235
- };
236
- const ctx = createContext({
237
- result: "myStr",
238
- typeInfo,
239
- currentIdentifier: "myStr",
240
- });
241
- const result = accessGenerators.generateLengthProperty(ctx);
242
- expect(result.code).toBe("strlen(myStr)");
243
- expect(result.effects).toContainEqual({
244
- type: "include",
245
- header: "string",
246
- });
247
- });
248
- });
249
-
250
- describe("array type handling", () => {
251
- it("returns dimension at subscript depth for partial subscript", () => {
252
- const typeInfo: TTypeInfo = {
253
- baseType: "u32",
254
- bitWidth: 32,
255
- isArray: true,
256
- arrayDimensions: [10, 20, 30],
257
- isConst: false,
258
- };
259
- const ctx = createContext({
260
- typeInfo,
261
- subscriptDepth: 1,
262
- });
263
- const result = accessGenerators.generateLengthProperty(ctx);
264
- expect(result.code).toBe("20");
265
- });
266
-
267
- it("returns first dimension when no subscript", () => {
268
- const typeInfo: TTypeInfo = {
269
- baseType: "u8",
270
- bitWidth: 8,
271
- isArray: true,
272
- arrayDimensions: [5],
273
- isConst: false,
274
- };
275
- const ctx = createContext({ typeInfo });
276
- const result = accessGenerators.generateLengthProperty(ctx);
277
- expect(result.code).toBe("5");
278
- });
279
-
280
- it("returns 32 for fully subscripted enum array", () => {
281
- const typeInfo: TTypeInfo = {
282
- baseType: "Color",
283
- bitWidth: 32,
284
- isArray: true,
285
- arrayDimensions: [3],
286
- isConst: false,
287
- isEnum: true,
288
- enumTypeName: "Color",
289
- };
290
- const ctx = createContext({
291
- typeInfo,
292
- subscriptDepth: 1,
293
- });
294
- const result = accessGenerators.generateLengthProperty(ctx);
295
- expect(result.code).toBe("32");
296
- });
297
-
298
- it("returns strlen for fully subscripted string array", () => {
299
- const typeInfo: TTypeInfo = {
300
- baseType: "string<64>",
301
- bitWidth: 8,
302
- isArray: true,
303
- arrayDimensions: [4],
304
- isConst: false,
305
- isString: true,
306
- };
307
- const ctx = createContext({
308
- result: "strArr[0]",
309
- typeInfo,
310
- subscriptDepth: 1,
311
- });
312
- const result = accessGenerators.generateLengthProperty(ctx);
313
- expect(result.code).toBe("strlen(strArr[0])");
314
- });
315
-
316
- it("returns element bit width for fully subscripted primitive array", () => {
317
- const typeInfo: TTypeInfo = {
318
- baseType: "u64",
319
- bitWidth: 64,
320
- isArray: true,
321
- arrayDimensions: [10],
322
- isConst: false,
323
- };
324
- const ctx = createContext({
325
- typeInfo,
326
- subscriptDepth: 1,
327
- });
328
- const result = accessGenerators.generateLengthProperty(ctx);
329
- expect(result.code).toBe("64");
330
- });
331
-
332
- it("returns bitmap bit width for fully subscripted bitmap array", () => {
333
- const typeInfo: TTypeInfo = {
334
- baseType: "MyBitmap",
335
- bitWidth: 16,
336
- isArray: true,
337
- arrayDimensions: [5],
338
- isConst: false,
339
- isBitmap: true,
340
- bitmapTypeName: "MyBitmap",
341
- };
342
- const ctx = createContext({
343
- typeInfo,
344
- subscriptDepth: 1,
345
- getBitmapBitWidth: (name: string) =>
346
- name === "MyBitmap" ? 16 : undefined,
347
- });
348
- const result = accessGenerators.generateLengthProperty(ctx);
349
- expect(result.code).toBe("16");
350
- });
351
-
352
- it("returns comment for unknown array length", () => {
353
- const typeInfo: TTypeInfo = {
354
- baseType: "u32",
355
- bitWidth: 32,
356
- isArray: true,
357
- isConst: false,
358
- };
359
- const ctx = createContext({
360
- typeInfo,
361
- currentIdentifier: "unknownArr",
362
- });
363
- const result = accessGenerators.generateLengthProperty(ctx);
364
- expect(result.code).toContain("unknown for unknownArr");
365
- });
366
- });
367
-
368
- describe("enum type handling", () => {
369
- it("returns 32 for enum type", () => {
370
- const typeInfo: TTypeInfo = {
371
- baseType: "Color",
372
- bitWidth: 32,
373
- isArray: false,
374
- isConst: false,
375
- isEnum: true,
376
- enumTypeName: "Color",
377
- };
378
- const ctx = createContext({ typeInfo });
379
- const result = accessGenerators.generateLengthProperty(ctx);
380
- expect(result.code).toBe("32");
381
- });
382
- });
383
-
384
- describe("integer type handling", () => {
385
- it("returns bit width for integer types", () => {
386
- // Test all C-Next integer types (u8-u64, i8-i64) return their bit width
387
- const testCases: [string, number][] = [
388
- ["u8", 8],
389
- ["u16", 16],
390
- ["u32", 32],
391
- ["u64", 64],
392
- ["i8", 8],
393
- ["i16", 16],
394
- ["i32", 32],
395
- ["i64", 64],
396
- ];
397
-
398
- for (const [type, expectedWidth] of testCases) {
399
- const typeInfo: TTypeInfo = {
400
- baseType: type,
401
- bitWidth: expectedWidth,
402
- isArray: false,
403
- isConst: false,
404
- };
405
- const ctx = createContext({ typeInfo });
406
- const result = accessGenerators.generateLengthProperty(ctx);
407
- expect(result.code).toBe(String(expectedWidth));
408
- }
409
- });
410
-
411
- it("returns bit width for float types", () => {
412
- // Test C-Next float types (f32, f64) return their bit width
413
- const testCases: [string, number][] = [
414
- ["f32", 32],
415
- ["f64", 64],
416
- ];
417
-
418
- for (const [type, expectedWidth] of testCases) {
419
- const typeInfo: TTypeInfo = {
420
- baseType: type,
421
- bitWidth: expectedWidth,
422
- isArray: false,
423
- isConst: false,
424
- };
425
- const ctx = createContext({ typeInfo });
426
- const result = accessGenerators.generateLengthProperty(ctx);
427
- expect(result.code).toBe(String(expectedWidth));
428
- }
429
- });
430
-
431
- it("returns bit width for bool type", () => {
432
- const typeInfo: TTypeInfo = {
433
- baseType: "bool",
434
- bitWidth: 1,
435
- isArray: false,
436
- isConst: false,
437
- };
438
- const ctx = createContext({ typeInfo });
439
- const result = accessGenerators.generateLengthProperty(ctx);
440
- expect(result.code).toBe("1");
441
- });
442
- });
443
-
444
- describe("C type width handling for struct members", () => {
445
- it("returns bit width for C integer types in struct members", () => {
446
- // Test C standard integer types from headers (uint8_t, int32_t, etc.)
447
- // These are used when struct fields come from C header definitions
448
- const testCases: [string, number][] = [
449
- ["uint8_t", 8],
450
- ["uint16_t", 16],
451
- ["uint32_t", 32],
452
- ["uint64_t", 64],
453
- ["int8_t", 8],
454
- ["int16_t", 16],
455
- ["int32_t", 32],
456
- ["int64_t", 64],
457
- ];
458
-
459
- for (const [type, expectedWidth] of testCases) {
460
- const ctx = createContext({
461
- previousStructType: "MyStruct",
462
- previousMemberName: "value",
463
- getStructFieldInfo: () => ({ type }),
464
- });
465
- const result = accessGenerators.generateLengthProperty(ctx);
466
- expect(result.code).toBe(String(expectedWidth));
467
- }
468
- });
469
-
470
- it("returns bit width for C float types in struct members", () => {
471
- // Test C standard float types (float, double) from header definitions
472
- const testCases: [string, number][] = [
473
- ["float", 32],
474
- ["double", 64],
475
- ];
476
-
477
- for (const [type, expectedWidth] of testCases) {
478
- const ctx = createContext({
479
- previousStructType: "MyStruct",
480
- previousMemberName: "value",
481
- getStructFieldInfo: () => ({ type }),
482
- });
483
- const result = accessGenerators.generateLengthProperty(ctx);
484
- expect(result.code).toBe(String(expectedWidth));
485
- }
486
- });
487
- });
488
-
489
- describe("edge cases", () => {
490
- it("uses result when currentIdentifier is undefined for strlen", () => {
491
- const typeInfo: TTypeInfo = {
492
- baseType: "char",
493
- bitWidth: 8,
494
- isArray: false,
495
- isConst: false,
496
- isString: true,
497
- };
498
- const ctx = createContext({
499
- result: "expr.str",
500
- typeInfo,
501
- currentIdentifier: undefined,
502
- });
503
- const result = accessGenerators.generateLengthProperty(ctx);
504
- expect(result.code).toBe("strlen(expr.str)");
505
- });
506
-
507
- it("returns unsupported comment for fully subscripted array with unknown element type", () => {
508
- const typeInfo: TTypeInfo = {
509
- baseType: "UnknownCustomType",
510
- bitWidth: 0,
511
- isArray: true,
512
- arrayDimensions: [5],
513
- isConst: false,
514
- };
515
- const ctx = createContext({
516
- typeInfo,
517
- subscriptDepth: 1,
518
- });
519
- const result = accessGenerators.generateLengthProperty(ctx);
520
- expect(result.code).toContain(
521
- "unsupported element type UnknownCustomType",
522
- );
523
- expect(result.code).toContain("0");
524
- });
525
-
526
- it("returns 0 for bitmap array without getBitmapBitWidth function", () => {
527
- const typeInfo: TTypeInfo = {
528
- baseType: "MyBitmap",
529
- bitWidth: 0,
530
- isArray: true,
531
- arrayDimensions: [5],
532
- isConst: false,
533
- isBitmap: true,
534
- bitmapTypeName: "MyBitmap",
535
- };
536
- const ctx = createContext({
537
- typeInfo,
538
- subscriptDepth: 1,
539
- getBitmapBitWidth: undefined,
540
- });
541
- const result = accessGenerators.generateLengthProperty(ctx);
542
- expect(result.code).toContain("unsupported element type MyBitmap");
543
- expect(result.code).toContain("0");
544
- });
545
-
546
- it("returns 0 for bitmap array when getBitmapBitWidth returns undefined", () => {
547
- const typeInfo: TTypeInfo = {
548
- baseType: "MyBitmap",
549
- bitWidth: 0,
550
- isArray: true,
551
- arrayDimensions: [5],
552
- isConst: false,
553
- isBitmap: true,
554
- bitmapTypeName: "MyBitmap",
555
- };
556
- const ctx = createContext({
557
- typeInfo,
558
- subscriptDepth: 1,
559
- getBitmapBitWidth: () => undefined,
560
- });
561
- const result = accessGenerators.generateLengthProperty(ctx);
562
- expect(result.code).toContain("unsupported element type MyBitmap");
563
- expect(result.code).toContain("0");
564
- });
565
- });
566
-
567
- describe("error handling", () => {
568
- it("returns comment for unknown type", () => {
569
- const ctx = createContext({
570
- result: "unknown",
571
- });
572
- const result = accessGenerators.generateLengthProperty(ctx);
573
- expect(result.code).toContain("unknown type for unknown");
574
- expect(result.code).toContain("0");
575
- });
576
- });
577
- });
578
-
579
6
  describe("generateCapacityProperty", () => {
580
7
  it("returns string capacity for string type", () => {
581
8
  const typeInfo: TTypeInfo = {