text: // @flow
  import { mapNode } from 'walt-parser-tools/map-node';
  import walkNode from 'walt-parser-tools/walk-node';
  
  import makeParser from './parser';
  import semantics from './semantics';
  import validate from './validation';
  import generator from './generator';
  import emitter from './emitter';
  
  import debug from './utils/debug';
  import prettyPrintNode from './utils/print-node';
  
  import { VERSION_1 } from './emitter/preamble';
  import type { ConfigType } from './flow/types';
  import { stringEncoder, stringDecoder } from './utils/string';
  import { makeFragment } from './parser/fragment';
  
  export {
    makeParser,
    makeFragment,
    semantics,
    validate,
    generator,
    emitter,
    prettyPrintNode,
    debug,
    stringEncoder,
    stringDecoder,
    walkNode,
    mapNode,
  };
  export const VERSION = '0.21.0';
  
  // Used for debugging purposes
  export const getIR = (source: string, config: ConfigType) => {
    const {
      version = VERSION_1,
      encodeNames = false,
      lines = source.split('\n'),
      filename = 'unknown',
      extensions = [],
    } =
      config || {};
  
    const parser = makeParser([]);
    const stmt = makeFragment(parser);
  
    const options = {
      version,
      encodeNames,
      lines,
      filename,
      extensions,
    };
  
    const ast = parser(source);
    const semanticAST = semantics(ast, [], { ...options, parser, stmt });
    validate(semanticAST, { lines, filename });
    const intermediateCode = generator(semanticAST, options);
    const wasm = emitter(intermediateCode, {
      version,
      encodeNames,
      filename,
      lines,
    });
    return wasm;
  };
  
  // Compile with plugins, future default export
  export const compile = (source: string, config: ConfigType) => {
    const {
      filename = 'unknown.walt',
      extensions = [],
      linker,
      encodeNames = false,
    } =
      config || {};
  
    const options = {
      filename,
      lines: source.split('\n'),
      version: VERSION_1,
      encodeNames,
    };
  
    // Generate plugin instances and sort them by the extended compiler phase
    const plugins = extensions.reduce(
      (acc, plugin) => {
        // Default plugins to a specific to ensure correctness
        const instance = {
          semantics: _ => ({}),
          grammar: () => ({ ParserRules: [] }),
          ...plugin(options),
        };
  
        acc.grammar.push(instance.grammar);
        acc.semantics.push(instance.semantics);
  
        return acc;
      },
      {
        grammar: [],
        semantics: [],
      }
    );
  
    const parser = makeParser(plugins.grammar);
    const stmt = makeFragment(parser);
    const ast = parser(source);
  
    const semanticAST = semantics(ast, plugins.semantics, {
      parser,
      stmt,
    });
  
    validate(semanticAST, options);
  
    const intermediateCode = generator(semanticAST, { ...options, linker });
    const wasm = emitter(intermediateCode, options);
  
    return {
      wasm,
      buffer() {
        return wasm.buffer();
      },
      ast,
      semanticAST,
    };
  };
  