Skip to content

unsaved parsers in namedSequenceOf #112

@Fredderic

Description

@Fredderic

This is a small but mighty change that I consider absolutely amazing:

  • Pass in an initialiser object so we don't have to .map to add fixed fields
  • Don't bother saving fields that are not a string (eg. null)

This simple change replaced most of my uses of A.coroutine, and avoids having to map my namedSequenceOf's to remove a scratch field, or inject static ones.

export function namedSequenceOf(pairedParsers, template) {
	return new Parser(function namedSequenceOf$state(state) {
		if (state.isError)
			return state;
		const results = {};
		if ( template ) { // copy the template into results
			Object.assign(results, template);
		}
		let nextState = state;
		for (const [key, parser] of pairedParsers) {
			const out = parser.p(nextState);
			if (out.isError) {
				return out;
			}
			else {
				nextState = out;
				if ( typeof key === 'string' ) { // don't set null keys
					results[key] = out.result;
				}
			}
		}
		return updateResult(nextState, results);
	});
}

Plus, WeakValueMap (why isn't that built into JavaScript?!?) caching a bunch of the terminal parsers, and the mass decodes of the regex parser, also make for a huge improvement. (I also export those wrapped parsers as xxxUncached — though they are, but they won't be if WeakRef isn't available and I switch to a regular Map, so the name actually means "don't do dumb caching".) I apply these changes through a shim library that imports Arcsecond, and exports everything again with the handful of changes — I strongly recommend doing the same (the only issue with the shim library, is terminal parsers being used internally, but I haven't noticed any).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions