Skip to content

Instantly share code, notes, and snippets.

View evan-brass's full-sized avatar

Evan Brass evan-brass

View GitHub Profile
function parse_content(cursor) {
let run = true;
while (run && input.length > 0) {
// Parse an open tag
const success = pull(/^<([a-zA-Z][a-zA-Z0-9\-]*)>/, tag => {
const new_tag = { tag, attributes: {}, children: [] };
cursor.children.push(new_tag);
parse_content(new_tag);
}) ||
// Parse close tag
@evan-brass
evan-brass / regex-html-1.js
Created December 25, 2020 22:06
Step 1: Harness for a regex based recursive descent HTML parser.
export default function parse_html(input) {
const root = { children: [] };
function pull(regex, handler = () => {}) {
const match = regex.exec(input);
if (match !== null) {
const [full_match, ...captures] = match;
input = input.substr(full_match.length);
handler(...captures);
return true;
} else {
@evan-brass
evan-brass / double-array.js
Created June 15, 2020 20:39
An example of the problem that can arise from stateful trait protocols.
class Car {
get [Drivable]() {
return {
x: 0,
y: 0,
steer(direction, throttle) {
this.x += throttle * direction.x;
this.y += throttle * direction.y;
}
}
@evan-brass
evan-brass / generic-impl.js
Last active June 16, 2020 00:07
Implementing a trait using a function
const Undead = new Trait("Neither fully alive nor fully dead.");
const AI = new Trait("Has an AI script");
function implement_ai(base) {
let ai_impl;
if (base instanceof Undead) {
ai_impl = {
ai_tick() {
for (const creature of this.source.surroundings()) {
// Find living things in the surounding and eat them with a preference for brains...
@evan-brass
evan-brass / trait-test.js
Created June 15, 2020 00:56
Example usage of a trait class.
const Sayable = new Trait("Can be made to say something.");
const Drivable = new Trait("Can be driven.");
class Cow {
[Sayable]() {
return "Eat Mor ChiKin";
}
}
class Horse {
[Sayable]() {
@evan-brass
evan-brass / trait.mjs
Created June 15, 2020 00:40
A simple class for creating your own well-known symbols type traits.
export default class Trait {
constructor(description) {
this.symbol = Symbol(description);
}
[Symbol.toPrimitive]() {
return this.symbol;
}
[Symbol.hasInstance](target) {
return typeof target == 'object' && target[this.symbol] !== undefined;
}
@evan-brass
evan-brass / conflict.js
Created June 15, 2020 00:12
A class that implements the iterator protocol even though it has a conflicting method.
class Foo {
a = 5;
next() {
return false; // Doesn't implement the iterator protocol
}
[Symbol.iterator]() {
const self = this;
return {
i: 0,
next() {
@evan-brass
evan-brass / Fib.js
Last active June 15, 2020 20:11
An example of an iterable class
class Fib {
a = 0;
b = 0;
next() {
if (this.a == 0) {
this.a = 1;
return { value: 1, done: false };
}
if (this.b == 0) {
this.b = 1;
@evan-brass
evan-brass / ce-base.mjs
Created April 1, 2020 21:27
A simple base class for custom-elements
export function Base_extend(inherit = HTMLElement) {
return class Base extends inherit {
abortController = new AbortController()
constructor() {
super();
// Construct the shadow DOM
this.attachShadow({mode: 'open'});
}
function* testHelper() {
console.log('Entering Helper');
yield delay(1000); // State H-1
console.log('Helper: Transition 1');
yield delay(1000); // State H-2
console.log('Helper: Transition 2');
return 5;
}
function* test() {