All files / cnx/utils FloatBits.ts

100% Statements 8/8
100% Branches 11/11
100% Functions 3/3
100% Lines 7/7

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                            662x 535x   127x 59x 59x                       33x         1145x          
import type IChainStep from "../types/IChainStep";
import type IChainHead from "../types/IChainHead";
import invariant from "./invariant";
 
/**
 * ADR-007: whether a bit index or bit range reaches a float's bits, which C
 * cannot shift or mask, so they go through a union. Asked of the value the
 * subscript applies to -- the typer's step -- never of the chain's root, which
 * a field, an element or a `this.`/`global.` member is not (#2057, #1099). 2.1's
 * E0888 and 2.2's float-bit and narrowing plans ask this one function.
 */
class FloatBits {
  /** The float's cnx type, or null when the step reads no float's bits */
  static typeOf(step: IChainStep | undefined): string | null {
    if (step?.subscript !== "bit_single" && step?.subscript !== "bit_range") {
      return null;
    }
    if (step.before?.category !== "floating") return null;
    invariant(step.before.typeName !== null, "the typer names a float's type");
    return step.before.typeName;
  }
 
  /**
   * Whether the bits at `head.ops[index]` go through the variable's shadow
   * union, shared by its every bit read and write and invalidated by a write
   * of the whole variable -- a write that names it the same way. Only a bare
   * variable has one: a `this.`/`global.` member is written under another
   * name, so its shadow went stale (#2057), and a field or element has no
   * name of its own. Any other float is copied into a union of its own.
   */
  static sharesShadow(head: IChainHead, index: number): boolean {
    return head.root === null && head.identifier !== null && index === 0;
  }
 
  /** The float type a bit RANGE reads through a union, or null */
  static rangeTypeOf(step: IChainStep | undefined): string | null {
    return step?.subscript === "bit_range" ? FloatBits.typeOf(step) : null;
  }
}
 
export default FloatBits;