Files
BitwiseCmd/src/expression/numberParser.ts
2025-11-05 15:37:06 -05:00

90 lines
2.3 KiB
TypeScript

import { INT32_MAX_VALUE, UINT32_MAX_VALUE } from "../core/const";
import { NumberBase } from "../core/formatter";
import { Integer } from "../core/Integer";
const numberRegexString = "-?([0-9]+|0b[0-1]+|0x[0-9,a-f]+)(l|s|b|ul|us|ub|u)?";
const numberRegexFullString = "^"+numberRegexString+"$"
export interface ParsedNumber {
value: Integer;
base: NumberBase;
input: string;
}
class NumberParser {
numberRegexString: string;
constructor()
{
this.numberRegexString = numberRegexString;
}
caseParse(input : string) {
const regex = new RegExp(numberRegexFullString);
return regex.test(input);
}
parse (input : string) : ParsedNumber {
if(input.length === 0) throw new Error("input is null or empty");
const regex = new RegExp(numberRegexFullString, "i");
const m = regex.exec(input);
if(m === null || m.length === 0)
throw new Error(input + " is not a number");
const value = parseInteger(m[0], m[1], m[2] || '');
return {
value: value,
base: getBase(input),
input: input
}
};
}
function parseInteger(input : string, numberPart: string, suffix: string) : Integer {
const isNegative = input.startsWith('-');
let num = BigInt(numberPart);
const signed = !suffix.startsWith('u');
const bitSize = getSizeBySuffix(suffix, num, signed);
const newValue = isNegative ? -num : num;
if(!signed && isNegative)
{
const signed = new Integer(newValue, bitSize, true);
const bin = "0b" + signed.toString(2);
return Integer.unsigned(BigInt(bin), bitSize);
}
return new Integer(newValue, bitSize, signed);
}
function getSizeBySuffix(suffix: string, value : bigint, signed: boolean) {
const max32 = signed ? INT32_MAX_VALUE : UINT32_MAX_VALUE;
switch(suffix.replace('u', '').toLowerCase()) {
case 'l': return 64;
case 's': return 16;
case 'b': return 8;
default: return value > max32 ? 64 : 32;
}
}
function getBase(input: string): NumberBase {
if(input.indexOf('0b') > -1) return 'bin';
if(input.indexOf('0x') > -1) return 'hex';
return 'dec';
}
const numberParser = new NumberParser();
export {numberParser, numberRegexString};