mirror of
https://github.com/BorysLevytskyi/BitwiseCmd.git
synced 2025-12-10 06:52:05 +01:00
90 lines
2.3 KiB
TypeScript
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};
|