@microtronics/studio-cli 0.6.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,312 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.DloCompiler = void 0;
27
+ exports.uriToMemFsPath = uriToMemFsPath;
28
+ exports.generateConfigFile = generateConfigFile;
29
+ const preCompiler_1 = require("./preCompiler");
30
+ const vscode_uri_1 = require("vscode-uri");
31
+ const manifest_1 = require("../manifest");
32
+ const defaultFiles_1 = require("../defaultFiles");
33
+ const dependencies_1 = require("../dependencies");
34
+ const iconv = __importStar(require("iconv-lite"));
35
+ const helper_1 = require("../helper");
36
+ var convertBlobToStringArray = helper_1.Helper.convertBlobToStringArray;
37
+ const DLO_MODULE = require('./dlocc.js');
38
+ class DloCompiler {
39
+ preCompiler = new preCompiler_1.DloPreCompiler();
40
+ dloCC;
41
+ stdout = [];
42
+ stderr = [];
43
+ constructor() {
44
+ this.dloCC = null;
45
+ }
46
+ async initDloCC(noExit = false) {
47
+ this.stdout.length = 0;
48
+ this.stderr.length = 0;
49
+ this.dloCC = await DLO_MODULE({
50
+ noExitRuntime: noExit,
51
+ print: (data) => {
52
+ console.log(data);
53
+ this.stdout.push(data);
54
+ },
55
+ printErr: (err) => {
56
+ console.error(err);
57
+ this.stderr.push(err);
58
+ this.stdout.push(err);
59
+ }
60
+ });
61
+ }
62
+ get MEMFS() {
63
+ return this.dloCC.FS;
64
+ }
65
+ async compile(cwd, fs) {
66
+ const manifest = await manifest_1.Manifest.read(cwd, fs);
67
+ await this.initDloCC();
68
+ const precompilerDiagnostics = await this.persistDloFiles(cwd, fs, manifest);
69
+ const mainFile = vscode_uri_1.Utils.joinPath(cwd, manifest.dlo?.mainFile || defaultFiles_1.DefaultFiles.filePaths.dlo.mainDLO);
70
+ const options = [];
71
+ // todo only add cfg file to options if not already set!
72
+ const configFilePath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.cfg);
73
+ options.push(...(await this.readConfigFile(fs, configFilePath)));
74
+ if (this.preCompiler.pragmaDynamicFlag) {
75
+ options.push(this.preCompiler.pragmaDynamicFlag);
76
+ }
77
+ let exitCode = 0;
78
+ try {
79
+ exitCode = await this.dloCC.callMain([uriToMemFsPath(mainFile), ...options]);
80
+ // compiler doesn't have any errors
81
+ if (exitCode === 0) {
82
+ await this.persistGeneratedFiles(cwd, fs, mainFile);
83
+ }
84
+ }
85
+ catch (e) {
86
+ console.error(e);
87
+ }
88
+ return {
89
+ code: exitCode,
90
+ stdout: this.stdout,
91
+ stderr: this.stderr,
92
+ diagnostics: [...precompilerDiagnostics, ...this.parseWarningsAndErrors(this.stderr, mainFile)]
93
+ };
94
+ }
95
+ async persistGeneratedFiles(cwd, fs, mainFile) {
96
+ const baseName = vscode_uri_1.Utils.basename(mainFile).split('.')[0];
97
+ const possibleFiles = this.MEMFS.readdir('/');
98
+ for (const fileName of possibleFiles) {
99
+ if (fileName.startsWith(baseName)) {
100
+ const blob = this.MEMFS.readFile(fileName);
101
+ const distPath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.dist.dloPath, fileName);
102
+ await fs.writeFile(distPath, blob);
103
+ }
104
+ }
105
+ }
106
+ async readConfigFile(fs, configPath) {
107
+ if (await fs.stat(configPath)) {
108
+ const content = await fs.readFile(configPath);
109
+ return convertBlobToStringArray(content);
110
+ }
111
+ else {
112
+ return [];
113
+ }
114
+ }
115
+ /**
116
+ * Search for all dlo files and persist it to the MEMFS
117
+ * @param cwd
118
+ * @param fs
119
+ * @param manifest
120
+ * @private
121
+ */
122
+ async persistDloFiles(cwd, fs, manifest) {
123
+ const files = await fs.findFiles(cwd, '**/*.{dlo,inc}');
124
+ const precompilerDiagnostics = [];
125
+ // add dlo.cfg file to the file list
126
+ for (const file of files) {
127
+ if (await fs.stat(file)) {
128
+ const content = await fs.readFile(file);
129
+ const stringBlob = convertBlobToStringArray(content);
130
+ const diagnostics = await this.memFSwriteFile(cwd, manifest, file, stringBlob);
131
+ precompilerDiagnostics.push(...diagnostics);
132
+ }
133
+ }
134
+ return precompilerDiagnostics;
135
+ }
136
+ /**
137
+ * Precompile the given file and pass it to the MEMFS
138
+ * @param cwd
139
+ * @param manifest
140
+ * @param file
141
+ * @param stringBlob
142
+ */
143
+ async memFSwriteFile(cwd, manifest, file, stringBlob) {
144
+ const precompilerDiagnostics = [];
145
+ const preCompiled = await this.preCompiler.preCompileDloFile(cwd, manifest, file, stringBlob);
146
+ precompilerDiagnostics.push(...preCompiled.diagnostics);
147
+ this.memFSmkdir(file);
148
+ this.MEMFS.writeFile(uriToMemFsPath(file), iconv.encode(preCompiled.data, 'cp1252'));
149
+ return precompilerDiagnostics;
150
+ }
151
+ /**
152
+ * Move a file within the MEMFS
153
+ * @param oldUri
154
+ * @param newUri
155
+ */
156
+ async memFSmove(oldUri, newUri) {
157
+ try {
158
+ this.memFSmkdir(newUri);
159
+ this.MEMFS.rename(uriToMemFsPath(oldUri), uriToMemFsPath(newUri));
160
+ }
161
+ catch (e) {
162
+ console.error('memFSmove', e);
163
+ }
164
+ }
165
+ /**
166
+ * Remove a file from the MEMFS
167
+ * @param uri
168
+ */
169
+ async memFSunlink(uri) {
170
+ try {
171
+ this.MEMFS.unlink(uriToMemFsPath(uri));
172
+ }
173
+ catch (e) {
174
+ console.error('memFSunlink', e);
175
+ }
176
+ }
177
+ memFSmkdir(uri) {
178
+ const split = uriToMemFsPath(vscode_uri_1.Utils.dirname(uri)).split('/');
179
+ let dirname = '';
180
+ split.forEach(folder => {
181
+ if (!folder) {
182
+ return;
183
+ }
184
+ try {
185
+ dirname += `${folder}/`;
186
+ if (!this.memFSstat(dirname)) {
187
+ this.MEMFS.mkdir(dirname);
188
+ }
189
+ }
190
+ catch (e) {
191
+ console.error('memFSmkdir', e);
192
+ }
193
+ });
194
+ }
195
+ memFSstat(dirname) {
196
+ try {
197
+ this.MEMFS.stat(dirname);
198
+ return true;
199
+ }
200
+ catch (e) {
201
+ return false;
202
+ }
203
+ }
204
+ parseWarningsAndErrors(stderr, relatedFile) {
205
+ const compilerDiagnostics = [];
206
+ const messages = stderr.filter(line => !!line.trim());
207
+ for (const message of messages) {
208
+ if ((message.includes('Assertion failed:') || message.includes('Compilation aborted.')) && relatedFile) {
209
+ compilerDiagnostics.push({
210
+ file: relatedFile,
211
+ level: 'error',
212
+ line: 0,
213
+ message: message
214
+ });
215
+ continue;
216
+ }
217
+ // regular error/warning - such as:
218
+ // C:\Users\aai\rmstudio\apmparts\dlo-pawn\stdlib\rm-dde.inc(392) : error 036: empty statement
219
+ // main.p(138) : warning 203: symbol is never used: "log_str"
220
+ // main.p(6) : fatal error 100: cannot read from file: "oTests/module_t"
221
+ const i0 = message.indexOf(' : ');
222
+ const i1 = message.indexOf(': ', i0 + 3);
223
+ const fileNameAndLineNumber = message.substring(0, i0).trim();
224
+ const levelAndCode = message.substring(i0 + 3, i1).trim();
225
+ const msg = message.substring(i1 + 2).trim();
226
+ // ignore lines which do not contain err/warn msg (or are empty)
227
+ if (!fileNameAndLineNumber || !levelAndCode || !msg) {
228
+ continue;
229
+ }
230
+ const [fileName, lineNumber] = fileNameAndLineNumber.split(/[()(-)]/);
231
+ const decodeLevelAndCode = levelAndCode.split(' ');
232
+ const level = decodeLevelAndCode[decodeLevelAndCode.length - 2]; //lvl is always the second last
233
+ let posix = fileName.replace(/\\/g, '/');
234
+ if (posix.startsWith('/')) {
235
+ posix = posix.substring(1);
236
+ }
237
+ compilerDiagnostics.push({
238
+ file: vscode_uri_1.URI.parse(`file:///${posix}`),
239
+ level,
240
+ line: Number(lineNumber) - 1,
241
+ message: msg
242
+ });
243
+ }
244
+ return compilerDiagnostics;
245
+ }
246
+ //Symbol Compiler handling
247
+ /**
248
+ * Get a symbol compiler instance
249
+ */
250
+ async getSymbolCompiler() {
251
+ // generate a none exiting wasm compiler runtime as main filesystem
252
+ if (!this.dloCC) {
253
+ await this.initDloCC(true);
254
+ }
255
+ const compilerLog = {
256
+ stdout: [],
257
+ stderr: []
258
+ };
259
+ const dloSymbol = await DLO_MODULE({
260
+ noExitRuntime: false,
261
+ print: (data) => {
262
+ compilerLog.stdout.push(data);
263
+ },
264
+ printErr: (err) => {
265
+ compilerLog.stderr.push(err);
266
+ }
267
+ });
268
+ // mount the main filesystem
269
+ dloSymbol.FS.mkdir('/baseDir');
270
+ dloSymbol.FS.mount(dloSymbol.PROXYFS, {
271
+ root: '/',
272
+ fs: this.dloCC.FS
273
+ }, '/baseDir');
274
+ dloSymbol.FS.chdir('baseDir');
275
+ return {
276
+ compiler: dloSymbol,
277
+ print: compilerLog
278
+ };
279
+ }
280
+ }
281
+ exports.DloCompiler = DloCompiler;
282
+ function uriToMemFsPath(path) {
283
+ return path.fsPath.replace(/\\/g, '/');
284
+ }
285
+ /**
286
+ * Generates the DLO .cfg file for the dlo compiler
287
+ * @param cwd
288
+ * @param fs
289
+ * @param manifest
290
+ */
291
+ async function generateConfigFile(cwd, fs, manifest) {
292
+ const compileOptions = [
293
+ '-M', //map output for pawndbg to generate link map
294
+ '-v2' // verbosity of stdout -> 0=quiet, 1=normal, 2=code/data/stack usage report
295
+ ];
296
+ const defaultIncPath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.defaultInc);
297
+ compileOptions.push(`-p${uriToMemFsPath(defaultIncPath)}`);
298
+ const dloLibs = await dependencies_1.Dependencies.getDloDependencies(cwd, fs);
299
+ for (const dloLib of dloLibs) {
300
+ const dirName = vscode_uri_1.Utils.dirname(dloLib.path);
301
+ compileOptions.push(`-i${uriToMemFsPath(dirName)}`);
302
+ }
303
+ const dloConfiguration = manifest.dlo;
304
+ if (dloConfiguration) {
305
+ compileOptions.push(...dloConfiguration.compileOptions);
306
+ }
307
+ return {
308
+ path: vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.cfg),
309
+ data: compileOptions.join('\n')
310
+ };
311
+ }
312
+ //# sourceMappingURL=compiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dlo.d.ts","sourceRoot":"","sources":["../../src/dlo/dlo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAsB,cAAc,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAGjC,yBAAiB,GAAG,CAAC;IACb,MAAM,aAAa,yBAAmB,CAAC;IAC9C,KAAY,aAAa,GAAG,gBAAgB,CAAC;IAEtC,MAAM,WAAW,uBAAiB,CAAC;IAC1C,KAAY,WAAW,GAAG,cAAc,CAAC;IAEzC;;OAEG;IACI,MAAM,QAAQ,oBAAc,CAAC;IACpC,KAAY,QAAQ,GAAG,WAAW,CAAC;IAE5B,MAAM,UAAU,uBAAiB,CAAC;IAEzC;;;;OAIG;IACH,SAAsB,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,iBAK1D;CACD"}
package/out/dlo/dlo.js ADDED
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DLO = void 0;
4
+ const fileSequencer_1 = require("./fileSequencer");
5
+ const preCompiler_1 = require("./preCompiler");
6
+ const manifest_1 = require("../manifest");
7
+ const compiler_1 = require("./compiler");
8
+ const defaultFiles_1 = require("../defaultFiles");
9
+ var DLO;
10
+ (function (DLO) {
11
+ DLO.FileSequencer = fileSequencer_1.DloFileSequencer;
12
+ DLO.PreCompiler = preCompiler_1.DloPreCompiler;
13
+ /**
14
+ * The DLO Compiler
15
+ */
16
+ DLO.Compiler = compiler_1.DloCompiler;
17
+ DLO.uriToMemFs = compiler_1.uriToMemFsPath;
18
+ /**
19
+ * Generate the dlo.cfg file and write it to the .studio/auto/dlo directory
20
+ * @param cwd
21
+ * @param fs
22
+ */
23
+ async function exportDloConfig(cwd, fs) {
24
+ const manifest = await manifest_1.Manifest.read(cwd, fs);
25
+ const cfgData = await (0, compiler_1.generateConfigFile)(cwd, fs, manifest);
26
+ await fs.writeFile(cfgData.path, cfgData.data);
27
+ console.log('Generated', defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.cfg);
28
+ }
29
+ DLO.exportDloConfig = exportDloConfig;
30
+ })(DLO || (exports.DLO = DLO = {}));
31
+ //# sourceMappingURL=dlo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dlocc.d.ts","sourceRoot":"","sources":["../../src/dlo/dlocc.js"],"names":[],"mappings":";AAGQ,sDAgiHN"}