57 lines
1.6 KiB
TypeScript
57 lines
1.6 KiB
TypeScript
import { Value } from "./eval/value";
|
|
import { Implementation, Program } from "./program";
|
|
import { ThrownRuntimeError } from "./eval/error";
|
|
import { FunctionName } from "./expr";
|
|
import { valueToString } from "./debug/value_show";
|
|
|
|
// TODO: Primitive functions like +, -, *, div, <, <=, ==, mod
|
|
|
|
export function installPrimitives(program: Program) {
|
|
function R(name: FunctionName, implementation: Implementation) {
|
|
Program.registerPrimitive(program, name, implementation);
|
|
}
|
|
|
|
// addition
|
|
R("+", (args: Value[]): Value => {
|
|
let sum = 0;
|
|
for (const arg of args) {
|
|
if (arg.tag !== "number") {
|
|
throw ThrownRuntimeError.error({ tag: "TypeMismatch", expected: "number", received: arg });
|
|
}
|
|
sum += arg.value;
|
|
}
|
|
return Value.number(sum);
|
|
});
|
|
|
|
// multiplication
|
|
R("*", (args: Value[]): Value => {
|
|
let product = 1;
|
|
for (const arg of args) {
|
|
if (arg.tag !== "number") {
|
|
throw ThrownRuntimeError.error({ tag: "TypeMismatch", expected: "number", received: arg });
|
|
}
|
|
product = product*arg.value;
|
|
}
|
|
return Value.number(product);
|
|
});
|
|
|
|
// string concat
|
|
R("++", (args: Value[]): Value => {
|
|
let sum = "";
|
|
for (const arg of args) {
|
|
if (arg.tag !== "string") {
|
|
throw ThrownRuntimeError.error({ tag: "TypeMismatch", expected: "number", received: arg });
|
|
}
|
|
sum += arg.value;
|
|
}
|
|
return Value.string(sum);
|
|
});
|
|
|
|
R("log", (args: Value[]): Value => {
|
|
for (const arg of args) {
|
|
console.log(valueToString(arg));
|
|
}
|
|
return Value.tuple([]);
|
|
});
|
|
|
|
}
|