0.16.0 • Published 5 months ago

kenpali v0.16.0

Weekly downloads
-
License
MIT
Repository
github
Last release
5 months ago

Kenpali

THIS PACKAGE IS EXPERIMENTAL AND ANY PART OF IT MAY CHANGE AT ANY TIME. DO NOT USE IT FOR ANYTHING THAT MATTERS.

This is an implementation of the Kenpali minimalistic programming language in JavaScript.

Installation

Kenpali is available as an npm package. You can install it with

npm install --save-exact kenpali@0.13.0

Pinning the exact version is highly recommended, given that this package is still experimental and routinely makes backward-incompatible changes.

Usage

Evaluating Kenpali Expressions

This package's main exports are kpparse, which converts Kenpali Code to Kenpali JSON, and kpeval, which evaluates a Kenpali JSON expression. So the following function evaluates a Kenpali Code expression:

import { kpeval, kpparse } from "kenpali";

function evalKenpaliCode(code) {
  const json = kpparse(code);
  return kpeval(json);
}

To protect against infinite loops or runaway computations, you can set a time limit on kpeval:

import { kpeval, kpparse } from "kenpali";

function evalKenpaliCode(code) {
  const json = kpparse(code);
  return kpeval(json, { timeLimitSeconds: 10 });
}

If the computation takes more than 10 seconds, it will stop and return a timeLimitExceeded error.

Calling Kenpali functions from JavaScript

Since Kenpali's data types are based on JSON, most values can be passed seamlessly back and forth between Kenpali and JavaScript. But functions work quite differently in Kenpali, and need special handling.

Suppose you let the user define a function in Kenpali—often the easiest way to allow them to add custom behaviour to your application. Then kpeval will return a Kenpali function object, which can't be called using JavaScript's normal () syntax. Instead, use the kpcall function:

import { kpeval, kpparse, kpcall } from "kenpali";

const code = '(name) => join(["Hello, ", name, "!"])';
const kpFunction = kpeval(kpparse(code));
const result = kpcall(kpFunction, ["world"], {});
console.log(result);

The kpcall function takes an array of positional arguments and an object of named arguments. Here's an example with a named argument instead:

import { kpeval, kpparse, kpcall } from "kenpali";

const code = '(name:) => join(["Hello, ", name, "!"])';
const kpFunction = kpeval(kpparse(code));
const result = kpcall(kpFunction, [], { name: "world" });
console.log(result);

Like kpeval, kpcall accepts a time limit:

import { kpeval, kpparse, kpcall } from "kenpali";

function applyCustomTransform(code, input) {
  const json = kpparse(code);
  const kpFunction = kpeval(json, { timeLimitSeconds: 1 });
  return kpcall(kpFunction, [input], {}, { timeLimitSeconds: 10 });
}

Passing JavaScript Callbacks into Kenpali Functions

Kenpali doesn't know how to call normal JavaScript functions directly. If you need to pass a JavaScript callback to a Kenpali function, wrap it with toKpFunction:

import { kpeval, kpparse, kpcall } from "kenpali";

const code = '(callback) => join(["Hello, ", callback("world"), "!"])';
const kpFunction = kpeval(kpparse(code));
const callback = toKpFunction(([word]) => word.toUpperCase());
const result = kpcall(kpFunction, [callback], {});
console.log(result);

Calling Kenpali Functions inside JavaScript Callbacks

If a JavaScript callback needs to itself invoke a Kenpali callback, don't use kpcall, which starts a brand new interpreter session. Instead, have the JavaScript callback accept an extra kpcallback parameter, and use that in the same way as kpcall.

import { kpeval, kpparse, kpcall } from "kenpali";

const code = '(callback) => join(["Hello, ", callback(() => "world"), "!"])';
const kpFunction = kpeval(kpparse(code));
const callback = toKpFunction(([word], {}, kpcallback) =>
  kpcallback(word, [], {}).toUpperCase()
);
const result = kpcall(kpFunction, [callback], {});
console.log(result);

Contributing

See the contributing guide.

0.11.0

8 months ago

0.12.0

7 months ago

0.11.1

8 months ago

0.13.0

7 months ago

0.11.2

8 months ago

0.14.0

6 months ago

0.11.3

8 months ago

0.15.0

6 months ago

0.11.4

8 months ago

0.16.0

5 months ago

0.11.5

8 months ago

0.10.0

11 months ago

0.9.0

11 months ago

0.8.1

11 months ago

0.8.0

11 months ago

0.7.1

1 year ago

0.8.3

11 months ago

0.8.2

11 months ago

0.7.0

1 year ago

0.6.0

1 year ago

0.5.2

1 year ago

0.5.0

1 year ago

0.5.1

1 year ago

0.4.1

1 year ago

0.4.0

1 year ago

0.3.0

2 years ago

0.2.0

2 years ago

0.1.2

2 years ago

0.1.1

2 years ago

0.1.0

2 years ago