walt-compiler
Version:
Alternative syntax for WebAssembly text format
131 lines (112 loc) • 2.88 kB
JavaScript
// @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,
};
};