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,12 +1,14 @@
|
|
|
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
|
+
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
import path from 'path';
|
|
8
11
|
|
|
9
|
-
var comment_contents = /\/\*!?(?:\@preserve)?[ \t]*(?:\r\n|\n)([\s\S]*?)(?:\r\n|\n)[ \t]*\*\//;
|
|
10
12
|
var colors = ['red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'];
|
|
11
13
|
|
|
12
14
|
function ansi(code) {
|
|
@@ -14,13 +16,13 @@ function ansi(code) {
|
|
|
14
16
|
return String.fromCharCode(27) + '[' + code + 'm';
|
|
15
17
|
}
|
|
16
18
|
|
|
17
|
-
function path_exists(
|
|
18
|
-
var fs = require('fs');
|
|
19
|
+
async function path_exists(p) {
|
|
19
20
|
try {
|
|
20
|
-
fs.
|
|
21
|
+
await fs.promises.stat(p);
|
|
21
22
|
return true;
|
|
22
23
|
} catch(e) {
|
|
23
24
|
if (e.code != 'ENOENT') throw e;
|
|
25
|
+
return false;
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
28
|
|
|
@@ -57,7 +59,7 @@ function supports_color(stdout) {
|
|
|
57
59
|
|
|
58
60
|
}
|
|
59
61
|
|
|
60
|
-
function
|
|
62
|
+
function passthrough_colored(string) {
|
|
61
63
|
return string;
|
|
62
64
|
}
|
|
63
65
|
|
|
@@ -82,11 +84,11 @@ function wrap(lines, width) {
|
|
|
82
84
|
line = prev + line;
|
|
83
85
|
prev = '';
|
|
84
86
|
if (line.length > width) {
|
|
85
|
-
prev = line.substr(width);
|
|
87
|
+
prev = line.substr(width - 1);
|
|
86
88
|
if (prev) prev += ' ';
|
|
87
89
|
line = line.substr(0, width - 1);
|
|
88
|
-
if (line.substr(line.length - 1 !== ' ')
|
|
89
|
-
}
|
|
90
|
+
if (line.substr(line.length - 1) !== ' ') line += '-';
|
|
91
|
+
}
|
|
90
92
|
ans.push(line);
|
|
91
93
|
});
|
|
92
94
|
if (prev) ans = ans.concat(wrap([prev]));
|
|
@@ -105,24 +107,25 @@ function merge() {
|
|
|
105
107
|
}
|
|
106
108
|
|
|
107
109
|
function get_import_dirs(paths_string, ignore_env) {
|
|
108
|
-
var path = require('path');
|
|
109
110
|
var paths = [];
|
|
110
|
-
function
|
|
111
|
+
function add(new_path) {
|
|
111
112
|
if (paths.indexOf(new_path) == -1) paths.push(new_path);
|
|
112
113
|
}
|
|
113
114
|
if (!ignore_env && process && process.env && process.env.RAPYDSCRIPT_IMPORT_PATH) {
|
|
114
|
-
process.env.RAPYDSCRIPT_IMPORT_PATH.split(path.delimiter).forEach(
|
|
115
|
+
process.env.RAPYDSCRIPT_IMPORT_PATH.split(path.delimiter).forEach(add);
|
|
115
116
|
}
|
|
116
|
-
if (paths_string) paths_string.split(path.delimiter).forEach(
|
|
117
|
+
if (paths_string) paths_string.split(path.delimiter).forEach(add);
|
|
117
118
|
return paths;
|
|
118
119
|
}
|
|
119
120
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
121
|
+
export {
|
|
122
|
+
repeat,
|
|
123
|
+
wrap,
|
|
124
|
+
merge,
|
|
125
|
+
colored,
|
|
126
|
+
generators_available,
|
|
127
|
+
get_import_dirs,
|
|
128
|
+
path_exists,
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export var safe_colored = (supports_color()) ? colored : passthrough_colored;
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
/* vim:fileencoding=utf-8
|
|
2
|
-
*
|
|
2
|
+
*
|
|
3
3
|
* Copyright (C) 2016 Kovid Goyal <kovid at kovidgoyal.net>
|
|
4
4
|
*
|
|
5
5
|
* Distributed under terms of the BSD license
|
|
6
6
|
*/
|
|
7
|
-
"use strict";
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
import vm from 'vm';
|
|
10
|
+
import embedded_compiler from './embedded_compiler.mjs';
|
|
11
|
+
import tree_shake from './treeshake.mjs';
|
|
12
|
+
import { generate_source_map } from './sourcemap.mjs';
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
export default async function(compiler, baselib) {
|
|
12
15
|
var ctx = vm.createContext();
|
|
13
16
|
var LINE_CONTINUATION_CHARS = ':\\';
|
|
14
17
|
var find_completions = null;
|
|
15
|
-
var streaming_compiler = embedded_compiler(compiler, baselib, function(js) { return vm.runInContext(js, ctx); }, '__repl__');
|
|
18
|
+
var streaming_compiler = await embedded_compiler(compiler, baselib, function(js) { return vm.runInContext(js, ctx); }, '__repl__', tree_shake, generate_source_map);
|
|
16
19
|
|
|
17
20
|
return {
|
|
18
21
|
'in_block_mode': false,
|
|
@@ -20,13 +23,13 @@ module.exports = function(compiler, baselib) {
|
|
|
20
23
|
'replace_print': function replace_print(write_line_func) {
|
|
21
24
|
ctx.print = function() {
|
|
22
25
|
var parts = [];
|
|
23
|
-
for (var i = 0; i < arguments.length; i++)
|
|
26
|
+
for (var i = 0; i < arguments.length; i++)
|
|
24
27
|
parts.push(ctx.ρσ_str(arguments[i]));
|
|
25
28
|
write_line_func(parts.join(' '));
|
|
26
29
|
};
|
|
27
30
|
},
|
|
28
31
|
|
|
29
|
-
'is_input_complete': function is_input_complete(source) {
|
|
32
|
+
'is_input_complete': async function is_input_complete(source) {
|
|
30
33
|
if (!source || !source.trim()) return false;
|
|
31
34
|
var lines = source.split('\n');
|
|
32
35
|
var last_line = lines[lines.length - 1].trimRight();
|
|
@@ -45,7 +48,7 @@ module.exports = function(compiler, baselib) {
|
|
|
45
48
|
return false;
|
|
46
49
|
}
|
|
47
50
|
try {
|
|
48
|
-
compiler.parse(source, {'filename': '<repl>', 'basedir': '__stdlib__'});
|
|
51
|
+
await compiler.parse(source, {'filename': '<repl>', 'basedir': '__stdlib__'});
|
|
49
52
|
} catch(e) {
|
|
50
53
|
if (e.is_eof && e.line === lines.length && e.col > 0) {
|
|
51
54
|
return false;
|
|
@@ -57,11 +60,11 @@ module.exports = function(compiler, baselib) {
|
|
|
57
60
|
return true;
|
|
58
61
|
},
|
|
59
62
|
|
|
60
|
-
'compile': function web_repl_compile(code, opts) {
|
|
63
|
+
'compile': async function web_repl_compile(code, opts) {
|
|
61
64
|
opts = opts || {};
|
|
62
65
|
opts.keep_docstrings = true;
|
|
63
66
|
opts.filename = '<input>';
|
|
64
|
-
return streaming_compiler.compile(code, opts);
|
|
67
|
+
return await streaming_compiler.compile(code, opts);
|
|
65
68
|
},
|
|
66
69
|
|
|
67
70
|
'runjs': function runjs(code) {
|
|
@@ -83,5 +86,4 @@ module.exports = function(compiler, baselib) {
|
|
|
83
86
|
},
|
|
84
87
|
|
|
85
88
|
};
|
|
86
|
-
}
|
|
87
|
-
|
|
89
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* web_repl_export.mjs
|
|
3
|
+
* Copyright (C) 2015 Kovid Goyal <kovid at kovidgoyal.net>
|
|
4
|
+
*
|
|
5
|
+
* Distributed under terms of the BSD license.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import * as utils from './utils.mjs';
|
|
11
|
+
|
|
12
|
+
export default async function run_web_repl_export(base_path, lib_path, argv) {
|
|
13
|
+
if (globalThis.__rapydscript_embedded__) {
|
|
14
|
+
console.error('web-repl-export requires the full source repository and cannot run from a standalone binary.');
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
var output_dir = argv.files[0];
|
|
18
|
+
if (!output_dir) {
|
|
19
|
+
console.error('Usage: rapydscript web-repl-export /path/to/export/directory');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var meta = JSON.parse(await fs.promises.readFile(path.join(base_path, 'package.json'), 'utf-8'));
|
|
24
|
+
var commit_sha = (await fs.promises.readFile(path.join(base_path, '.git', 'refs', 'heads', 'master'), 'utf-8')).trim();
|
|
25
|
+
|
|
26
|
+
var manifest = {}, total = 0;
|
|
27
|
+
for (const x of ['compiler.js', 'baselib-plain-pretty.js']) {
|
|
28
|
+
manifest[x] = await fs.promises.readFile(path.join(lib_path, x), 'utf-8');
|
|
29
|
+
total += manifest[x].length;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
for (const x of ['web_repl.js', 'embedded_compiler.js', 'treeshake.js', 'sourcemap.js', 'utils.js', 'completer.js', 'msgfmt.js', 'gettext.js', 'ast_serialize.mjs']) {
|
|
33
|
+
var mjs = x.replace(/\.js$/, '.mjs');
|
|
34
|
+
var mjs_path = path.join(base_path, 'tools', mjs);
|
|
35
|
+
var js_path = path.join(base_path, 'tools', x);
|
|
36
|
+
var use_mjs = await utils.path_exists(mjs_path);
|
|
37
|
+
var key = 'tools/' + (use_mjs ? mjs : x);
|
|
38
|
+
manifest[key] = await fs.promises.readFile(use_mjs ? mjs_path : js_path, 'utf-8');
|
|
39
|
+
total += manifest[key].length;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
var stdlib = path.join(base_path, 'src', 'lib');
|
|
43
|
+
|
|
44
|
+
async function process_stdlib_dir(relpath) {
|
|
45
|
+
var fullpath = relpath ? path.join(stdlib, relpath) : stdlib;
|
|
46
|
+
var entries = await fs.promises.readdir(fullpath);
|
|
47
|
+
for (const x of entries) {
|
|
48
|
+
var q = path.join(fullpath, x);
|
|
49
|
+
var s = await fs.promises.stat(q);
|
|
50
|
+
if (s.isDirectory()) { await process_stdlib_dir(relpath + '/' + x); continue; }
|
|
51
|
+
if (!x.endsWith('.pyj')) continue;
|
|
52
|
+
var iname = path.normalize('__stdlib__' + '/' + relpath + '/' + x);
|
|
53
|
+
var raw = await fs.promises.readFile(q, 'utf-8');
|
|
54
|
+
manifest[iname] = raw;
|
|
55
|
+
total += s.size;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
await process_stdlib_dir('');
|
|
59
|
+
|
|
60
|
+
var rs = '// vim:fileencoding=utf-8\n';
|
|
61
|
+
rs += '(function(external_namespace) {\n';
|
|
62
|
+
rs += '"use strict;"\n';
|
|
63
|
+
rs += 'var rs_version = ' + JSON.stringify(meta.version) + ';\n';
|
|
64
|
+
rs += 'var rs_commit_sha = ' + JSON.stringify(commit_sha) + ';\n';
|
|
65
|
+
rs += '\n// Embedded modules {{{\n';
|
|
66
|
+
rs += 'var data = ' + JSON.stringify(manifest) + ';\n\n';
|
|
67
|
+
rs += '// End embedded modules }}}\n\n';
|
|
68
|
+
rs += await fs.promises.readFile(path.join(base_path, 'web-repl', 'env.js'));
|
|
69
|
+
rs += '\n// Embedded sha1 implementation {{{\n';
|
|
70
|
+
rs += '(function() {\n';
|
|
71
|
+
rs += await fs.promises.readFile(path.join(base_path, 'web-repl', 'sha1.js'));
|
|
72
|
+
rs += '}).call(jsSHA);\n';
|
|
73
|
+
rs += '// End embedded sha1 implementation }}}\n\n';
|
|
74
|
+
rs += 'var exports = namespace;\n';
|
|
75
|
+
rs += await fs.promises.readFile(path.join(base_path, 'tools', 'export.js'), 'utf-8');
|
|
76
|
+
rs += 'external_namespace.RapydScript = namespace;\n';
|
|
77
|
+
rs += '})(this);\n';
|
|
78
|
+
|
|
79
|
+
var base_dir = path.normalize(path.resolve(output_dir));
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
await fs.promises.mkdir(base_dir);
|
|
83
|
+
} catch(e) {
|
|
84
|
+
if (e.code !== 'EEXIST') throw e;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
await fs.promises.writeFile(path.join(base_dir, 'rapydscript.js'), rs, 'utf-8');
|
|
88
|
+
var web_repl_dir = path.join(base_path, 'web-repl');
|
|
89
|
+
var web_repl_files = await fs.promises.readdir(web_repl_dir);
|
|
90
|
+
for (const x of web_repl_files) {
|
|
91
|
+
if (['sha1.js', 'env.js'].indexOf(x) !== -1) continue;
|
|
92
|
+
var file_data = await fs.promises.readFile(path.join(web_repl_dir, x), 'utf-8');
|
|
93
|
+
await fs.promises.writeFile(path.join(base_dir, x), file_data, 'utf-8');
|
|
94
|
+
}
|
|
95
|
+
console.log('RapydScript compiler (uncompressed) size: ' + (total/(1024)).toFixed(1) + ' KB');
|
|
96
|
+
console.log('web-repl exported to: ' + base_dir);
|
|
97
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# tree-sitter-rapydscript
|
|
2
|
+
|
|
3
|
+
A [tree-sitter](https://tree-sitter.github.io/tree-sitter/) grammar for
|
|
4
|
+
[RapydScript](../README.md) (`.pyj` files).
|
|
5
|
+
|
|
6
|
+
RapydScript is a Python-like language that compiles to JavaScript. This grammar
|
|
7
|
+
covers the language as implemented by `rapydscript-ng`, including the features
|
|
8
|
+
that distinguish it from Python:
|
|
9
|
+
|
|
10
|
+
- **multi-line anonymous functions** declared with `def(...)` / `async def(...)`
|
|
11
|
+
(RapydScript's answer to Python's single-expression `lambda`), both inline
|
|
12
|
+
(`f = def(a, b): return a + b`) and with an indented block body;
|
|
13
|
+
- the **existential operator** `?` in all its forms — `a?` (existence check),
|
|
14
|
+
`a?.b` / `a?[i]` / `a?()` (safe access), and `a ? b` (default operator);
|
|
15
|
+
- **verbatim JavaScript** literals via the `v` string modifier (`v'...'`) and
|
|
16
|
+
the native `for v'i=0; i<n; i++':` loop;
|
|
17
|
+
- JavaScript **regular-expression literals**, including the verbose
|
|
18
|
+
`/// ... ///` form;
|
|
19
|
+
- `do: ... .while cond` loops;
|
|
20
|
+
- **scoped compiler flags** (`from __python__ import dict_literals, ...`).
|
|
21
|
+
|
|
22
|
+
It deliberately does **not** accept constructs that RapydScript itself rejects,
|
|
23
|
+
such as the walrus operator `:=`, `match`/`case`, or `*`-unpacking in assignment
|
|
24
|
+
targets.
|
|
25
|
+
|
|
26
|
+
It **does** handle the trickier corners of the language, including assignment as
|
|
27
|
+
an expression (`if m = re.exec(x):`, `a[i -= 1]`), keyword-vs-assignment
|
|
28
|
+
disambiguation in calls, named function *expressions* (`x = def named(a): ...`),
|
|
29
|
+
typed `*args`/`**kwargs`, bare generator arguments (`sum(x for x in xs)`),
|
|
30
|
+
multi-line anonymous-function arguments with the comma-on-the-next-line idiom,
|
|
31
|
+
and comma-first dict literals whose values are multi-line functions.
|
|
32
|
+
|
|
33
|
+
### Known limitations
|
|
34
|
+
|
|
35
|
+
A few rarely-used constructs — found only in the RapydScript compiler's own
|
|
36
|
+
source and standard library, not in ordinary programs — are not parsed. Every
|
|
37
|
+
file under `test/` (representative user code) and every example in the language
|
|
38
|
+
[README](../README.md) parses cleanly; the exceptions are:
|
|
39
|
+
|
|
40
|
+
- the colon-less one-line `if`: `if (cond) do_something()`;
|
|
41
|
+
- chained assignment whose value is a multi-line-block anonymous function:
|
|
42
|
+
`a = b = def(): <block>`;
|
|
43
|
+
- a ternary used as the return value of an *inline* anonymous function that is
|
|
44
|
+
itself a call argument, with a trailing `;`.
|
|
45
|
+
|
|
46
|
+
In these cases tree-sitter's error recovery still highlights the surrounding
|
|
47
|
+
code.
|
|
48
|
+
|
|
49
|
+
## Layout
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
tree-sitter/
|
|
53
|
+
├── grammar.js # the grammar
|
|
54
|
+
├── tree-sitter.json # grammar metadata (CLI)
|
|
55
|
+
├── package.json # npm package metadata
|
|
56
|
+
├── src/
|
|
57
|
+
│ ├── parser.c # generated parser (checked in)
|
|
58
|
+
│ ├── scanner.c # external scanner: indentation + regex literals
|
|
59
|
+
│ ├── grammar.json # generated
|
|
60
|
+
│ └── node-types.json # generated
|
|
61
|
+
├── queries/
|
|
62
|
+
│ ├── highlights.scm # syntax highlighting
|
|
63
|
+
│ └── injections.scm # embedded-language injections
|
|
64
|
+
└── test/corpus/ # tree-sitter test suite
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Building & testing
|
|
68
|
+
|
|
69
|
+
From this directory:
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
tree-sitter generate # regenerate src/parser.c from grammar.js
|
|
73
|
+
tree-sitter test # run the corpus tests in test/corpus/
|
|
74
|
+
tree-sitter parse FILE # parse a .pyj file and print its syntax tree
|
|
75
|
+
tree-sitter build # compile the parser (+ scanner) into a shared object
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Using it in Neovim
|
|
79
|
+
|
|
80
|
+
With [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter),
|
|
81
|
+
register the parser and map the `.pyj` extension to it:
|
|
82
|
+
|
|
83
|
+
```lua
|
|
84
|
+
local rapyd_repo_path = vim.fn.expand("/path/to/rapydscript/tree-sitter")
|
|
85
|
+
vim.api.nvim_create_autocmd('User', {
|
|
86
|
+
pattern = 'TSUpdate',
|
|
87
|
+
callback = function()
|
|
88
|
+
require("nvim-treesitter.parsers").rapydscript = {
|
|
89
|
+
install_info = {
|
|
90
|
+
path = rapyd_repo_path,
|
|
91
|
+
files = { "src/parser.c", "src/scanner.c" },
|
|
92
|
+
},
|
|
93
|
+
filetype = "rapydscript",
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
})
|
|
97
|
+
vim.opt.rtp:append(rapyd_repo_path)
|
|
98
|
+
vim.filetype.add({ extension = { pyj = "rapydscript" } })
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Then `:TSInstall rapydscript`.
|