js-slang
Version:
Javascript-based implementations of Source, written in Typescript
374 lines • 16 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.listBuiltinFunctions = void 0;
const acorn_1 = require("acorn");
const ArrayExpression_1 = require("../nodes/Expression/ArrayExpression");
const ArrowFunctionExpression_1 = require("../nodes/Expression/ArrowFunctionExpression");
const FunctionApplication_1 = require("../nodes/Expression/FunctionApplication");
const Identifier_1 = require("../nodes/Expression/Identifier");
const Literal_1 = require("../nodes/Expression/Literal");
const BinaryExpression_1 = require("../nodes/Expression/BinaryExpression");
exports.listBuiltinFunctions = {
pair: {
definition: (args) => {
return new ArrayExpression_1.StepperArrayExpression([args[0], args[1]]);
},
arity: 2
},
is_pair: {
definition: (arg) => {
return new Literal_1.StepperLiteral(arg[0].type === 'ArrayExpression' && arg[0].elements.length == 2);
},
arity: 1
},
head: {
definition: (args) => {
return args[0].elements[0];
},
arity: 1
},
tail: {
definition: (args) => {
return args[0].elements[1];
},
arity: 1
},
is_null: {
definition: (arg) => {
return new Literal_1.StepperLiteral(arg[0].type === 'Literal' && arg[0].value === null);
},
arity: 1
},
is_list: {
definition: (arg) => {
const $is_list = (arg) => arg === null ||
(arg.type === 'Literal' && arg.value === null) ||
(arg.type === 'ArrayExpression' &&
arg.elements.length === 2 &&
$is_list(arg.elements[1]));
return new Literal_1.StepperLiteral($is_list(arg[0]));
},
arity: 1
},
draw_data: {
definition: (args) => {
return args[0];
},
arity: 0
},
equal: {
definition: (args) => {
const parsedProgram = (0, acorn_1.parse)(`
(xs, ys) => is_pair(xs)
? is_pair(ys) && equal(head(xs), head(ys)) && equal(tail(xs), tail(ys))
: is_null(xs) ? is_null(ys) : is_number(xs) ? is_number(ys) && xs === ys
: is_boolean(xs) ? is_boolean(ys) && (xs && ys || !xs && !ys)
: is_string(xs) ? is_string(ys) && xs === ys
: is_undefined(xs) ? is_undefined(ys)
: is_function(xs) ? is_function(ys) && xs === ys : fals
`, { ecmaVersion: 10 });
const parsedExpressionStatement = parsedProgram.body[0];
const parsedExpression = parsedExpressionStatement.expression;
return new FunctionApplication_1.StepperFunctionApplication(ArrowFunctionExpression_1.StepperArrowFunctionExpression.create(parsedExpression), args);
},
arity: 2
},
list: {
definition: (args) => {
if (args.length === 0) {
return new Literal_1.StepperLiteral(null);
}
return exports.listBuiltinFunctions.pair.definition([
args[0],
exports.listBuiltinFunctions.list.definition(args.slice(1))
]);
},
arity: 0
},
length: {
definition: (args) => {
return new FunctionApplication_1.StepperFunctionApplication(new Identifier_1.StepperIdentifier('$length'), [
...args,
new Literal_1.StepperLiteral(0)
]);
},
arity: 1
},
$length: {
definition: (args) => {
const parsedProgram = (0, acorn_1.parse)(`
(xs, acc) => is_null(xs) ? acc : $length(tail(xs), acc + 1);
`, { ecmaVersion: 10 });
const parsedExpressionStatement = parsedProgram.body[0];
const parsedExpression = parsedExpressionStatement.expression;
return new FunctionApplication_1.StepperFunctionApplication(ArrowFunctionExpression_1.StepperArrowFunctionExpression.create(parsedExpression), args);
},
arity: 2
},
build_list: {
definition: (args) => {
return new FunctionApplication_1.StepperFunctionApplication(new Identifier_1.StepperIdentifier('$build_list'), [
new BinaryExpression_1.StepperBinaryExpression('-', args[1], new Literal_1.StepperLiteral(1)),
args[0],
new Literal_1.StepperLiteral(null)
]);
},
arity: 2
},
$build_list: {
definition: (args) => {
const parsedProgram = (0, acorn_1.parse)(`
(i, fun, already_built) => i < 0 ? already_built : $build_list(i - 1, fun, pair(fun(i), already_built));`, { ecmaVersion: 10 });
const parsedExpressionStatement = parsedProgram.body[0];
const parsedExpression = parsedExpressionStatement.expression;
return new FunctionApplication_1.StepperFunctionApplication(ArrowFunctionExpression_1.StepperArrowFunctionExpression.create(parsedExpression), args);
},
arity: 3
},
for_each: {
definition: (args) => {
const parsedProgram = (0, acorn_1.parse)(` (fun, xs) =>
{
if (is_null(xs)) {
return true;
} else {
fun(head(xs));
return for_each(fun, tail(xs));
}
}
`, { ecmaVersion: 10 });
const parsedExpressionStatement = parsedProgram.body[0];
const parsedExpression = parsedExpressionStatement.expression;
return new FunctionApplication_1.StepperFunctionApplication(ArrowFunctionExpression_1.StepperArrowFunctionExpression.create(parsedExpression), args);
},
arity: 2
},
list_to_string: {
definition: (args) => {
return new FunctionApplication_1.StepperFunctionApplication(new Identifier_1.StepperIdentifier('$list_to_string'), [
args[0],
new ArrowFunctionExpression_1.StepperArrowFunctionExpression([new Identifier_1.StepperIdentifier('x')], new Identifier_1.StepperIdentifier('x'))
]);
},
arity: 1
},
$list_to_string: {
definition: (args) => {
const parsedProgram = (0, acorn_1.parse)(`
(xs, cont) => is_null(xs) ? cont("null") : is_pair(xs) ? $list_to_string(head(xs),
x => $list_to_string(tail(xs), y => cont("[" + x + "," + y + "]"))) : cont(stringify(xs))
`, { ecmaVersion: 10 });
const parsedExpressionStatement = parsedProgram.body[0];
const parsedExpression = parsedExpressionStatement.expression;
return new FunctionApplication_1.StepperFunctionApplication(ArrowFunctionExpression_1.StepperArrowFunctionExpression.create(parsedExpression), args);
},
arity: 2
},
append: {
definition: (args) => {
return new FunctionApplication_1.StepperFunctionApplication(new Identifier_1.StepperIdentifier('$append'), [
...args,
new ArrowFunctionExpression_1.StepperArrowFunctionExpression([new Identifier_1.StepperIdentifier('xs')], new Identifier_1.StepperIdentifier('xs'))
]);
},
arity: 2
},
$append: {
definition: (args) => {
const parsedProgram = (0, acorn_1.parse)(`
(xs, ys, cont) => is_null(xs) ? cont(ys) : $append(tail(xs), ys, zs => cont(pair(head(xs), zs)));
`, { ecmaVersion: 10 });
const parsedExpressionStatement = parsedProgram.body[0];
const parsedExpression = parsedExpressionStatement.expression;
return new FunctionApplication_1.StepperFunctionApplication(ArrowFunctionExpression_1.StepperArrowFunctionExpression.create(parsedExpression), args);
},
arity: 3
},
reverse: {
definition: (args) => {
return new FunctionApplication_1.StepperFunctionApplication(new Identifier_1.StepperIdentifier('$reverse'), [
...args,
new Literal_1.StepperLiteral(null)
]);
},
arity: 1
},
$reverse: {
definition: (args) => {
const parsedProgram = (0, acorn_1.parse)(`
(original, reversed) => is_null(original) ? reversed : $reverse(tail(original), pair(head(original), reversed));
`, { ecmaVersion: 10 });
const parsedExpressionStatement = parsedProgram.body[0];
const parsedExpression = parsedExpressionStatement.expression;
return new FunctionApplication_1.StepperFunctionApplication(ArrowFunctionExpression_1.StepperArrowFunctionExpression.create(parsedExpression), args);
},
arity: 2
},
member: {
definition: (args) => {
const parsedProgram = (0, acorn_1.parse)(`
(v, xs) => is_null(xs)
? null
: (v === head(xs))
? xs
: member(v, tail(xs));
`, { ecmaVersion: 10 });
const parsedExpressionStatement = parsedProgram.body[0];
const parsedExpression = parsedExpressionStatement.expression;
return new FunctionApplication_1.StepperFunctionApplication(ArrowFunctionExpression_1.StepperArrowFunctionExpression.create(parsedExpression), args);
},
arity: 2
},
remove: {
definition: (args) => {
return new FunctionApplication_1.StepperFunctionApplication(new Identifier_1.StepperIdentifier('$remove'), [
...args,
new Literal_1.StepperLiteral(null)
]);
},
arity: 2
},
$remove: {
definition: (args) => {
const parsedProgram = (0, acorn_1.parse)(`
(v, xs, acc) => is_null(xs)
? append(reverse(acc), xs)
: v === head(xs)
? append(reverse(acc), tail(xs))
: $remove(v, tail(xs), pair(head(xs), acc));
`, { ecmaVersion: 10 });
const parsedExpressionStatement = parsedProgram.body[0];
const parsedExpression = parsedExpressionStatement.expression;
return new FunctionApplication_1.StepperFunctionApplication(ArrowFunctionExpression_1.StepperArrowFunctionExpression.create(parsedExpression), args);
},
arity: 3
},
remove_all: {
definition: (args) => {
return new FunctionApplication_1.StepperFunctionApplication(new Identifier_1.StepperIdentifier('$remove_all'), [
...args,
new Literal_1.StepperLiteral(null)
]);
},
arity: 2
},
$remove_all: {
definition: (args) => {
const parsedProgram = (0, acorn_1.parse)(`
(v, xs, acc) => is_null(xs)
? append(reverse(acc), xs)
: v === head(xs)
? $remove_all(v, tail(xs), acc)
: $remove_all(v, tail(xs), pair(head(xs), acc));
`, { ecmaVersion: 10 });
const parsedExpressionStatement = parsedProgram.body[0];
const parsedExpression = parsedExpressionStatement.expression;
return new FunctionApplication_1.StepperFunctionApplication(ArrowFunctionExpression_1.StepperArrowFunctionExpression.create(parsedExpression), args);
},
arity: 3
},
enum_list: {
definition: (args) => {
return new FunctionApplication_1.StepperFunctionApplication(new Identifier_1.StepperIdentifier('$enum_list'), [
...args,
new Literal_1.StepperLiteral(null)
]);
},
arity: 2
},
$enum_list: {
definition: (args) => {
const parsedProgram = (0, acorn_1.parse)(`
(start, end, acc) => start > end
? reverse(acc)
: $enum_list(start + 1, end, pair(start, acc));
`, { ecmaVersion: 10 });
const parsedExpressionStatement = parsedProgram.body[0];
const parsedExpression = parsedExpressionStatement.expression;
return new FunctionApplication_1.StepperFunctionApplication(ArrowFunctionExpression_1.StepperArrowFunctionExpression.create(parsedExpression), args);
},
arity: 3
},
list_ref: {
definition: (args) => {
const parsedProgram = (0, acorn_1.parse)(`
(xs, n) => n === 0
? head(xs)
: list_ref(tail(xs), n - 1);
`, { ecmaVersion: 10 });
const parsedExpressionStatement = parsedProgram.body[0];
const parsedExpression = parsedExpressionStatement.expression;
return new FunctionApplication_1.StepperFunctionApplication(ArrowFunctionExpression_1.StepperArrowFunctionExpression.create(parsedExpression), args);
},
arity: 2
},
map: {
definition: (args) => {
return new FunctionApplication_1.StepperFunctionApplication(new Identifier_1.StepperIdentifier('$map'), [
...args,
new Literal_1.StepperLiteral(null)
]);
},
arity: 2
},
$map: {
definition: (args) => {
const parsedProgram = (0, acorn_1.parse)(`
(f, xs, acc) => is_null(xs) ? reverse(acc) : $map(f, tail(xs), pair(f(head(xs)), acc));
`, { ecmaVersion: 10 });
const parsedExpressionStatement = parsedProgram.body[0];
const parsedExpression = parsedExpressionStatement.expression;
return new FunctionApplication_1.StepperFunctionApplication(ArrowFunctionExpression_1.StepperArrowFunctionExpression.create(parsedExpression), args);
},
arity: 3
},
filter: {
definition: (args) => {
return new FunctionApplication_1.StepperFunctionApplication(new Identifier_1.StepperIdentifier('$filter'), [
...args,
new Literal_1.StepperLiteral(null)
]);
},
arity: 2
},
$filter: {
definition: (args) => {
const parsedProgram = (0, acorn_1.parse)(`
(pred, xs, acc) => is_null(xs) ? reverse(acc) : pred(head(xs)) ? $filter(pred, tail(xs), pair(head(xs), acc)) : $filter(pred, tail(xs), acc);
`, { ecmaVersion: 10 });
const parsedExpressionStatement = parsedProgram.body[0];
const parsedExpression = parsedExpressionStatement.expression;
return new FunctionApplication_1.StepperFunctionApplication(ArrowFunctionExpression_1.StepperArrowFunctionExpression.create(parsedExpression), args);
},
arity: 3
},
accumulate: {
definition: (args) => {
return new FunctionApplication_1.StepperFunctionApplication(new Identifier_1.StepperIdentifier('$accumulate'), [
...args,
new ArrowFunctionExpression_1.StepperArrowFunctionExpression([new Identifier_1.StepperIdentifier('x')], new Identifier_1.StepperIdentifier('x'))
]);
},
arity: 3
},
$accumulate: {
definition: (args) => {
const parsedProgram = (0, acorn_1.parse)(`
(f, initial, xs, cont) => is_null(xs)
? cont(initial)
: $accumulate(f, initial, tail(xs), x => cont(f(head(xs), x)));
`, { ecmaVersion: 10 });
const parsedExpressionStatement = parsedProgram.body[0];
const parsedExpression = parsedExpressionStatement.expression;
return new FunctionApplication_1.StepperFunctionApplication(ArrowFunctionExpression_1.StepperArrowFunctionExpression.create(parsedExpression), args);
},
arity: 4
},
display_list: {
definition: (args) => {
return args[0]; // x => x
},
arity: 1
}
};
//# sourceMappingURL=lists.js.map