Complete of support of multi-operand expressions

This commit is contained in:
BorysLevytskyi
2015-12-04 21:28:33 +02:00
parent ded459b575
commit b101b89305
6 changed files with 124 additions and 91 deletions

View File

@@ -25,6 +25,7 @@ code { font-size: 1.2em; font-weight: bold; }
.expression { font-size: 1.5em; font-family: monospace }
.expression .prefix { font-weight: normal; display: none; font-size: 0.9em }
.expression .other { font-size: 0.9em}
.expression .sign { text-align: right}
.hex .prefix { display: inline; }

View File

@@ -150,6 +150,7 @@
<table class="expression">
{each itm in m.items}
<tr class="{itm.css}">
<td class="sign">{itm.sign}</td>
<td class="label">{itm.label}</td>
<td class="bin">{itm.bin.padLeft(m.maxNumberOfBits, '0')}</td>
<td class="other">{itm.other}</td>
@@ -161,12 +162,14 @@
<script data-template="notExpressionView" data-compiled="" type="text/template">
<table class="expression">
<tr>
<td class="sign"></td>
<td class="label">{m.operand1.input}</td>
<td class="bin">{m.operand1.bin.padLeft(m.bitsSize, '0')}</td>
<td class="other">{m.operand1.other}</td>
</tr>
<tr class="expression-result">
<td class="label">{m.sign}{m.operand1.input}={m.result.input}</td>
<td class="sign">{m.sign}</td>
<td class="label">{m.result.input}</td>
<td class="bin">{m.result.bin.padLeft(m.bitsSize, '0')}</td>
<td class="other">{m.result.other}</td>
</tr>
@@ -176,19 +179,19 @@
<script data-template="binaryExpressionView" data-compiled="" type="text/template">
<table class="expression">
<tr>
<td></td>
<td class="sign"></td>
<td class="label">{m.operand1.input}</td>
<td class="bin">{m.operand1.bin.padLeft(m.bitsSize, '0')}</td>
<td class="other">{m.operand1.other}</td>
</tr>
<tr>
<td>{m.sign}</td>
<td class="sign">{m.sign}</td>
<td class="label">{m.operand2.input}</td>
<td class="bin">{m.operand2.bin.padLeft(m.bitsSize, '0')}</td>
<td class="other">{m.operand2.other}</td>
</tr>
<tr class="expression-result">
<td>=</td>
<td class="sign">=</td>
<td class="label">{m.result.input}</td>
<td class="bin">{m.result.bin.padLeft(m.bitsSize, '0')}</td>
<td class="other">{m.result.other}</td>

View File

