c-next 0.1.63 → 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "c-next",
3
- "version": "0.1.63",
3
+ "version": "0.1.64",
4
4
  "description": "A safer C for embedded systems development. Transpiles to clean, readable C.",
5
5
  "packageManager": "npm@11.9.0",
6
6
  "type": "module",
@@ -3870,7 +3870,10 @@ export default class CodeGenerator implements IOrchestrator {
3870
3870
  const paramName = param.IDENTIFIER().getText();
3871
3871
  const isConst = param.constModifier() !== null;
3872
3872
  // arrayDimension() returns an array (due to grammar's *), so check length
3873
- const isArray = param.arrayDimension().length > 0;
3873
+ // Also check C-Next style array type (e.g., u8[8] param)
3874
+ const isArray =
3875
+ param.arrayDimension().length > 0 ||
3876
+ param.type().arrayType() !== null;
3874
3877
  const baseType = this.getTypeName(param.type());
3875
3878
  parameters.push({ name: paramName, baseType, isConst, isArray });
3876
3879
  }
@@ -3903,7 +3906,8 @@ export default class CodeGenerator implements IOrchestrator {
3903
3906
  const typeName = this.getTypeName(param.type());
3904
3907
  const isConst = param.constModifier() !== null;
3905
3908
  const dims = param.arrayDimension();
3906
- const isArray = dims.length > 0;
3909
+ const arrayTypeCtx = param.type().arrayType();
3910
+ const isArray = dims.length > 0 || arrayTypeCtx !== null;
3907
3911
 
3908
3912
  // ADR-029: Check if parameter type is itself a callback type
3909
3913
  const isCallbackParam = CodeGenState.callbackTypes.has(typeName);
@@ -3922,9 +3926,14 @@ export default class CodeGenerator implements IOrchestrator {
3922
3926
  isPointer = !isArray;
3923
3927
  }
3924
3928
 
3925
- const arrayDims = isArray
3926
- ? dims.map((d) => this.generateArrayDimension(d)).join("")
3927
- : "";
3929
+ let arrayDims: string;
3930
+ if (dims.length > 0) {
3931
+ arrayDims = dims.map((d) => this.generateArrayDimension(d)).join("");
3932
+ } else if (arrayTypeCtx) {
3933
+ arrayDims = `[${this.generateExpression(arrayTypeCtx.expression())}]`;
3934
+ } else {
3935
+ arrayDims = "";
3936
+ }
3928
3937
  parameters.push({
3929
3938
  name: paramName,
3930
3939
  type: paramType,
@@ -5181,6 +5190,15 @@ export default class CodeGenerator implements IOrchestrator {
5181
5190
 
5182
5191
  const type = this.generateType(ctx.type());
5183
5192
 
5193
+ // Handle C-Next style array type in parameter (e.g., u8[8] param)
5194
+ const arrayTypeCtx = ctx.type().arrayType();
5195
+ if (arrayTypeCtx) {
5196
+ const dimExpr = this.generateExpression(arrayTypeCtx.expression());
5197
+ const wasModified = this._isCurrentParameterModified(name);
5198
+ const autoConst = !wasModified && !constMod ? "const " : "";
5199
+ return `${autoConst}${constMod}${type} ${name}[${dimExpr}]`;
5200
+ }
5201
+
5184
5202
  // Try special cases first
5185
5203
  const stringArrayResult = this._tryGenerateStringArrayParam(
5186
5204
  ctx,
@@ -5814,6 +5832,14 @@ export default class CodeGenerator implements IOrchestrator {
5814
5832
  return "{}";
5815
5833
  }
5816
5834
  }
5835
+ // Also check C-Next style array type (e.g., CppClass[4]) where
5836
+ // the userType is nested inside arrayType.
5837
+ if (typeCtx.arrayType()?.userType()) {
5838
+ const typeName = typeCtx.arrayType()!.userType()!.getText();
5839
+ if (this._needsEmptyBraceInit(typeName)) {
5840
+ return "{}";
5841
+ }
5842
+ }
5817
5843
  // Template types are always C++ classes
5818
5844
  if (typeCtx.templateType()) {
5819
5845
  return "{}";
@@ -7169,6 +7169,142 @@ describe("CodeGenerator", () => {
7169
7169
 
7170
7170
  // Note: Template type tests skipped - template argument transformation
7171
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
+ });
7172
7308
  });
7173
7309
  });
7174
7310