diff --git a/package.json b/package.json
index cb9aed4..8c739c0 100644
--- a/package.json
+++ b/package.json
@@ -43,6 +43,7 @@
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
"body-parser": "^1.15.2",
+ "lodash": "^4.17.2",
"react": "^15.4.0",
"react-dom": "^15.4.0"
}
diff --git a/src/app/calc.js b/src/app/calc.js
new file mode 100644
index 0000000..5b0911e
--- /dev/null
+++ b/src/app/calc.js
@@ -0,0 +1,26 @@
+import should from './should';
+
+export default calc = {
+ numberOfBits: function (num) {
+ if(num < 0) {
+ return 32;
+ }
+ should.bePositiveInteger(num);
+ return Math.floor(Math.log(num) / Math.log(2)) + 1;
+ },
+
+ maxNumberOfBits: function (arr) {
+
+ var counts = [], num;
+ for (var i = 0; i < arr.length; i++) {
+ num = arr[i];
+ counts.push(this.numberOfBits(num));
+ }
+
+ return Math.max.apply(null, counts);
+ },
+
+ calcExpression: function (expr) {
+ return eval(expr.expressionString);
+ }
+ };
\ No newline at end of file
diff --git a/src/app/components/results/ListOfNumbersExpressionView.jsx b/src/app/components/results/ListOfNumbersExpressionView.jsx
index c98bdea..f687777 100644
--- a/src/app/components/results/ListOfNumbersExpressionView.jsx
+++ b/src/app/components/results/ListOfNumbersExpressionView.jsx
@@ -1,9 +1,10 @@
import React from 'react';
+import formatter from '../../formatter';
export default class ListOfNumersExpressionView extends React.Component {
render() {
const expr = this.props.expression;
- const numberViews = expr.numbers.map((n, i) => )
+ const numberViews = expr.numbers.map((n, i) => )
return
@@ -11,15 +12,43 @@ export default class ListOfNumersExpressionView extends React.Component {
}
class OperandView extends React.Component {
+ componentWillMount() {
+ this.setState(this.props.operand);
+ }
render() {
- const op = this.props.operand;
- console.log(op);
- // const bitsSize = this.propsю;
- // .padLeft(m.bitsSize, '0')
- return
+ const op = this.state;
+ const binaryString = formatter.padLeft(op.bin, this.props.maxBitsLegnth, '0');
+
+ return
| {op.input} |
- {op.bin} |
+ this.flipBit(i)} /> |
{op.other} |
};
+
+ flipBit(index) {
+ var op = this.props.operand;
+ const binaryString = formatter.padLeft(op.bin, this.props.maxBitsLegnth, '0');
+ var arr = binaryString.split('');
+ arr[index] = arr[index] == '0' ? '1' : '0';
+ op.update(arr.join(''));
+ this.setState(op);
+ }
+}
+
+class ClickableBinary extends React.Component {
+ render() {
+ const str = this.props.binaryString;
+ const chars = str.split('');
+ const classNames = { '0': 'zero flipable', '1' : 'one flipable' };
+ const children = chars.map((c, i) => this.onBitClick(i, e)}>{c});
+
+ return {children}
+ }
+
+ onBitClick(index, e) {
+ if(this.props.onFlipBit) {
+ this.props.onFlipBit(index);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/app/expression.js b/src/app/expression.js
index fae9385..d20d9c1 100644
--- a/src/app/expression.js
+++ b/src/app/expression.js
@@ -1,3 +1,5 @@
+import * as _ from 'lodash';
+
var expression = {
factories:[],
canParse: function(string) {
@@ -119,6 +121,7 @@ export class Operand {
this.bin = this.value < 0 ? (this.value >>> 0).toString(2) : this.value.toString(2);
this.kind = this.input.indexOf('0x') > -1 ? 'hex' : 'dec';
this.other = this.kind == 'dec' ? this.hex : this.dec;
+ this.lengthInBits = Operand.getBitLength(this.value);
}
getLengthInBits() {
@@ -128,19 +131,7 @@ export class Operand {
return Math.floor(Math.log(this.value) / Math.log(2)) + 1;
};
- toKindString(value, kind) {
- switch(kind) {
- case 'hex':
- var hexVal = Math.abs(value).toString(16);
- return value >= 0 ? '0x' + hexVal : '-0x' + hexVal;
- case 'bin':
- return (value>>>0).toString(2);
- case 'dec':
- return value.toString(10);
- default:
- throw new Error("Unexpected kind: " + kind)
- }
- };
+
getOtherKind(kind) {
switch(kind) {
@@ -153,6 +144,17 @@ export class Operand {
toString() {
return this.input;
}
+
+ update(binary) {
+ this.value = parseInt(2);
+ this.bin = binary;
+ this.dec = Operand.toKindString(this.value, 'dec');
+ this.hex = Operand.toKindString(this.value, 'hex');
+ }
+
+ static getBitLength(num) {
+ return Math.floor(Math.log(num) / Math.log(2)) + 1
+ }
static getBase(kind){
switch (kind){
@@ -171,6 +173,20 @@ export class Operand {
return new Operand(str);
};
+ static toKindString(value, kind) {
+ switch(kind) {
+ case 'hex':
+ var hexVal = Math.abs(value).toString(16);
+ return value >= 0 ? '0x' + hexVal : '-0x' + hexVal;
+ case 'bin':
+ return (value>>>0).toString(2);
+ case 'dec':
+ return value.toString(10);
+ default:
+ throw new Error("Unexpected kind: " + kind)
+ }
+ };
+
static toHexString (hex) {
return hex.indexOf('-') == 0 ? '-0x' + hex.substr(1) : '0x' + hex;
};
@@ -223,6 +239,7 @@ export class ListOfNumbersExpression {
constructor(expressionString, numbers) {
this.expressionString = expressionString;
this.numbers = numbers;
+ this.maxBitsLegnth = _.chain(numbers).map(n => n.lengthInBits).reduce((n , c) => n >= c ? n : c, 0).value();
}
}
diff --git a/src/app/formatter.js b/src/app/formatter.js
new file mode 100644
index 0000000..42dd5ee
--- /dev/null
+++ b/src/app/formatter.js
@@ -0,0 +1,26 @@
+export default {
+ formatString: function(num, kind) {
+ return num.toString(getBase(kind || "bin"));
+ },
+ padLeft: function (str, length, symbol) {
+ var sb = Array.prototype.slice.call(str), symbol = symbol || "0";
+
+ if(length == null) {
+ return str;
+ }
+
+ while(length > sb.length) {
+ sb.unshift(symbol);
+ }
+
+ return sb.join('');
+ }
+ };
+
+ function getBase(kind) {
+ switch (kind){
+ case 'bin': return 2;
+ case 'hex': return 16;
+ case 'dec': return 10;
+ }
+ }
\ No newline at end of file