scrowl/src/lang/primitive.ts

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([]);
});
}