catgirl-calculus/src/repl.mjs

108 lines
2.0 KiB
JavaScript

import Line from "./Line.mjs";
import Expr from "./Expr.mjs";
import { parse_line } from "./parse.mjs";
import { compile_line } from "./compile.mjs";
import { transpile } from "./transpile.mjs";
import { reduce } from "./reduce.mjs";
import { prettify } from "./prettify.mjs";
import "./renderers/main.mjs";
import prelude from "../lib/prelude.mjs";
import readline from "node:readline";
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
let running = true;
let env = new Map();
function print (str) {
console.log(str);
}
const specials = new Map();
specials.set("!.exit", _ => running = false);
specials.set("!.env", _ => {
const lines = [...env.entries()].map(([name, fn]) => name + " = " + prettify(fn));
print(lines.join("\n"));
});
specials.set("!.env_raw", _ => {
const lines = [...env.entries()].map(([name, fn]) => name + " = " + prettify(fn, true));
print(lines.join("\n"));
});
specials.set("!.clear", _ => console.clear());
specials.set("!.load prelude", _ => {
prelude.forEach(line => run(line, false));
});
function run (line, output = true) {
if (specials.has(line)) {
specials.get(line)();
return;
}
const parsed = parse_line(line);
if (parsed.type === Line.Comment) return;
const compiled = compile_line(env, parsed);
if (!compiled.valid) {
if (output) print("invalid line!");
return;
}
env = compiled.env;
if (!output) return;
if (parsed.type === Line.Expression) {
print(prettify(reduce(compiled.value)));
// js function that's equivalent to the entered lambda function.
// const fn = transpile(compiled.value));
} else if (parsed.type === Line.Binding) {
print(parsed.name + " = " + prettify(compiled.fn));
}
}
function evaluate (fn) {
return transpile(fn[0])(fn[1]);
}
function read (callback) {
rl.question("> ", callback);
}
function repl () {
read(line => {
run(line);
if (running) {
setImmediate(repl);
} else {
rl.close();
}
});
}
print("welcome to catgirl calculus!");
print("uwu");
repl();