Warning: session_start(): open(/var/lib/php/sessions/sess_5f3pga68kulqkk3l17c965sbtt, 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.
Note: LeftArrowScriptAutoCompleter uses a lot of this class's internals
*/
sclass GazelleV_LeftArrowScriptParser > SimpleLeftToRightParser {
replace Toolbox with GazelleV_LeftArrowScript.
delegate Script to Toolbox.
delegate Evaluable to Toolbox.
replace const with _const.
L functionContainers;
new LinkedHashSet knownVars;
Map functionDefs = new Map;
// object can be a class
srecord MethodOnObject(O object, S method) {}
Script parse(S text) {
setText(text);
ret parseScript();
}
Script parseScript() {
new Script script;
script.functionDefs = functionDefs;
try {
parseScript_2(script);
ret script;
} catch e {
print("Parsed so far:\n" + script);
throw rethrowAndAppendToMessage(e, squareBracketed(str(lineAndColumn())));
}
}
void parseScript_2(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());
temp tempAddAll(knownVars, args);
print(+knownVars);
var functionBody = parseScript();
assertEquals("}", tpp());
functionDefs.put(functionName, new Toolbox.FunctionDef(functionName, args, functionBody));
continue;
}
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());
}
}
Evaluable parseOptionalInnerExpression() {
if (atCmdEnd()) null;
ret parseInnerExpr();
}
Evaluable const(O o) { ret new Toolbox.Const(o); }
Evaluable parseInnerExpr() { ret parseExpr(true); }
Evaluable parseExpr(bool inner default false) {
if (atEnd()) null;
if (is(";")) null;
S t = token();
// int or double literal
if (is("-") && empty(nextSpace()) && startsWithDigit(token(1))
|| startsWithDigit(t)) {
t = consumeUntilSpace();
print(+t);
ret isInteger(t) ? const(parseInt(t)) : const(parseDouble(t));
}
consume();
if (isQuoted(t))
ret const(unquote(t));
if (was("true")) ret const(true);
if (was("false")) ret const(false);
if (was("null")) ret const(null);
if (was("new")) {
S className = tpp();
O o = findExternalObject(className);
if (o cast Class)
ret new Toolbox.NewObject(o, parseExpressions());
fail("Class not found: " + className);
}
if (knownVars.contains(t)) {
var e = new Toolbox.GetVar(t);
ret inner ? e : parseCall(e);
}
if (!inner) {
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 (inner)
ret const(o);
else if (o cast Class) {
/*if (atCmdEnd())
ret new Toolbox.NewObject(o);*/
/* old object creation syntax (e.g. Pair new a b)
if (is("new")) {
next();
ret new Toolbox.NewObject(o, parseExpressions());
} else*/ if (isIdentifier()) {
S name = tpp();
if (hasMethodNamed(o, name))
ret new Toolbox.CallMethod(const(o), name, parseExpressions());
fail("Method named " + name + " not found in " + o);
} else
fail("Method name expected: " + token());
} else if (o cast MethodOnObject) {
if (inner) fail("Can't call methods in arguments");
ret new Toolbox.CallMethod(const(o.object), o.method, parseExpressions());
} else
ret parseCall(const(o));
}
L parseExpressions() {
ret collectWhileNotNull(-> parseOptionalInnerExpression());
}
bool atCmdEnd() { ret atEndOrLineBreak() || is(";") || 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) {
this.functionContainers = asList(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;
}
void printFunctionDefs {
print(values(functionDefs));
}
}