All files / transpiler/logic/symbols/cnext/utils DimensionResolver.ts

100% Statements 2/2
100% Branches 2/2
100% Functions 1/1
100% Lines 2/2

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53                                                                                      106x       106x          
/**
 * DimensionResolver - resolves one array dimension expression during symbol
 * collection.
 *
 * Issue #1127: VariableCollector and StructCollector each carried their own
 * version of this, and they disagreed. StructCollector accepted only a bare
 * literal or a bare const and dropped everything else, so
 * `struct { u8[8+1] data; }` reached the header as a scalar. VariableCollector
 * kept unresolved text but folded nothing beyond a literal or a const, so
 * `u8[sizeof(u32)] sz;` put a C-Next type name into the generated C header:
 *
 *   .c   uint8_t sz[4]
 *   .h   extern uint8_t sz[sizeof(u32)]     error: 'u32' undeclared here
 *
 * Both now resolve through this one function, which folds through the same
 * ArrayDimensionParser and TYPE_WIDTH table codegen uses.
 */
 
import * as Parser from "../../../parser/grammar/CNextParser";
import ArrayDimensionParser from "../../../../../utils/ArrayDimensionParser";
import TYPE_WIDTH from "../../../../constants/TYPE_WIDTH";
 
class DimensionResolver {
  /**
   * Resolve one array dimension expression.
   *
   * @param sizeExpr The dimension expression
   * @param constValues Const name -> value, as known at collection time
   * @returns The folded size, or the expression's source text when it does not
   *          fold at compile time. Never undefined: dropping a dimension loses
   *          the field's array-ness and shifts every dimension after it.
   *
   *          Source text is only correct for a name C will also know -- an
   *          enum-qualified count, which qualifyStructFieldDimensions turns
   *          into `EColor__COUNT`, or a macro from an included header. For
   *          anything else it leaks a C-Next name into generated C and the
   *          header fails to compile. That hole is #1175; the evaluator folds
   *          the arithmetic forms that were hitting it in practice.
   */
  static resolve(
    sizeExpr: Parser.ExpressionContext,
    constValues?: Map<string, number>,
  ): number | string {
    const folded = ArrayDimensionParser.parseSingleDimension(sizeExpr, {
      constValues,
      typeWidths: TYPE_WIDTH,
    });
    return folded ?? sizeExpr.getText();
  }
}
 
export default DimensionResolver;