support of ~ not operator

This commit is contained in:
Borys Levytskyi
2015-04-12 00:24:03 +03:00
parent d0ff0a579f
commit 0b354ccaf4
4 changed files with 91 additions and 31 deletions

View File

@@ -93,9 +93,11 @@
<li><code>&</code> bitwise AND</li>
<li><code>|</code> bitwise inclusive OR</li>
<li><code>^</code> bitwise exclusive XOR</li>
<li><code><<</code> left shift</li>
<li><code>>></code> sign propagating right shift</li>
<li><code>>>></code> zero-fill right shift</li>
<li><code>~</code> bitwise NOT</li>
<li><code>&lt;<</code> left shift</li>
<li><code>&gt;&gt;</code> sign propagating right shift</li>
<li><code>&gt;&gt;&gt;</code> zero-fill right shift</li>
</ul>
</p>
</div>
@@ -136,6 +138,21 @@
</table>
</script>
<script data-template="notExpressionView" data-compiled="" type="text/template">
<table class="expression">
<tr>
<td class="label">{m.operand1.input}</td>
<td class="bin">{m.operand1Binary}</td>
<td class="other">{m.operand1.other}</td>
</tr>
<tr class="result">
<td class="label">{m.sign}{m.operand1.input}={m.result.input}</td>
<td class="bin">{m.resultBinary}</td>
<td class="other">{m.result.other}</td>
</tr>
</table>
</script>
<script data-template="binaryExpressionView" data-compiled="" type="text/template">
<table class="expression">
<tr>

View File

