Skip to content

Instantly share code, notes, and snippets.

@qoh
Last active May 11, 2020 04:50
Show Gist options
  • Save qoh/6e2eed286b85eb60ea01 to your computer and use it in GitHub Desktop.
Save qoh/6e2eed286b85eb60ea01 to your computer and use it in GitHub Desktop.
function isInfinity(%value)
{
return strcmp(%value, "-1.#INF") == 0 || strcmp(%value, "1.#INF") == 0;
}
function isNaN(%value)
{
return strcmp(%value, "-1.#IND") == 0;
}
function isFloat(%value)
{
return strcmp(%value, %value + 0) == 0 || isInfinity(%value) || isNaN(%value);
}
function isInteger(%value)
{
return strcmp(%value, %value | 0) == 0;
}
function isNumber(%value)
{
return isInteger(%value) || isFloat(%value);
}
function toRepr(%value, %maxDepth, %depth)
{
if (%maxDepth $= "")
%maxDepth = 3;
if (%depth > %maxDepth)
return "...";
// Duplicating implementation of above
// is...() functions for simplicity & speed.
if (strcmp(%value, %value | 0) == 0)
{
if (isObject(%value) && %value.getID() == %value)
return %value.toRepr(%depth);
return %value;
}
if (strcmp(%value, "-1.#IND") == 0) return "NaN";
if (strcmp(%value, "-1.#INF") == 0) return "-Infinity";
if (strcmp(%value, "1.#INF") == 0) return "Infinity";
if (strcmp(%value, %value + 0) == 0) return %value;
return "\"" @ expandEscape(%value) @ "\"";
}
function toString(%value)
{
if (isObject(%value) && strcmp(%value.getID(), %value) == 0)
return %value.toString();
return %value;
}
// ===========================================================================
// Generic/global metaprogramming
function callDynamic(%name,
%a0, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9,
%a10, %a11, %a12, %a13, %a14, %a15, %a16, %a17)
{
for (%args = 18; %args > 0; %args--)
{
if (%a[%args - 1] !$= "")
break;
}
return callArgs(%name, %args,
%a0, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9,
%a10, %a11, %a12, %a13, %a14, %a15, %a16, %a17);
}
function callArgs(%name, %args,
%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k,%l,%m,%n,%o,%p,%q,%r)
{
// This looks really ugly but it's worth it to avoid building an argument string.
switch (%args)
{
case 0: return call(%name);
case 1: return call(%name,%a);
case 2: return call(%name,%a,%b);
case 3: return call(%name,%a,%b,%c);
case 4: return call(%name,%a,%b,%c,%d);
case 5: return call(%name,%a,%b,%c,%d,%e);
case 6: return call(%name,%a,%b,%c,%d,%e,%f);
case 7: return call(%name,%a,%b,%c,%d,%e,%f,%g);
case 8: return call(%name,%a,%b,%c,%d,%e,%f,%g,%h);
case 9: return call(%name,%a,%b,%c,%d,%e,%f,%g,%h,%i);
case 10: return call(%name,%a,%b,%c,%d,%e,%f,%g,%h,%i,%j);
case 11: return call(%name,%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k);
case 12: return call(%name,%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k,%l);
case 13: return call(%name,%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k,%l,%m);
case 14: return call(%name,%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k,%l,%m,%n);
case 15: return call(%name,%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k,%l,%m,%n,%o);
case 16: return call(%name,%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k,%l,%m,%n,%o,%p);
case 17: return call(%name,%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k,%l,%m,%n,%o,%p,%q);
default: return call(%name,%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k,%l,%m,%n,%o,%p,%q,%r);
}
}
function getVariable(%name)
{
switch (stripos("_abcdefghijklmnopqrstuvwxyz", getSubStr(%name, 0, 1)))
{
case 0: return $_[getSubStr(%name, 1, strlen(%name))];
case 1: return $a[getSubStr(%name, 1, strlen(%name))];
case 2: return $b[getSubStr(%name, 1, strlen(%name))];
case 3: return $c[getSubStr(%name, 1, strlen(%name))];
case 4: return $d[getSubStr(%name, 1, strlen(%name))];
case 5: return $e[getSubStr(%name, 1, strlen(%name))];
case 6: return $f[getSubStr(%name, 1, strlen(%name))];
case 7: return $g[getSubStr(%name, 1, strlen(%name))];
case 8: return $h[getSubStr(%name, 1, strlen(%name))];
case 9: return $i[getSubStr(%name, 1, strlen(%name))];
case 10: return $j[getSubStr(%name, 1, strlen(%name))];
case 11: return $k[getSubStr(%name, 1, strlen(%name))];
case 12: return $l[getSubStr(%name, 1, strlen(%name))];
case 13: return $m[getSubStr(%name, 1, strlen(%name))];
case 14: return $n[getSubStr(%name, 1, strlen(%name))];
case 15: return $o[getSubStr(%name, 1, strlen(%name))];
case 16: return $p[getSubStr(%name, 1, strlen(%name))];
case 17: return $q[getSubStr(%name, 1, strlen(%name))];
case 18: return $r[getSubStr(%name, 1, strlen(%name))];
case 19: return $s[getSubStr(%name, 1, strlen(%name))];
case 20: return $t[getSubStr(%name, 1, strlen(%name))];
case 21: return $u[getSubStr(%name, 1, strlen(%name))];
case 22: return $v[getSubStr(%name, 1, strlen(%name))];
case 23: return $w[getSubStr(%name, 1, strlen(%name))];
case 24: return $x[getSubStr(%name, 1, strlen(%name))];
case 25: return $y[getSubStr(%name, 1, strlen(%name))];
case 26: return $z[getSubStr(%name, 1, strlen(%name))];
default: return "";
}
}
function setVariable(%name, %value)
{
switch (stripos("_abcdefghijklmnopqrstuvwxyz", getSubStr(%name, 0, 1)))
{
case 0: $_[getSubStr(%name, 1, strlen(%name))] = %value;
case 1: $a[getSubStr(%name, 1, strlen(%name))] = %value;
case 2: $b[getSubStr(%name, 1, strlen(%name))] = %value;
case 3: $c[getSubStr(%name, 1, strlen(%name))] = %value;
case 4: $d[getSubStr(%name, 1, strlen(%name))] = %value;
case 5: $e[getSubStr(%name, 1, strlen(%name))] = %value;
case 6: $f[getSubStr(%name, 1, strlen(%name))] = %value;
case 7: $g[getSubStr(%name, 1, strlen(%name))] = %value;
case 8: $h[getSubStr(%name, 1, strlen(%name))] = %value;
case 9: $i[getSubStr(%name, 1, strlen(%name))] = %value;
case 10: $j[getSubStr(%name, 1, strlen(%name))] = %value;
case 11: $k[getSubStr(%name, 1, strlen(%name))] = %value;
case 12: $l[getSubStr(%name, 1, strlen(%name))] = %value;
case 13: $m[getSubStr(%name, 1, strlen(%name))] = %value;
case 14: $n[getSubStr(%name, 1, strlen(%name))] = %value;
case 15: $o[getSubStr(%name, 1, strlen(%name))] = %value;
case 16: $p[getSubStr(%name, 1, strlen(%name))] = %value;
case 17: $q[getSubStr(%name, 1, strlen(%name))] = %value;
case 18: $r[getSubStr(%name, 1, strlen(%name))] = %value;
case 19: $s[getSubStr(%name, 1, strlen(%name))] = %value;
case 20: $t[getSubStr(%name, 1, strlen(%name))] = %value;
case 21: $u[getSubStr(%name, 1, strlen(%name))] = %value;
case 22: $v[getSubStr(%name, 1, strlen(%name))] = %value;
case 23: $w[getSubStr(%name, 1, strlen(%name))] = %value;
case 24: $x[getSubStr(%name, 1, strlen(%name))] = %value;
case 25: $y[getSubStr(%name, 1, strlen(%name))] = %value;
case 26: $z[getSubStr(%name, 1, strlen(%name))] = %value;
}
}
// ===========================================================================
// Object related metaprogramming
function SimObject::assignFieldsFrom(%this, %object)
{
for (%i = 0; (%tag = %object.getTaggedField(%i)) !$= ""; %i++)
%this.setAttribute(getField(%tag, 0), getFields(%tag, 1, getFieldCount(%tag)));
}
function SimObject::clone(%this)
{
%name = %this.getName();
%this.setName("__CloneTarget");
%copy = new (%this.getClassName())(%name : __CloneTarget);
%this.setName(%name);
return %copy;
}
function SimObject::isMethod(%this, %name)
{
%className = %this.getClassName();
return
(%className $= "ScriptObject" || %className $= "ScriptGroup" ?
isFunction(%this.class, %name) ||
isFunction(%this.superClass, %name)
: 0) ||
//(getSubStr(%className, strlen(%className) - 4, 4) $= "Data" ?
// isFunction(%this.className, %name) : 0) ||
isFunction(%this.getName(), %name) ||
isFunction(%this.getClassName(), %name) ||
isFunction("SimObject", %name);
}
function SimObject::callDynamic(%this, %name,
%a0, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9,
%a10, %a11, %a12, %a13, %a14, %a15, %a16)
{
for (%args = 17; %args > 0; %args--)
{
if (%a[%args - 1] !$= "")
break;
}
return %this.callArgs(%name, %args,
%a0, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9,
%a10, %a11, %a12, %a13, %a14, %a15, %a16);
}
function SimObject::callArgs(%this, %name, %args,
%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k,%l,%m,%n,%o,%p,%q)
{
// This looks really ugly but it's worth it to avoid building an argument string.
switch (%args)
{
case 0: return eval("return %this." @ %name @ "();");
case 1: return eval("return %this." @ %name @ "(%a);");
case 2: return eval("return %this." @ %name @ "(%a,%b);");
case 3: return eval("return %this." @ %name @ "(%a,%b,%c);");
case 4: return eval("return %this." @ %name @ "(%a,%b,%c,%d);");
case 5: return eval("return %this." @ %name @ "(%a,%b,%c,%d,%e);");
case 6: return eval("return %this." @ %name @ "(%a,%b,%c,%d,%e,%f);");
case 7: return eval("return %this." @ %name @ "(%a,%b,%c,%d,%e,%f,%g);");
case 8: return eval("return %this." @ %name @ "(%a,%b,%c,%d,%e,%f,%g,%h);");
case 9: return eval("return %this." @ %name @ "(%a,%b,%c,%d,%e,%f,%g,%h,%i);");
case 10: return eval("return %this." @ %name @ "(%a,%b,%c,%d,%e,%f,%g,%h,%i,%j);");
case 11: return eval("return %this." @ %name @ "(%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k);");
case 12: return eval("return %this." @ %name @ "(%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k,%l);");
case 13: return eval("return %this." @ %name @ "(%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k,%l,%m);");
case 14: return eval("return %this." @ %name @ "(%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k,%l,%m,%n);");
case 15: return eval("return %this." @ %name @ "(%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k,%l,%m,%n,%o);");
case 16: return eval("return %this." @ %name @ "(%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k,%l,%m,%n,%o,%p);");
default: return eval("return %this." @ %name @ "(%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k,%l,%m,%n,%o,%p,%q);");
}
}
function SimObject::call(%this, %name,
%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k,%l,%m,%n,%o,%p,%q,%r)
{
return eval("return %this." @ %name @
"(%a,%b,%c,%d,%e,%f,%g,%h,%i,%j,%k,%l,%m,%n,%o,%p,%q,%r);");
}
function SimObject::getField(%this, %name)
{
switch (stripos("_abcdefghijklmnopqrstuvwxyz", getSubStr(%name, 0, 1)))
{
case 0: return %this._[getSubStr(%name, 1, strlen(%name))];
case 1: return %this.a[getSubStr(%name, 1, strlen(%name))];
case 2: return %this.b[getSubStr(%name, 1, strlen(%name))];
case 3: return %this.c[getSubStr(%name, 1, strlen(%name))];
case 4: return %this.d[getSubStr(%name, 1, strlen(%name))];
case 5: return %this.e[getSubStr(%name, 1, strlen(%name))];
case 6: return %this.f[getSubStr(%name, 1, strlen(%name))];
case 7: return %this.g[getSubStr(%name, 1, strlen(%name))];
case 8: return %this.h[getSubStr(%name, 1, strlen(%name))];
case 9: return %this.i[getSubStr(%name, 1, strlen(%name))];
case 10: return %this.j[getSubStr(%name, 1, strlen(%name))];
case 11: return %this.k[getSubStr(%name, 1, strlen(%name))];
case 12: return %this.l[getSubStr(%name, 1, strlen(%name))];
case 13: return %this.m[getSubStr(%name, 1, strlen(%name))];
case 14: return %this.n[getSubStr(%name, 1, strlen(%name))];
case 15: return %this.o[getSubStr(%name, 1, strlen(%name))];
case 16: return %this.p[getSubStr(%name, 1, strlen(%name))];
case 17: return %this.q[getSubStr(%name, 1, strlen(%name))];
case 18: return %this.r[getSubStr(%name, 1, strlen(%name))];
case 19: return %this.s[getSubStr(%name, 1, strlen(%name))];
case 20: return %this.t[getSubStr(%name, 1, strlen(%name))];
case 21: return %this.u[getSubStr(%name, 1, strlen(%name))];
case 22: return %this.v[getSubStr(%name, 1, strlen(%name))];
case 23: return %this.w[getSubStr(%name, 1, strlen(%name))];
case 24: return %this.x[getSubStr(%name, 1, strlen(%name))];
case 25: return %this.y[getSubStr(%name, 1, strlen(%name))];
case 26: return %this.z[getSubStr(%name, 1, strlen(%name))];
default: return "";
}
}
function SimObject::setField(%this, %name, %value)
{
switch (stripos("_abcdefghijklmnopqrstuvwxyz", getSubStr(%name, 0, 1)))
{
case 0: %this._[getSubStr(%name, 1, strlen(%name))] = %value;
case 1: %this.a[getSubStr(%name, 1, strlen(%name))] = %value;
case 2: %this.b[getSubStr(%name, 1, strlen(%name))] = %value;
case 3: %this.c[getSubStr(%name, 1, strlen(%name))] = %value;
case 4: %this.d[getSubStr(%name, 1, strlen(%name))] = %value;
case 5: %this.e[getSubStr(%name, 1, strlen(%name))] = %value;
case 6: %this.f[getSubStr(%name, 1, strlen(%name))] = %value;
case 7: %this.g[getSubStr(%name, 1, strlen(%name))] = %value;
case 8: %this.h[getSubStr(%name, 1, strlen(%name))] = %value;
case 9: %this.i[getSubStr(%name, 1, strlen(%name))] = %value;
case 10: %this.j[getSubStr(%name, 1, strlen(%name))] = %value;
case 11: %this.k[getSubStr(%name, 1, strlen(%name))] = %value;
case 12: %this.l[getSubStr(%name, 1, strlen(%name))] = %value;
case 13: %this.m[getSubStr(%name, 1, strlen(%name))] = %value;
case 14: %this.n[getSubStr(%name, 1, strlen(%name))] = %value;
case 15: %this.o[getSubStr(%name, 1, strlen(%name))] = %value;
case 16: %this.p[getSubStr(%name, 1, strlen(%name))] = %value;
case 17: %this.q[getSubStr(%name, 1, strlen(%name))] = %value;
case 18: %this.r[getSubStr(%name, 1, strlen(%name))] = %value;
case 19: %this.s[getSubStr(%name, 1, strlen(%name))] = %value;
case 20: %this.t[getSubStr(%name, 1, strlen(%name))] = %value;
case 21: %this.u[getSubStr(%name, 1, strlen(%name))] = %value;
case 22: %this.v[getSubStr(%name, 1, strlen(%name))] = %value;
case 23: %this.w[getSubStr(%name, 1, strlen(%name))] = %value;
case 24: %this.x[getSubStr(%name, 1, strlen(%name))] = %value;
case 25: %this.y[getSubStr(%name, 1, strlen(%name))] = %value;
case 26: %this.z[getSubStr(%name, 1, strlen(%name))] = %value;
}
}
function SimObject::toRepr(%this, %maxDepth, %depth)
{
%className = %this.getClassName();
if ((%className $= "ScriptObject" || %className $= "ScriptGroup") &&
%this.class !$= "")
%className = %this.class;
return %className SPC %this.getName() @ "(" @ %this.getID() @ ")";
}
function SimObject::toString(%this)
{
return %this.toRepr(3, 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment