rapydscript-ng 0.7.24 → 0.8.1
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.
- package/CHANGELOG.md +28 -0
- package/README.md +80 -26
- package/bin/build.ts +117 -0
- package/bin/package.json +1 -0
- package/bin/rapydscript +65 -62
- package/build_wheels.py +133 -0
- package/editor-plugins/README.md +80 -0
- package/editor-plugins/nvim.lua +321 -0
- package/local-agent.md +28 -0
- package/package.json +4 -5
- package/publish.py +27 -17
- package/release/baselib-plain-pretty.js +448 -326
- package/release/baselib-plain-ugly.js +3 -3
- package/release/compiler.js +9027 -8139
- package/release/signatures.json +27 -27
- package/release/stdlib_modules.json +1 -0
- package/src/ast.pyj +428 -280
- package/src/baselib-builtins.pyj +49 -28
- package/src/baselib-containers.pyj +241 -226
- package/src/baselib-errors.pyj +8 -1
- package/src/baselib-internal.pyj +38 -23
- package/src/baselib-itertools.pyj +13 -7
- package/src/baselib-str.pyj +59 -84
- package/src/compiler.pyj +4 -4
- package/src/errors.pyj +3 -4
- package/src/lib/aes.pyj +46 -32
- package/src/lib/elementmaker.pyj +11 -9
- package/src/lib/encodings.pyj +15 -5
- package/src/lib/gettext.pyj +9 -4
- package/src/lib/math.pyj +106 -45
- package/src/lib/operator.pyj +10 -10
- package/src/lib/pythonize.pyj +2 -1
- package/src/lib/random.pyj +28 -21
- package/src/lib/re.pyj +492 -19
- package/src/lib/traceback.pyj +171 -29
- package/src/lib/uuid.pyj +2 -2
- package/src/output/classes.pyj +28 -27
- package/src/output/codegen.pyj +87 -83
- package/src/output/comments.pyj +8 -8
- package/src/output/exceptions.pyj +20 -21
- package/src/output/functions.pyj +66 -64
- package/src/output/literals.pyj +24 -23
- package/src/output/loops.pyj +84 -142
- package/src/output/modules.pyj +55 -68
- package/src/output/operators.pyj +40 -29
- package/src/output/statements.pyj +21 -15
- package/src/output/stream.pyj +82 -56
- package/src/output/utils.pyj +12 -8
- package/src/parse.pyj +971 -620
- package/src/string_interpolation.pyj +5 -3
- package/src/tokenizer.pyj +188 -148
- package/src/utils.pyj +32 -15
- package/test/_treeshake_mod.pyj +30 -0
- package/test/_treeshake_side_effect.pyj +9 -0
- package/test/ast_serialization.pyj +392 -0
- package/test/async.pyj +95 -0
- package/test/baselib.pyj +1 -2
- package/test/embedded_compiler.pyj +57 -0
- package/test/fmt.pyj +291 -0
- package/test/generic.pyj +16 -3
- package/test/imports.pyj +8 -6
- package/test/internationalization.pyj +38 -37
- package/test/lint.pyj +120 -117
- package/test/lsp.pyj +257 -0
- package/test/repl.pyj +70 -65
- package/test/sourcemaps.pyj +315 -0
- package/test/starargs.pyj +46 -39
- package/test/str.pyj +8 -0
- package/test/traceback.pyj +263 -0
- package/test/treeshaking.pyj +181 -0
- package/test/web_repl_export.pyj +88 -0
- package/tools/ast_serialize.mjs +557 -0
- package/tools/cli.mjs +531 -0
- package/tools/compile.mjs +205 -0
- package/tools/compiler.mjs +159 -0
- package/tools/{completer.js → completer.mjs} +6 -6
- package/tools/{embedded_compiler.js → embedded_compiler.mjs} +17 -13
- package/tools/export.js +109 -56
- package/tools/fmt.mjs +975 -0
- package/tools/{gettext.js → gettext.mjs} +46 -53
- package/tools/ini.mjs +175 -0
- package/tools/{lint.js → lint.mjs} +78 -55
- package/tools/lsp.mjs +964 -0
- package/tools/lsp_protocol.mjs +259 -0
- package/tools/lsp_symbols.mjs +418 -0
- package/tools/{msgfmt.js → msgfmt.mjs} +18 -18
- package/tools/{repl.js → repl.mjs} +56 -42
- package/tools/{self.js → self.mjs} +71 -46
- package/tools/sourcemap.mjs +123 -0
- package/tools/test.mjs +252 -0
- package/tools/treeshake.mjs +400 -0
- package/tools/{utils.js → utils.mjs} +26 -23
- package/tools/{web_repl.js → web_repl.mjs} +15 -13
- package/tools/web_repl_export.mjs +97 -0
- package/tree-sitter/README.md +101 -0
- package/tree-sitter/grammar.js +992 -0
- package/tree-sitter/package.json +43 -0
- package/tree-sitter/queries/highlights.scm +232 -0
- package/tree-sitter/queries/indents.scm +64 -0
- package/tree-sitter/queries/injections.scm +14 -0
- package/tree-sitter/queries/locals.scm +108 -0
- package/tree-sitter/src/grammar.json +4976 -0
- package/tree-sitter/src/node-types.json +2901 -0
- package/tree-sitter/src/parser.c +196465 -0
- package/tree-sitter/src/scanner.c +294 -0
- package/tree-sitter/src/tree_sitter/alloc.h +54 -0
- package/tree-sitter/src/tree_sitter/array.h +330 -0
- package/tree-sitter/src/tree_sitter/parser.h +286 -0
- package/tree-sitter/test/corpus/chaining.txt +99 -0
- package/tree-sitter/test/corpus/classes.txt +147 -0
- package/tree-sitter/test/corpus/comprehensions.txt +155 -0
- package/tree-sitter/test/corpus/containers.txt +242 -0
- package/tree-sitter/test/corpus/control_flow.txt +361 -0
- package/tree-sitter/test/corpus/decorators.txt +64 -0
- package/tree-sitter/test/corpus/existential.txt +102 -0
- package/tree-sitter/test/corpus/functions.txt +293 -0
- package/tree-sitter/test/corpus/imports.txt +117 -0
- package/tree-sitter/test/corpus/literals.txt +135 -0
- package/tree-sitter/test/corpus/operators.txt +296 -0
- package/tree-sitter/test/corpus/statements.txt +189 -0
- package/tree-sitter/test/corpus/strings.txt +90 -0
- package/tree-sitter/test/corpus/subscripts.txt +227 -0
- package/tree-sitter/tree-sitter.json +36 -0
- package/web-repl/env.js +35 -23
- package/web-repl/main.js +8 -8
- package/bin/export +0 -75
- package/bin/web-repl-export +0 -102
- package/tools/cli.js +0 -523
- package/tools/compile.js +0 -184
- package/tools/compiler.js +0 -84
- package/tools/ini.js +0 -65
- package/tools/test.js +0 -110
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/* vim:fileencoding=utf-8
|
|
2
|
-
*
|
|
2
|
+
*
|
|
3
3
|
* Copyright (C) 2015 Kovid Goyal <kovid at kovidgoyal.net>
|
|
4
4
|
*
|
|
5
5
|
* Distributed under terms of the BSD license
|
|
6
6
|
*/
|
|
7
|
-
"use strict";
|
|
7
|
+
"use strict";
|
|
8
8
|
|
|
9
9
|
function unesc(string) {
|
|
10
10
|
return string.replace(/\\"/g, '"').replace(/\\n/g, '\n').replace(/\\r/g, '\r').replace(/\\t/g, '\t').replace(/\\\\/g, '\\');
|
|
@@ -41,7 +41,7 @@ function parse(data, on_error) {
|
|
|
41
41
|
var match = /^nplurals\s*=\s*(\d+)\s*;/.exec(plural_forms);
|
|
42
42
|
if (!match || match[1] === undefined) fatal('Invalid Plural-Forms header:', plural_forms);
|
|
43
43
|
nplurals = parseInt(match[1]);
|
|
44
|
-
}
|
|
44
|
+
}
|
|
45
45
|
else if (line.startsWith('Language:')) {
|
|
46
46
|
language = line.slice('Language:'.length).trim();
|
|
47
47
|
}
|
|
@@ -87,7 +87,7 @@ function parse(data, on_error) {
|
|
|
87
87
|
} else if (line.startsWith('msgid ')) {
|
|
88
88
|
current_entry.msgid = read_string(line.slice('msgid '.length));
|
|
89
89
|
current_entry.lnum = lnum;
|
|
90
|
-
state = function(line, lines) {
|
|
90
|
+
state = function(line, lines) {
|
|
91
91
|
continuation(line, lines, function(x) { current_entry.msgid += x; }, after_msgid);
|
|
92
92
|
};
|
|
93
93
|
} else {
|
|
@@ -98,16 +98,16 @@ function parse(data, on_error) {
|
|
|
98
98
|
function after_msgid(line, lines) {
|
|
99
99
|
if (line.startsWith('msgid_plural ')) {
|
|
100
100
|
current_entry.msgid_plural = read_string(line.slice('msgid_plural '.length));
|
|
101
|
-
state = function(line, lines) {
|
|
101
|
+
state = function(line, lines) {
|
|
102
102
|
continuation(line, lines, function(x) { current_entry.msgid_plural += x; }, msgstr);
|
|
103
103
|
};
|
|
104
|
-
}
|
|
105
|
-
|
|
104
|
+
}
|
|
105
|
+
|
|
106
106
|
else if (line.startsWith('msgstr ') || line.startsWith('msgstr[')) {
|
|
107
107
|
state = msgstr;
|
|
108
108
|
msgstr(line, lines);
|
|
109
|
-
}
|
|
110
|
-
|
|
109
|
+
}
|
|
110
|
+
|
|
111
111
|
else fatal('Expecting either msgstr or msgid_plural at line number:', lnum);
|
|
112
112
|
|
|
113
113
|
}
|
|
@@ -116,10 +116,10 @@ function parse(data, on_error) {
|
|
|
116
116
|
if (line.startsWith('msgstr ')) {
|
|
117
117
|
if (current_entry.msgid_plural !== null) fatal('Expecting msgstr[0] at line number:', lnum);
|
|
118
118
|
current_entry.msgstr.push(read_string(line.slice('msgstr '.length)));
|
|
119
|
-
state = function(line, lines) {
|
|
119
|
+
state = function(line, lines) {
|
|
120
120
|
continuation(line, lines, function(x) { current_entry.msgstr[current_entry.msgstr.length - 1] += x; }, msgstr);
|
|
121
121
|
};
|
|
122
|
-
}
|
|
122
|
+
}
|
|
123
123
|
|
|
124
124
|
else if (line[0] === '#' || line.startsWith('msgid ')) {
|
|
125
125
|
if (!current_entry.msgstr.length) fatal('Expecting msgstr at line number:', lnum);
|
|
@@ -134,7 +134,7 @@ function parse(data, on_error) {
|
|
|
134
134
|
if (!pnum || pnum[1] === undefined) fatal('Malformed msgstr at line number:', lnum);
|
|
135
135
|
var idx = parseInt(pnum[1]);
|
|
136
136
|
current_entry.msgstr[idx] = read_string(line.slice(pnum[0].length));
|
|
137
|
-
state = function(line, lines) {
|
|
137
|
+
state = function(line, lines) {
|
|
138
138
|
continuation(line, lines, function(x) { current_entry.msgstr[idx] += x; }, msgstr);
|
|
139
139
|
};
|
|
140
140
|
}
|
|
@@ -159,9 +159,9 @@ function read_stdin(cont) {
|
|
|
159
159
|
var chunks = [];
|
|
160
160
|
process.stdin.setEncoding('utf8');
|
|
161
161
|
|
|
162
|
-
process.stdin.on('readable', function () {
|
|
162
|
+
process.stdin.on('readable', function () {
|
|
163
163
|
var chunk = process.stdin.read();
|
|
164
|
-
if (chunk) chunks.push(chunk);
|
|
164
|
+
if (chunk) chunks.push(chunk);
|
|
165
165
|
});
|
|
166
166
|
|
|
167
167
|
process.stdin.on('end', function() { cont(chunks.join('')); });
|
|
@@ -176,12 +176,12 @@ function serialize_catalog(catalog, options) {
|
|
|
176
176
|
return JSON.stringify({'plural_forms':catalog.plural_forms, 'entries':entries, 'language':catalog.language});
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
|
|
179
|
+
export function cli(argv, base_path, src_path, lib_path) {
|
|
180
180
|
read_stdin(function process(data) {
|
|
181
181
|
var catalog = parse(data);
|
|
182
182
|
console.log(serialize_catalog(catalog, argv));
|
|
183
183
|
});
|
|
184
|
-
}
|
|
184
|
+
}
|
|
185
185
|
|
|
186
|
-
|
|
187
|
-
|
|
186
|
+
export { parse };
|
|
187
|
+
export function build(data, options) { return serialize_catalog(parse(data), options); }
|
|
@@ -4,20 +4,26 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Distributed under terms of the BSD license.
|
|
6
6
|
*/
|
|
7
|
-
"use strict";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
import vm from 'vm';
|
|
12
|
+
import util from 'util';
|
|
13
|
+
import { createRequire } from 'module';
|
|
14
|
+
import * as utils from './utils.mjs';
|
|
15
|
+
import { EMBEDDED_STDLIB_PREFIX } from './compiler.mjs';
|
|
16
|
+
import completelib from './completer.mjs';
|
|
17
|
+
|
|
15
18
|
var colored = utils.safe_colored;
|
|
16
|
-
var
|
|
19
|
+
var _rapydscript_compiler = typeof create_rapydscript_compiler !== 'undefined' ? create_rapydscript_compiler : globalThis.create_rapydscript_compiler;
|
|
17
20
|
var has_prop = Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);
|
|
18
21
|
|
|
22
|
+
// In Node.js ESM context, require is not available; use createRequire.
|
|
23
|
+
var _cjs_require = typeof require !== 'undefined' ? require : createRequire(process.cwd() + '/');
|
|
24
|
+
|
|
19
25
|
function create_ctx(baselib, show_js, console) {
|
|
20
|
-
var ctx = vm.createContext({'console':console, 'show_js': !!show_js, 'RapydScript':
|
|
26
|
+
var ctx = vm.createContext({'console':console, 'show_js': !!show_js, 'RapydScript':null, 'require':_cjs_require});
|
|
21
27
|
vm.runInContext(baselib, ctx, {'filename':'baselib-plain-pretty.js'});
|
|
22
28
|
vm.runInContext('var __name__ = "__repl__";', ctx);
|
|
23
29
|
return ctx;
|
|
@@ -42,40 +48,57 @@ function repl_defaults(options) {
|
|
|
42
48
|
if (!options.ps1) options.ps1 = '>>> ';
|
|
43
49
|
if (!options.ps2) options.ps2 = '... ';
|
|
44
50
|
if (!options.console) options.console = console;
|
|
45
|
-
if (!options.readline) options.readline =
|
|
51
|
+
if (!options.readline) options.readline = _cjs_require('readline');
|
|
46
52
|
if (options.terminal === undefined) options.terminal = options.output.isTTY;
|
|
47
53
|
if (options.histfile === undefined) options.histfile = path.join(cachedir, 'rapydscript-repl.history');
|
|
48
|
-
|
|
54
|
+
|
|
49
55
|
options.colored = (options.terminal) ? colored : (function (string) { return string; });
|
|
50
56
|
options.historySize = options.history_size || 1000;
|
|
51
57
|
return options;
|
|
52
58
|
}
|
|
53
59
|
|
|
54
|
-
function read_history(options) {
|
|
60
|
+
async function read_history(options) {
|
|
55
61
|
if (options.histfile) {
|
|
56
62
|
try {
|
|
57
|
-
return fs.
|
|
63
|
+
return (await fs.promises.readFile(options.histfile, 'utf-8')).split('\n');
|
|
58
64
|
} catch (e) { return []; }
|
|
59
65
|
}
|
|
66
|
+
return [];
|
|
60
67
|
}
|
|
61
68
|
|
|
62
|
-
function write_history(options, history) {
|
|
69
|
+
async function write_history(options, history) {
|
|
63
70
|
if (options.histfile) {
|
|
64
|
-
history = history.join('\n');
|
|
65
71
|
try {
|
|
66
|
-
|
|
72
|
+
await fs.promises.writeFile(options.histfile, history.join('\n'), 'utf-8');
|
|
67
73
|
} catch (e) {}
|
|
68
74
|
}
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
|
|
72
|
-
|
|
78
|
+
export default async function(options) {
|
|
79
|
+
var RapydScript = _rapydscript_compiler();
|
|
73
80
|
options = repl_defaults(options);
|
|
74
81
|
options.completer = completer;
|
|
75
82
|
var rl = options.readline.createInterface(options);
|
|
76
83
|
var ps1 = options.colored(options.ps1, 'green');
|
|
77
84
|
var ps2 = options.colored(options.ps2, 'yellow');
|
|
78
|
-
|
|
85
|
+
|
|
86
|
+
// Read baselib synchronously: the repl must initialize synchronously so
|
|
87
|
+
// that the readline interface and prompt are ready before returning.
|
|
88
|
+
const _embedded = globalThis.__rapydscript_embedded__;
|
|
89
|
+
var baselib_plain = _embedded?.['baselib-plain-pretty.js'] ??
|
|
90
|
+
fs.readFileSync(path.join(options.lib_path, 'baselib-plain-pretty.js'), 'utf-8');
|
|
91
|
+
|
|
92
|
+
function print_ast(ast, keep_baselib) {
|
|
93
|
+
var output_options = {omit_baselib:!keep_baselib, write_name:false, private_scope:false, beautify:true, keep_docstrings:true};
|
|
94
|
+
if (keep_baselib) output_options.baselib_plain = baselib_plain;
|
|
95
|
+
var output = new RapydScript.OutputStream(output_options);
|
|
96
|
+
ast.print(output);
|
|
97
|
+
return output.get();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
var ctx = create_ctx(print_ast(await RapydScript.parse('(def ():\n yield 1\n)'), true), options.show_js, options.console);
|
|
101
|
+
ctx.RapydScript = RapydScript;
|
|
79
102
|
var buffer = [];
|
|
80
103
|
var more = false;
|
|
81
104
|
var LINE_CONTINUATION_CHARS = ':\\';
|
|
@@ -90,15 +113,6 @@ module.exports = function(options) {
|
|
|
90
113
|
options.console.log(options.colored('Use show_js=True to have the REPL show the compiled JavaScript before executing it.', 'green', true));
|
|
91
114
|
options.console.log();
|
|
92
115
|
|
|
93
|
-
function print_ast(ast, keep_baselib) {
|
|
94
|
-
var output_options = {omit_baselib:!keep_baselib, write_name:false, private_scope:false, beautify:true, keep_docstrings:true};
|
|
95
|
-
if (keep_baselib) output_options.baselib_plain = fs.readFileSync(path.join(options.lib_path, 'baselib-plain-pretty.js'), 'utf-8');
|
|
96
|
-
var output = new RapydScript.OutputStream(output_options);
|
|
97
|
-
ast.print(output);
|
|
98
|
-
return output.get();
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
102
116
|
function resetbuffer() { buffer = []; }
|
|
103
117
|
|
|
104
118
|
function completer(line) {
|
|
@@ -142,14 +156,14 @@ module.exports = function(options) {
|
|
|
142
156
|
}
|
|
143
157
|
}
|
|
144
158
|
|
|
145
|
-
function compile_source(source) {
|
|
159
|
+
async function compile_source(source) {
|
|
146
160
|
var classes = (toplevel) ? toplevel.classes : undefined;
|
|
147
161
|
var scoped_flags = (toplevel) ? toplevel.scoped_flags: undefined;
|
|
148
162
|
try {
|
|
149
|
-
toplevel = RapydScript.parse(source, {
|
|
163
|
+
toplevel = await RapydScript.parse(source, {
|
|
150
164
|
'filename':'<repl>',
|
|
151
165
|
'basedir': process.cwd(),
|
|
152
|
-
'libdir': options.imp_path,
|
|
166
|
+
'libdir': globalThis.__rapydscript_embedded__ ? EMBEDDED_STDLIB_PREFIX : options.imp_path,
|
|
153
167
|
'import_dirs': import_dirs,
|
|
154
168
|
'classes': classes,
|
|
155
169
|
'scoped_flags': scoped_flags,
|
|
@@ -174,33 +188,33 @@ module.exports = function(options) {
|
|
|
174
188
|
return false;
|
|
175
189
|
}
|
|
176
190
|
|
|
177
|
-
function push(line) {
|
|
191
|
+
async function push(line) {
|
|
178
192
|
buffer.push(line);
|
|
179
193
|
var ll = line.trimRight();
|
|
180
194
|
if (ll && LINE_CONTINUATION_CHARS.indexOf(ll.substr(ll.length - 1)) > -1)
|
|
181
195
|
return true;
|
|
182
196
|
var source = buffer.join('\n');
|
|
183
197
|
if (!source.trim()) { resetbuffer(); return false; }
|
|
184
|
-
var incomplete = compile_source(source);
|
|
198
|
+
var incomplete = await compile_source(source);
|
|
185
199
|
if (!incomplete) resetbuffer();
|
|
186
200
|
return incomplete;
|
|
187
201
|
}
|
|
188
202
|
|
|
189
|
-
rl.on('line', function(line) {
|
|
203
|
+
rl.on('line', async function(line) {
|
|
190
204
|
if (more) {
|
|
191
|
-
// We are in a block
|
|
205
|
+
// We are in a block
|
|
192
206
|
var line_is_empty = !line.trimLeft();
|
|
193
207
|
if (line_is_empty && buffer.length && !buffer[buffer.length - 1].trimLeft()) {
|
|
194
208
|
// We have two empty lines, evaluate the block
|
|
195
|
-
more = push(line.trimLeft());
|
|
209
|
+
more = await push(line.trimLeft());
|
|
196
210
|
} else buffer.push(line);
|
|
197
|
-
} else more = push(line); // Not in a block, evaluate line
|
|
211
|
+
} else more = await push(line); // Not in a block, evaluate line
|
|
198
212
|
prompt();
|
|
199
213
|
})
|
|
200
|
-
|
|
201
|
-
.on('close', function() {
|
|
214
|
+
|
|
215
|
+
.on('close', async function() {
|
|
202
216
|
options.console.log('Bye!');
|
|
203
|
-
if (rl.history) write_history(options, rl.history);
|
|
217
|
+
if (rl.history) await write_history(options, rl.history);
|
|
204
218
|
process.exit(0);
|
|
205
219
|
})
|
|
206
220
|
|
|
@@ -216,6 +230,6 @@ module.exports = function(options) {
|
|
|
216
230
|
prompt();
|
|
217
231
|
});
|
|
218
232
|
|
|
219
|
-
rl.history =
|
|
233
|
+
read_history(options).then(function(history) { rl.history = history; });
|
|
220
234
|
prompt();
|
|
221
|
-
}
|
|
235
|
+
}
|
|
@@ -4,25 +4,31 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Distributed under terms of the BSD license.
|
|
6
6
|
*/
|
|
7
|
-
"use strict"; /*jshint node:true */
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import crypto from 'crypto';
|
|
10
|
+
import fs from 'fs';
|
|
11
|
+
import vm from 'vm';
|
|
12
|
+
import zlib from 'zlib';
|
|
13
|
+
import { createRequire } from 'module';
|
|
14
|
+
import { fileURLToPath } from 'url';
|
|
15
|
+
import { create_compiler } from './compiler.mjs';
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
const require = createRequire(import.meta.url);
|
|
18
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
19
|
+
|
|
20
|
+
async function compile_baselib(RapydScript, src_path) {
|
|
21
|
+
var items = (await fs.promises.readdir(src_path)).filter(function(name) {
|
|
17
22
|
return name.slice(0, 'baselib-'.length) === 'baselib-' && name.slice(-4) == '.pyj';
|
|
18
23
|
});
|
|
19
24
|
var ans = {'pretty': '', 'ugly': ''};
|
|
20
25
|
|
|
21
|
-
items.sort()
|
|
26
|
+
items.sort();
|
|
27
|
+
for (const fname of items) {
|
|
22
28
|
var name = fname.slice('baselib-'.length, -4), ast;
|
|
23
|
-
var raw = fs.
|
|
29
|
+
var raw = await fs.promises.readFile(path.join(src_path, fname), 'utf-8');
|
|
24
30
|
try {
|
|
25
|
-
ast = RapydScript.parse(raw, {filename:fname, basedir:src_path});
|
|
31
|
+
ast = await RapydScript.parse(raw, {filename:fname, basedir:src_path});
|
|
26
32
|
} catch (e) {
|
|
27
33
|
if (!(e instanceof RapydScript.SyntaxError)) throw e;
|
|
28
34
|
console.error(e.toString());
|
|
@@ -30,52 +36,56 @@ function compile_baselib(RapydScript, src_path) {
|
|
|
30
36
|
}
|
|
31
37
|
[true, false].forEach(function (beautify) {
|
|
32
38
|
var output = new RapydScript.OutputStream({
|
|
33
|
-
beautify: beautify, write_name: false, private_scope:false, omit_baselib: true,
|
|
39
|
+
beautify: beautify, write_name: false, private_scope:false, omit_baselib: true,
|
|
34
40
|
});
|
|
35
41
|
ast.print(output);
|
|
36
42
|
ans[(beautify) ? 'pretty' : 'ugly'] += output.get();
|
|
37
43
|
});
|
|
38
|
-
}
|
|
44
|
+
}
|
|
39
45
|
return ans;
|
|
40
46
|
}
|
|
41
47
|
|
|
42
|
-
function check_for_changes(base_path, src_path, signatures) {
|
|
48
|
+
async function check_for_changes(base_path, src_path, signatures) {
|
|
43
49
|
// Check if any of the files involved in the build process have changed,
|
|
44
50
|
// as compared to the saved sha1 hashes from the last build
|
|
45
51
|
var saved_hashes = {}, hashes = {}, sources = {};
|
|
46
52
|
var compiler_changed = false, compiler_hash, source_hash;
|
|
47
53
|
try {
|
|
48
|
-
saved_hashes = JSON.parse(fs.
|
|
54
|
+
saved_hashes = JSON.parse(await fs.promises.readFile(signatures, 'utf-8'));
|
|
49
55
|
} catch (e) {
|
|
50
56
|
if (e.code != 'ENOENT') throw (e);
|
|
51
57
|
}
|
|
52
58
|
|
|
53
59
|
var src_file_names = [];
|
|
54
60
|
|
|
55
|
-
function process_dir(p) {
|
|
56
|
-
fs.
|
|
61
|
+
async function process_dir(p) {
|
|
62
|
+
var entries = await fs.promises.readdir(p);
|
|
63
|
+
for (const name of entries) {
|
|
57
64
|
var fp = path.join(p, name);
|
|
58
65
|
if (name.substr(-4) === '.pyj') src_file_names.push(path.relative(src_path, fp));
|
|
59
|
-
else if (name != 'lib'
|
|
60
|
-
|
|
66
|
+
else if (name != 'lib') {
|
|
67
|
+
var stat = await fs.promises.stat(fp);
|
|
68
|
+
if (stat.isDirectory()) await process_dir(fp);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
61
71
|
}
|
|
62
|
-
process_dir(src_path);
|
|
72
|
+
await process_dir(src_path);
|
|
63
73
|
|
|
64
74
|
compiler_hash = crypto.createHash('sha1');
|
|
65
75
|
source_hash = crypto.createHash('sha1');
|
|
66
|
-
|
|
76
|
+
for (const fname of src_file_names) {
|
|
67
77
|
var src = path.join(src_path, fname);
|
|
68
|
-
sources[src] = fs.
|
|
78
|
+
sources[src] = await fs.promises.readFile(src, 'utf-8');
|
|
69
79
|
compiler_hash.update(sources[src]);
|
|
70
80
|
source_hash.update(sources[src]);
|
|
71
81
|
var h = crypto.createHash('sha1');
|
|
72
82
|
h.update(sources[src]);
|
|
73
83
|
hashes[fname.split('.')[0]] = h.digest('hex');
|
|
74
|
-
}
|
|
75
|
-
var compiler_files = [
|
|
76
|
-
|
|
77
|
-
compiler_hash.update(fs.
|
|
78
|
-
}
|
|
84
|
+
}
|
|
85
|
+
var compiler_files = [__filename, path.join(base_path, 'tools', 'compiler.mjs')];
|
|
86
|
+
for (const fpath of compiler_files) {
|
|
87
|
+
compiler_hash.update(await fs.promises.readFile(fpath, 'utf-8'));
|
|
88
|
+
}
|
|
79
89
|
hashes['#compiler#'] = compiler_hash.digest('hex');
|
|
80
90
|
hashes['#compiled_with#'] = saved_hashes['#compiler#'] || 'unknown';
|
|
81
91
|
source_hash = source_hash.digest('hex');
|
|
@@ -91,15 +101,15 @@ function check_for_changes(base_path, src_path, signatures) {
|
|
|
91
101
|
}
|
|
92
102
|
|
|
93
103
|
|
|
94
|
-
function compile(src_path, lib_path, sources, source_hash, profile) {
|
|
104
|
+
async function compile(src_path, lib_path, sources, source_hash, profile) {
|
|
95
105
|
var file = path.join(src_path, 'compiler.pyj');
|
|
96
106
|
var t1 = new Date().getTime();
|
|
97
|
-
var RapydScript =
|
|
107
|
+
var RapydScript = await create_compiler();
|
|
98
108
|
var output_options, profiler, cpu_profile;
|
|
99
|
-
var compiled_baselib = compile_baselib(RapydScript, src_path);
|
|
109
|
+
var compiled_baselib = await compile_baselib(RapydScript, src_path);
|
|
100
110
|
var out_path = path.join(path.dirname(lib_path), 'dev');
|
|
101
111
|
try {
|
|
102
|
-
fs.
|
|
112
|
+
await fs.promises.mkdir(out_path);
|
|
103
113
|
} catch (e) {
|
|
104
114
|
if (e.code != 'EEXIST') throw e;
|
|
105
115
|
}
|
|
@@ -107,8 +117,8 @@ function compile(src_path, lib_path, sources, source_hash, profile) {
|
|
|
107
117
|
|
|
108
118
|
var raw = sources[file], toplevel;
|
|
109
119
|
|
|
110
|
-
function parse_file(code, file) {
|
|
111
|
-
return RapydScript.parse(code, {
|
|
120
|
+
async function parse_file(code, file) {
|
|
121
|
+
return await RapydScript.parse(code, {
|
|
112
122
|
filename: file,
|
|
113
123
|
basedir: path.dirname(file),
|
|
114
124
|
libdir: path.join(src_path, 'lib'),
|
|
@@ -120,10 +130,10 @@ function compile(src_path, lib_path, sources, source_hash, profile) {
|
|
|
120
130
|
profiler = require('v8-profiler');
|
|
121
131
|
profiler.startProfiling();
|
|
122
132
|
}
|
|
123
|
-
toplevel = parse_file(raw, file);
|
|
133
|
+
toplevel = await parse_file(raw, file);
|
|
124
134
|
if (profile) {
|
|
125
135
|
cpu_profile = profiler.stopProfiling();
|
|
126
|
-
fs.
|
|
136
|
+
await fs.promises.writeFile('self.cpuprofile', JSON.stringify(cpu_profile), 'utf-8');
|
|
127
137
|
}
|
|
128
138
|
} catch (e) {
|
|
129
139
|
if (!(e instanceof RapydScript.SyntaxError)) throw e;
|
|
@@ -133,30 +143,45 @@ function compile(src_path, lib_path, sources, source_hash, profile) {
|
|
|
133
143
|
var output = new RapydScript.OutputStream(output_options);
|
|
134
144
|
toplevel.print(output);
|
|
135
145
|
output = output.get().replace('__COMPILER_VERSION__', source_hash);
|
|
136
|
-
fs.
|
|
137
|
-
fs.
|
|
138
|
-
fs.
|
|
146
|
+
await fs.promises.writeFile(path.join(out_path, 'compiler.js'), output, "utf8");
|
|
147
|
+
await fs.promises.writeFile(path.join(out_path, 'baselib-plain-pretty.js'), compiled_baselib.pretty, 'utf-8');
|
|
148
|
+
await fs.promises.writeFile(path.join(out_path, 'baselib-plain-ugly.js'), compiled_baselib.ugly, 'utf-8');
|
|
139
149
|
console.log('Compiler built in', (new Date().getTime() - t1)/1000, 'seconds\n');
|
|
140
150
|
return output;
|
|
141
151
|
}
|
|
142
152
|
|
|
143
|
-
function run_single_compile(base_path, src_path, lib_path, profile) {
|
|
153
|
+
async function run_single_compile(base_path, src_path, lib_path, profile) {
|
|
144
154
|
var out_path = path.join(path.dirname(lib_path), 'dev');
|
|
145
155
|
var signatures = path.join(out_path, 'signatures.json');
|
|
146
|
-
var temp = check_for_changes(base_path, src_path, signatures);
|
|
156
|
+
var temp = await check_for_changes(base_path, src_path, signatures);
|
|
147
157
|
var source_hash = temp[0], compiler_changed = temp[1], sources = temp[2], hashes = temp[3];
|
|
148
|
-
|
|
158
|
+
|
|
149
159
|
if (compiler_changed) {
|
|
150
|
-
compile(src_path, lib_path, sources, source_hash, profile);
|
|
151
|
-
fs.
|
|
160
|
+
await compile(src_path, lib_path, sources, source_hash, profile);
|
|
161
|
+
await fs.promises.writeFile(signatures, JSON.stringify(hashes, null, 4));
|
|
152
162
|
} else console.log('Compiler is built with the up-to-date version of itself');
|
|
153
163
|
return compiler_changed;
|
|
154
164
|
}
|
|
155
165
|
|
|
156
|
-
|
|
166
|
+
async function write_stdlib_modules(src_path, out_path) {
|
|
167
|
+
var lib_dir = path.join(src_path, 'lib');
|
|
168
|
+
var entries = await fs.promises.readdir(lib_dir);
|
|
169
|
+
var modules = entries
|
|
170
|
+
.filter(function (name) { return name.slice(-4) === '.pyj'; })
|
|
171
|
+
.map(function (name) { return name.slice(0, -4); })
|
|
172
|
+
.sort();
|
|
173
|
+
await fs.promises.writeFile(
|
|
174
|
+
path.join(out_path, 'stdlib_modules.json'),
|
|
175
|
+
JSON.stringify(modules),
|
|
176
|
+
'utf-8'
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export default async function compile_self(base_path, src_path, lib_path, complete, profile) {
|
|
157
181
|
var changed;
|
|
158
182
|
do {
|
|
159
|
-
changed = run_single_compile(base_path, src_path, lib_path, profile);
|
|
183
|
+
changed = await run_single_compile(base_path, src_path, lib_path, profile);
|
|
160
184
|
lib_path = path.join(path.dirname(lib_path), 'dev');
|
|
161
185
|
} while (changed && complete);
|
|
162
|
-
|
|
186
|
+
await write_stdlib_modules(src_path, lib_path);
|
|
187
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* sourcemap.js
|
|
3
|
+
* Copyright (C) 2015 Kovid Goyal <kovid at kovidgoyal.net>
|
|
4
|
+
*
|
|
5
|
+
* Distributed under terms of the BSD license.
|
|
6
|
+
*/
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
import path from 'path';
|
|
10
|
+
|
|
11
|
+
// Base64 VLQ encoding for source maps (see http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/)
|
|
12
|
+
var BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
13
|
+
var VLQ_BASE_SHIFT = 5;
|
|
14
|
+
var VLQ_BASE = 1 << VLQ_BASE_SHIFT; // 32
|
|
15
|
+
var VLQ_BASE_MASK = VLQ_BASE - 1; // 31
|
|
16
|
+
var VLQ_CONTINUATION_BIT = VLQ_BASE; // 32
|
|
17
|
+
|
|
18
|
+
function to_vlq_signed(value) {
|
|
19
|
+
return (value < 0) ? ((-value) << 1) + 1 : (value << 1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function encode_vlq(value) {
|
|
23
|
+
var encoded = '';
|
|
24
|
+
var vlq = to_vlq_signed(value);
|
|
25
|
+
do {
|
|
26
|
+
var digit = vlq & VLQ_BASE_MASK;
|
|
27
|
+
vlq >>>= VLQ_BASE_SHIFT;
|
|
28
|
+
if (vlq > 0) digit |= VLQ_CONTINUATION_BIT;
|
|
29
|
+
encoded += BASE64_CHARS[digit];
|
|
30
|
+
} while (vlq > 0);
|
|
31
|
+
return encoded;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function encode_segment(fields) {
|
|
35
|
+
return fields.map(encode_vlq).join('');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Generate a source map JSON object from an array of segments.
|
|
39
|
+
// Each segment is: [gen_line_0based, gen_col, src_file, src_line_0based, src_col]
|
|
40
|
+
// output_file: the name of the generated JS file
|
|
41
|
+
// source_root: optional prefix for source paths
|
|
42
|
+
function generate_source_map(segments, output_file, source_root) {
|
|
43
|
+
if (!segments || !segments.length) {
|
|
44
|
+
return JSON.stringify({
|
|
45
|
+
version: 3,
|
|
46
|
+
file: output_file || '',
|
|
47
|
+
sourceRoot: source_root || '',
|
|
48
|
+
sources: [],
|
|
49
|
+
names: [],
|
|
50
|
+
mappings: ''
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Build sources index
|
|
55
|
+
var sources_index = {};
|
|
56
|
+
var sources = [];
|
|
57
|
+
segments.forEach(function(seg) {
|
|
58
|
+
var src = seg[2];
|
|
59
|
+
if (src && !(src in sources_index)) {
|
|
60
|
+
sources_index[src] = sources.length;
|
|
61
|
+
sources.push(src);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Sort segments by generated position
|
|
66
|
+
var sorted = segments.slice().sort(function(a, b) {
|
|
67
|
+
if (a[0] !== b[0]) return a[0] - b[0];
|
|
68
|
+
return a[1] - b[1];
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Remove duplicate segments at the same generated position
|
|
72
|
+
var deduped = [];
|
|
73
|
+
var prev_gen_line = -1, prev_gen_col = -1;
|
|
74
|
+
sorted.forEach(function(seg) {
|
|
75
|
+
if (seg[0] === prev_gen_line && seg[1] === prev_gen_col) return;
|
|
76
|
+
prev_gen_line = seg[0];
|
|
77
|
+
prev_gen_col = seg[1];
|
|
78
|
+
deduped.push(seg);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Find max line
|
|
82
|
+
var max_line = 0;
|
|
83
|
+
deduped.forEach(function(seg) { if (seg[0] > max_line) max_line = seg[0]; });
|
|
84
|
+
|
|
85
|
+
// Group segments by generated line
|
|
86
|
+
var by_line = [];
|
|
87
|
+
for (var i = 0; i <= max_line; i++) by_line.push([]);
|
|
88
|
+
deduped.forEach(function(seg) { by_line[seg[0]].push(seg); });
|
|
89
|
+
|
|
90
|
+
// Encode mappings
|
|
91
|
+
var prev_src_idx = 0, prev_src_line = 0, prev_src_col = 0;
|
|
92
|
+
var mappings_lines = by_line.map(function(line_segs) {
|
|
93
|
+
var prev_col = 0;
|
|
94
|
+
return line_segs.map(function(seg) {
|
|
95
|
+
var gen_col = seg[1];
|
|
96
|
+
var src_idx = sources_index[seg[2]];
|
|
97
|
+
var src_line = seg[3];
|
|
98
|
+
var src_col = seg[4];
|
|
99
|
+
var result = encode_segment([
|
|
100
|
+
gen_col - prev_col,
|
|
101
|
+
src_idx - prev_src_idx,
|
|
102
|
+
src_line - prev_src_line,
|
|
103
|
+
src_col - prev_src_col
|
|
104
|
+
]);
|
|
105
|
+
prev_col = gen_col;
|
|
106
|
+
prev_src_idx = src_idx;
|
|
107
|
+
prev_src_line = src_line;
|
|
108
|
+
prev_src_col = src_col;
|
|
109
|
+
return result;
|
|
110
|
+
}).join(',');
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
return JSON.stringify({
|
|
114
|
+
version: 3,
|
|
115
|
+
file: output_file ? path.basename(output_file) : '',
|
|
116
|
+
sourceRoot: source_root || '',
|
|
117
|
+
sources: sources,
|
|
118
|
+
names: [],
|
|
119
|
+
mappings: mappings_lines.join(';')
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export { generate_source_map };
|