diff --git a/src/app/components/results/BitwiseOperationExpressionView.jsx b/src/app/components/results/BitwiseOperationExpressionView.jsx index 5dd4d1f..42e5781 100644 --- a/src/app/components/results/BitwiseOperationExpressionView.jsx +++ b/src/app/components/results/BitwiseOperationExpressionView.jsx @@ -6,6 +6,10 @@ import BitwiseExpressionViewModel from './models/BitwiseExpressionViewModel'; import log from 'loglevel'; export default class BitwiseOperationEpxressionView extends React.Component { + constructor() { + super(); + this.state = {}; + } render() { var rows = this.getRows(); if(!rows) { @@ -26,19 +30,31 @@ export default class BitwiseOperationEpxressionView extends React.Component { if(expr instanceof ListOfNumbersExpression) { model = BitwiseExpressionViewModel.buildListOfNumbers(expr, { emphasizeBytes: this.props.emphasizeBytes, - allowFlipBits: true }); - } - - if(expr instanceof SingleOperandExpression) { - model = BitwiseExpressionViewModel.buildNot(expr, { emphasizeBytes: this.props.emphasizeBytes }); + allowFlipBits: true + }); } if(expr instanceof MultipleOperandsExpression) { - model = BitwiseExpressionViewModel.buildMultiple(expr, { emphasizeBytes: this.props.emphasizeBytes }); + model = BitwiseExpressionViewModel.buildMultiple(expr, { + emphasizeBytes: this.props.emphasizeBytes, + allowFlipBits: false + }); } log.info('Render model', model); - return model.items.map((itm, i) => ); + + return model.items.map((itm, i) => + this.onBitFlipped()} />); + } + + onBitFlipped() { + console.log('bit flipped'); + this.setState({d:new Date()}); } } @@ -56,7 +72,7 @@ class ExpressionRow extends React.Component { this.flipBit(idx)}/> @@ -65,10 +81,16 @@ class ExpressionRow extends React.Component { } getLabel(op) { + if(op.isExpression) { + return op.toString(); + } return op.toString(op.kind == 'bin' ? 'dec' : op.kind); } getOther(op) { + if(op.isExpression) { + return op.apply().toString(); + } return op.toString(op.getOtherKind()); } @@ -76,13 +98,15 @@ class ExpressionRow extends React.Component { const op = this.props.operand; const { index, binaryString } = args; - + var arr = binaryString.split(''); arr[index] = arr[index] == '0' ? '1' : '0'; var bin = arr.join(''); - op.setValue(parseInt(bin, 2)); + var newValue = parseInt(bin, 2); + console.log('flipped \n%s to \n%s from \n%s to \n%s', binaryString, bin, op.value, newValue); + op.setValue(newValue); - this.setState({ operand: op }); + this.props.onBitFlipped(); } } \ No newline at end of file diff --git a/src/app/components/results/models/BitwiseExpressionViewModel.js b/src/app/components/results/models/BitwiseExpressionViewModel.js index a412d93..e5588c7 100644 --- a/src/app/components/results/models/BitwiseExpressionViewModel.js +++ b/src/app/components/results/models/BitwiseExpressionViewModel.js @@ -1,3 +1,5 @@ +import { Operand, SingleOperandExpression } from '../../../expression'; + export default class BitwiseExpressionViewModel { constructor({ emphasizeBytes = false, allowFlipBits = false } = {}) { @@ -15,22 +17,36 @@ export default class BitwiseExpressionViewModel { } static buildMultiple (expr, config) { - + console.log('build: ', expr); var op = expr.expressions[0], - i = 1, l = expr.expressions.length, + i = 0, l = expr.expressions.length, ex, m = new BitwiseExpressionViewModel(config); - m.addOperand(op); - + var cur = null; for (;i>|>>>|\||\&|\^)?(-?([b,x,a-f,0-9]+)))+$/, - regex: /(<<|>>|>>>|\||\&|\^)?(-?([b,x,a-f,0-9]+))/g, + fullRegex: /^((<<|>>|>>>|\||\&|\^)?(~?-?([b,x,a-f,0-9]+)))+$/, + regex: /(<<|>>|>>>|\||\&|\^)?(~?-?(?:[b,x,a-f,0-9]+))/g, canCreate: function(string) { this.fullRegex.lastIndex = 0; return this.fullRegex.test(this.normalizeString(string)); @@ -93,11 +82,20 @@ var expression = { return new MultipleOperandsExpression(normalizedString, operands) }, parseMatch: function (m) { + console.log('match'); + console.log(m); var input = m[0], sign = m[1], num = m[2]; - var op = Operand.parse(num); + var op = null; + if(num.indexOf('~') == '0') { + op = new SingleOperandExpression(input, Operand.parse(num.substring(1)), '~'); + } + else { + op = Operand.parse(num); + } + if(sign == null) { return op; } else { @@ -110,45 +108,9 @@ var expression = { }); // Expressions like ~1 -export class SingleOperandExpression { - constructor(expressionString, operand, sign) { - this.expressionString = expressionString; - this.operand1 = operand; - this.sign = sign; - } - - apply(value) { - var str = ''; - if(this.sign == '~'){ - str = '~' + this.operand1.value; - } else { - str = value + this.sign + this.operand1.value - } - console.log('eval:' + str + " = " + eval(str), Operand.create(eval(str), this.operand1.kind)); - - const resultValue = eval(str); - return Operand.create(resultValue, this.operand1.kind); - }; - - isShiftExpression() { - return this.sign.indexOf('<') >= 0 || this.sign.indexOf('>')>= 0; - }; - - toString() { - return this.sign + this.operand1.toString(); - } -} // Expression like 1|2 or 4^5 -export class TwoOperandExpression { - constructor(expressionString, operand1, operand2, sign) { - this.expressionString = expressionString; - this.operand1 = operand1; - this.operand2 = operand2; - this.sign = sign; - } -} export class MultipleOperandsExpression { constructor(expressionString, expressions) { @@ -168,12 +130,6 @@ export class ListOfNumbersExpression { return this.numbers.map(n => n.value.toString()).join(' '); } } - -export class Expression { - toString() { - return this.expressionString ? "Expression: " + this.expressionString : this.toString(); - }; -} export var parser = expression; diff --git a/src/app/expression/Operand.js b/src/app/expression/Operand.js index faac0c9..8e4e2f1 100644 --- a/src/app/expression/Operand.js +++ b/src/app/expression/Operand.js @@ -1,12 +1,16 @@ import numberParser from './numberParser'; import ExpressionError from './ExpressionError'; +var id = 1; + // Represents numeric value export default class Operand { constructor(cfg) { + this.id = id++; this.value = cfg.value; this.kind = cfg.kind; this.lengthInBits = Operand.getBitLength(this.value); + this.isExpression = false; } getLengthInBits() { @@ -47,11 +51,16 @@ export default class Operand { } setValue(value) { + console.log('Operand:%s.setValue: %s', this.id, this.value); this.value = value; } + + apply() { + return this; + } static getBitLength(num) { - return Math.floor(Math.log(num) / Math.log(2)) + 1 + return Math.floor(Math.log(num) / Math.log(2)) + 1; } static getBase(kind){ diff --git a/src/app/expression/SingleOperandExpression.js b/src/app/expression/SingleOperandExpression.js new file mode 100644 index 0000000..e9ac7fe --- /dev/null +++ b/src/app/expression/SingleOperandExpression.js @@ -0,0 +1,40 @@ +import Operand from './Operand'; + +export default class SingleOperandExpression { + constructor(expressionString, operand, sign) { + this.expressionString = expressionString; + this.operand1 = operand; + this.sign = sign; + this.isExpression = true; + this.isShiftExpression = this.sign.indexOf('<') >= 0 || this.sign.indexOf('>')>= 0; + this.isNotExpression = this.sign == '~'; + } + + apply(operand) { + if (operand instanceof SingleOperandExpression) { + console.error("value shouldnt be expression", value); + throw new Error('value shouldnt be expression'); + } + + console.log('operand', operand); + + var str = ''; + if(this.sign == '~'){ + str = '~' + this.operand1.apply().value; + } else { + str = operand.value + this.sign + this.operand1.apply().value; + } + + console.log('eval:' + str, this); + const resultValue = eval(str); + + var resultOp = Operand.create(eval(str), this.operand1.kind || this.operand1.operand1.kind); + console.log(resultValue, resultOp); + + return resultOp; + }; + + toString() { + return this.sign + this.operand1.toString(); + } +} \ No newline at end of file diff --git a/tests/e2e/pageObject.js b/tests/e2e/pageObject.js index d5255e1..5d4e4c1 100644 --- a/tests/e2e/pageObject.js +++ b/tests/e2e/pageObject.js @@ -80,7 +80,7 @@ ExpressionResultObject.prototype.shouldBe = function(expectedResult) { for(var i=0;i