UNPKG

12.3 kBJavaScriptView Raw
1"use strict";
2var __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};
11var __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};
18Object.defineProperty(exports, "__esModule", { value: true });
19const fs = __importStar(require("fs"));
20const readline = __importStar(require("readline"));
21const lexer_1 = require("./lexer");
22const PP = __importStar(require("./preprocessor"));
23exports.preprocessor = PP;
24const componentprocessor_1 = require("./componentprocessor");
25const parser_1 = require("./parser");
26const interpreter_1 = require("./interpreter");
27const BrsError = __importStar(require("./Error"));
28const LexerParser = __importStar(require("./LexerParser"));
29const _lexer = __importStar(require("./lexer"));
30exports.lexer = _lexer;
31const BrsTypes = __importStar(require("./brsTypes"));
32exports.types = BrsTypes;
33const _parser = __importStar(require("./parser"));
34exports.parser = _parser;
35const url_1 = require("url");
36const 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 */
48function 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}
75exports.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 */
85function 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}
98exports.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 */
105function 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}
129exports.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 */
141function 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsdUNBQXlCO0FBQ3pCLG1EQUFxQztBQUVyQyxtQ0FBZ0M7QUFDaEMsbURBQXFDO0FBZXRCLDBCQUFZO0FBZDNCLDZEQUk4QjtBQUM5QixxQ0FBa0M7QUFDbEMsK0NBQXVGO0FBQ3ZGLGtEQUFvQztBQUNwQywyREFBNkM7QUFFN0MsZ0RBQWtDO0FBQ2YsdUJBQUs7QUFDeEIscURBQXVDO0FBQ2xCLHlCQUFLO0FBRTFCLGtEQUFvQztBQUNoQix5QkFBTTtBQUMxQiw2QkFBMEI7QUFDMUIsMkNBQTZCO0FBRTdCOzs7Ozs7Ozs7O0dBVUc7QUFDSCxTQUFzQixPQUFPLENBQUMsU0FBbUIsRUFBRSxPQUFrQzs7UUFDakYsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLHFDQUF1QixFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRXpFLElBQUksUUFBUSxHQUFHLE1BQU0sRUFBRSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMzRCxJQUFJLG9CQUFvQixHQUFHLE1BQU0sOENBQXlCLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFbEYsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUMsU0FBOEIsRUFBRSxFQUFFO1lBQzVELElBQUksU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQztnQkFBRSxPQUFPO1lBQ3pDLElBQUk7Z0JBQ0EsU0FBUyxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQXVCLEVBQUUsRUFBRTtvQkFDbEUsTUFBTSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUNsQixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFB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
\No newline at end of file