@@ -3,10 +3,11 @@ app.set('expression', function() {
var exprRegex = /^(-?(?:\d+|0x[\d,a-f]+))\s*(<<|>>|>>>|\||\&|\^)\s*(-?(?:\d+|0x[\d,a-f]+))$/;
var listRegex = /^(-?(?:\d+|0x[\d,a-f]+)\s?)+$/;
var notRex = /^(~)(-?(?:\d+|0x[\d,a-f]+))$/
return {
canParse: function(string) {
return exprRegex.test(string) || listRegex.test(string);
return exprRegex.test(string) || listRegex.test(string) || notRex.test(string)
},
parse: function(string) {
var trimmed = string.replace(/^\s+|\s+$/, '');
@@ -14,13 +15,19 @@ app.set('expression', function() {
var matches = exprRegex.exec(trimmed);
if(matches != null) {
return createCalculableExpression(matches);
return createTwoOperandExpr(matches);
}
matches = notRex.exec(trimmed);
if(matches != null) {
return createSingleOperandExpr(matches);
}
matches = listRegex.exec(string);
if(matches != null) {
return createListOfNumbersExpression(string)
}
},
parseOperand: function(input) {
return new Operand(input);
@@ -28,7 +35,7 @@ app.set('expression', function() {
createOperand: function(number, kind) {
var str = number.toString(getBase(kind));
if(kind == 'hex') {
str = "0x" + str;
str = toHex(str);
}
return new Operand(str);
@@ -36,7 +43,7 @@ app.set('expression', function() {
};
function createCalculableExpression(matches) {
function createTwoOperandExpr(matches) {
var m = new app.models.BitwiseOperation();
m.operand1 = new Operand(matches[1]);
@@ -48,6 +55,14 @@ app.set('expression', function() {
return m;
}
function createSingleOperandExpr(matches) {
var m = new app.models.BitwiseOperation();
m.operand1 = new Operand(matches[2]);
m.sign = matches[1];
m.string = matches.input;
return m;
}
function createListOfNumbersExpression(input) {
var operands = [];
input.split(' ').forEach(function(n){
@@ -68,13 +83,14 @@ app.set('expression', function() {
}
}
function toHex(hex) {
return hex.indexOf('-') == 0 ? '-0x' + hex.substr(1) : '0x' + hex;
}
function Operand(input) {
// console.log('input: ' + input);
this.input = input;
this.value = parseInt(input);
// console.log('value: ' + this.value);
var hex = this.value.toString(16);
this.hex = hex.indexOf('-') == 0 ? '-0x' + hex.substr(1) : '0x' + hex;
this.hex = toHex(this.value.toString(16));
this.dec = this.value.toString(10);
this.bin = (this.value>>>0).toString(2);
this.kind = this.input.indexOf('0x') > -1 ? 'hex' : 'dec';

View File

@@ -8,23 +8,41 @@ app.compose(function () {
var cmdConfig = app.get('cmdConfig');
var expression = app.get('expression');
app.modelView(app.models.BitwiseOperation, {
renderView: function(expr) {
var result = expression.createOperand(calc.calcExpression(expr), getResultMode([expr.operand1, expr.operand2]));
var maxLen = getBinaryLength([expr.operand1.value, expr.operand2.value, result.value]);
app.modelView(app.models.BitwiseOperation, function() {
function getTemplateId(model) {
switch (model.sign) {
case '<<':
case '>>':
case '>>>':
return 'shiftExpressionView';
case '~':
return 'notExpressionView';
default:
return 'binaryExpressionView';
}
}
var model = Object.create(expr);
model.result = result;
model.operand1Binary = formatter.padLeft(expr.operand1.bin, maxLen);
model.operand2Binary = formatter.padLeft(expr.operand2.bin, maxLen);
model.resultBinary = formatter.padLeft(model.result.bin, maxLen);
return {
renderView: function(expr) {
var templateId = /<<|>>/.test(model.sign) ? 'shiftExpressionView' : 'binaryExpressionView';
var template = app.template(templateId);
var result = expression.createOperand(calc.calcExpression(expr), getResultMode([expr.operand1, expr.operand2]));
var maxLen = getBinaryLength([expr.operand1.value, expr.operand2 != null ? expr.operand2.value : 0, result.value]);
var el = template.render(model);
colorizeBits(el);
return el;
var model = Object.create(expr);
model.result = result;
model.operand1Binary = formatter.padLeft(expr.operand1.bin, maxLen);
if(expr.operand2) {
model.operand2Binary = formatter.padLeft(expr.operand2.bin, maxLen);
}
model.resultBinary = formatter.padLeft(model.result.bin, maxLen);
var templateId = getTemplateId(model);
var template = app.template(templateId);
var el = template.render(model);
colorizeBits(el);
return el;
}
}
});
@@ -105,7 +123,7 @@ app.compose(function () {
function getResultMode(operands) {
for(var i=0; i<operands.length; i++) {
if(operands[i].kind == 'hex') {
if(operands[i] != null && operands[i].kind == 'hex') {
return 'hex';
}
}

View File

@@ -3,12 +3,11 @@ var expression = app.get('expression');
describe("expression parse", function() {
var shouldParse = ['0x2>>1', '1 2 3', '0x1 1 2 3 5', '0x1>>0x2', '1|2'];
var shouldParse = ['0x2>>1', '1 2 3', '0x1 1 2 3 5', '0x1>>0x2', '1|2', '-9', '-1|-2', '~3'];
it("should be able to parse", function() {
shouldParse.forEach(function(expr) {
console.log(expr);
expect(expression.canParse(expr)).toBe(true);
expect(expression.canParse(expr)).toBe(true, 'expr: ' + expr);
})
});
@@ -19,7 +18,10 @@ describe("expression parse", function() {
"0xf>>0xa": { operand1: 15, operand2:10, "sign":">>", string:"0xf>>0xa" },
"0x10&0x11": { operand1: 0x10, operand2:0x11, "sign":"&", string:"0x10&0x11" },
"0x1a^11": { operand1: 0x1a, operand2:11, "sign":"^", string:"0x1a^11" },
"0x1a>>>11": { operand1: 0x1a, operand2:11, "sign":">>>", string:"0x1a>>>11" }
"0x1a>>>11": { operand1: 0x1a, operand2:11, "sign":">>>", string:"0x1a>>>11" },
'~3': { operand1: 3, operand2: null, "sign":"~", string:"~3" },
'~0xa': { operand1: 0xa, operand2: null, "sign":"~", string:"~0xa" },
'~-0xa': { operand1: -0xa, operand2: null, "sign":"~", string:"~-0xa" }
};
it("should parse expressions", function() {
@@ -31,7 +33,14 @@ describe("expression parse", function() {
expect(actual).not.toBe(null);
expect(actual.sign).toBe(expected.sign);
expect(actual.operand1.value).toBe(expected.operand1);
expect(actual.operand2.value).toBe(expected.operand2);
if(expected.operand2 != null) {
expect(actual.operand2.value).toBe(expected.operand2);
}
else
{
expect(actual.operand2).not.toBeDefined();
}
expect(actual.string).toBe(expected.string);
}
});