mirror of
https://github.com/Baidicoot/rpncalc-v4
synced 2024-06-15 01:29:58 +00:00
improved parser to allow constants
This commit is contained in:
parent
83e6cb247a
commit
678dc200b2
|
@ -70,6 +70,14 @@ const len = (_, args) => {
|
||||||
return [{type:"int", val:args[0].length}];
|
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"], add);
|
||||||
addDefn("-", ["int", "int"], sub);
|
addDefn("-", ["int", "int"], sub);
|
||||||
addDefn("/", ["int", "int"], div);
|
addDefn("/", ["int", "int"], div);
|
||||||
|
@ -84,6 +92,7 @@ addDefn("snd", ["pair"], snd);
|
||||||
addDefn("arr", ["int"], arr);
|
addDefn("arr", ["int"], arr);
|
||||||
addDefn("!!", ["int", "array"], index);
|
addDefn("!!", ["int", "array"], index);
|
||||||
addDefn("len", ["array"], len);
|
addDefn("len", ["array"], len);
|
||||||
|
addDefn("coerce", 2, coerce);
|
||||||
//addRPNDefn("unit", "(-> 0 arr)");
|
//addRPNDefn("unit", "(-> 0 arr)");
|
||||||
//addRPNDefn("mono", "(-> 1 arr)");
|
//addRPNDefn("mono", "(-> 1 arr)");
|
||||||
//addRPNDefn("unwrap", "(-> 0 !!)");
|
//addRPNDefn("unwrap", "(-> 0 !!)");
|
||||||
|
|
1
main.js
1
main.js
|
@ -44,6 +44,7 @@ submit.onclick = (event) => {
|
||||||
outbox.innerHTML = "incorrect syntax somewhere";
|
outbox.innerHTML = "incorrect syntax somewhere";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
console.log(ast.parsed);
|
||||||
let out = execRPN({}, ast.parsed);
|
let out = execRPN({}, ast.parsed);
|
||||||
if (!out) {
|
if (!out) {
|
||||||
outbox.innerHTML = "failed to execute";
|
outbox.innerHTML = "failed to execute";
|
||||||
|
|
32
parse.mjs
32
parse.mjs
|
@ -172,10 +172,21 @@ const parsePush = (stream) => {
|
||||||
return {parsed:{type:"push", elem:id.parsed}, stream:id.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 */
|
/* takes in stream, outputs parsed item or null - FAILABLE */
|
||||||
const parseLambda = (stream) => {
|
const parseLambda = (stream) => {
|
||||||
let name = attempt(parseName)(stream);
|
let args = many(parseIdent)(stream);
|
||||||
let args = many(parseIdent)(name.stream);
|
|
||||||
let syn = parseSyntax("->")(args.stream);
|
let syn = parseSyntax("->")(args.stream);
|
||||||
if (syn.parsed === null) {
|
if (syn.parsed === null) {
|
||||||
throw 'no lambda body found!';
|
throw 'no lambda body found!';
|
||||||
|
@ -184,16 +195,19 @@ const parseLambda = (stream) => {
|
||||||
if (body.parsed === null) {
|
if (body.parsed === null) {
|
||||||
throw 'no lambda body found!';
|
throw 'no lambda body found!';
|
||||||
}
|
}
|
||||||
let func = {type:"func", args:args.parsed.map(x => x.val), body:body.parsed};
|
return {parsed:{type:"func", args:args.parsed.map(x => x.val), body:body.parsed}, stream:body.stream};
|
||||||
if (name.parsed === null) {
|
|
||||||
return {parsed:func, stream:body.stream};
|
|
||||||
} else {
|
|
||||||
return {parsed:{type:"defn", ident:name.parsed, defn:func}, stream:body.stream};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* takes in stream, outputs parsed item or null */
|
/* 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 */
|
/* takes in stream, outputs parsed items */
|
||||||
export const parseExprs = many(parseExpr);
|
export const parseExprs = many(parseExpr);
|
Loading…
Reference in New Issue
Block a user