UNPKG

@bablr/language-en-es6

Version:
161 lines (133 loc) 5.09 kB
import { spam as m } from '@bablr/boot'; import { Node } from '@bablr/helpers/decorators'; import { o, eat, eatMatch, match, fail } from '@bablr/helpers/grammar'; export const mixin = (Base) => class ES6ImportGrammar extends Base { @Node *ImportDeclaration() { yield eat(m`sigilToken: <*Keyword 'import' />`); if (yield eatMatch(m`specifiers[]$: <ImportNamespaceSpecifier '*' />`)) { yield eat(m`fromToken: <*Keyword 'from' />`); } else { let spec = yield eatMatch(m`specifiers[]$: <ImportDefaultSpecifier />`); let sep = spec ? null : yield eatMatch(m`separators[]: <*Punctuator ',' />`); let open = yield eatMatch( m`openSpecifiersToken: <*Punctuator '{' { balanced: '}' } />`, o({}), o({ bind: true }), ); if (open) { let first = true; while (first || sep) { spec = yield eatMatch(m`specifiers[]$: <ImportSpecifier />`); sep = yield eatMatch(m`separators[]: <*Punctuator ',' />`); first = false; } yield eat(m`closeSpecifiersToken: <*Punctuator '}' { balancer: true } />`); } else { yield eat(m`closeSpecifiersToken: null`); } yield eat(m`fromToken: <*Keyword 'from' />`); } yield eat(m`source$: <String />`); yield eatMatch(m`endToken: <*Punctuator ';' />`, o({}), o({ bind: true })); } @Node *ImportSpecifier() { let str; if ((str = yield eatMatch(m`imported$: <String /['"]/ />`))) { } else { yield eat(m`imported$: <Identifier />`); } if (str || (yield match('as'))) { yield eat(m`mapOperator: <*Keyword 'as' />`); yield eat(m`local$: <Identifier />`); } else { yield eat(m`mapOperator: null`); yield eat(m`local$: null`); } } @Node *ImportDefaultSpecifier() { yield eat(m`local: <Identifier />`); } @Node *ImportNamespaceSpecifier() { yield eat(m`sigilToken: <*Punctuator '*' />`); yield eat(m`mapOperator: <*Keyword 'as' />`); yield eat(m`local$: <Identifier />`); } @Node *ExportDeclaration() { yield eat(m`sigilToken: <*Keyword 'export' />`); let curly, defSpec, spec, def, from, sep; yield eatMatch(m`declaration$: null`); if ((def = yield match('default'))) { yield eatMatch(m`defaultToken: <*Keyword 'default' />`); if (yield eatMatch(m`declaration$: <ClassDeclaration 'class' />`)) { } else if (yield eatMatch(m`declaration: <FunctionStatement /function|async/ />`)) { } else { yield eat(m`declaration$: <__Expression />`); } } else { yield eat(m`defaultToken: null`); } defSpec = spec = yield eatMatch(m`specifiers[]$: <ExportDefaultSpecifier />`); defSpec = defSpec || (yield eatMatch(m`specifiers[]$: <ExportAllSpecifier '*' />`)); if (spec) { sep = yield eatMatch(m`specifierSeparatorTokens[]: <*Punctuator ',' />`); } if ((!defSpec || sep) && (curly = yield match('{'))) { yield eat(m`openSpecifiersToken: <*Punctuator '{' { balanced: '}' } />`); let first = true; while (first || (spec && sep)) { spec = yield eat(m`specifiers[]$: <ExportSpecifier />`); sep = yield eatMatch(m`specifierSeparatorTokens[]: <*Punctuator ',' />`); first = false; } yield eat(m`closeSpecifiersToken: <*Punctuator '}' { balancer: true } />`); } else { yield eat(m`openSpecifiersToken: null />`); yield eat(m`specifiers[]$: []`); yield eat(m`specifierSeparatorTokens[]: []`); yield eat(m`closeSpecifiersToken: null />`); } if ((defSpec || curly) && (from = yield match('from'))) { yield eatMatch(m`fromToken: <*Keyword 'from' />`); yield eat(m`source$: <String />`); } else { yield eatMatch(m`fromToken: null`); yield eat(m`source$: null`); } if (!def && !defSpec && !curly && !from) { if (yield eatMatch(m`declaration: <VariableDeclarationStatement /var|const|let/ />`)) { } else if (yield eatMatch(m`declaration: <ClassDeclaration 'class' />`)) { } else if (yield eatMatch(m`declaration: <FunctionStatement />`)) { } else { yield fail(); } } yield eatMatch(m`endToken: <*Punctuator ';' />`, o({}), o({ bind: true })); } @Node *ExportDefaultSpecifier() { yield eat(m`local$: <Identifier />`); } @Node *ExportAllSpecifier() { yield eat(m`sigilToken: <*Keyword '*' />`); } @Node *ExportSpecifier() { yield eat(m`local$: <Identifier />`); let as_ = yield eatMatch(m`mapOperator: <*Keyword 'as' />`, o({}), o({ bind: true })); if (as_) { if (yield eatMatch(m`imported$: <String /['"]/ />`)) { } else { yield eat(m`imported$: <Identifier />`); } } else { yield eat(m`imported$: null`); } } };