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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | 77x 77x 47x 30x 7x 23x 5x 18x 5x 13x 3x 10x 3x 7x 5x 2x 16x 16x 16x 67x 6x 61x 61x 1389x 1389x 784x 605x 72x 533x 17x 516x | /**
* Utility class for analyzing literal values in the parse tree.
*
* Extracted from DivisionByZeroAnalyzer and FloatModuloAnalyzer
* to eliminate duplicate literal checking code.
*/
import * as Parser from "../transpiler/logic/parser/grammar/CNextParser";
/**
* Static utility methods for literal analysis
*/
class LiteralUtils {
/**
* Check if a literal represents zero.
*
* Handles all C-Next literal formats:
* - Integer: 0
* - Hex: 0x0, 0X0
* - Binary: 0b0, 0B0
* - Suffixed decimal: 0u8, 0i32, etc.
* - Suffixed hex: 0x0u8, 0x0i32, etc.
* - Suffixed binary: 0b0u8, 0b0i32, etc.
*
* @param ctx - The literal context from the parse tree
* @returns true if the literal is zero
*/
static isZero(ctx: Parser.LiteralContext): boolean {
const text = ctx.getText();
// Integer literal: exactly "0"
if (ctx.INTEGER_LITERAL()) {
return text === "0";
}
// Hex literal: 0x0 or 0X0
if (ctx.HEX_LITERAL()) {
return text === "0x0" || text === "0X0";
}
// Binary literal: 0b0 or 0B0
if (ctx.BINARY_LITERAL()) {
return text === "0b0" || text === "0B0";
}
// Suffixed decimal: 0u8, 0i32, etc.
if (ctx.SUFFIXED_DECIMAL()) {
return text.startsWith("0u") || text.startsWith("0i");
}
// Suffixed hex: 0x0u8, 0x0i32, etc.
if (ctx.SUFFIXED_HEX()) {
return (
text.startsWith("0x0u") ||
text.startsWith("0x0i") ||
text.startsWith("0X0u") ||
text.startsWith("0X0i")
);
}
// Suffixed binary: 0b0u8, 0b0i32, etc.
if (ctx.SUFFIXED_BINARY()) {
return (
text.startsWith("0b0u") ||
text.startsWith("0b0i") ||
text.startsWith("0B0u") ||
text.startsWith("0B0i")
);
}
// Issue #1010: Float literals (0.0, 0.0f, .0, etc.)
if (ctx.FLOAT_LITERAL()) {
return LiteralUtils.isFloatZero(text);
}
return false;
}
/**
* Check if a float literal string represents zero.
* Issue #1010: Detect float zero for division-by-zero checking.
*
* Handles: 0.0, .0, 0., 0.0f, 0.0F, 0.0e0, 0.0E0, etc.
*
* @param text - The float literal text
* @returns true if the float is zero
*/
static isFloatZero(text: string): boolean {
// Remove optional float suffix (f, F)
const withoutSuffix = text.replace(/[fF]$/, "");
// Parse to number and check if zero
const value = Number.parseFloat(withoutSuffix);
return value === 0;
}
/**
* Check if a literal is a floating-point number.
*
* @param ctx - The literal context from the parse tree
* @returns true if the literal is a float
*/
static isFloat(ctx: Parser.LiteralContext): boolean {
// Check for FLOAT_LITERAL token
if (ctx.FLOAT_LITERAL()) {
return true;
}
// Fallback: check text for decimal point (not in strings)
const text = ctx.getText();
return text.includes(".") && !text.startsWith('"');
}
/**
* Parse an integer literal string to a numeric value.
*
* Handles all C-Next integer formats:
* - Decimal: 42, -17
* - Hex: 0x2A, 0X2a
* - Binary: 0b101010, 0B101010
*
* Issue #455: Used for resolving const values in array dimensions.
*
* @param text - The literal text to parse
* @returns The numeric value, or undefined if not a valid integer literal
*/
static parseIntegerLiteral(text: string): number | undefined {
const trimmed = text.trim();
// Decimal integer (including negative)
if (/^-?\d+$/.test(trimmed)) {
return Number.parseInt(trimmed, 10);
}
// Hex literal (0x or 0X prefix)
if (/^0[xX][0-9a-fA-F]+$/.test(trimmed)) {
return Number.parseInt(trimmed, 16);
}
// Binary literal (0b or 0B prefix)
if (/^0[bB][01]+$/.test(trimmed)) {
return Number.parseInt(trimmed.substring(2), 2);
}
return undefined;
}
}
export default LiteralUtils;
|