Skip to content

Instantly share code, notes, and snippets.

@conartist6
Created November 10, 2023 18:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save conartist6/dcf15e9efdd0a75445994258a94fcd71 to your computer and use it in GitHub Desktop.
Save conartist6/dcf15e9efdd0a75445994258a94fcd71 to your computer and use it in GitHub Desktop.
BABLR-VM minimal parse trampoline
import { buildExpression, effectsFor } from './utils/instruction.js';
import { getCooked } from './utils/token.js';
import { Match } from './match.js';
import { Context } from './context.js';
import { Source } from './source.js';
import { runSync } from './run.js';
import { dispatcher } from './dispatcher.js';
import { transformTokenMatcher } from './transforms.generated.js';
const defer = Symbol('defer');
export function parse(language, sourceText, matchable) {
const ctx = Context.from(language);
const source = Source.from(ctx, sourceText);
return runSync(dispatcher(ctx, source, matchable, parseTrampoline));
}
export function* parseTrampoline(ctx, rootMatcher, rootProps) {
let m = Match.from(ctx, rootMatcher, rootProps);
while (m) {
m.co.advance();
while (!m.co.done) {
const instr = m.co.value;
let returnValue = undefined;
const {
verb: verbToken,
arguments: {
properties: { values: { 0: matchable, 1: props } = [] },
},
} = instr.properties;
const verb = getCooked(verbToken);
switch (verb) {
case 'eat':
case 'eatMatch':
case 'match':
case 'guard': {
if (matchable.type === 'NodeMatcher' || matchable.type === 'TokenMatcher') {
const [matchable_, props_ = props] =
matchable.type === 'TokenMatcher' ? transformTokenMatcher(matchable) : [matchable];
m = m.exec(effectsFor(verb), matchable_, buildExpression(props_));
m.co.advance();
returnValue = defer;
break;
}
// fallthrough
}
default: {
returnValue = yield instr;
break;
}
}
if (returnValue === defer) {
// execution is suspeneded until the state stack unwinds
} else if (!m.co.done) {
m.co.advance(returnValue);
}
}
m = m.terminate();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment