Implement concrete expression types. Models are bound to those types.

This commit is contained in:
BorysLevytskyi
2015-12-01 20:01:17 +02:00
parent 252e940328
commit 49fa80e459
7 changed files with 81 additions and 35 deletions

View File

@@ -24,7 +24,7 @@ app.set('calc', function() {
}, },
calcExpression: function (expr) { calcExpression: function (expr) {
return eval(expr.string); return eval(expr.expressionString);
} }
} }
}); });

View File

@@ -5,7 +5,7 @@ app.set('expression', function() {
var listRegex = /^(-?(?:\d+|0x[\d,a-f]+)\s?)+$/; var listRegex = /^(-?(?:\d+|0x[\d,a-f]+)\s?)+$/;
var notRex = /^(~)(-?(?:\d+|0x[\d,a-f]+))$/; var notRex = /^(~)(-?(?:\d+|0x[\d,a-f]+))$/;
return { var expression = {
canParse: function(string) { canParse: function(string) {
return exprRegex.test(string) || listRegex.test(string) || notRex.test(string) return exprRegex.test(string) || listRegex.test(string) || notRex.test(string)
}, },
@@ -39,40 +39,36 @@ app.set('expression', function() {
} }
return new Operand(str); return new Operand(str);
} },
TwoOperandExpression: TwoOperandExpression,
SingleOperandExpression: SingleOperandExpression,
ListOfNumbersExpression: ListOfNumbersExpression
}; };
function createTwoOperandExpr(matches) { function createTwoOperandExpr(matches) {
var m = new app.models.BitwiseOperation(); var operand1 = new Operand(matches[1]),
m.operand1 = new Operand(matches[1]); operand2 = new Operand(matches[3]),
m.operand2 = new Operand(matches[3]); sign = matches[2],
m.sign = matches[2]; expressionString = matches.input;
m.string = matches.input;
//m.result = eval(matches.input);
return m; return new TwoOperandExpression(expressionString, operand1, operand2, sign);
} }
function createSingleOperandExpr(matches) { function createSingleOperandExpr(matches) {
var m = new app.models.BitwiseOperation(); var operand = new Operand(matches[2])
m.operand1 = new Operand(matches[2]); return new SingleOperandExpression(matches.input, operand, matches[1]);
m.sign = matches[1];
m.string = matches.input;
return m;
} }
function createListOfNumbersExpression(input) { function createListOfNumbersExpression(input) {
var operands = []; var numbers = [];
input.split(' ').forEach(function(n){ input.split(' ').forEach(function(n){
if(n.trim().length > 0) { if(n.trim().length > 0) {
operands.push(new Operand(n.trim())); numbers.push(new Operand(n.trim()));
} }
}); });
return new app.models.BitwiseNumbers(operands); return new ListOfNumbersExpression(input, numbers);
} }
function getBase(kind) { function getBase(kind) {
@@ -97,4 +93,35 @@ app.set('expression', function() {
this.kind = this.input.indexOf('0x') > -1 ? 'hex' : 'dec'; this.kind = this.input.indexOf('0x') > -1 ? 'hex' : 'dec';
this.other = this.kind == 'dec' ? this.hex : this.dec; this.other = this.kind == 'dec' ? this.hex : this.dec;
} }
function SingleOperandExpression(expressionString, operand, sign) {
this.expressionString = expressionString;
this.operand1 = operand;
this.sign = sign;
}
function TwoOperandExpression(expressionString, operand1, operand2, sign) {
this.expressionString = expressionString;
this.operand1 = operand1;
this.operand2 = operand2;
this.sign = sign;
}
function ListOfNumbersExpression(expressionString, numbers) {
this.expressionString = expressionString;
this.numbers = numbers;
}
function Expression() {
}
Expression.prototype.toString = function() {
return this.expressionString ? "Expression: " + this.expressionString : this.toString();
};
//TwoOperandExpression.prototype = Expression.prototype;
//SingleOperandExpression.prototype = Expression.prototype;
//ListOfNumbersExpression.prototype = Expression.prototype;
return expression;
}); });

