1 | ;
|
2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4 | return new (P || (P = Promise))(function (resolve, reject) {
|
5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9 | });
|
10 | };
|
11 | var __importStar = (this && this.__importStar) || function (mod) {
|
12 | if (mod && mod.__esModule) return mod;
|
13 | var result = {};
|
14 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
15 | result["default"] = mod;
|
16 | return result;
|
17 | };
|
18 | Object.defineProperty(exports, "__esModule", { value: true });
|
19 | const fs = __importStar(require("fs"));
|
20 | const readline = __importStar(require("readline"));
|
21 | const lexer_1 = require("./lexer");
|
22 | const PP = __importStar(require("./preprocessor"));
|
23 | exports.preprocessor = PP;
|
24 | const componentprocessor_1 = require("./componentprocessor");
|
25 | const parser_1 = require("./parser");
|
26 | const interpreter_1 = require("./interpreter");
|
27 | const BrsError = __importStar(require("./Error"));
|
28 | const LexerParser = __importStar(require("./LexerParser"));
|
29 | const _lexer = __importStar(require("./lexer"));
|
30 | exports.lexer = _lexer;
|
31 | const BrsTypes = __importStar(require("./brsTypes"));
|
32 | exports.types = BrsTypes;
|
33 | const _parser = __importStar(require("./parser"));
|
34 | exports.parser = _parser;
|
35 | const url_1 = require("url");
|
36 | const path = __importStar(require("path"));
|
37 | /**
|
38 | * Executes a BrightScript file by path and writes its output to the streams
|
39 | * provided in `options`.
|
40 | *
|
41 | * @param filename the absolute path to the `.brs` file to be executed
|
42 | * @param options configuration for the execution, including the streams to use for `stdout` and
|
43 | * `stderr` and the base directory for path resolution
|
44 | *
|
45 | * @returns a `Promise` that will be resolve if `filename` is successfully
|
46 | * executed, or be rejected if an error occurs.
|
47 | */
|
48 | function execute(filenames, options) {
|
49 | return __awaiter(this, void 0, void 0, function* () {
|
50 | const executionOptions = Object.assign(interpreter_1.defaultExecutionOptions, options);
|
51 | let manifest = yield PP.getManifest(executionOptions.root);
|
52 | let componentDefinitions = yield componentprocessor_1.getComponentDefinitionMap(executionOptions.root);
|
53 | componentDefinitions.forEach((component) => {
|
54 | if (component.scripts.length < 1)
|
55 | return;
|
56 | try {
|
57 | component.scripts = component.scripts.map((script) => {
|
58 | script.uri = path.join(options.root ? options.root : __dirname, new url_1.URL(script.uri).pathname);
|
59 | return script;
|
60 | });
|
61 | }
|
62 | catch (error) {
|
63 | throw new Error(`Encountered an error when parsing component ${component.name}: ${error}`);
|
64 | }
|
65 | });
|
66 | let lexerParserFn = LexerParser.getLexerParserFn(manifest, options);
|
67 | const interpreter = yield interpreter_1.Interpreter.withSubEnvsFromComponents(componentDefinitions, lexerParserFn);
|
68 | if (!interpreter) {
|
69 | throw new Error("Unable to build interpreter.");
|
70 | }
|
71 | let mainStatements = yield lexerParserFn(filenames);
|
72 | return interpreter.exec(mainStatements);
|
73 | });
|
74 | }
|
75 | exports.execute = execute;
|
76 | /**
|
77 | * A synchronous version of the lexer-parser flow.
|
78 | *
|
79 | * @param filename the paths to BrightScript files to lex and parse synchronously
|
80 | * @param options configuration for the execution, including the streams to use for `stdout` and
|
81 | * `stderr` and the base directory for path resolution
|
82 | *
|
83 | * @returns the AST produced from lexing and parsing the provided files
|
84 | */
|
85 | function lexParseSync(filenames, options) {
|
86 | const executionOptions = Object.assign(interpreter_1.defaultExecutionOptions, options);
|
87 | let manifest = PP.getManifestSync(executionOptions.root);
|
88 | return filenames
|
89 | .map(filename => {
|
90 | let contents = fs.readFileSync(filename, "utf8");
|
91 | let scanResults = lexer_1.Lexer.scan(contents, filename);
|
92 | let preprocessor = new PP.Preprocessor();
|
93 | let preprocessorResults = preprocessor.preprocess(scanResults.tokens, manifest);
|
94 | return parser_1.Parser.parse(preprocessorResults.processedTokens).statements;
|
95 | })
|
96 | .reduce((allStatements, statements) => [...allStatements, ...statements], []);
|
97 | }
|
98 | exports.lexParseSync = lexParseSync;
|
99 | /**
|
100 | * Launches an interactive read-execute-print loop, which reads input from
|
101 | * `stdin` and executes it.
|
102 | *
|
103 | * **NOTE:** Currently limited to single-line inputs :(
|
104 | */
|
105 | function repl() {
|
106 | const replInterpreter = new interpreter_1.Interpreter();
|
107 | replInterpreter.onError(BrsError.getLoggerUsing(process.stderr));
|
108 | const rl = readline.createInterface({
|
109 | input: process.stdin,
|
110 | output: process.stdout,
|
111 | });
|
112 | rl.setPrompt("brs> ");
|
113 | rl.on("line", line => {
|
114 | if (line.toLowerCase() === "quit" || line.toLowerCase() === "exit") {
|
115 | process.exit();
|
116 | }
|
117 | let results = run(line, interpreter_1.defaultExecutionOptions, replInterpreter);
|
118 | if (results) {
|
119 | results.map(result => {
|
120 | if (result !== BrsTypes.BrsInvalid.Instance) {
|
121 | console.log(result.toString());
|
122 | }
|
123 | });
|
124 | }
|
125 | rl.prompt();
|
126 | });
|
127 | rl.prompt();
|
128 | }
|
129 | exports.repl = repl;
|
130 | /**
|
131 | * Runs an arbitrary string of BrightScript code.
|
132 | * @param contents the BrightScript code to lex, parse, and interpret.
|
133 | * @param options the streams to use for `stdout` and `stderr`. Mostly used for
|
134 | * testing.
|
135 | * @param interpreter an interpreter to use when executing `contents`. Required
|
136 | * for `repl` to have persistent state between user inputs.
|
137 | * @returns an array of statement execution results, indicating why each
|
138 | * statement exited and what its return value was, or `undefined` if
|
139 | * `interpreter` threw an Error.
|
140 | */
|
141 | function run(contents, options = interpreter_1.defaultExecutionOptions, interpreter) {
|
142 | const lexer = new lexer_1.Lexer();
|
143 | const parser = new parser_1.Parser();
|
144 | const logErrorFn = BrsError.getLoggerUsing(options.stderr);
|
145 | lexer.onError(logErrorFn);
|
146 | parser.onError(logErrorFn);
|
147 | const scanResults = lexer.scan(contents, "REPL");
|
148 | if (scanResults.errors.length > 0) {
|
149 | return;
|
150 | }
|
151 | const parseResults = parser.parse(scanResults.tokens);
|
152 | if (parseResults.errors.length > 0) {
|
153 | return;
|
154 | }
|
155 | if (parseResults.statements.length === 0) {
|
156 | return;
|
157 | }
|
158 | try {
|
159 | return interpreter.exec(parseResults.statements);
|
160 | }
|
161 | catch (e) {
|
162 | //options.stderr.write(e.message);
|
163 | return;
|
164 | }
|
165 | }
|
166 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsdUNBQXlCO0FBQ3pCLG1EQUFxQztBQUVyQyxtQ0FBZ0M7QUFDaEMsbURBQXFDO0FBZXRCLDBCQUFZO0FBZDNCLDZEQUk4QjtBQUM5QixxQ0FBa0M7QUFDbEMsK0NBQXVGO0FBQ3ZGLGtEQUFvQztBQUNwQywyREFBNkM7QUFFN0MsZ0RBQWtDO0FBQ2YsdUJBQUs7QUFDeEIscURBQXVDO0FBQ2xCLHlCQUFLO0FBRTFCLGtEQUFvQztBQUNoQix5QkFBTTtBQUMxQiw2QkFBMEI7QUFDMUIsMkNBQTZCO0FBRTdCOzs7Ozs7Ozs7O0dBVUc7QUFDSCxTQUFzQixPQUFPLENBQUMsU0FBbUIsRUFBRSxPQUFrQzs7UUFDakYsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLHFDQUF1QixFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRXpFLElBQUksUUFBUSxHQUFHLE1BQU0sRUFBRSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMzRCxJQUFJLG9CQUFvQixHQUFHLE1BQU0sOENBQXlCLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFbEYsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUMsU0FBOEIsRUFBRSxFQUFFO1lBQzVELElBQUksU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQztnQkFBRSxPQUFPO1lBQ3pDLElBQUk7Z0JBQ0EsU0FBUyxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQXVCLEVBQUUsRUFBRTtvQkFDbEUsTUFBTSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUNsQixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQ3ZDLElBQUksU0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQy9CLENBQUM7b0JBQ0YsT0FBTyxNQUFNLENBQUM7Z0JBQ2xCLENBQUMsQ0FBQyxDQUFDO2FBQ047WUFBQyxPQUFPLEtBQUssRUFBRTtnQkFDWixNQUFNLElBQUksS0FBSyxDQUNYLCtDQUErQyxTQUFTLENBQUMsSUFBSSxLQUFLLEtBQUssRUFBRSxDQUM1RSxDQUFDO2FBQ0w7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksYUFBYSxHQUFHLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDcEUsTUFBTSxXQUFXLEdBQUcsTUFBTSx5QkFBVyxDQUFDLHlCQUF5QixDQUMzRCxvQkFBb0IsRUFDcEIsYUFBYSxDQUNoQixDQUFDO1FBQ0YsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNkLE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQztTQUNuRDtRQUVELElBQUksY0FBYyxHQUFHLE1BQU0sYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3BELE9BQU8sV0FBVyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUM1QyxDQUFDO0NBQUE7QUFsQ0QsMEJBa0NDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxTQUFnQixZQUFZLENBQUMsU0FBbUIsRUFBRSxPQUFrQztJQUNoRixNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMscUNBQXVCLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFFekUsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFDLGVBQWUsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUV6RCxPQUFPLFNBQVM7U0FDWCxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUU7UUFDWixJQUFJLFFBQVEsR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNqRCxJQUFJLFdBQVcsR0FBRyxhQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNqRCxJQUFJLFlBQVksR0FBRyxJQUFJLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN6QyxJQUFJLG1CQUFtQixHQUFHLFlBQVksQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNoRixPQUFPLGVBQU0sQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsZUFBZSxDQUFDLENBQUMsVUFBVSxDQUFDO0lBQ3hFLENBQUMsQ0FBQztTQUNELE1BQU0sQ0FBQyxDQUFDLGFBQWEsRUFBRSxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxhQUFhLEVBQUUsR0FBRyxVQUFVLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUN0RixDQUFDO0FBZEQsb0NBY0M7QUFFRDs7Ozs7R0FLRztBQUNILFNBQWdCLElBQUk7SUFDaEIsTUFBTSxlQUFlLEdBQUcsSUFBSSx5QkFBVyxFQUFFLENBQUM7SUFDMUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBRWpFLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUM7UUFDaEMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLO1FBQ3BCLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTTtLQUN6QixDQUFDLENBQUM7SUFDSCxFQUFFLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3RCLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxFQUFFO1FBQ2pCLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxLQUFLLE1BQU0sSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLEtBQUssTUFBTSxFQUFFO1lBQ2hFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUNsQjtRQUNELElBQUksT0FBTyxHQUFHLEdBQUcsQ0FBQyxJQUFJLEVBQUUscUNBQXVCLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFDbEUsSUFBSSxPQUFPLEVBQUU7WUFDVCxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUNqQixJQUFJLE1BQU0sS0FBSyxRQUFRLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRTtvQkFDekMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztpQkFDbEM7WUFDTCxDQUFDLENBQUMsQ0FBQztTQUNOO1FBQ0QsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2hCLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBQ2hCLENBQUM7QUF6QkQsb0JBeUJDO0FBRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNILFNBQVMsR0FBRyxDQUNSLFFBQWdCLEVBQ2hCLFVBQTRCLHFDQUF1QixFQUNuRCxXQUF3QjtJQUV4QixNQUFNLEtBQUssR0FBRyxJQUFJLGFBQUssRUFBRSxDQUFDO0lBQzFCLE1BQU0sTUFBTSxHQUFHLElBQUksZUFBTSxFQUFFLENBQUM7SUFDNUIsTUFBTSxVQUFVLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7SUFFM0QsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQixNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBRTNCLE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ2pELElBQUksV0FBVyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1FBQy9CLE9BQU87S0FDVjtJQUVELE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RELElBQUksWUFBWSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1FBQ2hDLE9BQU87S0FDVjtJQUVELElBQUksWUFBWSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1FBQ3RDLE9BQU87S0FDVjtJQUVELElBQUk7UUFDQSxPQUFPLFdBQVcsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0tBQ3BEO0lBQUMsT0FBTyxDQUFDLEVBQUU7UUFDUixrQ0FBa0M7UUFDbEMsT0FBTztLQUNWO0FBQ0wsQ0FBQyJ9 |
\ | No newline at end of file |