You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
50 lines
924 B
50 lines
924 B
3 years ago
|
import { Cons, Nil, String, Symbol, Number } from './datatypes.js';
|
||
|
|
||
|
export class ReaderMacros {
|
||
|
static setMacroCharacter(macros, c, fn) {
|
||
|
macros[c] = { outer: macros[c], fn };
|
||
|
}
|
||
|
|
||
|
static popMacroCharacter(macros, c) {
|
||
|
macros[c] = macros[c].outer;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export class Reader {
|
||
|
static readData(data) {
|
||
|
if (isNaN(data)) {
|
||
|
return new Symbol(data.toUpperCase());
|
||
|
}
|
||
|
return new Number(parseFloat(data));
|
||
|
}
|
||
|
|
||
|
static read(macros, stream) {
|
||
|
let data = '';
|
||
|
let c = null;
|
||
|
while (c = stream.peekChar()) {
|
||
|
const macro = macros[c];
|
||
|
if (macro) {
|
||
|
if (data) {
|
||
|
return Reader.readData(data);
|
||
|
}
|
||
|
return macro.fn(stream.readChar(), stream);
|
||
|
}
|
||
|
|
||
|
c = stream.readChar();
|
||
|
if (!c.trim()) {
|
||
|
if (data.length) {
|
||
|
return Reader.readData(data);
|
||
|
}
|
||
|
} else {
|
||
|
data += c;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (data.length) {
|
||
|
return Reader.readData(data);
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
}
|