c-next 0.2.2 → 0.2.3
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/dist/index.js +105 -22
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
- package/src/transpiler/logic/symbols/c/utils/DeclaratorUtils.ts +99 -2
- package/src/transpiler/logic/symbols/c/utils/__tests__/DeclaratorUtils.test.ts +128 -0
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +49 -36
- package/src/transpiler/output/codegen/__tests__/RequireInclude.test.ts +4 -2
- package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +23 -14
- package/src/transpiler/output/codegen/generators/expressions/__tests__/PostfixExpressionGenerator.test.ts +9 -6
- package/src/transpiler/output/codegen/generators/statements/SwitchGenerator.ts +10 -1
- package/src/transpiler/output/codegen/helpers/ArrayAccessHelper.ts +6 -3
- package/src/transpiler/output/codegen/helpers/FloatBitHelper.ts +36 -22
- package/src/transpiler/output/codegen/helpers/__tests__/ArrayAccessHelper.test.ts +8 -6
- package/src/transpiler/output/codegen/helpers/__tests__/FloatBitHelper.test.ts +34 -18
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import { hideBin } from "yargs/helpers";
|
|
|
10
10
|
// package.json
|
|
11
11
|
var package_default = {
|
|
12
12
|
name: "c-next",
|
|
13
|
-
version: "0.2.
|
|
13
|
+
version: "0.2.3",
|
|
14
14
|
description: "A safer C for embedded systems development. Transpiles to clean, readable C.",
|
|
15
15
|
packageManager: "npm@11.9.0",
|
|
16
16
|
type: "module",
|
|
@@ -116790,37 +116790,37 @@ var handleBitRangeSubscript = (ctx, exprs, input, state, orchestrator, effects,
|
|
|
116790
116790
|
}
|
|
116791
116791
|
return output;
|
|
116792
116792
|
};
|
|
116793
|
+
var getFloatTypeName = (baseType) => {
|
|
116794
|
+
return baseType === "f64" ? "double" : "float";
|
|
116795
|
+
};
|
|
116793
116796
|
var handleFloatBitRange = (ctx, state, orchestrator, effects) => {
|
|
116794
116797
|
if (!state.inFunctionBody) {
|
|
116795
116798
|
throw new Error(
|
|
116796
116799
|
`Float bit indexing reads (${ctx.rootIdentifier}[${ctx.start}, ${ctx.width}]) cannot be used at global scope.`
|
|
116797
116800
|
);
|
|
116798
116801
|
}
|
|
116799
|
-
effects.push(
|
|
116800
|
-
{ type: "include", header: "string" },
|
|
116801
|
-
{ type: "include", header: "float_static_assert" }
|
|
116802
|
-
);
|
|
116802
|
+
effects.push({ type: "include", header: "float_static_assert" });
|
|
116803
116803
|
const isF64 = ctx.baseType === "f64";
|
|
116804
|
-
const
|
|
116804
|
+
const floatType = getFloatTypeName(ctx.baseType);
|
|
116805
|
+
const intType = isF64 ? "uint64_t" : "uint32_t";
|
|
116805
116806
|
const shadowName = `__bits_${ctx.rootIdentifier}`;
|
|
116806
116807
|
const mask = orchestrator.generateBitMask(ctx.width, isF64);
|
|
116807
116808
|
const needsDeclaration = !orchestrator.hasFloatBitShadow(shadowName);
|
|
116808
116809
|
if (needsDeclaration) {
|
|
116809
116810
|
orchestrator.registerFloatBitShadow(shadowName);
|
|
116810
|
-
orchestrator.addPendingTempDeclaration(
|
|
116811
|
+
orchestrator.addPendingTempDeclaration(
|
|
116812
|
+
`union { ${floatType} f; ${intType} u; } ${shadowName};`
|
|
116813
|
+
);
|
|
116811
116814
|
}
|
|
116812
116815
|
const shadowIsCurrent = orchestrator.isFloatShadowCurrent(shadowName);
|
|
116813
116816
|
orchestrator.markFloatShadowCurrent(shadowName);
|
|
116814
|
-
if (shadowIsCurrent) {
|
|
116815
|
-
|
|
116816
|
-
return `(${shadowName} & ${mask})`;
|
|
116817
|
-
}
|
|
116818
|
-
return `((${shadowName} >> ${ctx.start}) & ${mask})`;
|
|
116817
|
+
if (!shadowIsCurrent) {
|
|
116818
|
+
orchestrator.addPendingTempDeclaration(`${shadowName}.f = ${ctx.result};`);
|
|
116819
116819
|
}
|
|
116820
116820
|
if (ctx.start === "0") {
|
|
116821
|
-
return `(
|
|
116821
|
+
return `(${shadowName}.u & ${mask})`;
|
|
116822
116822
|
}
|
|
116823
|
-
return `(
|
|
116823
|
+
return `((${shadowName}.u >> ${ctx.start}) & ${mask})`;
|
|
116824
116824
|
};
|
|
116825
116825
|
var applyAccessEffects = (sourceEffects, targetEffects) => {
|
|
116826
116826
|
for (const effect of sourceEffects) {
|
|
@@ -117370,6 +117370,12 @@ var generateSwitch = (node, input, state, orchestrator) => {
|
|
|
117370
117370
|
);
|
|
117371
117371
|
lines.push(defaultResult.code);
|
|
117372
117372
|
effects.push(...defaultResult.effects);
|
|
117373
|
+
} else {
|
|
117374
|
+
lines.push(
|
|
117375
|
+
orchestrator.indent("default: {"),
|
|
117376
|
+
orchestrator.indent(orchestrator.indent("break;")),
|
|
117377
|
+
orchestrator.indent("}")
|
|
117378
|
+
);
|
|
117373
117379
|
}
|
|
117374
117380
|
lines.push("}");
|
|
117375
117381
|
return { code: lines.join("\n"), effects };
|
|
@@ -122737,11 +122743,16 @@ var MemberChainAnalyzer = class _MemberChainAnalyzer {
|
|
|
122737
122743
|
var MemberChainAnalyzer_default = MemberChainAnalyzer;
|
|
122738
122744
|
|
|
122739
122745
|
// src/transpiler/output/codegen/helpers/FloatBitHelper.ts
|
|
122746
|
+
var getFloatTypeName2 = (baseType) => {
|
|
122747
|
+
return baseType === "f64" ? "double" : "float";
|
|
122748
|
+
};
|
|
122740
122749
|
var FloatBitHelper = class {
|
|
122741
122750
|
/**
|
|
122742
|
-
* Generate float bit write using
|
|
122751
|
+
* Generate float bit write using union-based type punning.
|
|
122743
122752
|
* Returns null if typeInfo is not a float type.
|
|
122744
122753
|
*
|
|
122754
|
+
* Uses union { float f; uint32_t u; } for MISRA 21.15 compliance instead of memcpy.
|
|
122755
|
+
*
|
|
122745
122756
|
* @param name - Variable name being written
|
|
122746
122757
|
* @param typeInfo - Type information for the variable
|
|
122747
122758
|
* @param bitIndex - Bit index expression (start position)
|
|
@@ -122755,10 +122766,10 @@ var FloatBitHelper = class {
|
|
|
122755
122766
|
if (!isFloatType) {
|
|
122756
122767
|
return null;
|
|
122757
122768
|
}
|
|
122758
|
-
callbacks.requireInclude("string");
|
|
122759
122769
|
callbacks.requireInclude("float_static_assert");
|
|
122760
122770
|
const isF64 = typeInfo.baseType === "f64";
|
|
122761
|
-
const
|
|
122771
|
+
const floatType = getFloatTypeName2(typeInfo.baseType);
|
|
122772
|
+
const intType = isF64 ? "uint64_t" : "uint32_t";
|
|
122762
122773
|
const shadowName = `__bits_${name}`;
|
|
122763
122774
|
const maskSuffix = isF64 ? "ULL" : "U";
|
|
122764
122775
|
const needsDeclaration = !CodeGenState.floatBitShadows.has(shadowName);
|
|
@@ -122766,14 +122777,18 @@ var FloatBitHelper = class {
|
|
|
122766
122777
|
CodeGenState.floatBitShadows.add(shadowName);
|
|
122767
122778
|
}
|
|
122768
122779
|
const shadowIsCurrent = CodeGenState.floatShadowCurrent.has(shadowName);
|
|
122769
|
-
const decl = needsDeclaration ?
|
|
122770
|
-
|
|
122780
|
+
const decl = needsDeclaration ? `union { ${floatType} f; ${intType} u; } ${shadowName};
|
|
122781
|
+
` : "";
|
|
122782
|
+
const readUnion = shadowIsCurrent ? "" : `${shadowName}.f = ${name};
|
|
122783
|
+
`;
|
|
122771
122784
|
CodeGenState.floatShadowCurrent.add(shadowName);
|
|
122772
122785
|
if (width === null) {
|
|
122773
|
-
return `${decl}${
|
|
122786
|
+
return `${decl}${readUnion}${shadowName}.u = (${shadowName}.u & ~(1${maskSuffix} << ${bitIndex})) | ((${intType})${callbacks.foldBooleanToInt(value)} << ${bitIndex});
|
|
122787
|
+
${name} = ${shadowName}.f;`;
|
|
122774
122788
|
} else {
|
|
122775
122789
|
const mask = callbacks.generateBitMask(width, isF64);
|
|
122776
|
-
return `${decl}${
|
|
122790
|
+
return `${decl}${readUnion}${shadowName}.u = (${shadowName}.u & ~(${mask} << ${bitIndex})) | (((${intType})${value} & ${mask}) << ${bitIndex});
|
|
122791
|
+
${name} = ${shadowName}.f;`;
|
|
122777
122792
|
}
|
|
122778
122793
|
}
|
|
122779
122794
|
};
|
|
@@ -132808,7 +132823,7 @@ var DeclaratorUtils = class _DeclaratorUtils {
|
|
|
132808
132823
|
if (identifier) {
|
|
132809
132824
|
parts.push(identifier.getText());
|
|
132810
132825
|
} else {
|
|
132811
|
-
parts.push(
|
|
132826
|
+
parts.push(_DeclaratorUtils.reconstructAnonymousStruct(structSpec));
|
|
132812
132827
|
}
|
|
132813
132828
|
} else {
|
|
132814
132829
|
parts.push(typeSpec.getText());
|
|
@@ -132822,6 +132837,74 @@ var DeclaratorUtils = class _DeclaratorUtils {
|
|
|
132822
132837
|
}
|
|
132823
132838
|
return parts.join(" ") || "int";
|
|
132824
132839
|
}
|
|
132840
|
+
/**
|
|
132841
|
+
* Reconstruct an anonymous struct/union type with proper spacing.
|
|
132842
|
+
* For `struct { unsigned int flag_a: 1; }`, returns the properly formatted string
|
|
132843
|
+
* instead of the concatenated tokens from getText().
|
|
132844
|
+
*/
|
|
132845
|
+
static reconstructAnonymousStruct(structSpec) {
|
|
132846
|
+
const structOrUnion = structSpec.structOrUnion();
|
|
132847
|
+
const keyword = structOrUnion.Struct() ? "struct" : "union";
|
|
132848
|
+
const declList = structSpec.structDeclarationList();
|
|
132849
|
+
if (!declList) {
|
|
132850
|
+
return `${keyword} { }`;
|
|
132851
|
+
}
|
|
132852
|
+
const fields = _DeclaratorUtils.reconstructStructFields(declList);
|
|
132853
|
+
return `${keyword} { ${fields} }`;
|
|
132854
|
+
}
|
|
132855
|
+
/**
|
|
132856
|
+
* Reconstruct struct fields with proper spacing.
|
|
132857
|
+
*/
|
|
132858
|
+
static reconstructStructFields(declList) {
|
|
132859
|
+
const fieldStrings = [];
|
|
132860
|
+
for (const decl of declList.structDeclaration()) {
|
|
132861
|
+
const fieldStr = _DeclaratorUtils.reconstructStructField(decl);
|
|
132862
|
+
if (fieldStr) {
|
|
132863
|
+
fieldStrings.push(fieldStr);
|
|
132864
|
+
}
|
|
132865
|
+
}
|
|
132866
|
+
return fieldStrings.join(" ");
|
|
132867
|
+
}
|
|
132868
|
+
/**
|
|
132869
|
+
* Reconstruct a single struct field declaration.
|
|
132870
|
+
*/
|
|
132871
|
+
static reconstructStructField(decl) {
|
|
132872
|
+
const specQualList = decl.specifierQualifierList();
|
|
132873
|
+
if (!specQualList) return null;
|
|
132874
|
+
const baseType = _DeclaratorUtils.extractTypeFromSpecQualList(specQualList);
|
|
132875
|
+
const declaratorList = decl.structDeclaratorList();
|
|
132876
|
+
if (!declaratorList) {
|
|
132877
|
+
return `${baseType};`;
|
|
132878
|
+
}
|
|
132879
|
+
const declarators = [];
|
|
132880
|
+
for (const structDecl of declaratorList.structDeclarator()) {
|
|
132881
|
+
const declStr = _DeclaratorUtils.reconstructStructDeclarator(structDecl);
|
|
132882
|
+
if (declStr) {
|
|
132883
|
+
declarators.push(declStr);
|
|
132884
|
+
}
|
|
132885
|
+
}
|
|
132886
|
+
if (declarators.length === 0) {
|
|
132887
|
+
return `${baseType};`;
|
|
132888
|
+
}
|
|
132889
|
+
return `${baseType} ${declarators.join(", ")};`;
|
|
132890
|
+
}
|
|
132891
|
+
/**
|
|
132892
|
+
* Reconstruct a struct declarator (field name with optional bitfield width).
|
|
132893
|
+
*/
|
|
132894
|
+
static reconstructStructDeclarator(structDecl) {
|
|
132895
|
+
const declarator = structDecl.declarator();
|
|
132896
|
+
const hasColon = structDecl.Colon() !== null;
|
|
132897
|
+
const constExpr = structDecl.constantExpression();
|
|
132898
|
+
let name = "";
|
|
132899
|
+
if (declarator) {
|
|
132900
|
+
name = _DeclaratorUtils.extractDeclaratorName(declarator) || "";
|
|
132901
|
+
}
|
|
132902
|
+
if (hasColon && constExpr) {
|
|
132903
|
+
const width = constExpr.getText();
|
|
132904
|
+
return `${name}: ${width}`;
|
|
132905
|
+
}
|
|
132906
|
+
return name || null;
|
|
132907
|
+
}
|
|
132825
132908
|
/**
|
|
132826
132909
|
* Extract typedef name from declaration specifiers.
|
|
132827
132910
|
* For "typedef struct { ... } AppConfig;", this returns "AppConfig".
|