kopia lustrzana https://github.com/backface/turtlestitch
[experimental] blockify simple arithmetic expressions inside comments
rodzic
5dc4874352
commit
955aabfc93
142
blocks.js
142
blocks.js
|
@ -149,7 +149,7 @@ isSnapObject, copy, PushButtonMorph, SpriteIconMorph, Process, AlignmentMorph*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.blocks = '2016-December-12';
|
||||
modules.blocks = '2016-December-19';
|
||||
|
||||
var SyntaxElementMorph;
|
||||
var BlockMorph;
|
||||
|
@ -12330,7 +12330,8 @@ CommentMorph.prototype.fixLayout = function () {
|
|||
|
||||
CommentMorph.prototype.userMenu = function () {
|
||||
var menu = new MenuMorph(this),
|
||||
myself = this;
|
||||
myself = this,
|
||||
block = this.blockify();
|
||||
|
||||
menu.addItem(
|
||||
"duplicate",
|
||||
|
@ -12353,6 +12354,24 @@ CommentMorph.prototype.userMenu = function () {
|
|||
},
|
||||
'open a new window\nwith a picture of this comment'
|
||||
);
|
||||
if (block) {
|
||||
menu.addLine();
|
||||
menu.addItem(
|
||||
block,
|
||||
function () {
|
||||
var world = myself.world(),
|
||||
ide = myself.parentThatIsA(IDE_Morph);
|
||||
block.pickUp(world);
|
||||
if (ide) {
|
||||
world.hand.grabOrigin = {
|
||||
origin: ide.palette,
|
||||
position: ide.palette.center()
|
||||
};
|
||||
}
|
||||
},
|
||||
'blockify this expression'
|
||||
);
|
||||
}
|
||||
return menu;
|
||||
};
|
||||
|
||||
|
@ -12489,6 +12508,125 @@ CommentMorph.prototype.stackHeight = function () {
|
|||
return this.height();
|
||||
};
|
||||
|
||||
// CommentMorph parsing simple arithmetic expressions to reporters
|
||||
|
||||
CommentMorph.prototype.blockify = function () {
|
||||
// highly experimental Christmas Easter Egg 2016 :-)
|
||||
var ast;
|
||||
|
||||
function parseInfix(expression, operator, already) {
|
||||
// very basic binary infix parser for arithmetic expressions
|
||||
// with strict left-to-right operator precedence (like in Smalltalk)
|
||||
// which can be overriden by - nested - parentheses.
|
||||
// assumes well-formed expressions, no graceful error handling yet.
|
||||
|
||||
var inputs = ['', ''],
|
||||
idx = 0,
|
||||
ch;
|
||||
|
||||
function format(value) {
|
||||
return value instanceof Array || isNaN(+value) ? value : +value;
|
||||
}
|
||||
|
||||
function nested() {
|
||||
var level = 1,
|
||||
expr = '';
|
||||
while (idx < expression.length) {
|
||||
ch = expression[idx];
|
||||
idx += 1;
|
||||
switch (ch) {
|
||||
case '(':
|
||||
level += 1;
|
||||
break;
|
||||
case ')':
|
||||
level -= 1;
|
||||
if (!level) {
|
||||
return expr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
expr += ch;
|
||||
}
|
||||
}
|
||||
|
||||
while (idx < expression.length) {
|
||||
ch = expression[idx];
|
||||
idx += 1;
|
||||
switch (ch) {
|
||||
case ' ':
|
||||
break;
|
||||
case '(':
|
||||
inputs[operator ? 1 : 0] = parseInfix(nested());
|
||||
break;
|
||||
case '-':
|
||||
case '+':
|
||||
case '*':
|
||||
case '/':
|
||||
if (!operator && !inputs[0].length) {
|
||||
inputs[0] += ch;
|
||||
} else if (operator) {
|
||||
return parseInfix(
|
||||
expression.slice(idx),
|
||||
ch,
|
||||
[operator, already, format(inputs[1])]
|
||||
);
|
||||
} else {
|
||||
operator = ch;
|
||||
already = format(inputs[0]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
inputs[operator ? 1 : 0] += ch;
|
||||
}
|
||||
}
|
||||
if (operator) {
|
||||
return [operator, already, format(inputs[1])];
|
||||
}
|
||||
return format(inputs[0]);
|
||||
}
|
||||
|
||||
function blockFromAST(ast) {
|
||||
var block, selectors, i, inps;
|
||||
selectors = {
|
||||
'+': 'reportSum',
|
||||
'-': 'reportDifference',
|
||||
'*': 'reportProduct',
|
||||
'/': 'reportQuotient'
|
||||
};
|
||||
block = SpriteMorph.prototype.blockForSelector(selectors[ast[0]], true);
|
||||
block.isDraggable = true;
|
||||
inps = block.inputs();
|
||||
for (i = 1; i < 3; i += 1) {
|
||||
if (ast[i] instanceof Array) {
|
||||
block.silentReplaceInput(inps[i - 1], blockFromAST(ast[i]));
|
||||
} else if (isString(ast[i])) {
|
||||
block.silentReplaceInput(
|
||||
inps[i - 1],
|
||||
SpriteMorph.prototype.variableBlock(ast[i])
|
||||
);
|
||||
} else { // number
|
||||
inps[i - 1].setContents(ast[i]);
|
||||
}
|
||||
}
|
||||
block.fixLayout();
|
||||
block.fixBlockColor(null, true);
|
||||
return block;
|
||||
}
|
||||
|
||||
if (this.contents.text.length > 100) {return null; }
|
||||
if (Process.prototype.isCatchingErrors) {
|
||||
try {
|
||||
ast = parseInfix(this.contents.text);
|
||||
return ast instanceof Array ? blockFromAST(ast) : null;
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
ast = parseInfix(this.contents.text);
|
||||
return ast instanceof Array ? blockFromAST(ast) : null;
|
||||
}
|
||||
};
|
||||
|
||||
// ScriptFocusMorph //////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
|
|
|
@ -3196,6 +3196,7 @@ http://snap.berkeley.edu/run#cloud:Username=jens&ProjectName=rotation
|
|||
161219
|
||||
------
|
||||
* GUI: new url-switch: &noExitWarning
|
||||
* Blocks: highly experimental infix-expression-to-reporter parser
|
||||
|
||||
|
||||
== v4.10 === (in development)
|
||||
|
@ -3210,6 +3211,7 @@ Features:
|
|||
* new url option switch: &noExitWarning
|
||||
* svg support for images from the web (svg files have been supported for a long time)
|
||||
* use media dialog for browsing and importing sounds
|
||||
* highly experimental infix-expression-to-reporter parser
|
||||
|
||||
Fixes:
|
||||
* Music (play note) to work again in new and recent browser versions (Chrome 55)
|
||||
|
|
Ładowanie…
Reference in New Issue