Skip to content

Instantly share code, notes, and snippets.

@clinuxrulz
Created May 23, 2025 00:32
Show Gist options
  • Save clinuxrulz/bb090a574ec6aab0a0a79a2c15c44de3 to your computer and use it in GitHub Desktop.
Save clinuxrulz/bb090a574ec6aab0a0a79a2c15c44de3 to your computer and use it in GitHub Desktop.
`Cont` monad being used for code generation (used as a Reified Monad)
import { Cont, do_, exec, execR, } from "prelude";
let freeVar = 0;
let code = "";
function main(): Cont<void> {
return do_(() => {
let name = ask(_("What is your name?"));
print(append(_("Hello "), name));
});
}
console.log(compile(main()));
function allocVar(): string {
return `x${freeVar++}`;
}
function compile(x: Cont<void>) {
let outer = code;
try {
code = "";
x.run();
code = code
.split("\r\n")
.filter((line) => line != "")
.map((line) => ` ${line}`)
.join("\r\n");
return `function() {\r\n${code}\r\n}`;
} finally {
code = outer;
}
}
function ask(msg: Cont<string>): Cont<string> {
return execR(msg.then((msg) => Cont.of((k) => {
let v = allocVar();
code += `let ${v} = window.prompt(${msg})\r\n`;
k(v);
})));
}
function print(v: Cont<string>) {
exec(v.then((v) => Cont.of((k) => {
code += `console.log(${v}};\r\n`;
k();
})));
}
function append(a: Cont<string>, b: Cont<string>): Cont<string> {
return execR(a.then((a) => b.then((b) => Cont.of((k) => {
let v = allocVar();
code += `let ${v} = ${a} + ${b};\r\n`;
k(v);
}))));
}
function _(x: string): Cont<string> {
return execR(Cont.of((k) => {
let v = allocVar();
code += `let ${v} = "${x}";\r\n`;
k(v);
}));
}
export function onUnload() {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment