Skip to content

Instantly share code, notes, and snippets.

@jlongster
Last active December 29, 2016 21:51
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jlongster/587b45576dce436f96c40beeb3cca2aa to your computer and use it in GitHub Desktop.
Save jlongster/587b45576dce436f96c40beeb3cca2aa to your computer and use it in GitHub Desktop.
syntax where = function(ctx) {
const binaryOps = ["or", "and", "==", ">", "<", "-", "+", "*", "/", "."];
const dummy = #`dummy`.get(0);
function matchNext(names) {
const marker = ctx.mark();
const next = ctx.next();
ctx.reset(marker);
return !next.done && names.includes(next.value.val());
}
function readBinaryOp(op) {
const precIdx = binaryOps.indexOf(op);
const isLast = precIdx === binaryOps.length - 1;
const readNext = () => {
if(isLast) {
return dummy.fromString("" + ctx.next().value.val());
}
return readBinaryOp(binaryOps[precIdx + 1]);
}
const left = readNext();
while(matchNext([op])) {
ctx.next();
const right = readNext();
left = #`({ op: ${dummy.fromString(op)}, left: ${left}, right: ${right} })`;
}
return left;
}
function read() {
return readBinaryOp(binaryOps[0]);
}
return read();
}
where t.x == 3 / 4 * 2 and z > 10;
// Output:
//
// ({
// op: "and",
// left: {
// op: "==",
// left: {
// op: ".",
// left: "t",
// right: "x"
// },
// right: {
// op: "*",
// left: {
// op: "/",
// left: "3",
// right: "4"
// },
// right: "2"
// }
// },
// right: {
// op: ">",
// left: "z",
// right: "10"
// }
// });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment