Created
May 9, 2018 07:01
-
-
Save ulve/26d6087bbab6d9a67c4b6f1a226807ed to your computer and use it in GitHub Desktop.
Sample DSL with interpreter in TypeScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Program<T> = Read<T> | Write<T> | Done<T>; | |
interface Read<T> { | |
kind: "Read"; | |
next: (data: T) => Program<T>; | |
} | |
interface Write<T> { | |
kind: "Write"; | |
valToWrite: string; | |
next: Program<T>; | |
} | |
interface Done<T> { | |
kind: "Done"; | |
val: T; | |
} | |
// Data constructors | |
const read = <T>(next: (data: T) => Program<T>): Program<T> => ({ | |
kind: "Read", | |
next | |
}); | |
const write = <T>(valToWrite: string, next: Program<T>): Program<T> => ({ | |
kind: "Write", | |
valToWrite, | |
next | |
}); | |
const done = <T>(val: T): Program<T> => ({ | |
kind: "Done", | |
val | |
}); | |
// Program in our DSL | |
const greetingProgram: Program<string> = write("Hello, what is your name?", | |
read(name => write(`Hello ${name}`, | |
done(name))) | |
); | |
// Interpreter | |
export const consoleInterpreter = async (program: Program<string>): Promise<string> => { | |
switch (program.kind) { | |
case "Done": | |
process.exit(0); | |
return program.val; | |
case "Write": | |
console.log(program.valToWrite); | |
return consoleInterpreter(program.next); | |
case "Read": | |
var stdin = process.openStdin(); | |
const p: Promise<string> = new Promise<string>((res, rej) => | |
stdin.addListener("data", (d: any) => res(d.toString().trim())) | |
); | |
// const p = Promise.resolve("Katt"); | |
const data: string = await p; | |
return consoleInterpreter(program.next(data)); | |
} | |
}; | |
// Run | |
const result: Promise<string> = consoleInterpreter(greetingProgram); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment