@rbxts/insitux
Version:
Extensible s-expression scripting language enabling players to safely mod Roblox games themselves.
201 lines (200 loc) • 4.99 kB
TypeScript
export type Val = {
t: "vec";
v: Val[];
} | {
t: "str" | "func" | "key" | "ref" | "unm";
v: string;
} | {
t: "null";
v: undefined;
} | {
t: "wild";
v: undefined;
} | {
t: "bool";
v: boolean;
} | {
t: "num";
v: number;
} | {
t: "clo";
v: Func;
} | {
t: "dict";
v: Dict;
} | {
t: "ext";
v: unknown;
};
export type ErrCtx = {
invokeId: string;
line: number;
col: number;
};
export type InvokeError = {
e: string;
m: string;
errCtx: ErrCtx;
};
export type ValOrErr = Val | {
err: string;
};
/**
* @summary "empty" occurs when there was only function declaration;
* "val" occurs when there were no errors and there is a final value;
* "errors" occurs when there were any errors.
*/
export type InvokeResult = {
kind: "empty";
} | Val | {
kind: "errors";
errors: InvokeError[];
};
export type Dict = {
keys: Val[];
vals: Val[];
};
export type Func = {
name?: string;
ins: Ins[];
};
export type Funcs = {
[key: string]: Func;
};
export type Env = {
funcs: Funcs;
vars: {
[key: string]: Val;
};
mocks: {
[key: string]: Val;
};
};
/** A context supplied with an Insitux invocation to provide its environment. */
export type Ctx = {
/** Called to set an external variable, returning nothing or an error. */
set?: (key: string, val: Val) => undefined | string;
/** Called to retrieve an external variable,
* returning the value or an error. */
get?: (key: string) => ValOrErr;
/** Called to print data out of Insitux. */
print: (str: string, withNewline: boolean) => void;
/** Extra function definitions to make available within this invocation */
functions: ExternalFunctions;
/** Called when Insitux cannot find a function definition otherwise.
* You should return an error if unknown externally too. */
exe?: (name: string, args: Val[]) => ValOrErr;
/** Function and variable definitions, retained by you for each invocation. */
env: Env;
/** The number of loops an invocation is permitted. */
loopBudget: number;
/** The total length of all `range` calls permitted. */
rangeBudget: number;
/** The total number of function calls permitted. */
callBudget: number;
/** The total number of explicit recursions permitted.
* Explicit recursions are unlikely to cause a stack-overflow,
* rather this effectively limits the time an Insitux program may hang for. */
recurBudget: number;
};
export declare const defaultCtx: {
env: {
funcs: {};
vars: {};
mocks: {};
};
loopBudget: number;
rangeBudget: number;
callBudget: number;
recurBudget: number;
};
export type ParamsShape = {
name: string;
position: number[];
}[];
export type Closure = {
readonly name: string;
readonly length: number;
captures: boolean[];
derefs: Ins[];
};
export type Ins = {
errCtx: ErrCtx;
} & ({
typ: "var" | "let" | "ref";
value: string;
} | {
typ: "npa" | "upa";
value: number;
text: string;
} | {
typ: "dpa";
value: number[];
} | {
typ: "dva" | "dle";
value: ParamsShape;
} | {
typ: "exe";
value: number;
} | {
typ: "exa";
value: number;
} | {
typ: "or" | "if" | "jmp" | "loo" | "cat" | "mat" | "sat";
value: number;
} | {
typ: "ret";
value: boolean;
} | {
typ: "pop";
value: number;
} | {
typ: "clo";
value: Closure;
} | {
typ: "val";
value: Val;
});
/** Definition of an operation in Insitux,
* with guarantees made for arity (number of parameters) and parameter types.
* Return type is specified to inform the parse-time type-checker. */
export type Operation = {
minArity?: number;
maxArity?: number;
exactArity?: number;
/** Does the function cause side-effects when used? */
hasEffects?: boolean;
numeric?: true | "in only";
params?: ("any" | Val["t"] | Val["t"][])[];
returns?: [Val["t"], ...Val["t"][]];
};
export type ExternalHandler = (params: Val[], errCtx: ErrCtx) => ValOrErr | void;
export type ExternalFunction = {
definition: Operation;
handler: ExternalHandler;
};
export type ExternalFunctions = {
[name: string]: ExternalFunction;
};
export declare const ops: {
[name: string]: Operation & {
external?: boolean;
};
};
export declare const syntaxes: string[];
export declare const typeNames: {
null: string;
str: string;
num: string;
bool: string;
key: string;
ref: string;
vec: string;
dict: string;
func: string;
clo: string;
wild: string;
ext: string;
unm: string;
};
export declare const assertUnreachable: (_x: never) => never;