From 678dc200b2352350978e93bb37e61b3de17e2ef9 Mon Sep 17 00:00:00 2001 From: "Aidan K. Ewart" Date: Sun, 31 May 2020 00:40:37 +0100 Subject: [PATCH] improved parser to allow constants --- builtin.mjs | 9 +++++++++ main.js | 1 + parse.mjs | 32 +++++++++++++++++++++++--------- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/builtin.mjs b/builtin.mjs index df8cfc7..b5dc85d 100644 --- a/builtin.mjs +++ b/builtin.mjs @@ -70,6 +70,14 @@ const len = (_, args) => { return [{type:"int", val:args[0].length}]; } +const coerce = (_, args) => { + if (args[0].type === "type") { + return [{type:args[0].val, val:args[1].val}]; + } else { + throw 'typeerror' + } +} + addDefn("+", ["int", "int"], add); addDefn("-", ["int", "int"], sub); addDefn("/", ["int", "int"], div); @@ -84,6 +92,7 @@ addDefn("snd", ["pair"], snd); addDefn("arr", ["int"], arr); addDefn("!!", ["int", "array"], index); addDefn("len", ["array"], len); +addDefn("coerce", 2, coerce); //addRPNDefn("unit", "(-> 0 arr)"); //addRPNDefn("mono", "(-> 1 arr)"); //addRPNDefn("unwrap", "(-> 0 !!)"); diff --git a/main.js b/main.js index 597df28..2b34661 100644 --- a/main.js +++ b/main.js @@ -44,6 +44,7 @@ submit.onclick = (event) => { outbox.innerHTML = "incorrect syntax somewhere"; return; } + console.log(ast.parsed); let out = execRPN({}, ast.parsed); if (!out) { outbox.innerHTML = "failed to execute"; diff --git a/parse.mjs b/parse.mjs index efa0c0c..06ff215 100644 --- a/parse.mjs +++ b/parse.mjs @@ -172,10 +172,21 @@ const parsePush = (stream) => { return {parsed:{type:"push", elem:id.parsed}, stream:id.stream}; } +const parseDefn = (stream) => { + let name = parseName(stream); + if (name.parsed === null) { + return {parsed:null, stream:name.stream}; + } + let expr = parseExpr(stream); + if (expr.parsed === null) { + return {parsed:null, stream:expr.stream}; + } + return {parsed:{type:"defn", ident:name.parsed, defn:expr.parsed}, stream:expr.stream} +} + /* takes in stream, outputs parsed item or null - FAILABLE */ const parseLambda = (stream) => { - let name = attempt(parseName)(stream); - let args = many(parseIdent)(name.stream); + let args = many(parseIdent)(stream); let syn = parseSyntax("->")(args.stream); if (syn.parsed === null) { throw 'no lambda body found!'; @@ -184,16 +195,19 @@ const parseLambda = (stream) => { if (body.parsed === null) { throw 'no lambda body found!'; } - let func = {type:"func", args:args.parsed.map(x => x.val), body:body.parsed}; - if (name.parsed === null) { - return {parsed:func, stream:body.stream}; - } else { - return {parsed:{type:"defn", ident:name.parsed, defn:func}, stream:body.stream}; - } + return {parsed:{type:"func", args:args.parsed.map(x => x.val), body:body.parsed}, stream:body.stream}; } /* takes in stream, outputs parsed item or null */ -const parseExpr = or(parseType, or(parseIdent, or(parseInteger, or(parsePush, attempt(parens(parseLambda)))))); +const parseExpr = or( + attempt(parens(parseDefn)), or( + attempt(parens(parseLambda)), or( + attempt(parseLambda), or( + parseType, or( + parseIdent, or( + parseInteger, + parsePush + )))))); /* takes in stream, outputs parsed items */ export const parseExprs = many(parseExpr); \ No newline at end of file