2017-09-28 13:08:25 +02:00
|
|
|
/*
|
|
|
|
|
|
|
|
Exports a C-like API to the embedder.
|
|
|
|
|
|
|
|
[obtain entrySource, entryPath]
|
|
|
|
parseFile(entrySource, entryPath) -> parser
|
|
|
|
while nextPath = nextFile(parser)
|
|
|
|
[obtain nextSource]
|
|
|
|
parseFile(nextSource, nextPath)
|
|
|
|
|
|
|
|
Checking for errors:
|
|
|
|
|
|
|
|
while diagnostic = nextDiagnostic(parser)
|
|
|
|
[print] formatDiagnostic(diagnostic, useColors?, showContext?)
|
|
|
|
if (isError(diagnostic))
|
|
|
|
[abort parsing afterwards]
|
|
|
|
|
|
|
|
compile(parser) -> module
|
|
|
|
|
2017-12-14 11:55:35 +01:00
|
|
|
[check diagnostics again]
|
|
|
|
[output module]
|
|
|
|
|
2017-09-28 13:08:25 +02:00
|
|
|
*/
|
|
|
|
|
2017-12-24 03:19:47 +01:00
|
|
|
import {
|
|
|
|
Module
|
|
|
|
} from "./module";
|
|
|
|
|
|
|
|
import {
|
|
|
|
Compiler,
|
|
|
|
Options,
|
|
|
|
Target
|
|
|
|
} from "./compiler";
|
|
|
|
|
|
|
|
import {
|
|
|
|
DiagnosticMessage,
|
|
|
|
DiagnosticCategory,
|
|
|
|
formatDiagnosticMessage
|
|
|
|
} from "./diagnostics";
|
|
|
|
|
|
|
|
import {
|
|
|
|
Parser
|
|
|
|
} from "./parser";
|
|
|
|
|
|
|
|
import {
|
|
|
|
Program
|
|
|
|
} from "./program";
|
|
|
|
|
|
|
|
import {
|
|
|
|
Decompiler
|
|
|
|
} from "./decompiler";
|
2017-09-28 13:08:25 +02:00
|
|
|
|
2018-02-02 03:07:54 +01:00
|
|
|
export { LIBRARY_PREFIX } from "./program";
|
|
|
|
|
2017-12-08 04:03:44 +01:00
|
|
|
/** Parses a single source file. If `parser` has been omitted a new one is created. */
|
2017-12-09 02:52:20 +01:00
|
|
|
export function parseFile(text: string, path: string, parser: Parser | null = null, isEntry: bool = false): Parser {
|
2017-09-28 13:08:25 +02:00
|
|
|
if (!parser) {
|
|
|
|
parser = new Parser();
|
|
|
|
isEntry = true;
|
|
|
|
}
|
|
|
|
parser.parseFile(text, path, isEntry);
|
|
|
|
return parser;
|
|
|
|
}
|
|
|
|
|
2017-12-08 04:03:44 +01:00
|
|
|
/** Obtains the path to the next file required by the parser. Returns `null` once complete. */
|
2017-09-28 13:08:25 +02:00
|
|
|
export function nextFile(parser: Parser): string | null {
|
|
|
|
return parser.nextFile();
|
|
|
|
}
|
|
|
|
|
2017-12-08 04:03:44 +01:00
|
|
|
/** Obtains the next diagnostic message. Returns `null` once there are no more messages. */
|
2017-09-28 13:08:25 +02:00
|
|
|
export function nextDiagnostic(parser: Parser): DiagnosticMessage | null {
|
2017-12-28 04:09:40 +01:00
|
|
|
var program = parser.program;
|
2018-01-01 20:27:21 +01:00
|
|
|
return program.diagnosticsOffset < program.diagnostics.length
|
|
|
|
? program.diagnostics[program.diagnosticsOffset++]
|
|
|
|
: null;
|
2017-09-28 13:08:25 +02:00
|
|
|
}
|
|
|
|
|
2017-12-08 04:03:44 +01:00
|
|
|
/** Formats a diagnostic message to a string. */
|
|
|
|
export function formatDiagnostic(message: DiagnosticMessage, useColors: bool, showContext: bool): string {
|
|
|
|
return formatDiagnosticMessage(message, useColors, showContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Tests whether a diagnostic is informatory. */
|
|
|
|
export function isInfo(message: DiagnosticMessage): bool {
|
|
|
|
return message.category == DiagnosticCategory.INFO;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Tests whether a diagnostic is a warning. */
|
|
|
|
export function isWarning(message: DiagnosticMessage): bool {
|
|
|
|
return message.category == DiagnosticCategory.WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Tests whether a diagnostic is an error. */
|
2017-09-28 13:08:25 +02:00
|
|
|
export function isError(message: DiagnosticMessage): bool {
|
|
|
|
return message.category == DiagnosticCategory.ERROR;
|
|
|
|
}
|
|
|
|
|
2017-12-08 04:03:44 +01:00
|
|
|
/** Creates a new set of compiler options. */
|
|
|
|
export function createOptions(): Options {
|
|
|
|
return new Options();
|
2017-09-28 13:08:25 +02:00
|
|
|
}
|
|
|
|
|
2017-12-08 04:03:44 +01:00
|
|
|
/** Sets the `target` option. */
|
|
|
|
export function setTarget(options: Options, target: Target): void {
|
|
|
|
options.target = target;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Sets the `noTreeShaking` option. */
|
|
|
|
export function setNoTreeShaking(options: Options, noTreeShaking: bool): void {
|
|
|
|
options.noTreeShaking = noTreeShaking;
|
|
|
|
}
|
|
|
|
|
2017-12-13 23:24:13 +01:00
|
|
|
/** Sets the `noAssert` option. */
|
|
|
|
export function setNoAssert(options: Options, noAssert: bool): void {
|
|
|
|
options.noAssert = noAssert;
|
2017-12-08 04:03:44 +01:00
|
|
|
}
|
|
|
|
|
2017-12-25 12:08:51 +01:00
|
|
|
/** Sets the `noMemory` option. */
|
|
|
|
export function setNoMemory(options: Options, noMemory: bool): void {
|
|
|
|
options.noMemory = noMemory;
|
|
|
|
}
|
|
|
|
|
2018-02-02 03:07:54 +01:00
|
|
|
/** Sets the `sourceMap` option. */
|
|
|
|
export function setSourceMap(options: Options, sourceMap: bool): void {
|
|
|
|
options.sourceMap = sourceMap;
|
|
|
|
}
|
|
|
|
|
2017-12-08 04:03:44 +01:00
|
|
|
/** Compiles the sources computed by the parser to a module. */
|
|
|
|
export function compile(parser: Parser, options: Options | null = null): Module {
|
2017-12-28 04:09:40 +01:00
|
|
|
var program = parser.finish();
|
|
|
|
var compiler = new Compiler(program, options);
|
2017-12-08 04:03:44 +01:00
|
|
|
return compiler.compile();
|
|
|
|
}
|
2017-12-12 04:35:30 +01:00
|
|
|
|
|
|
|
/** Decompiles a module to its (low level) source. */
|
|
|
|
export function decompile(module: Module): string {
|
2017-12-28 04:09:40 +01:00
|
|
|
var decompiler = new Decompiler();
|
2017-12-12 04:35:30 +01:00
|
|
|
decompiler.decompile(module);
|
|
|
|
return decompiler.finish();
|
|
|
|
}
|