author | Alan Dipert
<alan@dipert.org> 2019-08-14 12:36:08 UTC |
committer | Alan Dipert
<alan@dipert.org> 2019-08-14 12:36:08 UTC |
parent | 87e788105a77e6710576efdd4e47f80d620ebf87 |
jacl.js | +54 | -7 |
diff --git a/jacl.js b/jacl.js index 01c36f8..4bed07b 100644 --- a/jacl.js +++ b/jacl.js @@ -193,27 +193,69 @@ class ReadTable { const READTABLE = Package.get('CL').intern('*READTABLE*'); +// TODO +const CLOSE_PAREN = new Object(); +const readList = async rdr => { + rdr.depth = (rdr.depth || 0) + 1; + const x = await rdr.read(); + if (x === CLOSE_PAREN) { + return new Values(null); + } else { + return new Values(new Cons(x, (await readList(rdr))[0])); + } + //while (true) { + // const x = await rdr.read(); + // if (x === CLOSE_PAREN) { + // return new Values(head); + // } else if (cons !== null) { + // cons.cdr = new Cons(x); + // cons = cons.cdr; + // } else { + // cons = head = new Cons(x); + // } + //} +} + READTABLE.value = new ReadTable() - .setMacro(';', true, async function(stream) { - for await(const ch of stream) { + .setMacro(';', true, async rdr => { + for await(const ch of rdr.stream) { if (ch === '\n') return new Values(); } }) - .setMacro('"', true, async function(stream) { + .setMacro('"', true, async rdr => { let str = new LispString(); - for await(const x of stream) { + for await(const x of rdr.stream) { if (x === '"') { return new Values(str); } else if(x === '\\') { - str.push(await stream.read()); + str.push(await rdr.stream.read()); } else { str.push(x); } } + }) + .setMacro('(', true, readList) + .setMacro(')', true, async rdr => { + if (!rdr.depth || rdr.depth-- == 0) { + throw new Error(`Unmatched ')'`); + } else { + return new Values(CLOSE_PAREN); + } }); const isWhitespace = ch => ' \t\n\r\b'.indexOf(ch) > -1; +const consumeWhitespace = async stream => { + for await(const ch of stream) { + if (isWhitespace(ch)) { + continue; + } else { + stream.unread(ch); + break; + } + } +} + const isConstituent = ch => { return /[A-Za-z]/.test(ch) || '!$%&*+-./:<=>?@[]^_{}~'.indexOf(ch) > -1 @@ -268,6 +310,7 @@ const readSingleEscaped = async function(stream, token) { } }; + class Reader { constructor(stream) { this.stream = stream; @@ -278,8 +321,12 @@ class Reader { if (isWhitespace(x)) { continue; } else if (macroFun = READTABLE.val().getMacro(x)) { - const vals = await macroFun(this.stream); - if (vals.length) return vals[0]; else continue; + const vals = await macroFun(this); + if (vals.length) { + return vals[0]; + } else { + continue + } } else if (x === '\\') { let y = await this.stream.read(); return readSingleEscaped(this.stream, y);