Note: This work is definitely not complete, functional or ready to be merged.
This is my first (published) pass at a readtable implementation. It isn't hooked into the pipeline yet but does show the general strategy and initial API. Per some previous discussions https://github.com/sweet-js/sweet.js/issues/535#issuecomment-242791944 I've intentionally implemented a very limited API (utility libs can build on these).
Readtables can currently be created as follows:
import { defaultReadtable } from 'src/readtable';
import CharStream from 'src/char-stream';
const newTable = defaultReadtable.extendReadtable({
key: '@',
action(stream) {
return {
type: 'Punctuator',
value: stream.readString(),
locationInfo: stream.locationInfo
};
}
});
const entry = newTable.getEntry('@');
const stream = new CharStream('@foo');
entry.action(stream);
// =>
// {
// type: 'Punctuator',
// value: '@',
// locationInfo: {
// filename: '',
// line: 0,
// column: 0,
// position: 0
// }
// }
The intention is to allow lookbehind of already read tokens. I'll have to implement this for '/' resolution. So the signature of action
will be action(stream: CharStream, prefix: TokenTree?)
. TokenTree = Token | List<TokenTree>
.
I have not implemented Racket style reader modes as I believe they can be build using the current primitives (i.e. by referencing other readtables in a closure).
As a note, I'm using some "private" fields (denoted by a _
prefix). I'm reserving the right to truly hide them in the future if there is a reason and efficiencies don't suffer too greatly. So their presence shouldn't be relied upon and shouldn't be part of the public API.
@disnet I'd appreciate some feedback as soon as you get the chance. I'm going to have a lot of time the next few days to hack on this and don't want to go too far down the wrong path.