Warning: session_start(): open(/var/lib/php/sessions/sess_auu4kaissg63nl8v2ss3dujgqt, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
/* e.g.
overlay <- ScreenOverlay
bounds <- rightScreenBounds
overlay bounds bounds
overlay show
Can separate commands with ";" also.
For how to define functions in a script see #1033988.
*/
sclass GazelleV_LeftArrowScriptParser > SimpleLeftToRightParser {
replace Toolbox with GazelleV_LeftArrowScript.
delegate Script to Toolbox.
delegate Evaluable to Toolbox.
replace const with _const.
new LinkedHashSet knownVars;
Map functionDefs = new Map;
// object can be a class
srecord MethodOnObject(O object, S method) {}
Script parse(S text) {
setText(text);
}
Script parseScript() {
new Script script;
while (mainLoop()) {
if (is(";")) continue with next();
if (is("}")) break;
S t = token();
if (is("def")) {
next();
S functionName = assertIdentifier(tpp());
new LS args;
while (isIdentifier())
args.add(tpp());
assertEquals("{", tpp());
var functionBody = parseScript();
assertEquals("}", tpp());
functions.put(functionName, new Toolbox.FunctionDef(functionName, args, functionBody));
}
if (isIdentifier(t) && eq(token(1), "<") && eq(token(2), "-")) {
next(3);
knownVars.add(t);
script.add(new Toolbox.Assignment(t, parseExpr()));
} else
addUnlessNull(script, parseExpr());
}
ret script;
}
Evaluable parseOptionalExpression() {
if (lineBreak()) null;
ret parseExpr();
}
Evaluable const(O o) { ret new Toolbox.Const(o); }
Evaluable parseExpr() {
if (atEnd()) null;
if (is(";")) null;
S t = tpp();
if (isInteger(t))
ret const(parseInt(t));
if (was("true")) ret const(true);
if (was("false")) ret const(false);
if (was("null")) ret const(null);
if (knownVars.contains(t))
ret parseCall(new Toolbox.GetVar(t));
var fdef = functionDefs.get(t);
if (fdef != null)
ret new Toolbox.CallFunction(fdef, parseExpressions());
O o = findExternalObject(t);
if (o == null)
fail("Unknown object: " + t);
else if (o cast Class) {
L args = null;
if (!atCmdEnd() && is("new")) {
next();
args = parseExpressions();
}
ret new Toolbox.NewObject(o, args);
} else if (o cast MethodOnObject)
ret new Toolbox.CallMethod(const(o.object), o.method, parseExpressions());
else
ret parseCall(const(o));
}
L parseExpressions() {
ret collectWhileNotNull(-> parseOptionalExpression());
}
bool atCmdEnd() { ret atEndOrLineBreak() || is(";"); }
Evaluable parseCall(Evaluable target) {
if (atCmdEnd()) ret target;
S methodName = tpp();
var args = parseExpressions();
ret new Toolbox.CallMethod(target, methodName, args);
}
// can return MethodOnObject
swappable O findExternalObject(S name) { null; }
selfType allowTheWorld() { ret allowTheWorld(mc()); }
selfType allowTheWorld(Class... functionContainers) {
findExternalObject = name -> {
try object findClassThroughDefaultClassFinder(name);
try object findClassInStandardImports(name);
fOr (container : functionContainers)
if (hasMethodNamed(container, name))
ret new MethodOnObject(container, name);
null;
};
this;
}
}