Skip to content

Instantly share code, notes, and snippets.

Avatar

Conrad Buck conartist6

  • Boulder, CO
View GitHub Profile
@conartist6
conartist6 / index.md
Last active March 16, 2023 15:55
cst-tokens internal data stucture
View index.md
  A range is represented as a [Token, Token] tuple.

  A range can only be iterated backwards, which creates the need to store tokens in an array!

  Each node must have its own tokens array to enable efficient editing.

  A context object often abbreviated `ctx` holds WeakMaps, including `paths` and `previousTokens`.

  Tokens reference their preceding token using the `previousTokens` WeakMap.
@conartist6
conartist6 / index.js
Last active March 1, 2023 19:33
cst-tokens grammar snippet
View index.js
import { prod, tok, sym, Grammar } from '@/helpers';
new Grammar({
productions: {
// This version of ImportSpecifier uses helpers to be concise:
*ImportSpecifier() {
yield eat(prod`Identifier:imported`);
yield eatMatch(tok`Keyword:as`, prod`Identifier:local`);
},
@conartist6
conartist6 / index.js
Last active January 28, 2023 00:00
ReadOnlyMap
View index.js
const _ = Symbol('private');
class ReadOnlyMap {
constructor(map) {
this[_] = map;
}
static from(entries) {
return new ReadOnlyMap(new Map(entries));
}
@conartist6
conartist6 / ranges.js
Last active January 22, 2023 18:10
Tokenizer ranges
View ranges.js
class Tokenizer {
constructor(source) {
this.source = source;
this.result = null; // result is a token, i.e. a stack of tokens
this.pathRangesByToken = new WeakMap();
this.prevTokensByToken = new WeakMap();
}
ownTokensFor(path) {
const { prevTokensByToken, pathRangesByToken } = this;
@conartist6
conartist6 / parse-grammar.js
Last active December 4, 2022 21:35
Parser spitballing
View parse-grammar.js
import { Grammar } from '@cst-tokens/grammar';
import { objectEntries } from '@cst-tokens/helpers/iterable';
import { eat, match } from '@cst-tokens/helpers/commands';
import { capture, ref, PN } from '@cst-tokens/helpers/shorthand';
// 2-+2+-2
/*
$capture = '2';
$node = { type: 'Digit', value: $caputure };
$capture = '-';
@conartist6
conartist6 / bench.js
Created November 26, 2022 03:37
Common empties microbenchmark
View bench.js
console.time('new Set');
for (let i = 0; i < 1_000_000; i++) {
new Set();
}
console.timeEnd('new Set');
console.time('new Map');
for (let i = 0; i < 1_000_000; i++) {
new Map();
}
View 1.fixture.js
function /*1*/ foo /*2*/ (/*3*/) /*4*/ {/*5*/} /*6*/
@conartist6
conartist6 / index.js
Created November 7, 2022 22:33
splitWhen for trusted destructuring
View index.js
export class Coroutine {
constructor(generator) {
this.generator = generator[Symbol.iterator]();
this.current = this.generator?.next();
}
get value() {
return this.current.value;
}
@conartist6
conartist6 / output.md
Last active September 15, 2022 22:21
cst-tokens alpha output
View output.md

Input:

if (foo) {
  // comment
}

Traversal log

@conartist6
conartist6 / lamp.js
Last active December 16, 2022 16:28
State machine with generators
View lamp.js
/*
Lamps often have on-off switches that twist clockwise, clicking as they do.
Some such switches have four states, even though the lamp has only two (on, and off).
On these lamps clicking the switch will only cause an on/off transition every other click.
Just looking at the lamp you'll know if it's on, but not if the next click will turn it off.
To reliably interact with such a lamp you will use an algorithm, even in real life.
I use the term strategy to refer to an algorithm expressed with generators like this --
the strategy pattern is useful to abstract an algorithm from the representation of the data.
*/