@tsukiroku/tiny
Version:
Tiny interpreter
226 lines (225 loc) • 8.65 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.builtin = void 0;
const Tiny = __importStar(require("../../index"));
const importEnviroment = (parameters, enviroment, evaluator, position) => {
if (parameters.length !== 1 || parameters[0]?.kind !== 301 /* Tiny.ObjectKind.STRING */)
return Tiny.invalidArgument(position, evaluator.option);
return evaluator.importEnv(parameters[0].value, enviroment, evaluator, position);
};
const length = (parameters) => {
if (parameters.length !== 1 ||
(parameters[0]?.kind !== 303 /* Tiny.ObjectKind.ARRAY */ &&
parameters[0]?.kind !== 304 /* Tiny.ObjectKind.OBJECT */ &&
parameters[0]?.kind !== 301 /* Tiny.ObjectKind.STRING */))
return Tiny.NULL;
if (parameters[0]?.kind === 303 /* Tiny.ObjectKind.ARRAY */)
return {
kind: 300 /* Tiny.ObjectKind.NUMBER */,
value: parameters[0].value.length,
};
if (parameters[0]?.kind === 301 /* Tiny.ObjectKind.STRING */)
return {
kind: 300 /* Tiny.ObjectKind.NUMBER */,
value: parameters[0].value.length,
};
return {
kind: 300 /* Tiny.ObjectKind.NUMBER */,
value: parameters[0].pairs.size,
};
};
const evalCode = (parameters, enviroment, evaluator, position) => {
if (parameters.length !== 1 || parameters[0]?.kind !== 301 /* Tiny.ObjectKind.STRING */)
return Tiny.invalidArgument(position, evaluator.option);
if (!evaluator.option.allowEval)
return {
kind: 308 /* Tiny.ObjectKind.ERROR */,
message: Tiny.localization(evaluator.option).builtinError.disableAllowEval,
...position,
};
return new Tiny.Evaluator(new Tiny.Parser(new Tiny.Lexer(parameters[0].value, {
...evaluator.option,
stderr: evaluator.option.stdio.stderr,
}, evaluator.option.filename), evaluator.option).parseProgram(), enviroment, evaluator.option).eval();
};
const evalJSCode = (parameters, enviroment, evaluator, position) => {
if (parameters.length !== 1 || parameters[0]?.kind !== 301 /* Tiny.ObjectKind.STRING */)
return Tiny.invalidArgument(position, evaluator.option);
if (!evaluator.option.allowJavaScript)
return {
kind: 308 /* Tiny.ObjectKind.ERROR */,
message: evaluator.messages.builtinError.disableAllowJavaScript,
...position,
};
try {
return eval(parameters[0].value);
}
catch (e) {
if (e instanceof Error)
return {
kind: 308 /* Tiny.ObjectKind.ERROR */,
message: Tiny.errorFormatter(evaluator.messages.builtinError.couldNotEval, e.message),
...position,
};
return {
kind: 308 /* Tiny.ObjectKind.ERROR */,
message: Tiny.errorFormatter(evaluator.messages.builtinError.couldNotEval, `${e}`),
...position,
};
}
};
const toString = (parameters, enviroment, evaluator, position) => {
if (parameters.length !== 1)
return Tiny.invalidArgument(position, evaluator.option);
return {
kind: 301 /* Tiny.ObjectKind.STRING */,
value: Tiny.objectStringify(parameters[0]),
};
};
const toNumber = (parameters, enviroment, evaluator, position) => {
if (parameters.length !== 1)
return Tiny.invalidArgument(position, evaluator.option);
switch (parameters[0]?.kind) {
case 300 /* Tiny.ObjectKind.NUMBER */:
return parameters[0];
case 302 /* Tiny.ObjectKind.BOOLEAN */:
return {
kind: 300 /* Tiny.ObjectKind.NUMBER */,
value: parameters[0].value ? 1 : 0,
};
case 301 /* Tiny.ObjectKind.STRING */:
const num = Number(parameters[0]?.value);
return isNaN(num) ? Tiny.NULL : { kind: 300 /* Tiny.ObjectKind.NUMBER */, value: num };
default:
return Tiny.NULL;
}
};
const toBoolean = (parameters, enviroment, evaluator, position) => {
if (parameters.length !== 1)
return Tiny.invalidArgument(position, evaluator.option);
switch (parameters[0]?.kind) {
case 302 /* Tiny.ObjectKind.BOOLEAN */:
return {
kind: 302 /* Tiny.ObjectKind.BOOLEAN */,
value: parameters[0].value,
};
case 300 /* Tiny.ObjectKind.NUMBER */:
return {
kind: 302 /* Tiny.ObjectKind.BOOLEAN */,
value: parameters[0].value !== 0,
};
case 301 /* Tiny.ObjectKind.STRING */:
return {
kind: 302 /* Tiny.ObjectKind.BOOLEAN */,
value: parameters[0].value !== '',
};
default:
return Tiny.NULL;
}
};
const toArray = (parameters, enviroment, evaluator, position) => {
if (parameters.length !== 1)
return Tiny.invalidArgument(position, evaluator.option);
switch (parameters[0]?.kind) {
case 303 /* Tiny.ObjectKind.ARRAY */:
return parameters[0];
case 304 /* Tiny.ObjectKind.OBJECT */:
return {
kind: 303 /* Tiny.ObjectKind.ARRAY */,
value: [...parameters[0].pairs.values()],
};
case 301 /* Tiny.ObjectKind.STRING */:
return {
kind: 303 /* Tiny.ObjectKind.ARRAY */,
value: parameters[0].value.split('').map((v) => ({
kind: 301 /* Tiny.ObjectKind.STRING */,
value: v,
})),
};
default:
return Tiny.NULL;
}
};
const options = (parameters, enviroment, evaluator) => {
return {
kind: 304 /* Tiny.ObjectKind.OBJECT */,
pairs: new Map(Object.entries(evaluator.option).map(([key, value]) => [
{
kind: 301 /* Tiny.ObjectKind.STRING */,
value: key,
},
typeof value === 'string'
? {
kind: 301 /* Tiny.ObjectKind.STRING */,
value: value,
}
: {
kind: 302 /* Tiny.ObjectKind.BOOLEAN */,
value: value,
},
])),
};
};
const rootDir = (parameters, enviroment, evaluator) => ({
kind: 301 /* Tiny.ObjectKind.STRING */,
value: evaluator.option.root,
});
const curr = (parameters, enviroment, evaluator, position) => ({
kind: 304 /* Tiny.ObjectKind.OBJECT */,
pairs: new Map([
[
{ kind: 301 /* Tiny.ObjectKind.STRING */, value: 'line' },
{ kind: 300 /* Tiny.ObjectKind.NUMBER */, value: position.line },
],
[
{ kind: 301 /* Tiny.ObjectKind.STRING */, value: 'column' },
{ kind: 300 /* Tiny.ObjectKind.NUMBER */, value: position.column },
],
]),
});
const filename = (parameters, enviroment, evaluator) => ({
kind: 301 /* Tiny.ObjectKind.STRING */,
value: evaluator.option.filename,
});
const enviromentLength = (parameters, enviroment) => ({
kind: 300 /* Tiny.ObjectKind.NUMBER */,
value: enviroment.store.size,
});
exports.builtin = new Map([
['import', importEnviroment],
['eval', evalCode],
['js', evalJSCode],
['to_s', toString],
['to_n', toNumber],
['to_b', toBoolean],
['to_a', toArray],
['options', options],
['__builtin_length', length],
['__root', rootDir],
['__pos', curr],
['__filename', filename],
['__env_store_length', enviromentLength],
]);