summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--blocks.js45
-rw-r--r--gui.js4
-rwxr-xr-xhistory.txt19
-rwxr-xr-xlang-pt.js32
-rw-r--r--lang-ru.js6
-rw-r--r--locale.js6
-rw-r--r--objects.js7
-rw-r--r--store.js10
-rw-r--r--threads.js164
9 files changed, 119 insertions, 174 deletions
diff --git a/blocks.js b/blocks.js
index 5f9bb29..58cab68 100644
--- a/blocks.js
+++ b/blocks.js
@@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, Costume*/
// Global stuff ////////////////////////////////////////////////////////
-modules.blocks = '2014-August-13';
+modules.blocks = '2014-September-22';
var SyntaxElementMorph;
@@ -6755,9 +6755,6 @@ InputSlotMorph.prototype.soundsMenu = function () {
InputSlotMorph.prototype.getVarNamesDict = function () {
var block = this.parentThatIsA(BlockMorph),
rcvr,
- proto,
- rings,
- declarations,
tempVars = [],
dict;
@@ -6765,28 +6762,26 @@ InputSlotMorph.prototype.getVarNamesDict = function () {
return {};
}
rcvr = block.receiver();
-
- proto = detect(block.allParents(), function (morph) {
- return morph instanceof PrototypeHatBlockMorph;
- });
- if (proto) {
- tempVars = proto.inputs()[0].inputFragmentNames();
- }
-
- rings = block.allParents().filter(function (block) {
- return block instanceof RingMorph;
- });
- rings.forEach(function (block) {
- tempVars = tempVars.concat(block.inputs()[1].evaluate());
- });
-
- declarations = block.allParents().filter(function (block) {
- return block.selector === 'doDeclareVariables';
- });
- declarations.forEach(function (block) {
- tempVars = tempVars.concat(block.inputs()[0].evaluate());
+ block.allParents().forEach(function (morph) {
+ if (morph instanceof PrototypeHatBlockMorph) {
+ tempVars.push.apply(
+ tempVars,
+ morph.inputs()[0].inputFragmentNames()
+ );
+ } else if (morph instanceof BlockMorph) {
+ morph.inputs().forEach(function (inp) {
+ if (inp instanceof TemplateSlotMorph) {
+ tempVars.push(inp.contents());
+ } else if (inp instanceof MultiArgMorph) {
+ inp.children.forEach(function (m) {
+ if (m instanceof TemplateSlotMorph) {
+ tempVars.push(m.contents());
+ }
+ });
+ }
+ });
+ }
});
-
if (rcvr) {
dict = rcvr.variables.allNamesDict();
tempVars.forEach(function (name) {
diff --git a/gui.js b/gui.js
index 6af9137..7f4d7db 100644
--- a/gui.js
+++ b/gui.js
@@ -69,7 +69,7 @@ SpeechBubbleMorph*/
// Global stuff ////////////////////////////////////////////////////////
-modules.gui = '2014-July-30';
+modules.gui = '2014-September-22';
// Declarations
@@ -1859,7 +1859,7 @@ IDE_Morph.prototype.newSpriteName = function (name, ignoredSprite) {
stem = (ix < 0) ? name : name.substring(0, ix),
count = 1,
newName = stem,
- all = this.sprites.asArray().filter(
+ all = this.sprites.asArray().concat(this.stage).filter(
function (each) {return each !== ignoredSprite; }
).map(
function (each) {return each.name; }
diff --git a/history.txt b/history.txt
index d18452e..3194cfd 100755
--- a/history.txt
+++ b/history.txt
@@ -2262,3 +2262,22 @@ ______
------
* Threads, Blocks: enable Zombiefication of JS-Functions
* Morphic: Fix #563 (Paste into Chrome), thanks, @Muon, for the hint!
+
+140917
+------
+* Threads, Objects, Store: Refactor variables handling, introducing Variable objects, all functionality stays the same
+
+140918
+------
+* Threads: fixed #174, replace UpvarReferences with references to Variable objects, fixes upvar scope issues
+
+140922
+------
+* Blocks: Make upvars mutable
+* GUI: fixed #585 (sprite name conflict with stage). Thanks, Michael, for the report!
+
+140929
+------
+* Threads: fixed #591 fully copy local variables for sprite duplicates and (Scratch-like) clones
+* Portuguese translation update, thanks, Manuel!
+* fixed #590 (Russian translation syntax glitches) Thanks @alexf2000 !
diff --git a/lang-pt.js b/lang-pt.js
index 2c0e1be..c59a184 100755
--- a/lang-pt.js
+++ b/lang-pt.js
@@ -185,7 +185,7 @@ SnapTranslator.dict.pt = {
'translator_e-mail':
'mmsequeira@gmail.com',
'last_changed':
- '2014-07-29',
+ '2014-09-29',
// GUI
// control bar:
@@ -943,7 +943,7 @@ SnapTranslator.dict.pt = {
'Delete Project':
'Remover Projecto',
'Are you sure you want to delete':
- 'Quer mesmo remover?',
+ 'Quer mesmo remover',
'rename...':
'alterar o nome…',
@@ -1430,10 +1430,10 @@ SnapTranslator.dict.pt = {
'Actualizando a\nlista de projectos…',
'Opening project...':
'Abrindo o projecto…',
- 'Fetching project from the cloud...':
- 'Obtendo o projecto da nuvem…',
- 'Saving project to the cloud...':
- 'Guardando o projecto na nuvem…',
+ 'Fetching project\nfrom the cloud...':
+ 'Obtendo o projecto\nda nuvem…',
+ 'Saving project\nto the cloud...':
+ 'Guardando o projecto\nna nuvem…',
'Sprite Nesting':
'Actores compostos',
'uncheck to disable\nsprite composition':
@@ -1597,6 +1597,26 @@ SnapTranslator.dict.pt = {
'ponta',
'middle':
'meio',
+ 'last changed':
+ 'alterado pela última vez em',
+ 'Are you sure you want to publish':
+ 'Quer mesmo publicar',
+ 'Are you sure you want to unpublish':
+ 'Quer mesmo deixar de publicar',
+ 'Share Project':
+ 'Partilhar Projecto',
+ 'Unshare Project':
+ 'Deixar de Partilhar Projecto',
+ 'sharing\nproject...':
+ 'partilhando\nprojecto…',
+ 'unsharing\nproject...':
+ 'deixando de partilhar\nprojecto…',
+ 'shared.':
+ 'partilhado.',
+ 'unshared.':
+ 'deixado de partilhar.',
+ 'Unshare':
+ 'Deixar de Partilhar'
// produção de código
'map %cmdRing to %codeKind %code':
diff --git a/lang-ru.js b/lang-ru.js
index f113f2c..5932bb4 100644
--- a/lang-ru.js
+++ b/lang-ru.js
@@ -182,7 +182,7 @@ SnapTranslator.dict.ru = {
'translator_e-mail':
'svetlanap@berkeley.edu', // optional
'last_changed':
- '2013-03-19', // this, too, will appear in the Translators tab
+ '2014-09-29', // this, too, will appear in the Translators tab
// GUI
// control bar:
@@ -1117,9 +1117,9 @@ SnapTranslator.dict.ru = {
'last':
'последний',
'any':
- 'любой'
+ 'любой',
'now connected':
- 'вы вошли в систему'
+ 'вы вошли в систему',
'undo':
'отменить'
};
diff --git a/locale.js b/locale.js
index e12ac03..fa2e9e0 100644
--- a/locale.js
+++ b/locale.js
@@ -42,7 +42,7 @@
/*global modules, contains*/
-modules.locale = '2014-July-29';
+modules.locale = '2014-September-29';
// Global stuff
@@ -209,7 +209,7 @@ SnapTranslator.dict.pt = {
'translator_e-mail':
'mmsequeira@gmail.com',
'last_changed':
- '2014-07-29'
+ '2014-09-29'
};
SnapTranslator.dict.cs = {
@@ -281,7 +281,7 @@ SnapTranslator.dict.ru = {
'translator_e-mail':
'svetlanap@berkeley.edu',
'last_changed':
- '2013-03-19'
+ '2014-09-29'
};
SnapTranslator.dict.es = {
diff --git a/objects.js b/objects.js
index fbb9e84..2ed20f2 100644
--- a/objects.js
+++ b/objects.js
@@ -125,7 +125,7 @@ PrototypeHatBlockMorph*/
// Global stuff ////////////////////////////////////////////////////////
-modules.objects = '2014-July-30';
+modules.objects = '2014-September-17';
var SpriteMorph;
var StageMorph;
@@ -6735,7 +6735,8 @@ WatcherMorph.prototype.update = function () {
if (this.target && this.getter) {
this.updateLabel();
if (this.target instanceof VariableFrame) {
- newValue = this.target.vars[this.getter];
+ newValue = this.target.vars[this.getter] ?
+ this.target.vars[this.getter].value : undefined;
} else {
newValue = this.target[this.getter]();
}
@@ -6820,7 +6821,7 @@ WatcherMorph.prototype.fixLayout = function () {
this.sliderMorph.button.pressColor.b += 100;
this.sliderMorph.setHeight(fontSize);
this.sliderMorph.action = function (num) {
- myself.target.vars[myself.getter] = Math.round(num);
+ myself.target.vars[myself.getter].value = Math.round(num);
};
this.add(this.sliderMorph);
}
diff --git a/store.js b/store.js
index f8d46bf..b743239 100644
--- a/store.js
+++ b/store.js
@@ -57,11 +57,11 @@ newCanvas, Costume, Sound, Audio, IDE_Morph, ScriptsMorph, BlockMorph,
ArgMorph, InputSlotMorph, TemplateSlotMorph, CommandSlotMorph,
FunctionSlotMorph, MultiArgMorph, ColorSlotMorph, nop, CommentMorph, isNil,
localize, sizeOf, ArgLabelMorph, SVG_Costume, MorphicPreferences,
-SyntaxElementMorph*/
+SyntaxElementMorph, Variable*/
// Global stuff ////////////////////////////////////////////////////////
-modules.store = '2014-July-29';
+modules.store = '2014-September-17';
// XML_Serializer ///////////////////////////////////////////////////////
@@ -730,8 +730,8 @@ SnapSerializer.prototype.loadVariables = function (varFrame, element) {
return;
}
value = child.children[0];
- varFrame.vars[child.attributes.name] = value ?
- myself.loadValue(value) : 0;
+ varFrame.vars[child.attributes.name] = new Variable(value ?
+ myself.loadValue(value) : 0);
});
};
@@ -1509,7 +1509,7 @@ Sound.prototype.toXML = function (serializer) {
VariableFrame.prototype.toXML = function (serializer) {
var myself = this;
return Object.keys(this.vars).reduce(function (vars, v) {
- var val = myself.vars[v],
+ var val = myself.vars[v].value,
dta;
if (val === undefined || val === null) {
dta = serializer.format('<variable name="@"/>', v);
diff --git a/threads.js b/threads.js
index 335b5d0..2b2c1f6 100644
--- a/threads.js
+++ b/threads.js
@@ -40,8 +40,8 @@
ThreadManager
Process
Context
+ Variable
VariableFrame
- UpvarReference
credits
@@ -83,13 +83,12 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/
// Global stuff ////////////////////////////////////////////////////////
-modules.threads = '2014-August-13';
+modules.threads = '2014-September-29';
var ThreadManager;
var Process;
var Context;
var VariableFrame;
-var UpvarReference;
function snapEquals(a, b) {
if (a instanceof List || (b instanceof List)) {
@@ -600,8 +599,7 @@ Process.prototype.evaluateSequence = function (arr) {
outer = this.context.outerContext,
isLambda = this.context.isLambda,
isImplicitLambda = this.context.isImplicitLambda,
- isCustomBlock = this.context.isCustomBlock,
- upvars = this.context.upvars;
+ isCustomBlock = this.context.isCustomBlock;
if (pc === (arr.length - 1)) { // tail call elimination
this.context = new Context(
this.context.parentContext,
@@ -612,9 +610,6 @@ Process.prototype.evaluateSequence = function (arr) {
this.context.isLambda = isLambda;
this.context.isImplicitLambda = isImplicitLambda;
this.context.isCustomBlock = isCustomBlock;
- if (upvars) {
- this.context.upvars = new UpvarReference(upvars);
- }
} else {
if (pc >= arr.length) {
this.popContext();
@@ -860,9 +855,6 @@ Process.prototype.evaluate = function (
}
}
}
- if (this.context.upvars) {
- runnable.upvars = new UpvarReference(this.context.upvars);
- }
if (runnable.expression instanceof CommandBlockMorph) {
runnable.expression = runnable.expression.blockSequence();
@@ -1026,7 +1018,6 @@ Process.prototype.evaluateCustomBlock = function () {
extra,
i,
value,
- upvars,
outer;
if (!context) {return null; }
@@ -1061,26 +1052,14 @@ Process.prototype.evaluateCustomBlock = function () {
outer.variables.addVar(context.inputs[i], value);
// if the parameter is an upvar,
- // create an UpvarReference to it
+ // create a reference to the variable it points to
if (declarations[context.inputs[i]][0] === '%upvar') {
- if (!upvars) { // lazy initialization
- upvars = new UpvarReference(this.context.upvars);
- }
- upvars.addReference(
- value,
- context.inputs[i],
- outer.variables
- );
+ this.context.outerContext.variables.vars[value] =
+ outer.variables.vars[context.inputs[i]];
}
}
}
- if (upvars) {
- runnable.upvars = upvars;
- } else if (this.context.upvars) {
- runnable.upvars = new UpvarReference(this.context.upvars);
- }
-
if (runnable.expression instanceof CommandBlockMorph) {
runnable.expression = runnable.expression.blockSequence();
}
@@ -1121,11 +1100,8 @@ Process.prototype.doChangeVar = function (varName, value) {
Process.prototype.reportGetVar = function () {
// assumes a getter block whose blockSpec is a variable name
- var varName = this.context.expression.blockSpec;
-
return this.context.variables.getVar(
- varName,
- this.context.upvars
+ this.context.expression.blockSpec
);
};
@@ -1332,8 +1308,7 @@ Process.prototype.doIf = function () {
outer = this.context.outerContext, // for tail call elimination
isLambda = this.context.isLambda,
isImplicitLambda = this.context.isImplicitLambda,
- isCustomBlock = this.context.isCustomBlock,
- upvars = this.context.upvars;
+ isCustomBlock = this.context.isCustomBlock;
this.popContext();
if (args[0]) {
@@ -1342,7 +1317,6 @@ Process.prototype.doIf = function () {
this.context.isLambda = isLambda;
this.context.isImplicitLambda = isImplicitLambda;
this.context.isCustomBlock = isCustomBlock;
- this.context.upvars = new UpvarReference(upvars);
}
}
this.pushContext();
@@ -1353,8 +1327,7 @@ Process.prototype.doIfElse = function () {
outer = this.context.outerContext, // for tail call elimination
isLambda = this.context.isLambda,
isImplicitLambda = this.context.isImplicitLambda,
- isCustomBlock = this.context.isCustomBlock,
- upvars = this.context.upvars;
+ isCustomBlock = this.context.isCustomBlock;
this.popContext();
if (args[0]) {
@@ -1372,7 +1345,6 @@ Process.prototype.doIfElse = function () {
this.context.isLambda = isLambda;
this.context.isImplicitLambda = isImplicitLambda;
this.context.isCustomBlock = isCustomBlock;
- this.context.upvars = new UpvarReference(upvars);
}
this.pushContext();
@@ -1551,8 +1523,7 @@ Process.prototype.doRepeat = function (counter, body) {
outer = this.context.outerContext, // for tail call elimination
isLambda = this.context.isLambda,
isImplicitLambda = this.context.isImplicitLambda,
- isCustomBlock = this.context.isCustomBlock,
- upvars = this.context.upvars;
+ isCustomBlock = this.context.isCustomBlock;
if (counter < 1) { // was '=== 0', which caused infinite loops on non-ints
return null;
@@ -1564,7 +1535,6 @@ Process.prototype.doRepeat = function (counter, body) {
this.context.isLambda = isLambda;
this.context.isImplicitLambda = isImplicitLambda;
this.context.isCustomBlock = isCustomBlock;
- this.context.upvars = new UpvarReference(upvars);
this.context.addInput(counter - 1);
@@ -2742,7 +2712,6 @@ Process.prototype.inputOption = function (dta) {
// Process stack
Process.prototype.pushContext = function (expression, outerContext) {
- var upvars = this.context ? this.context.upvars : null;
this.context = new Context(
this.context,
expression,
@@ -2751,9 +2720,6 @@ Process.prototype.pushContext = function (expression, outerContext) {
this.context ? // check needed due to tail call elimination
this.context.receiver : this.homeContext.receiver
);
- if (upvars) {
- this.context.upvars = new UpvarReference(upvars);
- }
};
Process.prototype.popContext = function () {
@@ -2799,7 +2765,6 @@ Process.prototype.reportFrameCount = function () {
null or a String denoting a selector, e.g. 'doYield'
receiver the object to which the expression applies, if any
variables the current VariableFrame, if any
- upvars the current UpvarReference, if any (default: null)
inputs an array of input values computed so far
(if expression is a BlockMorph)
pc the index of the next block to evaluate
@@ -2829,7 +2794,6 @@ function Context(
this.variables.parentFrame = this.outerContext.variables;
this.receiver = this.outerContext.receiver;
}
- this.upvars = null; // set to an UpvarReference in custom blocks
this.inputs = [];
this.pc = 0;
this.startTime = null;
@@ -2982,6 +2946,20 @@ Context.prototype.stackSize = function () {
return 1 + this.parentContext.stackSize();
};
+// Variable /////////////////////////////////////////////////////////////////
+
+function Variable(value) {
+ this.value = value;
+}
+
+Variable.prototype.toString = function () {
+ return 'a Variable [' + this.value + ']';
+};
+
+Variable.prototype.copy = function () {
+ return new Variable(this.value);
+};
+
// VariableFrame ///////////////////////////////////////////////////////
function VariableFrame(parentFrame, owner) {
@@ -2995,8 +2973,11 @@ VariableFrame.prototype.toString = function () {
};
VariableFrame.prototype.copy = function () {
- var frame = new VariableFrame(this.parentFrame);
- frame.vars = copy(this.vars);
+ var frame = new VariableFrame(this.parentFrame),
+ myself = this;
+ this.names().forEach(function (vName) {
+ frame.addVar(vName, myself.getVar(vName));
+ });
return frame;
};
@@ -3049,7 +3030,7 @@ VariableFrame.prototype.setVar = function (name, value) {
*/
var frame = this.find(name);
if (frame) {
- frame.vars[name] = value;
+ frame.vars[name].value = value;
}
};
@@ -3063,21 +3044,20 @@ VariableFrame.prototype.changeVar = function (name, delta) {
var frame = this.find(name),
value;
if (frame) {
- value = parseFloat(frame.vars[name]);
+ value = parseFloat(frame.vars[name].value);
if (isNaN(value)) {
- frame.vars[name] = delta;
+ frame.vars[name].value = delta;
} else {
- frame.vars[name] = value + parseFloat(delta);
+ frame.vars[name].value = value + parseFloat(delta);
}
}
};
-VariableFrame.prototype.getVar = function (name, upvars) {
+VariableFrame.prototype.getVar = function (name) {
var frame = this.silentFind(name),
- value,
- upvarReference;
+ value;
if (frame) {
- value = frame.vars[name];
+ value = frame.vars[name].value;
return (value === 0 ? 0
: value === false ? false
: value === '' ? ''
@@ -3087,12 +3067,6 @@ VariableFrame.prototype.getVar = function (name, upvars) {
// empty input with a Binding-ID called without an argument
return '';
}
- if (upvars) {
- upvarReference = upvars.find(name);
- if (upvarReference) {
- return upvarReference.getVar(name);
- }
- }
throw new Error(
'a variable of name \''
+ name
@@ -3101,7 +3075,7 @@ VariableFrame.prototype.getVar = function (name, upvars) {
};
VariableFrame.prototype.addVar = function (name, value) {
- this.vars[name] = (value === 0 ? 0
+ this.vars[name] = new Variable(value === 0 ? 0
: value === false ? false
: value === '' ? '' : value || 0);
};
@@ -3158,67 +3132,3 @@ VariableFrame.prototype.allNames = function () {
}
return answer;
};
-
-// Variable /////////////////////////////////////////////////////////////////
-
-function Variable(value) {
- this.value = value;
-}
-
-Variable.prototype.toString = function () {
- return 'a Variable [' + this.value + ']';
-};
-
-Variable.prototype.copy = function () {
- return new Variable(this.value);
-};
-
-// UpvarReference ///////////////////////////////////////////////////////////
-
-// ... quasi-inherits some features from VariableFrame
-
-function UpvarReference(parent) {
- this.vars = {}; // structure: {upvarName : [varName, varFrame]}
- this.parentFrame = parent || null;
-}
-
-UpvarReference.prototype.addReference = function (
- upvarName,
- varName,
- varFrame
-) {
- this.vars[upvarName] = [varName, varFrame];
-};
-
-UpvarReference.prototype.find = function (name) {
-/*
- answer the closest upvar reference containing
- the specified variable, or answer null.
-*/
- if (this.vars[name] !== undefined) {
- return this;
- }
- if (this.parentFrame) {
- return this.parentFrame.find(name);
- }
- return null;
-};
-
-UpvarReference.prototype.getVar = function (name) {
- var varName = this.vars[name][0],
- varFrame = this.vars[name][1],
- value = varFrame.vars[varName];
- return (value === 0 ? 0 : value || 0); // don't return null
-};
-
-// UpvarReference tools
-
-UpvarReference.prototype.toString = function () {
- return 'an UpvarReference {' + this.names() + '}';
-};
-
-// UpvarReference quasi-inheritance from VariableFrame
-
-UpvarReference.prototype.names = VariableFrame.prototype.names;
-UpvarReference.prototype.allNames = VariableFrame.prototype.allNames;
-UpvarReference.prototype.allNamesDict = VariableFrame.prototype.allNamesDict;