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
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
3926
|
-
|
|
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
|
|