-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgetAssignable.js
More file actions
47 lines (42 loc) · 1.78 KB
/
getAssignable.js
File metadata and controls
47 lines (42 loc) · 1.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
var errors = require('./errors');
module.exports = function getAssignable(expression, ctx) {
var currentNode = expression;
var isMap = false;
var variableName, variableIndexExpression, variableIndex;
var variable;
while (!variableName) {
if (currentNode.type === "Expression") currentNode = currentNode.expression;
else if (currentNode.type === "Identifier") variableName = currentNode.name;
else if (currentNode.type === "MemberExpression") {
isMap = true;
variableIndexExpression = currentNode.property;
currentNode = currentNode.map;
} else if (currentNode.type === "MapExpression" && isMap) variable = ctx.executor.execute(currentNode.map, ctx).start();
else errors.referenceError("Invalid assignable expression");
}
var variableScopeName, scope;
if (isMap) {
variableIndex = ctx.executor.execute(variableIndexExpression, ctx).start();
if (variableName) variable = ctx.getVariable(variableName);
if (!variable || !variable.isMap) errors.typeError("Cannot use index of a non-map");
} else {
variableScopeName = ctx.findVariableScope(variableName);
if (variableScopeName === false) {
variableScopeName = 0;
ctx.setVariable(variableName, null, 0);
}
scope = ctx.scopes[variableScopeName];
}
return {
isAssignable: true,
getValue: function() {
if (isMap) return variable.getIndex(variableIndex);
return ctx.getVariableIn(variableName, scope);
},
setValue: function(newValue) {
if (isMap) variable.setIndex(variableIndex, newValue);
else ctx.setVariableIn(variableName, newValue, scope);
return newValue;
}
};
};