Skip to content

Instantly share code, notes, and snippets.

@Lucifier129
Created January 11, 2020 08:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lucifier129/35dbe3f70f1d656f740a5bfcd6d289cc to your computer and use it in GitHub Desktop.
Save Lucifier129/35dbe3f70f1d656f740a5bfcd6d289cc to your computer and use it in GitHub Desktop.
const createOperation = name => (...args) => {
let operation = interpreter =>
interpreter[name](
...args.map(f => (f && f.operation ? f(interpreter) : f))
);
operation.operation = true;
return operation;
};
const createOperations = (...names) =>
names.reduce(
(operations, name) => ({ ...operations, [name]: createOperation(name) }),
{}
);
const { abs, app, int, add, mul } = createOperations(
"abs",
"app",
"int",
"add",
"mul"
);
const runExpr = (expr, interpreter) => expr(interpreter);
const expr = app(
abs(n => n - 14),
mul(int(2), add(int(3), int(4)))
);
const astBuilder = {
abs: f => ({ type: "FunctionDefinition", f }),
app: (f, ...args) => ({ type: "FunctionApplication", f, args }),
int: n => ({ type: "NumberLiteral", value: n }),
add: (a, b) => ({ type: "NumberAddition", left: a, right: b }),
mul: (a, b) => ({ type: "NumberMultiplication", left: a, right: b })
};
const evaluator = {
abs: f => f,
app: (f, ...args) => f(...args),
int: n => n,
add: (a, b) => a + b,
mul: (a, b) => a * b
};
const printer = {
abs: f => f.toString(),
app: (f, ...args) => `(${f})(${args.join(", ")})`,
int: n => `${n}`,
add: (a, b) => `(${a} + ${b})`,
mul: (a, b) => `(${a} * ${b})`
};
console.log("ast", runExpr(expr, astBuilder));
console.log("result", runExpr(expr, evaluator));
console.log("print", runExpr(expr, printer));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment