mirror of
https://github.com/Baidicoot/rpncalc-v4
synced 2025-01-08 06:41:22 +00:00
fixed random throws + non-backtracing stream
This commit is contained in:
parent
e29e83789c
commit
ccff5a14a3
38
parse.js
38
parse.js
@ -65,7 +65,7 @@ const attempt = (parser) => (stream) => {
|
|||||||
const or = (a, b) => (stream) => {
|
const or = (a, b) => (stream) => {
|
||||||
let aout = a(stream);
|
let aout = a(stream);
|
||||||
if (aout.parsed === null) {
|
if (aout.parsed === null) {
|
||||||
return b(stream);
|
return b(aout.stream);
|
||||||
} else {
|
} else {
|
||||||
return aout;
|
return aout;
|
||||||
}
|
}
|
||||||
@ -74,15 +74,15 @@ const or = (a, b) => (stream) => {
|
|||||||
/* (parser) */
|
/* (parser) */
|
||||||
const parens = (parser) => (stream) => {
|
const parens = (parser) => (stream) => {
|
||||||
let a = parseSyntax("(", stream);
|
let a = parseSyntax("(", stream);
|
||||||
if (a === null) {
|
if (a.parsed === null) {
|
||||||
return {parsed:null, stream:stream};
|
return {parsed:null, stream:a.stream};
|
||||||
}
|
}
|
||||||
let dat = parser(stream);
|
let dat = parser(a.stream);
|
||||||
a = parseSyntax(")", stream);
|
a = parseSyntax(")", dat.stream);
|
||||||
if (a === null) {
|
if (a.parsed === null) {
|
||||||
throw 'mismatched parens!';
|
throw 'mismatched parens!';
|
||||||
}
|
}
|
||||||
return dat;
|
return {parsed:dat.parsed, stream:a.stream};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [parser] */
|
/* [parser] */
|
||||||
@ -90,6 +90,7 @@ const many = (parser) => (stream) => {
|
|||||||
let parsed = [];
|
let parsed = [];
|
||||||
for (let i = parser(stream); i.parsed !== null; i = parser(stream)) {
|
for (let i = parser(stream); i.parsed !== null; i = parser(stream)) {
|
||||||
parsed.push(i.parsed);
|
parsed.push(i.parsed);
|
||||||
|
stream = i.stream;
|
||||||
}
|
}
|
||||||
return {parsed:parsed, stream:stream};
|
return {parsed:parsed, stream:stream};
|
||||||
}
|
}
|
||||||
@ -160,30 +161,31 @@ const parseSyntax = (syntax, stream) => {
|
|||||||
const parseName = (stream) => {
|
const parseName = (stream) => {
|
||||||
let id = parseIdent(stream);
|
let id = parseIdent(stream);
|
||||||
if (id.parsed === null) {
|
if (id.parsed === null) {
|
||||||
return {parsed:null, stream:stream};
|
return {parsed:null, stream:id.stream};
|
||||||
}
|
}
|
||||||
let syn = parseSyntax(";", stream);
|
let syn = parseSyntax(";", id.stream);
|
||||||
if (syn.parsed === null) {
|
if (syn.parsed === null) {
|
||||||
throw 'could not parse name!'
|
throw 'could not parse name!'
|
||||||
}
|
}
|
||||||
return {parsed:id.parsed.val, stream:stream};
|
return {parsed:id.parsed.val, stream:syn.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).parsed;
|
let name = attempt(parseName)(stream);
|
||||||
if (name === null) {
|
if (name.parsed === null) {
|
||||||
name = "";
|
name.parsed = "";
|
||||||
}
|
}
|
||||||
let args = many(parseIdent)(stream).parsed;
|
let args = many(parseIdent)(name.stream);
|
||||||
if (parseSyntax("->", stream).parsed === null) {
|
let syn = parseSyntax("->", args.stream);
|
||||||
|
if (syn.parsed === null) {
|
||||||
throw 'no lambda body found!';
|
throw 'no lambda body found!';
|
||||||
}
|
}
|
||||||
let body = parseExprs(stream).parsed; // .parsed should never be null, but anyway...
|
let body = parseExprs(syn.stream); // .parsed should never be null, but anyway...
|
||||||
if (body === null) {
|
if (body.parsed === null) {
|
||||||
throw 'no lambda body found!';
|
throw 'no lambda body found!';
|
||||||
}
|
}
|
||||||
return {parsed:{type:"func", name:name, args:args, body:body}, stream:stream};
|
return {parsed:{type:"func", name:name.parsed, args:args.parsed, body:body.parsed}, stream:body.stream};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* takes in stream, outputs parsed item or null */
|
/* takes in stream, outputs parsed item or null */
|
||||||
|
Loading…
Reference in New Issue
Block a user