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 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.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 shadowType = isF64 ? "uint64_t" : "uint32_t";
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(`${shadowType} ${shadowName};`);
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
- if (ctx.start === "0") {
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 `(memcpy(&${shadowName}, &${ctx.result}, sizeof(${ctx.result})), (${shadowName} & ${mask}))`;
116821
+ return `(${shadowName}.u & ${mask})`;
116822
116822
  }
116823
- return `(memcpy(&${shadowName}, &${ctx.result}, sizeof(${ctx.result})), ((${shadowName} >> ${ctx.start}) & ${mask}))`;
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 shadow variable + memcpy.
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 shadowType = isF64 ? "uint64_t" : "uint32_t";
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 ? `${shadowType} ${shadowName}; ` : "";
122770
- const readMemcpy = shadowIsCurrent ? "" : `memcpy(&${shadowName}, &${name}, sizeof(${name})); `;
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}${readMemcpy}${shadowName} = (${shadowName} & ~(1${maskSuffix} << ${bitIndex})) | ((${shadowType})${callbacks.foldBooleanToInt(value)} << ${bitIndex}); memcpy(&${name}, &${shadowName}, sizeof(${name}));`;
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}${readMemcpy}${shadowName} = (${shadowName} & ~(${mask} << ${bitIndex})) | (((${shadowType})${value} & ${mask}) << ${bitIndex}); memcpy(&${name}, &${shadowName}, sizeof(${name}));`;
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(typeSpec.getText());
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".