Support for flipped bits

Signed-off-by: BorysLevytskyi <blevitsky@yandex.ru>
This commit is contained in:
Borys Levytskyi
2015-07-26 20:27:09 +03:00
committed by BorysLevytskyi
parent 252e940328
commit 263f34c06d
7 changed files with 145 additions and 45 deletions

View File

@@ -20,6 +20,8 @@ code { font-size: 1.2em; font-weight: bold; }
.expression .label { font-weight: bold; padding-right: 5px; text-align: right; }
.expression .bin { letter-spacing: 3px; }
.expression .flipable { cursor: pointer; opacity: 1 }
.expression .flipable:hover { opacity: 0.8 }
.expression .byte { margin: 0 3px; }
.expression-result td { border-top: dotted 1px gray; }
.expression { font-size: 1.5em; font-family: monospace }

View File

@@ -186,7 +186,7 @@
<script data-template="numbersList" data-compiled="" type="text/template">
<table class="expression">
{each op in m.operands}
<tr>
<tr data-kind="{op.kind}">
<td class="label">{op.input}</td>
<td class="bin">{op.bin.padLeft(m.bitsSize, '0')}</td>
<td class="other">{op.other}</td>

View File

@@ -18,7 +18,6 @@
this.initialize();
};
window.app = app;
})(window.core);

View File

@@ -5,44 +5,6 @@ app.set('expression', function() {
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) || notRex.test(string)
},
parse: function(string) {
var trimmed = string.replace(/^\s+|\s+$/, '');
var matches = exprRegex.exec(trimmed);
if(matches != null) {
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);
},
createOperand: function(number, kind) {
var str = number.toString(getBase(kind));
if(kind == 'hex') {
str = toHex(str);
}
return new Operand(str);
}
};
function createTwoOperandExpr(matches) {
var m = new app.models.BitwiseOperation();
@@ -87,6 +49,20 @@ app.set('expression', function() {
return hex.indexOf('-') == 0 ? '-0x' + hex.substr(1) : '0x' + hex;
}
function 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)
}
}
function Operand(input) {
this.input = input;
this.value = parseInt(input);
@@ -97,4 +73,50 @@ app.set('expression', function() {
this.kind = this.input.indexOf('0x') > -1 ? 'hex' : 'dec';
this.other = this.kind == 'dec' ? this.hex : this.dec;
}
return {
canParse: function(string) {
return exprRegex.test(string) || listRegex.test(string) || notRex.test(string)
},
parse: function(string) {
var trimmed = string.replace(/^\s+|\s+$/, '');
var matches = exprRegex.exec(trimmed);
if(matches != null) {
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);
},
createOperand: function(number, kind) {
var str = number.toString(getBase(kind));
if(kind == 'hex') {
str = toHex(str);
}
return new Operand(str);
},
getOtherKind: function(kind) {
switch(kind) {
case 'dec': return 'hex';
case 'hex': return 'dec';
default : throw new Error(kind + " kind doesn't have opposite kind")
}
},
toKindString: toKindString
};
});

View File

@@ -11,10 +11,10 @@ app.compose(function () {
var expression = app.get('expression');
// TODO: move to protojs
String.prototype.padLeft = function(size, char) { return formatter.padLeft(this, size, char); }
String.prototype.padLeft = function(size, char) { return formatter.padLeft(this, size, char); };
app.modelView(app.models.BitwiseOperation, function() {
app.modelView(app.models.BitwiseOperation, function() {
function getTemplateId(model) {
switch (model.sign) {
case '<<':
@@ -49,7 +49,16 @@ app.compose(function () {
app.modelView(app.models.BitwiseNumbers, {
renderView: function(model) {
model.bitsSize = getBinaryLength(model.numbers);
return colorizeBits(app.template('numbersList').render(model));
var templateElement = colorizeBits(app.template('numbersList').render(model));
var list = templateElement.querySelectorAll('.bit');
Array.prototype.forEach.call(list, function(el) {
el.classList.add('flipable');
el.setAttribute('title', 'Click to flip this bit');
el.addEventListener('click', flipBits);
});
return templateElement;
}
});
@@ -98,8 +107,8 @@ app.compose(function () {
}
el.innerHTML = bin
.replace(/0/g, '<span class="zero">0</span>')
.replace(/1/g, '<span class="one">1</span>');
.replace(/0/g, '<span class="bit zero">0</span>')
.replace(/1/g, '<span class="bit one">1</span>');
});
return container;
}
@@ -113,5 +122,34 @@ app.compose(function () {
return 'dec';
}
function flipBits(evt) {
var el = evt.target;
var content = el.textContent;
if(content == '0') {
el.innerHTML = '1';
el.classList.remove('zero');
el.classList.add('one');
} else {
el.innerHTML = '0';
el.classList.add('zero');
el.classList.remove('one');
}
var row = findParent(el, 'TR');
var value = parseInt(row.cells[1].textContent, 2);
var kind = row.dataset.kind;
row.cells[0].innerHTML = expression.toKindString(value, kind);
row.cells[2].innerHTML = expression.toKindString(value, expression.getOtherKind(kind));
}
function findParent(el, tageName) {
var parent = el.parentNode;
while(parent.tagName != tageName) {
parent = parent.parentNode;
}
return parent;
}
});