View File

@@ -4,6 +4,7 @@ app.run(function() {
var cmd = app.get('cmd'); var cmd = app.get('cmd');
var cmdConfig = app.get('cmdConfig'); var cmdConfig = app.get('cmdConfig');
var rootView = app.get('rootView'); var rootView = app.get('rootView');
var expression = app.get('expression');
cmd.commands({ cmd.commands({
'help': function() { 'help': function() {
@@ -36,6 +37,7 @@ app.run(function() {
}, },
'-debug': function() { '-debug': function() {
app.debugMode = true; app.debugMode = true;
console.log('debug is on');
}, },
'-notrack': function () {} '-notrack': function () {}
}); });
@@ -44,7 +46,19 @@ app.run(function() {
cmd.command({ cmd.command({
canHandle: function(input) { return app.get('expression').canParse(input); }, canHandle: function(input) { return app.get('expression').canParse(input); },
handle: function(input) { handle: function(input) {
return app.get('expression').parse(input); var expr = expression.parse(input);
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);
}
return new app.models.ErrorResult('Cannot create model for expression: ' + expr.toString());
} }
}); });

View File

@@ -29,12 +29,12 @@ app.compose(function () {
} }
return { return {
renderView: function(expr) { renderView: function(model) {
// TODO: move all this to expression // TODO: move all this to expression
var result = expression.createOperand(calc.calcExpression(expr), getResultMode([expr.operand1, expr.operand2])); var result = expression.createOperand(calc.calcExpression(model.expression), getResultMode([model.operand1, model.operand2]));
var maxLen = getBinaryLength([expr.operand1.value, expr.operand2 != null ? expr.operand2.value : 0, result.value]); var maxLen = getBinaryLength([model.operand1.value, model.operand2 != null ? model.operand2.value : 0, result.value]);
var model = Object.create(expr); var model = Object.create(model);
model.bitsSize = maxLen; model.bitsSize = maxLen;
model.result = result; model.result = result;

View File

@@ -1,18 +1,21 @@
(function(app) { (function(app) {
"use strict"; "use strict";
function BitwiseOperation () { function BitwiseOperation (expression) {
this.expression = expression;
this.operand1 = expression.operand1;
this.operand2 = expression.operand2;
this.sign = expression.sign;
this.string = expression.expressionString;
} }
BitwiseOperation.prototype.calculate = function () { function BitwiseNumbers(expression) {
return eval(this.string); this.expression = expression;
}; this.operands = expression.numbers;
function BitwiseNumbers(operands) {
this.operands = operands;
var numbers = this.numbers = []; var numbers = this.numbers = [];
operands.forEach(function (o) { expression.numbers.forEach(function (o) {
numbers.push(o.value); numbers.push(o.value);
}); });
} }

View File

@@ -35,7 +35,7 @@
function resolveInternal(name) { function resolveInternal(name) {
if(contains(this.resolutionStack, name)) { if(contains(this.resolutionStack, name)) {
throw new Error("Failed to resolve service: " + name + ". Circular reference: " + this.resolutionStack.join(' < ')); throw new Error("Failed to resolve dependency: " + name + ". Circular reference: " + this.resolutionStack.join(' < '));
} }
this.resolutionStack.unshift(name); this.resolutionStack.unshift(name);

View File

@@ -41,7 +41,8 @@ describe("expression parse", function() {
expect(actual.operand2).not.toBeDefined(); expect(actual.operand2).not.toBeDefined();
} }
expect(actual.string).toBe(expected.string); expect(actual.expressionString).toBe(expected.string);
console.log(actual.toString());
} }
}); });
@@ -59,7 +60,8 @@ describe("expression parse", function() {
var expected = listCases[input]; var expected = listCases[input];
for(i =0; i<expected.length;i++) { for(i =0; i<expected.length;i++) {
expect(actual.operands[i].value).toBe(expected[i]); expect(actual.numbers[i].value).toBe(expected[i]);
expect(actual.expressionString).toBe(input)
} }
} }
}); });