diff --git a/blocks.js b/blocks.js index 3f644e79..7526a15d 100644 --- a/blocks.js +++ b/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 ////////////////////////////////////////////////////////// /* diff --git a/history.txt b/history.txt index f0e9c1b3..8b8155a1 100755 --- a/history.txt +++ b/history.txt @@ -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)