mirror of
https://github.com/BorysLevytskyi/BitwiseCmd.git
synced 2026-01-22 11:44:19 +01:00
Better support for 64 bit numbers (#44)
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import { ScalarOperand, ListOfNumbersExpression, BitwiseOperationExpression, ExpressionOperand } from '../expression';
|
||||
import { ExpressionInputItem, ExpressionInput } from '../expression-interfaces';
|
||||
import { ScalarExpression, ListOfNumbersExpression, BitwiseOperationExpression, OperatorExpression } from '../expression';
|
||||
import { Expression, ExpressionInput } from '../expression-interfaces';
|
||||
import calc from '../../core/calc';
|
||||
import formatter from '../../core/formatter';
|
||||
|
||||
type Config = {
|
||||
emphasizeBytes: boolean;
|
||||
@@ -9,7 +11,7 @@ type Config = {
|
||||
type ExpressionItemModel = {
|
||||
sign: string;
|
||||
css: string;
|
||||
expressionItem: ExpressionInputItem;
|
||||
expression: Expression;
|
||||
allowFlipBits: boolean;
|
||||
label: string;
|
||||
}
|
||||
@@ -30,28 +32,28 @@ export default class BitwiseExpressionViewModel {
|
||||
|
||||
static buildListOfNumbers(expr : ListOfNumbersExpression, config : Config) {
|
||||
var model = new BitwiseExpressionViewModel(config);
|
||||
expr.numbers.forEach(op => model.addOperandRow(op));
|
||||
model.maxNumberOfBits = BitwiseExpressionViewModel.getNumberOfBits(model.maxNumberOfBits, model.emphasizeBytes);
|
||||
expr.numbers.forEach(op => model.addScalarRow(op));
|
||||
model.maxNumberOfBits = BitwiseExpressionViewModel.applyEmphasizeBytes(model.maxNumberOfBits, model.emphasizeBytes);
|
||||
return model;
|
||||
}
|
||||
|
||||
static buildMultiple (expr : BitwiseOperationExpression, config : Config) {
|
||||
|
||||
var op = expr.expressionItems[0],
|
||||
i = 0, len = expr.expressionItems.length,
|
||||
var op = expr.children[0],
|
||||
i = 0, len = expr.children.length,
|
||||
ex, m = new BitwiseExpressionViewModel(config);
|
||||
|
||||
var prev : ScalarOperand | null = null;
|
||||
var prev : ScalarExpression | null = null;
|
||||
|
||||
for (;i<len;i++) {
|
||||
ex = expr.expressionItems[i];
|
||||
if(ex instanceof ScalarOperand) {
|
||||
m.addOperandRow(ex);
|
||||
ex = expr.children[i];
|
||||
if(ex instanceof ScalarExpression) {
|
||||
m.addScalarRow(ex);
|
||||
prev = ex;
|
||||
continue;
|
||||
}
|
||||
|
||||
var eo = ex as ExpressionOperand;
|
||||
var eo = ex as OperatorExpression;
|
||||
|
||||
// If it a single NOT expression
|
||||
if(eo.isNotExpression) {
|
||||
@@ -61,86 +63,88 @@ export default class BitwiseExpressionViewModel {
|
||||
prev = notResult;
|
||||
}
|
||||
else if(eo.isShiftExpression){
|
||||
prev = eo.evaluate(prev as ScalarOperand);
|
||||
prev = eo.evaluate(prev as ScalarExpression);
|
||||
m.addShiftExpressionResultRow(eo, prev);
|
||||
} else {
|
||||
|
||||
prev = eo.evaluate(prev as ScalarOperand);
|
||||
prev = eo.evaluate(prev as ScalarExpression);
|
||||
m.addExpressionOperandRow(eo);
|
||||
m.addExpressionResultRow(prev);
|
||||
}
|
||||
}
|
||||
|
||||
m.maxNumberOfBits = BitwiseExpressionViewModel.getNumberOfBits(m.maxNumberOfBits, m.emphasizeBytes);
|
||||
m.maxNumberOfBits = BitwiseExpressionViewModel.applyEmphasizeBytes(m.maxNumberOfBits, m.emphasizeBytes);
|
||||
return m;
|
||||
};
|
||||
|
||||
static buildNot (expression: ExpressionOperand, config : Config) {
|
||||
static buildNot (expression: OperatorExpression, config : Config) {
|
||||
|
||||
var m = new BitwiseExpressionViewModel(config);
|
||||
m.addExpressionOperandRow(expression);
|
||||
m.addExpressionResultRow(expression.evaluate());
|
||||
m.maxNumberOfBits = BitwiseExpressionViewModel.getNumberOfBits(m.maxNumberOfBits, m.emphasizeBytes);
|
||||
m.maxNumberOfBits = BitwiseExpressionViewModel.applyEmphasizeBytes(m.maxNumberOfBits, m.emphasizeBytes);
|
||||
return m;
|
||||
};
|
||||
|
||||
addOperandRow(operand: ScalarOperand) {
|
||||
this.maxNumberOfBits = Math.max(operand.getLengthInBits(), this.maxNumberOfBits);
|
||||
addScalarRow(expr: ScalarExpression) {
|
||||
const bits = calc.numberOfBitsDisplayed(expr.value);
|
||||
this.maxNumberOfBits = Math.max(bits, this.maxNumberOfBits);
|
||||
this.items.push({
|
||||
sign:'',
|
||||
css: '',
|
||||
expressionItem: operand,
|
||||
expression: expr,
|
||||
allowFlipBits: this.allowFlipBits,
|
||||
label: ''
|
||||
});
|
||||
};
|
||||
|
||||
addExpressionOperandRow(expression: ExpressionOperand) {
|
||||
const resultNumber = expression.isNotExpression ? expression.evaluate() : expression.getUnderlyingOperand();
|
||||
this.maxNumberOfBits = Math.max(resultNumber.getLengthInBits(), this.maxNumberOfBits);
|
||||
addExpressionOperandRow(expr: OperatorExpression) {
|
||||
|
||||
const resultNumber = expr.isNotExpression ? expr.evaluate() : expr.getUnderlyingScalarOperand();
|
||||
const bits = calc.numberOfBitsDisplayed(resultNumber.value);
|
||||
this.maxNumberOfBits = Math.max(bits, this.maxNumberOfBits);
|
||||
|
||||
this.items.push({
|
||||
sign: expression.sign,
|
||||
sign: expr.sign,
|
||||
css: '',
|
||||
label: this.getLabel(resultNumber),
|
||||
expressionItem: expression.operand,
|
||||
expression: expr.operand,
|
||||
allowFlipBits: this.allowFlipBits
|
||||
});
|
||||
};
|
||||
|
||||
addShiftExpressionResultRow(expression : ExpressionOperand, resultOperand : ScalarOperand) {
|
||||
this.maxNumberOfBits = Math.max(resultOperand.getLengthInBits(), this.maxNumberOfBits);
|
||||
|
||||
addShiftExpressionResultRow(expr : OperatorExpression, resultExpr : ScalarExpression) {
|
||||
const bits = calc.numberOfBitsDisplayed(resultExpr.value);
|
||||
this.maxNumberOfBits = Math.max(bits, this.maxNumberOfBits);
|
||||
const child = expr.operand.getUnderlyingScalarOperand();
|
||||
this.items.push({
|
||||
sign: expression.sign + expression.operand.toString(),
|
||||
sign: expr.sign + formatter.numberToString(child.value, child.base),
|
||||
css: 'expression-result',
|
||||
expressionItem: resultOperand,
|
||||
expression: resultExpr,
|
||||
allowFlipBits: false,
|
||||
label: ''
|
||||
});
|
||||
};
|
||||
|
||||
addExpressionResultRow(operand : ScalarOperand) {
|
||||
this.maxNumberOfBits = Math.max(operand.getLengthInBits(), this.maxNumberOfBits);
|
||||
addExpressionResultRow(expr : ScalarExpression) {
|
||||
const bits = calc.numberOfBitsDisplayed(expr.value);
|
||||
this.maxNumberOfBits = Math.max(bits, this.maxNumberOfBits);
|
||||
this.items.push({
|
||||
sign:'=',
|
||||
css: 'expression-result',
|
||||
expressionItem: operand,
|
||||
expression: expr,
|
||||
allowFlipBits: false,
|
||||
label: '',
|
||||
});
|
||||
};
|
||||
|
||||
getLabel (op: ScalarOperand) : string {
|
||||
|
||||
if(op.base == 'bin') {
|
||||
return op.toString("dec");
|
||||
}
|
||||
getLabel (op: ScalarExpression) : string {
|
||||
|
||||
return op.toString();
|
||||
return formatter.numberToString(op.value, op.base === 'bin' ? 'dec' : op.base)
|
||||
}
|
||||
|
||||
// TODO: move this method elsewhere. It is also used in LisOfNumbersExpressionView.js
|
||||
static getNumberOfBits = function (bits : number, emphasizeBytes : boolean) : number {
|
||||
static applyEmphasizeBytes (bits : number, emphasizeBytes : boolean) : number {
|
||||
|
||||
if(emphasizeBytes && bits % 8 != 0) {
|
||||
if(bits < 8) {
|
||||
return 8;
|
||||
|
||||
@@ -2,8 +2,8 @@ import React from 'react';
|
||||
import formatter from '../../core/formatter';
|
||||
import BinaryStringView, { FlipBitEventArg } from '../../core/components/BinaryString';
|
||||
import BitwiseExpressionViewModel from './BitwiseExpressionModel';
|
||||
import { ExpressionInput, ExpressionInputItem } from '../expression-interfaces';
|
||||
import { ExpressionOperand, ScalarOperand } from '../expression';
|
||||
import { ExpressionInput, Expression } from '../expression-interfaces';
|
||||
import { OperatorExpression, ScalarExpression } from '../expression';
|
||||
|
||||
type BitwiseOperationExpressionViewProps = {
|
||||
expression: ExpressionInput;
|
||||
@@ -41,7 +41,7 @@ export default class BitwiseOperationExpressionView extends React.Component<Bitw
|
||||
sign={itm.sign}
|
||||
css={itm.css}
|
||||
allowFlipBits={itm.allowFlipBits}
|
||||
expressionItem={itm.expressionItem}
|
||||
expressionItem={itm.expression}
|
||||
emphasizeBytes={this.props.emphasizeBytes}
|
||||
maxNumberOfBits={model.maxNumberOfBits}
|
||||
onBitFlipped={() => this.onBitFlipped()} />);
|
||||
@@ -59,7 +59,7 @@ type ExpressionRowProps = {
|
||||
maxNumberOfBits: number,
|
||||
emphasizeBytes: boolean,
|
||||
allowFlipBits: boolean,
|
||||
expressionItem: ExpressionInputItem,
|
||||
expressionItem: Expression,
|
||||
onBitFlipped: any
|
||||
}
|
||||
|
||||
@@ -81,46 +81,48 @@ class ExpressionRow extends React.Component<ExpressionRowProps> {
|
||||
allowFlipBits={allowFlipBits}
|
||||
onFlipBit={args => this.flipBit(args)}/>
|
||||
</td>
|
||||
<td className="other">{this.getOther()}</td>
|
||||
<td className="other">{this.getAlternative()}</td>
|
||||
</tr>;;
|
||||
}
|
||||
|
||||
getBinaryString() : string {
|
||||
var binary = this.props.expressionItem.evaluate().toBinaryString();
|
||||
return binary;
|
||||
var v = this.props.expressionItem.evaluate();
|
||||
return formatter.numberToString(v.value, 'bin');
|
||||
}
|
||||
|
||||
getLabel(): string {
|
||||
|
||||
// For expressions like |~2
|
||||
// TODO: find a better way...
|
||||
if(this.props.expressionItem.isExpression) {
|
||||
const ex = this.props.expressionItem as ExpressionOperand;
|
||||
return ex.sign + this.getLabelString(ex.getUnderlyingOperand());
|
||||
if(this.props.expressionItem.isOperator) {
|
||||
const ex = this.props.expressionItem as OperatorExpression;
|
||||
return ex.sign + this.getLabelString(ex.getUnderlyingScalarOperand());
|
||||
}
|
||||
|
||||
return this.getLabelString(this.props.expressionItem.getUnderlyingOperand());
|
||||
return this.getLabelString(this.props.expressionItem.getUnderlyingScalarOperand());
|
||||
}
|
||||
|
||||
getOther() {
|
||||
getAlternative() {
|
||||
|
||||
if(this.props.expressionItem.isExpression) {
|
||||
const ex = this.props.expressionItem as ExpressionOperand;
|
||||
const op = ex.evaluate();
|
||||
if(this.props.expressionItem.isOperator) {
|
||||
const ex = this.props.expressionItem as OperatorExpression;
|
||||
const res = ex.evaluate();
|
||||
|
||||
return op.toString();
|
||||
return formatter.numberToString(res.value, res.base);
|
||||
}
|
||||
|
||||
return this.props.expressionItem.evaluate().toOtherKindString();
|
||||
const v = this.props.expressionItem.evaluate();
|
||||
const altBase = formatter.getAlternativeBase(v.base);
|
||||
return formatter.numberToString(v.value, altBase);
|
||||
}
|
||||
|
||||
getLabelString (op: ScalarOperand) : string {
|
||||
return op.toString(op.base == 'bin' ? 'dec' : op.base);
|
||||
getLabelString (op: ScalarExpression) : string {
|
||||
return formatter.numberToString(op.value, op.base == 'bin' ? 'dec' : op.base);
|
||||
}
|
||||
|
||||
flipBit(args: FlipBitEventArg) {
|
||||
|
||||
const op = this.props.expressionItem.getUnderlyingOperand();
|
||||
const op = this.props.expressionItem.getUnderlyingScalarOperand();
|
||||
const { index, binaryString } = args;
|
||||
|
||||
var arr = binaryString.split('');
|
||||
|
||||
Reference in New Issue
Block a user