mirror of
https://github.com/BorysLevytskyi/BitwiseCmd.git
synced 2025-12-21 20:22:48 +01:00
Support of help and clear commands. Add view models
This commit is contained in:
@@ -19,7 +19,9 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-cli": "^6.18.0",
|
"babel-cli": "^6.18.0",
|
||||||
"babel-plugin-syntax-jsx": "^6.18.0",
|
"babel-plugin-syntax-jsx": "^6.18.0",
|
||||||
|
"babel-plugin-transform-class-properties": "^6.19.0",
|
||||||
"babel-plugin-transform-react-jsx": "^6.8.0",
|
"babel-plugin-transform-react-jsx": "^6.8.0",
|
||||||
|
"babel-preset-es2015": "^6.18.0",
|
||||||
"babel-preset-react": "^6.16.0",
|
"babel-preset-react": "^6.16.0",
|
||||||
"grunt-contrib-clean": "latest",
|
"grunt-contrib-clean": "latest",
|
||||||
"grunt-contrib-copy": "latest",
|
"grunt-contrib-copy": "latest",
|
||||||
|
|||||||
@@ -6,12 +6,13 @@ app.set('cmd', function() {
|
|||||||
var cmdController = app.controller('cmdController');
|
var cmdController = app.controller('cmdController');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
debugMode: true,
|
||||||
execute: function(rawInput) {
|
execute: function(rawInput) {
|
||||||
var input = rawInput.trim().toLowerCase();
|
var input = rawInput.trim().toLowerCase();
|
||||||
var handler = findHandler(input);
|
var handler = findHandler(input);
|
||||||
|
|
||||||
if(handler != null) {
|
if(handler != null) {
|
||||||
if(app.debugMode) {
|
if(this.debugMode) {
|
||||||
invokeHandler(input, handler);
|
invokeHandler(input, handler);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
@@ -52,13 +53,12 @@ app.set('cmd', function() {
|
|||||||
handlers.push(h);
|
handlers.push(h);
|
||||||
},
|
},
|
||||||
clear: function() {
|
clear: function() {
|
||||||
cmdController.clear();
|
console.error('[displayCommandError] not implemented');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function displayCommandError(input, message) {
|
function displayCommandError(input, message) {
|
||||||
var error = new app.models.ErrorResult(message);
|
console.error('[displayCommandError] not implemented');
|
||||||
cmdController.display(new app.models.DisplayResult(input, error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function invokeHandler (input, handler) {
|
function invokeHandler (input, handler) {
|
||||||
|
|||||||
@@ -6,42 +6,6 @@ app.run(function() {
|
|||||||
var rootView = app.get('rootView');
|
var rootView = app.get('rootView');
|
||||||
var expression = app.get('expression');
|
var expression = app.get('expression');
|
||||||
|
|
||||||
cmd.commands({
|
|
||||||
'help': function() {
|
|
||||||
var helpResult = document.querySelector('.result .helpResultTpl');
|
|
||||||
if(helpResult != null) {
|
|
||||||
moveResultUp(helpResult);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return new app.models.ViewResult('helpResultTpl');
|
|
||||||
},
|
|
||||||
'clear': function() {
|
|
||||||
cmd.clear();
|
|
||||||
},
|
|
||||||
'em': function() {
|
|
||||||
cmdConfig.emphasizeBytes = !cmdConfig.emphasizeBytes;
|
|
||||||
},
|
|
||||||
'dark': function() {
|
|
||||||
cmdConfig.theme = 'dark';
|
|
||||||
},
|
|
||||||
light: function () {
|
|
||||||
cmdConfig.theme = 'light';
|
|
||||||
},
|
|
||||||
about: function() {
|
|
||||||
var aboutResult = document.querySelector('.result .aboutTpl');
|
|
||||||
if(aboutResult != null) {
|
|
||||||
moveResultUp(aboutResult);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return new app.models.ViewResult('aboutTpl');
|
|
||||||
},
|
|
||||||
'-debug': function() {
|
|
||||||
app.debugMode = true;
|
|
||||||
console.log('debug is on');
|
|
||||||
},
|
|
||||||
'-notrack': function () {}
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: Make as function
|
// TODO: Make as function
|
||||||
cmd.command({
|
cmd.command({
|
||||||
canHandle: function(input) { return app.get('expression').canParse(input); },
|
canHandle: function(input) { return app.get('expression').canParse(input); },
|
||||||
|
|||||||
35
src/app/appState.js
Normal file
35
src/app/appState.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
class AppState {
|
||||||
|
constructor() {
|
||||||
|
this.emphasizeBytes = true;
|
||||||
|
this.commandResults = [];
|
||||||
|
this.handlers = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
addCommandResult(result) {
|
||||||
|
this.commandResults.unshift(result);
|
||||||
|
this.triggerChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
clearCommmandResults() {
|
||||||
|
this.commandResults = [];
|
||||||
|
this.triggerChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleEmphasizeBytes() {
|
||||||
|
this.emphasizeBytes = !this.emphasizeBytes;
|
||||||
|
this.triggerChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange(handler) {
|
||||||
|
this.handlers.push(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
triggerChanged() {
|
||||||
|
for(var h of this.handlers) {
|
||||||
|
h();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var appState = new AppState();
|
||||||
|
export default appState;
|
||||||
91
src/app/cmd.js
Normal file
91
src/app/cmd.js
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
import is from './is';
|
||||||
|
|
||||||
|
var handlers = [];
|
||||||
|
|
||||||
|
var cmd = {
|
||||||
|
debugMode: true,
|
||||||
|
execute: function(rawInput) {
|
||||||
|
var input = rawInput.trim().toLowerCase();
|
||||||
|
var handler = findHandler(input);
|
||||||
|
|
||||||
|
if(handler != null) {
|
||||||
|
if(this.debugMode) {
|
||||||
|
invokeHandler(input, handler);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
invokeHandler(input, handler);
|
||||||
|
} catch (e) {
|
||||||
|
displayCommandError(input, "Error: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
displayCommandError(input, "Unsupported expression: " + input.trim());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
commands: function(catalog) {
|
||||||
|
for(var key in catalog) {
|
||||||
|
if(catalog.hasOwnProperty(key)) {
|
||||||
|
this.command(key, catalog[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
command: function(cmd, handler) {
|
||||||
|
var h = createHandler(cmd, handler);
|
||||||
|
if(h == null){
|
||||||
|
console.warn('unexpected set of arguments: ', Array.prototype.splice.call(arguments));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!is.aFunction(h.canHandle)) {
|
||||||
|
console.warn('handler is missing "canHandle" function. registration denied.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!is.aFunction(h.handle)) {
|
||||||
|
console.warn('handler is missing "handle" function. registration denied.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlers.push(h);
|
||||||
|
},
|
||||||
|
clear: function() {
|
||||||
|
console.log('clear');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function displayCommandError(input, message) {
|
||||||
|
var error = new app.models.ErrorResult(message);
|
||||||
|
cmdController.display(new app.models.DisplayResult(input, error));
|
||||||
|
}
|
||||||
|
|
||||||
|
function invokeHandler (input, handler) {
|
||||||
|
console.log('[invokeHandler]: ' + input);
|
||||||
|
var cmdResult = handler.handle(input);
|
||||||
|
if(cmdResult != null) {
|
||||||
|
console.log(cmdResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createHandler (cmd, handler) {
|
||||||
|
if(is.plainObject(cmd)) {
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is.string(cmd)) {
|
||||||
|
return { canHandle: function (input) { return input === cmd; }, handle: handler };
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function findHandler (input) {
|
||||||
|
var i= 0;
|
||||||
|
for(i;i<handlers.length; i++) {
|
||||||
|
if(handlers[i].canHandle(input)) {
|
||||||
|
return handlers[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default cmd;
|
||||||
44
src/app/commands.js
Normal file
44
src/app/commands.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import appState from './appState';
|
||||||
|
import * as result from './result/result';
|
||||||
|
var cmdConfig = {};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
initialize (cmd) {
|
||||||
|
cmd.commands({
|
||||||
|
'help': function() {
|
||||||
|
var helpResult = document.querySelector('.result .helpResultTpl');
|
||||||
|
if(helpResult != null) {
|
||||||
|
moveResultUp(helpResult);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
appState.addCommandResult(new result.HelpResult());
|
||||||
|
},
|
||||||
|
'clear': function() {
|
||||||
|
appState.clearCommmandResults();
|
||||||
|
},
|
||||||
|
'em': function() {
|
||||||
|
cmdConfig.emphasizeBytes = !cmdConfig.emphasizeBytes;
|
||||||
|
},
|
||||||
|
'dark': function() {
|
||||||
|
cmdConfig.theme = 'dark';
|
||||||
|
},
|
||||||
|
'light': function () {
|
||||||
|
cmdConfig.theme = 'light';
|
||||||
|
},
|
||||||
|
'about': function() {
|
||||||
|
var aboutResult = document.querySelector('.result .aboutTpl');
|
||||||
|
if(aboutResult != null) {
|
||||||
|
moveResultUp(aboutResult);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return new app.models.ViewResult('aboutTpl');
|
||||||
|
},
|
||||||
|
'-debug': function() {
|
||||||
|
app.debugMode = true;
|
||||||
|
console.log('debug is on');
|
||||||
|
},
|
||||||
|
'-notrack': function () {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
55
src/app/components/AppRoot.jsx
Normal file
55
src/app/components/AppRoot.jsx
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import InputBox from './InputBox';
|
||||||
|
import * as results from '../result/result';
|
||||||
|
import HelpView from './HelpView';
|
||||||
|
|
||||||
|
export default class AppRoot extends React.Component {
|
||||||
|
componentWillMount() {
|
||||||
|
this.refresh();
|
||||||
|
this.props.appState.onChange(() => this.refresh());
|
||||||
|
}
|
||||||
|
refresh() {
|
||||||
|
console.log(this.props.appState.commandResults);
|
||||||
|
this.setState(this.props.appState);
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
var results = this.state.commandResults.map((r, i) => this.findResultComponent(r, i));
|
||||||
|
return <div>
|
||||||
|
<div className="header">
|
||||||
|
<h1>Bitwise<span style={{color: "#c5c5c5"}}>Cmd</span></h1>
|
||||||
|
<div>State: <span>{JSON.stringify(this.state)}</span></div>
|
||||||
|
<ul className="top-links">
|
||||||
|
<li>
|
||||||
|
<a href="https://github.com/BorisLevitskiy/BitwiseCmd"><i className="icon github"> </i><span className="link-text">Project on GitHub</span></a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://twitter.com/BitwiseCmd"><i className="icon twitter"> </i><span className="link-text">Twitter</span></a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="mailto:bitwisecmd@gmail.com?subject=Feedback"><i className="icon feedback"> </i><span className="link-text">Send Feedback</span></a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="expressionInput-container">
|
||||||
|
<InputBox />
|
||||||
|
|
||||||
|
<span className="configPnl">
|
||||||
|
<span id="emphasizeBytes" data-cmd="em" className="indicator on" title="Emphasize Bytes">[em]</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="output">
|
||||||
|
{results}
|
||||||
|
</div>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
findResultComponent(result, key) {
|
||||||
|
if(result instanceof results.HelpResult) {
|
||||||
|
return <HelpView key={key} />
|
||||||
|
}
|
||||||
|
|
||||||
|
return <span>Unknown result {typeof result}</span>
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/app/components/HelpView.jsx
Normal file
45
src/app/components/HelpView.jsx
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export default class HelpView extends React.Component {
|
||||||
|
render() {
|
||||||
|
return <div className="help helpResultTpl">
|
||||||
|
<div style={{overflow: "hidden"}}>
|
||||||
|
<div style={{float: "left", "marginRight": "20px"}}>
|
||||||
|
<p className="section">
|
||||||
|
<strong>Supported Commands</strong>
|
||||||
|
<ul>
|
||||||
|
<li><code>23 ^ 34</code> — type bitwise expression to see result in binary (only positive integers are supported now)</li>
|
||||||
|
<li><code>23 34</code> — type one or more numbers to see their binary representations</li>
|
||||||
|
<li><code>clear</code> — clear output pane</li>
|
||||||
|
<li><code>help</code> — display this help</li>
|
||||||
|
<li><code>em</code> — turn On/Off Emphasize Bytes</li>
|
||||||
|
<li><code>dark</code> — set Dark theme</li>
|
||||||
|
<li><code>light</code> — set Light theme</li>
|
||||||
|
<li><code>about</code> — about the app</li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div style={{"float":"left"}}>
|
||||||
|
<p className="section">
|
||||||
|
<strong>Supported Bitwise Operations</strong><br/>
|
||||||
|
<small>
|
||||||
|
<a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators">
|
||||||
|
as implemented in JavaScript engine
|
||||||
|
</a>
|
||||||
|
</small>
|
||||||
|
<ul>
|
||||||
|
<li><code>&</code> — bitwise AND</li>
|
||||||
|
<li><code>|</code> — bitwise inclusive OR</li>
|
||||||
|
<li><code>^</code> — bitwise exclusive XOR</li>
|
||||||
|
<li><code>~</code> — bitwise NOT</li>
|
||||||
|
<li><code><<</code> — left shift</li>
|
||||||
|
<li><code>>></code> — sign propagating right shift</li>
|
||||||
|
<li><code>>>></code> — zero-fill right shift</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import cmd from '../cmd';
|
||||||
|
|
||||||
export default class InputBox extends React.Component {
|
export default class InputBox extends React.Component {
|
||||||
history = [];
|
constructor() {
|
||||||
historyIndex = 0;
|
super();
|
||||||
|
this.history = [];
|
||||||
|
this.historyIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <input type="text"
|
return <input type="text"
|
||||||
onKeyUp={e => this.onKeyUp(e)}
|
onKeyUp={e => this.onKeyUp(e)}
|
||||||
@@ -18,10 +23,10 @@ export default class InputBox extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var value = input.value;
|
var value = input.value;
|
||||||
console.log(value);
|
|
||||||
this.history.unshift(value);
|
this.history.unshift(value);
|
||||||
input.value = '';
|
|
||||||
console.log(this.history);
|
input.value = '';
|
||||||
|
cmd.execute(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
onKeyDown(args) {
|
onKeyDown(args) {
|
||||||
|
|||||||
237
src/app/expression.js
Normal file
237
src/app/expression.js
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
var expression = {
|
||||||
|
factories:[],
|
||||||
|
canParse: function(string) {
|
||||||
|
var trimmed = string.replace(/^\s+|\s+$/, '');
|
||||||
|
var i = this.factories.length-1;
|
||||||
|
for(;i>=0;i--) {
|
||||||
|
if(this.factories[i].canCreate(trimmed) === true){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
parse: function(string) {
|
||||||
|
var trimmed = string.replace(/^\s+|\s+$/, '');
|
||||||
|
var i = 0, l = this.factories.length, factory;
|
||||||
|
|
||||||
|
for(;i<l;i++) {
|
||||||
|
factory = this.factories[i];
|
||||||
|
|
||||||
|
if(factory.canCreate(trimmed) == true){
|
||||||
|
return factory.create(trimmed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
parseOperand: function(input) {
|
||||||
|
return new Operand(input);
|
||||||
|
},
|
||||||
|
createOperand: function(number, kind) {
|
||||||
|
return Operand.create(number, kind);
|
||||||
|
},
|
||||||
|
addFactory: function(factory) {
|
||||||
|
this.factories.push(factory);
|
||||||
|
},
|
||||||
|
Operand:Operand,
|
||||||
|
TwoOperandExpression: TwoOperandExpression,
|
||||||
|
SingleOperandExpression: SingleOperandExpression,
|
||||||
|
ListOfNumbersExpression: ListOfNumbersExpression,
|
||||||
|
MultipleOperandsExpression: MultipleOperandsExpression
|
||||||
|
};
|
||||||
|
|
||||||
|
// List of numbers
|
||||||
|
expression.addFactory({
|
||||||
|
regex: /^(-?(?:\d+|0x[\d,a-f]+)\s?)+$/,
|
||||||
|
canCreate: function(string) {
|
||||||
|
return this.regex.test(string);
|
||||||
|
},
|
||||||
|
create: function (string) {
|
||||||
|
var matches = this.regex.exec(string),
|
||||||
|
numbers = [],
|
||||||
|
input = matches.input;
|
||||||
|
|
||||||
|
input.split(' ').forEach(function(n){
|
||||||
|
if(n.trim().length > 0) {
|
||||||
|
numbers.push(new Operand(n.trim()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return new ListOfNumbersExpression(input, numbers);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Not Expression
|
||||||
|
expression.addFactory({
|
||||||
|
regex: /^(~)(-?(?:\d+|0x[\d,a-f]+))$/,
|
||||||
|
canCreate: function(string) {
|
||||||
|
return this.regex.test(string);
|
||||||
|
},
|
||||||
|
create: function (string) {
|
||||||
|
var matches = this.regex.exec(string),
|
||||||
|
operand = new Operand(matches[2]);
|
||||||
|
|
||||||
|
return new SingleOperandExpression(matches.input, operand, matches[1]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Multiple operands expression
|
||||||
|
expression.addFactory({
|
||||||
|
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(this.normalizeString(string));
|
||||||
|
},
|
||||||
|
create: function (string) {
|
||||||
|
var m, operands = [],
|
||||||
|
normalizedString = this.normalizeString(string);
|
||||||
|
|
||||||
|
while ((m = this.regex.exec(normalizedString)) != null) {
|
||||||
|
operands.push(this.parseMatch(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MultipleOperandsExpression(normalizedString, operands)
|
||||||
|
},
|
||||||
|
parseMatch: function (m) {
|
||||||
|
var input = m[0],
|
||||||
|
sign = m[1],
|
||||||
|
num = m[2];
|
||||||
|
|
||||||
|
if(sign == null) {
|
||||||
|
return new Operand(num);
|
||||||
|
} else {
|
||||||
|
return new SingleOperandExpression(input, new Operand(num), sign);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
normalizeString: function (string) {
|
||||||
|
return string.replace(/\s+/g,'');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export class Operand {
|
||||||
|
constructor(input) {
|
||||||
|
this.input = input;
|
||||||
|
this.value = parseInt(input);
|
||||||
|
this.hex = Operand.toHexString(this.value.toString(16));
|
||||||
|
this.dec = this.value.toString(10);
|
||||||
|
// >>> 0 makes negative numbers like -1 to be displayed as '11111111111111111111111111111111' in binary instead of -1
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
toHexString (hex) {
|
||||||
|
return hex.indexOf('-') == 0 ? '-0x' + hex.substr(1) : '0x' + hex;
|
||||||
|
};
|
||||||
|
|
||||||
|
getLengthInBits() {
|
||||||
|
if(this.value < 0) {
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
case 'dec': return 'hex';
|
||||||
|
case 'hex': return 'dec';
|
||||||
|
default : throw new Error(kind + " kind doesn't have opposite kind")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static getBase(kind){
|
||||||
|
switch (kind){
|
||||||
|
case 'bin': return 2;
|
||||||
|
case 'hex': return 16;
|
||||||
|
case 'dec': return 10;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static create(number, kind) {
|
||||||
|
var str = number.toString(Operand.getBase(kind));
|
||||||
|
if(kind == 'hex') {
|
||||||
|
str = Operand.toHexString(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Operand(str);
|
||||||
|
};
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
return this.input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SingleOperandExpression {
|
||||||
|
constructor(expressionString, operand, sign) {
|
||||||
|
this.expressionString = expressionString;
|
||||||
|
this.operand1 = operand;
|
||||||
|
this.sign = sign;
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(value) {
|
||||||
|
var str = '';
|
||||||
|
if(this.sign == '~'){
|
||||||
|
str = '~' + this.operand1.value;
|
||||||
|
} else {
|
||||||
|
str = value + this.sign + this.operand1.value
|
||||||
|
}
|
||||||
|
|
||||||
|
return Operand.create(eval(str), this.operand1.kind);
|
||||||
|
};
|
||||||
|
|
||||||
|
isShiftExpression() {
|
||||||
|
return this.sign.indexOf('<') >= 0 || this.sign.indexOf('>')>= 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
return this.sign + this.operand1.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TwoOperandExpression {
|
||||||
|
constructor(expressionString, operand1, operand2, sign) {
|
||||||
|
this.expressionString = expressionString;
|
||||||
|
this.operand1 = operand1;
|
||||||
|
this.operand2 = operand2;
|
||||||
|
this.sign = sign;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MultipleOperandsExpression {
|
||||||
|
constructor(expressionString, expressions) {
|
||||||
|
this.expressionString = expressionString;
|
||||||
|
this.expressions = expressions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ListOfNumbersExpression {
|
||||||
|
constructor(expressionString, numbers) {
|
||||||
|
this.expressionString = expressionString;
|
||||||
|
this.numbers = numbers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Expression {
|
||||||
|
toString() {
|
||||||
|
return this.expressionString ? "Expression: " + this.expressionString : this.toString();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default expression;
|
||||||
@@ -1,35 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import InputBox from './components/InputBox.jsx';
|
import InputBox from './components/InputBox.jsx';
|
||||||
var rootView = <div>
|
import appState from './appState';
|
||||||
<div className="header">
|
import cmd from './cmd';
|
||||||
<h1>Bitwise<span style={{color: "#c5c5c5"}}>Cmd</span></h1>
|
import commands from './commands';
|
||||||
|
import AppRoot from './components/AppRoot';
|
||||||
|
|
||||||
<ul className="top-links">
|
commands.initialize(cmd);
|
||||||
<li>
|
|
||||||
<a href="https://github.com/BorisLevitskiy/BitwiseCmd"><i className="icon github"> </i><span className="link-text">Project on GitHub</span></a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="https://twitter.com/BitwiseCmd"><i className="icon twitter"> </i><span className="link-text">Twitter</span></a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="mailto:bitwisecmd@gmail.com?subject=Feedback"><i className="icon feedback"> </i><span className="link-text">Send Feedback</span></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="expressionInput-container">
|
var root = <AppRoot appState={appState} />;
|
||||||
<InputBox />
|
ReactDOM.render(root, document.getElementById('root'));
|
||||||
|
|
||||||
<span className="configPnl">
|
|
||||||
<span id="emphasizeBytes" data-cmd="em" className="indicator on" title="Emphasize Bytes">[em]</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="output">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>;
|
|
||||||
|
|
||||||
|
|
||||||
ReactDOM.render(rootView, document.getElementById('root'));
|
|
||||||
33
src/app/is.js
Normal file
33
src/app/is.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
export default {
|
||||||
|
plainObject: function(obj) {
|
||||||
|
return typeof obj == "object" && obj instanceof Object;
|
||||||
|
},
|
||||||
|
|
||||||
|
aFunction: function (obj) {
|
||||||
|
return typeof obj == "function";
|
||||||
|
},
|
||||||
|
|
||||||
|
string: function (obj) {
|
||||||
|
return typeof obj == "string";
|
||||||
|
},
|
||||||
|
|
||||||
|
regex: function (obj) {
|
||||||
|
return typeof obj == "object" && this.constructedFrom(RegExp);
|
||||||
|
},
|
||||||
|
|
||||||
|
constructedFrom: function (obj, ctor) {
|
||||||
|
return obj instanceof ctor;
|
||||||
|
},
|
||||||
|
|
||||||
|
htmlElement: function(obj) {
|
||||||
|
return obj instanceof HtmlElement;
|
||||||
|
},
|
||||||
|
|
||||||
|
array: function(obj) {
|
||||||
|
return obj instanceof Array;
|
||||||
|
},
|
||||||
|
|
||||||
|
number: function(num) {
|
||||||
|
return typeof num == "number" && !isNaN(num)
|
||||||
|
}
|
||||||
|
}
|
||||||
2
src/app/result/result.js
Normal file
2
src/app/result/result.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export class HelpResult {
|
||||||
|
}
|
||||||
@@ -8,14 +8,14 @@ module.exports = {
|
|||||||
devtool: 'source-maps',
|
devtool: 'source-maps',
|
||||||
module: {
|
module: {
|
||||||
loaders: [{
|
loaders: [{
|
||||||
test: /\.jsx$/,
|
test: /\.jsx?$/,
|
||||||
loader: 'babel',
|
loader: 'babel',
|
||||||
//exclude: /node-modules/,
|
exclude: /node-modules/,
|
||||||
output: { path: __dirname + '/src', filename: 'bundle.js' },
|
output: { path: __dirname + '/src', filename: 'bundle.js' },
|
||||||
query: {
|
query: {
|
||||||
presets: ['es2015', 'react'],
|
presets: [require.resolve('babel-preset-es2015'), require.resolve('babel-preset-react')],
|
||||||
plugins: ['transform-class-properties']
|
plugins: [require.resolve('babel-plugin-transform-class-properties')]
|
||||||
}
|
},
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
// externals: {
|
// externals: {
|
||||||
|
|||||||
Reference in New Issue
Block a user