mirror of
https://github.com/BorysLevytskyi/BitwiseCmd.git
synced 2025-12-10 06:52:05 +01:00
Refactor and enable bits flipping in bitwise expression
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import calc from './calc';
|
||||
import { BitwiseOperationExpression, ScalarExpression, OperatorExpression } from '../expression/expression';
|
||||
import { BitwiseOperationExpression, ScalarToken, OperatorToken } from '../expression/expression';
|
||||
import exp from 'constants';
|
||||
import { INT_MAX_VALUE } from './const';
|
||||
import formatter from './formatter';
|
||||
@@ -23,9 +23,9 @@ describe("calc", () => {
|
||||
var result = calc.calcExpression(new BitwiseOperationExpression(
|
||||
"1|2&3",
|
||||
[
|
||||
new ScalarExpression(1),
|
||||
new OperatorExpression(new ScalarExpression(2), "|"),
|
||||
new OperatorExpression(new ScalarExpression(3), "&"),
|
||||
new ScalarToken(1),
|
||||
new OperatorToken(new ScalarToken(2), "|"),
|
||||
new OperatorToken(new ScalarToken(3), "&"),
|
||||
]
|
||||
));
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { dblClick } from "@testing-library/user-event/dist/click";
|
||||
import { ExpressionInput } from "../expression/expression-interfaces";
|
||||
import { Expression } from "../expression/expression-interfaces";
|
||||
import { INT_MAX_VALUE } from "./const";
|
||||
import { start } from "repl";
|
||||
|
||||
@@ -23,7 +23,7 @@ export default {
|
||||
return Math.max.apply(null, counts);
|
||||
},
|
||||
|
||||
calcExpression: function (expr: ExpressionInput) {
|
||||
calcExpression: function (expr: Expression) {
|
||||
return eval(expr.expressionString);
|
||||
},
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { ExpressionInput, Expression } from "./expression-interfaces";
|
||||
import { Expression, ExpressionToken } from "./expression-interfaces";
|
||||
|
||||
export default class BitwiseOperationExpression implements ExpressionInput {
|
||||
export default class BitwiseOperationExpression implements Expression {
|
||||
|
||||
expressionString: string;
|
||||
children: Expression[];
|
||||
children: ExpressionToken[];
|
||||
|
||||
constructor(expressionString: string, children: Expression[]) {
|
||||
constructor(expressionString: string, children: ExpressionToken[]) {
|
||||
this.expressionString = expressionString;
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import OperatorExpression from "./OperatorExpression";
|
||||
import { ScalarExpression } from "./expression";
|
||||
import { Expression } from "./expression-interfaces";
|
||||
import OperatorToken from "./OperatorToken";
|
||||
import { ScalarToken } from "./expression";
|
||||
import { ExpressionToken } from "./expression-interfaces";
|
||||
import { type } from "os";
|
||||
import { InputType } from "zlib";
|
||||
import exp from "constants";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import ScalarExpression from "./ScalarExpression";
|
||||
import ScalarToken from "./ScalarToken";
|
||||
import ListOfNumbersExpression from "./ListOfNumbersExpression";
|
||||
|
||||
it('calculates max bits length', () => {
|
||||
var expr = new ListOfNumbersExpression("10 0xabef 0b01010", [ScalarExpression.parse("10"), ScalarExpression.parse("0xabef"), ScalarExpression.parse("0b01010")])
|
||||
var expr = new ListOfNumbersExpression("10 0xabef 0b01010", [ScalarToken.parse("10"), ScalarToken.parse("0xabef"), ScalarToken.parse("0b01010")])
|
||||
expect(expr.maxBitsLength).toBe(16);
|
||||
});
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import calc from "../core/calc";
|
||||
import ScalarExpression from "./ScalarExpression";
|
||||
import { ExpressionInput, Expression } from "./expression-interfaces";
|
||||
import ScalarToken from "./ScalarToken";
|
||||
import { Expression, ExpressionToken } from "./expression-interfaces";
|
||||
|
||||
export default class ListOfNumbersExpression implements ExpressionInput {
|
||||
children: ScalarExpression[];
|
||||
export default class ListOfNumbersExpression implements Expression {
|
||||
children: ScalarToken[];
|
||||
expressionString: string;
|
||||
maxBitsLength: number;
|
||||
|
||||
constructor(expressionString: string, numbers: ScalarExpression[]) {
|
||||
constructor(expressionString: string, numbers: ScalarToken[]) {
|
||||
this.expressionString = expressionString;
|
||||
this.children = numbers;
|
||||
this.maxBitsLength = numbers.map(n => calc.numberOfBitsDisplayed(n.value)).reduce((n , c) => n >= c ? n : c, 0);
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
import ScalarExpression from "./ScalarExpression";
|
||||
import OperatorExpression from './OperatorExpression';
|
||||
import ScalarToken from "./ScalarToken";
|
||||
import OperatorToken from './OperatorToken';
|
||||
import { INT_MAX_VALUE } from "../core/const";
|
||||
|
||||
it('can apply ~ operand', () => {
|
||||
var op = new ScalarExpression(10, 'dec');
|
||||
var expr = new OperatorExpression(op, "~");
|
||||
var op = new ScalarToken(10, 'dec');
|
||||
var expr = new OperatorToken(op, "~");
|
||||
var result = expr.evaluate();
|
||||
expect(result.value).toBe(-11);
|
||||
expect(result.base).toBe('dec');
|
||||
});
|
||||
|
||||
it('can apply & operand', () => {
|
||||
var op1 = new ScalarExpression(3, 'dec');
|
||||
var op2 = new ScalarExpression(4, 'dec');
|
||||
var expr = new OperatorExpression(op1, "|");
|
||||
var op1 = new ScalarToken(3, 'dec');
|
||||
var op2 = new ScalarToken(4, 'dec');
|
||||
var expr = new OperatorToken(op1, "|");
|
||||
var result = expr.evaluate(op2);
|
||||
expect(result.value).toBe(7);
|
||||
expect(result.base).toBe('dec');
|
||||
});
|
||||
|
||||
it("doesn't support opreations with numbers larger than 32-bit", () => {
|
||||
expect(() => new OperatorExpression(new ScalarExpression(2147483648), "^"))
|
||||
expect(() => new OperatorToken(new ScalarToken(2147483648), "^"))
|
||||
.toThrowError("2147483648 has more than 32 bits. JavaScript converts all numbers to 32-bit integers when applying bitwise operators. BitwiseCmd currently uses the JavaScript engine of your browser for results calculation and supports numbers in the range from -2147483647 to 2147483647");
|
||||
});
|
||||
@@ -1,18 +1,18 @@
|
||||
import { INT_MAX_VALUE } from '../core/const';
|
||||
import formatter from '../core/formatter';
|
||||
import ScalarExpression from './ScalarExpression';
|
||||
import { Expression } from './expression-interfaces';
|
||||
import ScalarToken from './ScalarToken';
|
||||
import { ExpressionToken } from './expression-interfaces';
|
||||
|
||||
export default class OperatorExpression implements Expression {
|
||||
operand: Expression;
|
||||
export default class OperatorToken implements ExpressionToken {
|
||||
operand: ExpressionToken;
|
||||
operator: string;
|
||||
isOperator: boolean;
|
||||
isShiftExpression: boolean;
|
||||
isNotExpression: boolean;
|
||||
|
||||
constructor(operand : Expression, operator : string) {
|
||||
constructor(operand : ExpressionToken, operator : string) {
|
||||
|
||||
if(operand instanceof ScalarExpression) {
|
||||
if(operand instanceof ScalarToken) {
|
||||
const o = operand.getUnderlyingScalarOperand();
|
||||
if(Math.abs(o.value) > INT_MAX_VALUE) {
|
||||
const n = formatter.numberToString(o.value, o.base);
|
||||
@@ -27,8 +27,8 @@ export default class OperatorExpression implements Expression {
|
||||
this.isNotExpression = this.operator === '~';
|
||||
}
|
||||
|
||||
evaluate(operand?: ScalarExpression) : ScalarExpression {
|
||||
if (operand instanceof OperatorExpression) {
|
||||
evaluate(operand?: ScalarToken) : ScalarToken {
|
||||
if (operand instanceof OperatorToken) {
|
||||
throw new Error('value shouldnt be expression');
|
||||
}
|
||||
|
||||
@@ -44,10 +44,10 @@ export default class OperatorExpression implements Expression {
|
||||
str = operand.value + this.operator + evaluatedOperand.value;
|
||||
}
|
||||
|
||||
return ScalarExpression.create(eval(str), evaluatedOperand.base);
|
||||
return ScalarToken.create(eval(str), evaluatedOperand.base);
|
||||
}
|
||||
|
||||
getUnderlyingScalarOperand() : ScalarExpression {
|
||||
getUnderlyingScalarOperand() : ScalarToken {
|
||||
return this.operand.getUnderlyingScalarOperand();
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import ScalarExpression from './ScalarExpression';
|
||||
import ScalarToken from './ScalarToken';
|
||||
|
||||
it('parsed from dec string', () => {
|
||||
var op = ScalarExpression.parse('123');
|
||||
var op = ScalarToken.parse('123');
|
||||
expect(op.base).toBe('dec');
|
||||
expect(op.value).toBe(123);
|
||||
});
|
||||
|
||||
it('parsed from bin string', () => {
|
||||
var op = ScalarExpression.parse('0b10');
|
||||
var op = ScalarToken.parse('0b10');
|
||||
expect(op.base).toBe('bin');
|
||||
expect(op.value).toBe(2);
|
||||
});
|
||||
|
||||
it('parsed from hex string', () => {
|
||||
var op = ScalarExpression.parse('0x10');
|
||||
var op = ScalarToken.parse('0x10');
|
||||
expect(op.base).toBe('hex');
|
||||
expect(op.value).toBe(16);
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {numberParser} from './numberParser';
|
||||
import { Expression as Expression } from './expression-interfaces';
|
||||
import { ExpressionToken as ExpressionToken } from './expression-interfaces';
|
||||
import { NumberBase } from '../core/formatter';
|
||||
import { INT_MAX_VALUE } from '../core/const';
|
||||
|
||||
@@ -7,7 +7,7 @@ var globalId : number = 1;
|
||||
|
||||
|
||||
// Represents scalar numeric value
|
||||
export default class ScalarExpression implements Expression {
|
||||
export default class ScalarToken implements ExpressionToken {
|
||||
id: number;
|
||||
value: number;
|
||||
base: NumberBase;
|
||||
@@ -25,21 +25,21 @@ export default class ScalarExpression implements Expression {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
evaluate() : ScalarExpression {
|
||||
evaluate() : ScalarToken {
|
||||
return this;
|
||||
}
|
||||
|
||||
getUnderlyingScalarOperand() : ScalarExpression {
|
||||
getUnderlyingScalarOperand() : ScalarToken {
|
||||
return this
|
||||
}
|
||||
|
||||
static create(value : number, base? : NumberBase) {
|
||||
return new ScalarExpression(value, base || "dec");
|
||||
return new ScalarToken(value, base || "dec");
|
||||
};
|
||||
|
||||
static parse(input: string) : ScalarExpression {
|
||||
static parse(input: string) : ScalarToken {
|
||||
|
||||
var parsed = ScalarExpression.tryParse(input);
|
||||
var parsed = ScalarToken.tryParse(input);
|
||||
|
||||
if(parsed == null) {
|
||||
throw new Error(input + " is not a valid number");
|
||||
@@ -48,7 +48,7 @@ export default class ScalarExpression implements Expression {
|
||||
return parsed;
|
||||
}
|
||||
|
||||
static tryParse(input: string) : ScalarExpression | null {
|
||||
static tryParse(input: string) : ScalarToken | null {
|
||||
|
||||
var parsed = numberParser.parse(input);
|
||||
|
||||
@@ -56,7 +56,7 @@ export default class ScalarExpression implements Expression {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ScalarExpression(parsed.value, parsed.base);
|
||||
return new ScalarToken(parsed.value, parsed.base);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,11 +2,11 @@ import React from 'react';
|
||||
import formatter from '../../core/formatter';
|
||||
import BinaryStringView, { FlipBitEventArg } from '../../core/components/BinaryString';
|
||||
import BitwiseResultViewModel from './BitwiseResultViewModel';
|
||||
import { ExpressionInput, Expression } from '../expression-interfaces';
|
||||
import { OperatorExpression, ScalarExpression } from '../expression';
|
||||
import { Expression, ExpressionToken } from '../expression-interfaces';
|
||||
import { OperatorToken, ScalarToken } from '../expression';
|
||||
|
||||
type BitwiseOperationExpressionViewProps = {
|
||||
expression: ExpressionInput;
|
||||
expression: Expression;
|
||||
emphasizeBytes: boolean;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ type ExpressionRowProps = {
|
||||
maxNumberOfBits: number,
|
||||
emphasizeBytes: boolean,
|
||||
allowFlipBits: boolean,
|
||||
expressionItem: Expression,
|
||||
expressionItem: ExpressionToken,
|
||||
onBitFlipped: any
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ class ExpressionRow extends React.Component<ExpressionRowProps> {
|
||||
render() {
|
||||
const { sign, css, maxNumberOfBits, emphasizeBytes, allowFlipBits } = this.props;
|
||||
|
||||
return <tr className={css}>
|
||||
return <tr className={"row-with-bits " + css}>
|
||||
<td className="sign">{sign}</td>
|
||||
<td className="label">{this.getLabel()}</td>
|
||||
<td className="bin">
|
||||
@@ -95,7 +95,7 @@ class ExpressionRow extends React.Component<ExpressionRowProps> {
|
||||
// For expressions like |~2
|
||||
// TODO: find a better way...
|
||||
if(this.props.expressionItem.isOperator) {
|
||||
const ex = this.props.expressionItem as OperatorExpression;
|
||||
const ex = this.props.expressionItem as OperatorToken;
|
||||
return ex.operator + this.getLabelString(ex.getUnderlyingScalarOperand());
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ class ExpressionRow extends React.Component<ExpressionRowProps> {
|
||||
getAlternative() {
|
||||
|
||||
if(this.props.expressionItem.isOperator) {
|
||||
const ex = this.props.expressionItem as OperatorExpression;
|
||||
const ex = this.props.expressionItem as OperatorToken;
|
||||
const res = ex.evaluate();
|
||||
|
||||
return formatter.numberToString(res.value, res.base);
|
||||
@@ -116,7 +116,7 @@ class ExpressionRow extends React.Component<ExpressionRowProps> {
|
||||
return formatter.numberToString(v.value, altBase);
|
||||
}
|
||||
|
||||
getLabelString (op: ScalarExpression) : string {
|
||||
getLabelString (op: ScalarToken) : string {
|
||||
return formatter.numberToString(op.value, op.base == 'bin' ? 'dec' : op.base);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ScalarExpression, ListOfNumbersExpression, BitwiseOperationExpression, OperatorExpression } from '../expression';
|
||||
import { Expression, ExpressionInput } from '../expression-interfaces';
|
||||
import { ScalarToken, ListOfNumbersExpression, BitwiseOperationExpression, OperatorToken } from '../expression';
|
||||
import { ExpressionToken, Expression } from '../expression-interfaces';
|
||||
import calc from '../../core/calc';
|
||||
import formatter from '../../core/formatter';
|
||||
|
||||
@@ -8,10 +8,10 @@ type Config = {
|
||||
allowFlipBits: boolean;
|
||||
}
|
||||
|
||||
type ExpressionItemModel = {
|
||||
type ExpressionRowModel = {
|
||||
sign: string;
|
||||
css: string;
|
||||
expression: Expression;
|
||||
expression: ExpressionToken;
|
||||
allowFlipBits: boolean;
|
||||
label: string;
|
||||
}
|
||||
@@ -19,7 +19,7 @@ type ExpressionItemModel = {
|
||||
export default class BitwiseResultViewModel {
|
||||
|
||||
emphasizeBytes: boolean;
|
||||
items: ExpressionItemModel[];
|
||||
items: ExpressionRowModel[];
|
||||
maxNumberOfBits: number;
|
||||
allowFlipBits: boolean;
|
||||
|
||||
@@ -43,17 +43,17 @@ export default class BitwiseResultViewModel {
|
||||
i = 0, len = expr.children.length,
|
||||
ex, m = new BitwiseResultViewModel(config);
|
||||
|
||||
var prev : ScalarExpression | null = null;
|
||||
var prev : ScalarToken | null = null;
|
||||
|
||||
for (;i<len;i++) {
|
||||
ex = expr.children[i];
|
||||
if(ex instanceof ScalarExpression) {
|
||||
if(ex instanceof ScalarToken) {
|
||||
m.addScalarRow(ex);
|
||||
prev = ex;
|
||||
continue;
|
||||
}
|
||||
|
||||
var eo = ex as OperatorExpression;
|
||||
var eo = ex as OperatorToken;
|
||||
|
||||
// If it a single NOT expression
|
||||
if(eo.isNotExpression) {
|
||||
@@ -63,11 +63,11 @@ export default class BitwiseResultViewModel {
|
||||
prev = notResult;
|
||||
}
|
||||
else if(eo.isShiftExpression){
|
||||
prev = eo.evaluate(prev as ScalarExpression);
|
||||
prev = eo.evaluate(prev as ScalarToken);
|
||||
m.addShiftExpressionResultRow(eo, prev);
|
||||
} else {
|
||||
|
||||
prev = eo.evaluate(prev as ScalarExpression);
|
||||
prev = eo.evaluate(prev as ScalarToken);
|
||||
m.addOperatorRow(eo);
|
||||
m.addExpressionResultRow(prev);
|
||||
}
|
||||
@@ -77,7 +77,7 @@ export default class BitwiseResultViewModel {
|
||||
return m;
|
||||
};
|
||||
|
||||
addScalarRow(expr: ScalarExpression) {
|
||||
addScalarRow(expr: ScalarToken) {
|
||||
const bits = calc.numberOfBitsDisplayed(expr.value);
|
||||
this.maxNumberOfBits = Math.max(bits, this.maxNumberOfBits);
|
||||
this.items.push({
|
||||
@@ -89,7 +89,7 @@ export default class BitwiseResultViewModel {
|
||||
});
|
||||
};
|
||||
|
||||
addOperatorRow(expr: OperatorExpression) {
|
||||
addOperatorRow(expr: OperatorToken) {
|
||||
|
||||
const resultNumber = expr.isNotExpression ? expr.evaluate() : expr.getUnderlyingScalarOperand();
|
||||
const bits = calc.numberOfBitsDisplayed(resultNumber.value);
|
||||
@@ -104,7 +104,7 @@ export default class BitwiseResultViewModel {
|
||||
});
|
||||
};
|
||||
|
||||
addShiftExpressionResultRow(expr : OperatorExpression, resultExpr : ScalarExpression) {
|
||||
addShiftExpressionResultRow(expr : OperatorToken, resultExpr : ScalarToken) {
|
||||
const bits = calc.numberOfBitsDisplayed(resultExpr.value);
|
||||
this.maxNumberOfBits = Math.max(bits, this.maxNumberOfBits);
|
||||
const child = expr.operand.getUnderlyingScalarOperand();
|
||||
@@ -117,7 +117,7 @@ export default class BitwiseResultViewModel {
|
||||
});
|
||||
};
|
||||
|
||||
addExpressionResultRow(expr : ScalarExpression) {
|
||||
addExpressionResultRow(expr : ScalarToken) {
|
||||
const bits = calc.numberOfBitsDisplayed(expr.value);
|
||||
this.maxNumberOfBits = Math.max(bits, this.maxNumberOfBits);
|
||||
this.items.push({
|
||||
@@ -129,7 +129,7 @@ export default class BitwiseResultViewModel {
|
||||
});
|
||||
};
|
||||
|
||||
getLabel (op: ScalarExpression) : string {
|
||||
getLabel (op: ScalarToken) : string {
|
||||
|
||||
return formatter.numberToString(op.value, op.base === 'bin' ? 'dec' : op.base)
|
||||
}
|
||||
@@ -148,7 +148,7 @@ export default class BitwiseResultViewModel {
|
||||
return bits;
|
||||
};
|
||||
|
||||
static createModel(expr : ExpressionInput, emphasizeBytes: boolean) : BitwiseResultViewModel {
|
||||
static createModel(expr : Expression, emphasizeBytes: boolean) : BitwiseResultViewModel {
|
||||
if(expr instanceof ListOfNumbersExpression) {
|
||||
return BitwiseResultViewModel.buildListOfNumbers(expr, {
|
||||
emphasizeBytes: emphasizeBytes,
|
||||
@@ -159,7 +159,7 @@ export default class BitwiseResultViewModel {
|
||||
if(expr instanceof BitwiseOperationExpression) {
|
||||
return BitwiseResultViewModel.buildBitwiseOperation(expr, {
|
||||
emphasizeBytes: emphasizeBytes,
|
||||
allowFlipBits: false
|
||||
allowFlipBits: true
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { ScalarExpression } from "./expression";
|
||||
import { ScalarToken } from "./expression";
|
||||
|
||||
export interface ExpressionInput
|
||||
export interface Expression
|
||||
{
|
||||
expressionString: string;
|
||||
}
|
||||
|
||||
export interface Expression
|
||||
export interface ExpressionToken
|
||||
{
|
||||
isOperator: boolean;
|
||||
getUnderlyingScalarOperand: () => ScalarExpression;
|
||||
evaluate(operand? : ScalarExpression): ScalarExpression;
|
||||
getUnderlyingScalarOperand: () => ScalarToken;
|
||||
evaluate(operand? : ScalarToken): ScalarToken;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { parser, ListOfNumbersExpression, BitwiseOperationExpression, ScalarExpression, OperatorExpression } from "./expression";
|
||||
import { parser, ListOfNumbersExpression, BitwiseOperationExpression, ScalarToken, OperatorToken } from "./expression";
|
||||
|
||||
describe("expression parser", () => {
|
||||
|
||||
@@ -36,16 +36,16 @@ describe("expression parser", () => {
|
||||
const first = result.children[0];
|
||||
const second = result.children[1];
|
||||
|
||||
expect(first).toBeInstanceOf(ScalarExpression);
|
||||
expect(first).toBeInstanceOf(ScalarToken);
|
||||
|
||||
expect((first as ScalarExpression).value).toBe(1);
|
||||
expect((first as ScalarToken).value).toBe(1);
|
||||
|
||||
expect(second).toBeInstanceOf(OperatorExpression);
|
||||
var secondOp = second as OperatorExpression;
|
||||
expect(second).toBeInstanceOf(OperatorToken);
|
||||
var secondOp = second as OperatorToken;
|
||||
expect(secondOp.operator).toBe("^");
|
||||
|
||||
expect(secondOp.operand).toBeInstanceOf(ScalarExpression);
|
||||
var childOp = secondOp.operand as ScalarExpression;
|
||||
expect(secondOp.operand).toBeInstanceOf(ScalarToken);
|
||||
var childOp = secondOp.operand as ScalarToken;
|
||||
expect(childOp.value).toBe(2);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import ScalarExpression from './ScalarExpression';
|
||||
import OperatorExpression from './OperatorExpression'
|
||||
import ScalarToken from './ScalarToken';
|
||||
import OperatorToken from './OperatorToken'
|
||||
import ListOfNumbersExpression from './ListOfNumbersExpression';
|
||||
import BitwiseOperationExpression from './BitwiseOperationExpression';
|
||||
import { ExpressionInput, Expression } from './expression-interfaces';
|
||||
import { Expression, ExpressionToken } from './expression-interfaces';
|
||||
import { NumberBase } from '../core/formatter';
|
||||
|
||||
export { default as ScalarExpression } from './ScalarExpression';
|
||||
export { default as OperatorExpression } from './OperatorExpression';
|
||||
export { default as ScalarToken } from './ScalarToken';
|
||||
export { default as OperatorToken } from './OperatorToken';
|
||||
export { default as ListOfNumbersExpression } from './ListOfNumbersExpression';
|
||||
export { default as BitwiseOperationExpression } from './BitwiseOperationExpression';
|
||||
|
||||
interface IExpressionParserFactory {
|
||||
canCreate: (input: string) => boolean;
|
||||
create: (input: string) => ExpressionInput;
|
||||
create: (input: string) => Expression;
|
||||
};
|
||||
|
||||
class ExpressionParser {
|
||||
@@ -32,7 +32,7 @@ class ExpressionParser {
|
||||
return false;
|
||||
};
|
||||
|
||||
parse (input: string) : ExpressionInput | null {
|
||||
parse (input: string) : Expression | null {
|
||||
var trimmed = input.replace(/^\s+|\s+$/, '');
|
||||
var i = 0, l = this.factories.length, factory;
|
||||
|
||||
@@ -47,12 +47,12 @@ class ExpressionParser {
|
||||
return null;
|
||||
};
|
||||
|
||||
parseOperand (input : string) : ScalarExpression {
|
||||
return ScalarExpression.parse(input);
|
||||
parseOperand (input : string) : ScalarToken {
|
||||
return ScalarToken.parse(input);
|
||||
};
|
||||
|
||||
createOperand (number : number, base : NumberBase) : ScalarExpression {
|
||||
return ScalarExpression.create(number, base);
|
||||
createOperand (number : number, base : NumberBase) : ScalarToken {
|
||||
return ScalarToken.create(number, base);
|
||||
};
|
||||
|
||||
addFactory (factory: IExpressionParserFactory) {
|
||||
@@ -70,16 +70,16 @@ class ListOfNumbersExpressionFactory implements IExpressionParserFactory
|
||||
|
||||
return input.split(' ')
|
||||
.filter(p => p.length > 0)
|
||||
.map(p => ScalarExpression.tryParse(p))
|
||||
.map(p => ScalarToken.tryParse(p))
|
||||
.filter(n => n == null)
|
||||
.length == 0;
|
||||
};
|
||||
|
||||
create (input : string) : ExpressionInput {
|
||||
create (input : string) : Expression {
|
||||
|
||||
const numbers = input.split(' ')
|
||||
.filter(p => p.length > 0)
|
||||
.map(m => ScalarExpression.parse(m));
|
||||
.map(m => ScalarToken.parse(m));
|
||||
|
||||
return new ListOfNumbersExpression(input, numbers);
|
||||
}
|
||||
@@ -99,9 +99,9 @@ class BitwiseOperationExpressionFactory implements IExpressionParserFactory {
|
||||
return this.fullRegex.test(this.normalizeString(input));
|
||||
};
|
||||
|
||||
create (input: string) : ExpressionInput {
|
||||
create (input: string) : Expression {
|
||||
var m : RegExpExecArray | null;
|
||||
const operands : Expression[] = [];
|
||||
const operands : ExpressionToken[] = [];
|
||||
const normalizedString = this.normalizeString(input);
|
||||
|
||||
this.regex.lastIndex = 0;
|
||||
@@ -113,23 +113,23 @@ class BitwiseOperationExpressionFactory implements IExpressionParserFactory {
|
||||
return new BitwiseOperationExpression(normalizedString, operands)
|
||||
};
|
||||
|
||||
parseMatch (m:any): Expression {
|
||||
parseMatch (m:any): ExpressionToken {
|
||||
var input = m[0],
|
||||
operator = m[1],
|
||||
num = m[2];
|
||||
|
||||
var parsed = null;
|
||||
if(num.indexOf('~') == 0) {
|
||||
parsed = new OperatorExpression(ScalarExpression.parse(num.substring(1)), '~');
|
||||
parsed = new OperatorToken(ScalarToken.parse(num.substring(1)), '~');
|
||||
}
|
||||
else {
|
||||
parsed = ScalarExpression.parse(num);
|
||||
parsed = ScalarToken.parse(num);
|
||||
}
|
||||
|
||||
if(operator == null) {
|
||||
return parsed as OperatorExpression;
|
||||
return parsed as OperatorToken;
|
||||
} else {
|
||||
return new OperatorExpression(parsed as ScalarExpression, operator);
|
||||
return new OperatorToken(parsed as ScalarToken, operator);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ export class IpAddressView extends React.Component<IpAddressViewProps>
|
||||
render() {
|
||||
return <table className="expression">
|
||||
<tbody>
|
||||
{this.props.ipAddresses.map((ip, i) => <tr key={i}>
|
||||
{this.props.ipAddresses.map((ip, i) => <tr key={i} className='row-with-bits'>
|
||||
<td className="label"><strong>{ip.toString()}</strong></td>
|
||||
<td className="bin">
|
||||
{this.bin(ip.firstByte, 1, ip)}<span className="soft">.</span>
|
||||
|
||||
Reference in New Issue
Block a user