@@ -15,7 +15,7 @@ app.set('expression', function() {
},
parse: function(string) {
var trimmed = string.replace(/^\s+|\s+$/, '');
var i = 0, l = this.factories.length, factory, matches;
var i = 0, l = this.factories.length, factory;
for(;i<l;i++) {
factory = this.factories[i];
@@ -77,48 +77,23 @@ app.set('expression', function() {
}
});
// Two operands expression
expression.addFactory({
regex: /^(-?(?:\d+|0x[\d,a-f]+))\s*(<<|>>|>>>|\||\&|\^)\s*(-?(?:\d+|0x[\d,a-f]+))$/,
canCreate: function(string) {
return this.regex.test(string);
},
create: function (string) {
var matches = this.regex.exec(string),
operand1 = new Operand(matches[1]),
operand2 = new Operand(matches[3]),
sign = matches[2],
expressionString = matches.input;
return new TwoOperandExpression(expressionString, operand1, operand2, sign);
}
});
// Multiple operands expression
expression.addFactory({
fullRegex: /^((?:\s*)(<<|>>|>>>|\||\&|\^)?(?:\s*)(-?(?:\d+|0x[\d,a-f]+)))+$/,
regex: /(?:\s*)(<<|>>|>>>|\||\&|\^)?(?:\s*)(-?(?:\d+|0x[\d,a-f]+))/g,
fullRegex: /^((<<|>>|>>>|\||\&|\^)?(-?((?:\d+(?!x))|(?:0x[\d,a-f]+))))+$/,
regex: /(<<|>>|>>>|\||\&|\^)?(-?((?:\d+(?!x))|(?:0x[\d,a-f]+)))/g,
canCreate: function(string) {
this.fullRegex.lastIndex = 0;
return this.fullRegex.test(string);
return this.fullRegex.test(this.normalizeString(string));
},
create: function (string) {
var m = null, operands = [];
var m, operands = [],
normalizedString = this.normalizeString(string);
while ((m = this.regex.exec(string)) != null) {
while ((m = this.regex.exec(normalizedString)) != null) {
operands.push(this.parseMatch(m));
}
//matches.input.replace(this.regex, function(inpt, sign, num) {
// if(sign == null) {
// operands.push(new Operand(num));
// } else {
// operands.push(new SingleOperandExpression(inpt, new Operand(num), sign))
// }
//
//});
return new MultipleOperandsExpression(string, operands)
return new MultipleOperandsExpression(normalizedString, operands)
},
parseMatch: function (m) {
var input = m[0],
@@ -130,6 +105,9 @@ app.set('expression', function() {
} else {
return new SingleOperandExpression(input, new Operand(num), sign);
}
},
normalizeString: function (string) {
return string.replace(/\s+/g,'');
}
});
@@ -189,6 +167,10 @@ app.set('expression', function() {
return Operand.create(eval(str), this.operand1.kind);
};
SingleOperandExpression.prototype.isShiftExpression = function () {
return this.sign.indexOf('<') >= 0 || this.sign.indexOf('>')>= 0;
};
function TwoOperandExpression(expressionString, operand1, operand2, sign) {
this.expressionString = expressionString;
this.operand1 = operand1;

View File

@@ -50,16 +50,16 @@ app.run(function() {
return this.locateModel(expr);
},
locateModel: function (expr) {
if(expr instanceof expression.SingleOperandExpression || expr instanceof expression.TwoOperandExpression){
return new app.models.BitwiseOperation(expr);
}
if(expr instanceof expression.ListOfNumbersExpression) {
return new app.models.BitwiseNumbers(expr);
}
if(expr instanceof expression.SingleOperandExpression ){
return new app.models.BitwiseExpression.buildNot(expr);
}
if(expr instanceof expression.MultipleOperandsExpression) {
return new app.models.BitwiseExpression(expr);
return new app.models.BitwiseExpression.buildMultiple(expr);
}
return new app.models.ErrorResult('Cannot create model for expression: ' + expr.toString());

View File

@@ -1,59 +1,84 @@
(function(app) {
"use strict";
function BitwiseOperation (expression) {
this.expression = expression;
this.operand1 = expression.operand1;
this.operand2 = expression.operand2;
this.sign = expression.sign;
this.string = expression.expressionString;
function BitwiseOperation (expr) {
this.expression = expr;
this.operand1 = expr.operand1;
this.operand2 = expr.operand2;
this.sign = expr.sign;
this.string = expr.expressionString;
}
function BitwiseNumbers(expression) {
this.expression = expression;
this.operands = expression.numbers;
function BitwiseNumbers(expr) {
this.expression = expr;
this.operands = expr.numbers;
var numbers = this.numbers = [];
expression.numbers.forEach(function (o) {
expr.numbers.forEach(function (o) {
numbers.push(o.value);
});
}
function BitwiseExpression(expression) {
function BitwiseExpression() {
this.items = [];
this.maxNumberOfBits = 0;
}
var op = expression.expressions[0],
i = 1, l = expression.expressions.length,
ex;
BitwiseExpression.buildMultiple = function (expr) {
var op = expr.expressions[0],
i = 1, l = expr.expressions.length,
ex, m = new BitwiseExpression();
this.addOperand(op);
m.addOperand(op);
for (;i<l;i++) {
ex = expression.expressions[i];
this.addExpression(ex);
ex = expr.expressions[i];
op = ex.apply(op.value);
this.addResult(op);
if(ex.isShiftExpression()){
m.addShiftExpressionResult(ex, op);
} else {
m.addExpression(ex);
m.addExpressionResult(op);
}
}
this.maxNumberOfBits = this.emphasizeBytes(this.maxNumberOfBits);
}
m.maxNumberOfBits = m.emphasizeBytes(m.maxNumberOfBits);
return m;
};
BitwiseExpression.buildNot = function (expression) {
var m = new BitwiseExpression();
m.addExpression(expression);
m.addExpressionResult(expression.apply());
m.maxNumberOfBits = m.emphasizeBytes(m.maxNumberOfBits);
return m;
};
BitwiseExpression.prototype.addOperand = function(operand) {
this.maxNumberOfBits = Math.max(operand.getLengthInBits(), this.maxNumberOfBits);
this.items.push({ label: operand.toString(), bin: operand.bin, other: operand.other, css: ''});
this.items.push({ sign:'', label: operand.toString(), bin: operand.bin, other: operand.other, css: ''});
};
BitwiseExpression.prototype.addExpression = function(expression) {
this.maxNumberOfBits = Math.max(expression.operand1.getLengthInBits(), this.maxNumberOfBits);
this.items.push({ label: expression.toString(), bin: expression.operand1.bin, other: expression.operand1.other, css: ''});
this.items.push({ sign: expression.sign, label: expression.operand1.input, bin: expression.operand1.bin, other: expression.operand1.other, css: ''});
};
BitwiseExpression.prototype.addResult = function(operand) {
BitwiseExpression.prototype.addShiftExpressionResult = function(expression, resultOperand) {
this.maxNumberOfBits = Math.max(resultOperand.getLengthInBits(), this.maxNumberOfBits);
this.items.push({
sign: expression.sign + expression.operand1.input,
label: resultOperand,
bin: resultOperand.bin,
other: resultOperand.other,
css: 'expression-result'});
};
BitwiseExpression.prototype.addExpressionResult = function(operand) {
this.maxNumberOfBits = Math.max(operand.getLengthInBits(), this.maxNumberOfBits);
this.items.push({ label: "=" + operand.toString(), bin: operand.bin, other: operand.other, css: 'expression-result'});
this.items.push({ sign:'=', label: operand.toString(), bin: operand.bin, other: operand.other, css: 'expression-result'});
};
BitwiseExpression.prototype.emphasizeBytes = function (bits) {