All files / src index.js

100% Statements 43/43
100% Branches 12/12
100% Functions 5/5
100% Lines 43/43
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131  21x 21x   21x 21x 21x 21x 21x   21x 21x   21x   21x 21x                               21x     21x               1x   1x 1x   1x               1x 1x 1x 1x 1x           1x       21x             67x   67x               67x     2x 1x 1x       2x 2x   2x               67x 67x 67x   65x         65x   65x 64x   64x     62x            
// @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.20.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,
  };
};