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 ////////////////////////////////////////////////////////
|
// Global stuff ////////////////////////////////////////////////////////
|
||||||
|
|
||||||
modules.blocks = '2016-December-12';
|
modules.blocks = '2016-December-19';
|
||||||
|
|
||||||
var SyntaxElementMorph;
|
var SyntaxElementMorph;
|
||||||
var BlockMorph;
|
var BlockMorph;
|
||||||
|
@ -12330,7 +12330,8 @@ CommentMorph.prototype.fixLayout = function () {
|
||||||
|
|
||||||
CommentMorph.prototype.userMenu = function () {
|
CommentMorph.prototype.userMenu = function () {
|
||||||
var menu = new MenuMorph(this),
|
var menu = new MenuMorph(this),
|
||||||
myself = this;
|
myself = this,
|
||||||
|
block = this.blockify();
|
||||||
|
|
||||||
menu.addItem(
|
menu.addItem(
|
||||||
"duplicate",
|
"duplicate",
|
||||||
|
@ -12353,6 +12354,24 @@ CommentMorph.prototype.userMenu = function () {
|
||||||
},
|
},
|
||||||
'open a new window\nwith a picture of this comment'
|
'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;
|
return menu;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12489,6 +12508,125 @@ CommentMorph.prototype.stackHeight = function () {
|
||||||
return this.height();
|
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 //////////////////////////////////////////////////////////
|
// ScriptFocusMorph //////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -3196,6 +3196,7 @@ http://snap.berkeley.edu/run#cloud:Username=jens&ProjectName=rotation
|
||||||
161219
|
161219
|
||||||
------
|
------
|
||||||
* GUI: new url-switch: &noExitWarning
|
* GUI: new url-switch: &noExitWarning
|
||||||
|
* Blocks: highly experimental infix-expression-to-reporter parser
|
||||||
|
|
||||||
|
|
||||||
== v4.10 === (in development)
|
== v4.10 === (in development)
|
||||||
|
@ -3210,6 +3211,7 @@ Features:
|
||||||
* new url option switch: &noExitWarning
|
* new url option switch: &noExitWarning
|
||||||
* svg support for images from the web (svg files have been supported for a long time)
|
* svg support for images from the web (svg files have been supported for a long time)
|
||||||
* use media dialog for browsing and importing sounds
|
* use media dialog for browsing and importing sounds
|
||||||
|
* highly experimental infix-expression-to-reporter parser
|
||||||
|
|
||||||
Fixes:
|
Fixes:
|
||||||
* Music (play note) to work again in new and recent browser versions (Chrome 55)
|
* Music (play note) to work again in new and recent browser versions (Chrome 55)
|
||||||
|
|
Ładowanie…
Reference in New Issue