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
// See GazelleV_LeftArrowScriptParser
// TODO: decide whether we allow calling methods/getting fields on
// a null reference (just returning null), or whether we throw a
// NullPointerException. Currently we just return null. Probably
// that's pretty cool. Null propagation as a default, just like in
// JavaX. Just more automatic!
sclass GazelleV_LeftArrowScript {
asclass Base is IHasTokenRangeWithSrc {
TokenRangeWithSrc src;
public void setTokenRangeWithSrc(TokenRangeWithSrc src) { this.src = src; }
public TokenRangeWithSrc tokenRangeWithSrc() { ret src; }
RuntimeException rethrowWithSrc(Throwable e) {
if (src != null)
throw rethrowAndAppendToMessage(e, squareBracketed(str(src)));
else
throw rethrow(e);
}
}
interface Evaluable {
public O get(VarContext ctx default new);
public default LASValueDescriptor returnType() { null; }
}
asclass BaseEvaluable > Base is Evaluable {
settable LASValueDescriptor returnType;
}
/*interface Cmd {
// returns true if a return was issued
public bool run(VarContext ctx default new);
}*/
static new AtomicLong scriptIDCounter;
static long scriptID() { ret incAtomicLong(scriptIDCounter); }
sclass Script is Evaluable {
long id = scriptID(); // just for printing
Map functionDefs;
Evaluable[] steps;
public O get(VarContext ctx) {
O result = null;
for (step : steps) {
ping();
result = step.get(ctx);
// exiting from anything?
var exiting = ctx.exitFromScript;
if (exiting != null) {
printVars ifdef ReturnFromScript_debug("Checking exitFromScript",
+ctx, +exiting, script := this);
// we're the exit point
if (exiting == this)
ctx.exitFromScript = null;
// exit further
break;
}
}
ret result;
}
S toStringLong() { ret pnlToLines(steps); }
toString { ret "Script " + n2(id); }
FunctionDef getFunction(S name) { ret mapGet(functionDefs, name); }
} // end of Script
srecord noeq FunctionDef(S name, LS args, Evaluable body) > Base {
public O call(VarContext ctx, O... args) {
var ctx2 = new VarContext(ctx);
int n = min(l(args), l(this.args));
for i to n:
ctx2.put(this.args.get(i), args[i]);
print ifdef GazelleV_LeftArrowScript_debug(ctx2 := ctx2.vars);
ret body.get(ctx2);
}
}
srecord noeq Assignment(S var, Evaluable expression) > Base is Evaluable {
public O get(VarContext ctx) {
O o = expression.get(ctx);
ctx.set(var, o);
ret o;
}
toString { ret var + " <- " + expression; }
}
persistable sclass NewObject > Base is Evaluable {
Class c;
L args;
*(Class *c) {}
*(Class *c, L *args) {}
public O get(VarContext ctx) {
ret callConstructor(c, mapToArray(args, arg -> arg.get(ctx)));
}
toString { ret "new " + formatFunctionCall(className(c), args); }
}
srecord noeq CallFunction(FunctionDef f, L args) > Base is Evaluable {
public O get(VarContext ctx) {
//ping();
ret f.call(ctx, mapToArray(args, a -> a.get(ctx));
}
toString { ret formatFunctionCall(f.name, args); }
}
srecord noeq GetVar(S var) > BaseEvaluable {
public O get(VarContext ctx) {
ret ctx.get(var);
}
toString { ret var; }
}
srecord noeq Const(O value) > Base is Evaluable {
public O get(VarContext ctx) {
ret value;
}
toString { ret strOrClassName(value); }
public LASValueDescriptor returnType() {
ret new LASValueDescriptor.KnownValue(value);
}
}
srecord noeq GetStaticField(Field field) > Base is Evaluable {
public O get(VarContext ctx) ctex {
ret field.get(null);
}
}
srecord noeq CallMethodOrGetField(Evaluable target, S name) > Base is Evaluable {
public O get(VarContext ctx) {
try {
O object = target.get(ctx);
if (object == null)
null; // throw new NullPointerException();
// could optimize more for sure
if (canCallWithVarargs(object, name))
ret call(object, name);
ret _get(object, name);
} catch e {
throw rethrowWithSrc(e);
}
}
}
srecord ThrowMethodNotFoundException(CallMethod instruction) > Base is Evaluable {
public O get(VarContext ctx) {
fail("Method not found: " + instruction);
}
}
srecord ThrowNullPointerException(CallMethod instruction) > Base is Evaluable {
public O get(VarContext ctx) {
fail("Null pointer exception: " + instruction);
}
}
srecord CallMethod(Evaluable target, S methodName, L args) > Base is Evaluable {
public O get(VarContext ctx) {
ret call(target.get(ctx), methodName, mapToArray(args, arg -> arg.get(ctx)));
}
toString { ret target + "." + formatFunctionCall(methodName, args);
Evaluable optimize() {
var targetType = target.returnType();
if (targetType.knownValue()) {
O o = targetType.value();
if (o == null) ret new ThrowNullPointerException(this);
Class[] argTypes = new[l(args)];
for i over args: {
var type = args.get(i).returnType();
if (!type.javaClassIsExact())
this;
argTypes[i] = type.javaClass();
}
// TODO: varargs
var method = findMethod_precise_onTypes(o, methodName, argTypes);
if (method == null) ret new ThrowMethodNotFoundException(this);
ret new DirectMethodCallOnKnownTarget(target instanceof Class ? null : target, method, args);
}
this;
}
}
srecord DirectMethodCallOnKnownTarget(O target, Method method, L args) > Base is Evaluable {
public O get(VarContext ctx) {
ret invokeMethod(method, target, mapToArray(args, arg -> arg.get(ctx)));
}
public LASValueDescriptor returnType() {
ret LASValueDescriptor.fromClass(method.getReturnType());
}
}
srecord While(Evaluable condition, Evaluable body) > Base is Evaluable {
public O get(VarContext ctx) {
while (ping() && (Bool) condition.get(ctx)) {
body.get(ctx);
}
// while loops don't return anything
null;
}
}
srecord ForEach(Evaluable collection, S var, Evaluable body) > Base is Evaluable {
public O get(VarContext ctx) {
var coll = collection.get(ctx);
Iterator iterator;
if (coll cast O[])
for (element : coll) {
ping();
ctx.set(var, element);
body.get(ctx);
}
else if (coll cast Iterable) {
for (element : coll) {
ping();
ctx.set(var, element);
body.get(ctx);
}
} else if (coll == null) {} // ok
else
fail("Not iterable: " + className(coll));
ctx.unset(var);
null;
}
}
srecord IfThen(Evaluable condition, Evaluable body) > Base is Evaluable {
public O get(VarContext ctx) {
if ((Bool) condition.get(ctx))
ret body.get(ctx);
else
null;
}
}
srecord ReturnFromScript(Script script, Evaluable value) > Base is Evaluable {
public O get(VarContext ctx) {
O result = value.get(ctx);
printVars ifdef ReturnFromScript_debug("ReturnFromScript",
+result, +ctx, +script);
ctx.exitFromScript(script);
ret result;
}
toString {
ret formatFunctionCall ReturnFromScript(script, value);
}
}
}