UNPKG

@bablr/language-en-blank-space

Version:

A BABLR language for tabs, spaces, and line terminators

60 lines (49 loc) 1.73 kB
import { m, o, eat, match, eatMatch } from '@bablr/helpers/grammar'; import * as BListKeyed from '@bablr/agast-helpers/b-list-keyed'; import { freezeClass, freezeRecord } from '@bablr/agast-helpers/object'; let { freeze } = Object; export default class BlankSpace { static canonicalURL = 'https://bablr.org/languages/core/en/space-tab-newline'; static dependencies = freeze({}); static defaultMatcher = m`<__Blanks />`; static fragmentProduction = null; static context = freezeRecord({}); *Blank({ s }) { let span = BListKeyed.get('Trivia', s().spans); if (span && span.props?.spaces > 0 && (yield match(m`/^[ \t\r\n]/m`))) { if (yield eatMatch(m`<LeftOffset />`)) { } else if (yield eatMatch(m`<*Space /[ \t]+/ />`)) { } else { yield eat(m`<*Newline /\r?\n?/ />`, o({}), o({ literal: true })); } } else if (yield match(m`/[\r\n]/`)) { yield eat(m`<*Newline /\r?\n?/ />`, o({}), o({ literal: true })); } else { yield eat(m`<*Space /[ \t]+/ />`, o({}), o({ literal: true })); } } *Space({ props: { onlySameLine } }) { if (onlySameLine) { yield eat(m`/[ \t]+/`); } else { yield eat(m`/[ \t\r\n]+/`); } } *LeftOffset({ s }) { let { span } = s(); span = BListKeyed.get('Trivia', s().spans); if (!span || !span.props) { while (yield eatMatch(m`indents[]: <*Indent /\t| / />`, o({}), o({ literal: true }))) {} } else { let spaces = ' '.repeat(span.props.spaces); while (yield eatMatch(m`indents[]: <*Indent '${spaces}' />`, o({}), o({ literal: true }))) {} } } *Newline() { yield eat(m`/\r?\n?/`); } *Indent() { yield eat(m`/\t| /`); } } freezeClass(BlankSpace);