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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | import type TChainRoot from "./TChainRoot";
import type ISourcePosition from "../utils/types/ISourcePosition";
/**
* An integer expression whose value may be needed while the program compiles
* -- an array dimension, an enum member's value, a const's initializer -- as
* plain data (#1175, #1669).
*
* ## Why not the parse tree, and why not its text
*
* The tree is Tier 1 with a short lifetime: 1.3 Declare consumes it and does
* not re-export it (#1317, docs/architecture/README.md), so a pass after 1.3
* cannot hold one. Its `getText()` is not a substitute. ANTLR joins the tokens
* with no separator, so the text re-lexes as different tokens: `(LIM < -1)`
* reads back as `(LIM<-1)`, where `<-` is assignment, and `1 - -1` reaches C as
* `1--1`, which C reads as a decrement. This form is lowered from the tree once,
* where the tree is in hand, and every pass evaluates it by the one rule in
* `ConstantEvaluator`.
*
* Plain data, so a symbol carrying it stays JSON-encodable (#1298): a literal
* holds its value as decimal digits, because a u64 is past what a `number`
* holds exactly and a `bigint` is not JSON.
*/
type TConstExpr =
| {
readonly kind: "literal";
/** The value in decimal digits, whatever notation the source used */
readonly digits: string;
/**
* A suffixed literal's type (`9u8`); `bool` for `true` and `false`; null
* for an unsuffixed integer literal, which has no type of its own (ADR-052)
*/
readonly typeName: string | null;
}
| {
readonly kind: "name";
readonly root: TChainRoot;
/** `N` is `["N"]`; `Scope.N` and `EColor.COUNT` are two segments */
readonly path: readonly string[];
/** Where the name is written, which is where it binds (ADR-057) */
readonly at: ISourcePosition;
}
| {
readonly kind: "sizeof";
readonly typeName: string;
/** Where it is written, which decides what a bare type name means */
readonly at: ISourcePosition;
}
| {
readonly kind: "cast";
readonly typeName: string;
readonly operand: TConstExpr;
readonly at: ISourcePosition;
}
| {
readonly kind: "unary";
readonly op: "-" | "~" | "!";
readonly operand: TConstExpr;
}
| {
readonly kind: "binary";
readonly op:
| "*"
| "/"
| "%"
| "+"
| "-"
| "<<"
| ">>"
| "&"
| "^"
| "|"
| "<"
| ">"
| "<="
| ">="
| "="
| "!="
| "&&"
| "||";
readonly left: TConstExpr;
readonly right: TConstExpr;
}
| {
readonly kind: "ternary";
readonly condition: TConstExpr;
readonly whenTrue: TConstExpr;
readonly whenFalse: TConstExpr;
}
| {
/** Something no constant expression contains, kept so the reason can be reported */
readonly kind: "other";
readonly what:
| "call"
| "subscript"
| "float"
| "string"
| "character"
| "initializer"
| "address"
| "member"
| "leadingZero"
| "sizeofExpression";
/** The source spelling, for a diagnostic's message only -- never emitted */
readonly spelling: string;
readonly at: ISourcePosition;
};
export default TConstExpr;
|