rapydscript-ng 0.7.24 → 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.
Files changed (114) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +72 -26
  3. package/bin/package.json +1 -0
  4. package/bin/rapydscript +65 -62
  5. package/editor-plugins/nvim/rapydscript/README.md +184 -0
  6. package/editor-plugins/nvim/rapydscript/bin/rapydscript.so +0 -0
  7. package/editor-plugins/nvim/rapydscript/ftdetect/rapydscript.lua +10 -0
  8. package/editor-plugins/nvim/rapydscript/lua/rapydscript/health.lua +88 -0
  9. package/editor-plugins/nvim/rapydscript/lua/rapydscript/init.lua +279 -0
  10. package/local-agent.md +28 -0
  11. package/package.json +4 -5
  12. package/release/baselib-plain-pretty.js +448 -326
  13. package/release/baselib-plain-ugly.js +3 -3
  14. package/release/compiler.js +2528 -1672
  15. package/release/signatures.json +17 -17
  16. package/src/ast.pyj +73 -25
  17. package/src/baselib-builtins.pyj +2 -2
  18. package/src/baselib-containers.pyj +153 -151
  19. package/src/baselib-internal.pyj +3 -3
  20. package/src/baselib-str.pyj +5 -5
  21. package/src/lib/aes.pyj +1 -1
  22. package/src/lib/encodings.pyj +1 -1
  23. package/src/lib/pythonize.pyj +1 -1
  24. package/src/lib/re.pyj +2 -2
  25. package/src/lib/traceback.pyj +165 -28
  26. package/src/lib/uuid.pyj +1 -1
  27. package/src/output/codegen.pyj +10 -3
  28. package/src/output/functions.pyj +31 -40
  29. package/src/output/literals.pyj +11 -14
  30. package/src/output/loops.pyj +25 -87
  31. package/src/output/modules.pyj +5 -47
  32. package/src/output/statements.pyj +1 -1
  33. package/src/output/stream.pyj +58 -31
  34. package/src/parse.pyj +777 -427
  35. package/src/tokenizer.pyj +16 -4
  36. package/src/utils.pyj +1 -1
  37. package/test/_treeshake_mod.pyj +30 -0
  38. package/test/_treeshake_side_effect.pyj +9 -0
  39. package/test/ast_serialization.pyj +392 -0
  40. package/test/async.pyj +95 -0
  41. package/test/baselib.pyj +1 -2
  42. package/test/embedded_compiler.pyj +57 -0
  43. package/test/fmt.pyj +201 -0
  44. package/test/generic.pyj +7 -3
  45. package/test/imports.pyj +8 -6
  46. package/test/internationalization.pyj +38 -37
  47. package/test/lint.pyj +120 -117
  48. package/test/lsp.pyj +222 -0
  49. package/test/repl.pyj +70 -65
  50. package/test/sourcemaps.pyj +315 -0
  51. package/test/starargs.pyj +46 -39
  52. package/test/traceback.pyj +263 -0
  53. package/test/treeshaking.pyj +181 -0
  54. package/test/web_repl_export.pyj +88 -0
  55. package/tools/ast_serialize.mjs +557 -0
  56. package/tools/cli.mjs +510 -0
  57. package/tools/compile.mjs +201 -0
  58. package/tools/compiler.mjs +127 -0
  59. package/tools/{completer.js → completer.mjs} +6 -6
  60. package/tools/{embedded_compiler.js → embedded_compiler.mjs} +17 -13
  61. package/tools/export.js +109 -56
  62. package/tools/fmt.mjs +735 -0
  63. package/tools/{gettext.js → gettext.mjs} +46 -53
  64. package/tools/{ini.js → ini.mjs} +9 -10
  65. package/tools/{lint.js → lint.mjs} +78 -55
  66. package/tools/lsp.mjs +914 -0
  67. package/tools/lsp_protocol.mjs +259 -0
  68. package/tools/lsp_symbols.mjs +418 -0
  69. package/tools/{msgfmt.js → msgfmt.mjs} +18 -18
  70. package/tools/{repl.js → repl.mjs} +52 -41
  71. package/tools/{self.js → self.mjs} +56 -46
  72. package/tools/sourcemap.mjs +123 -0
  73. package/tools/test.mjs +152 -0
  74. package/tools/treeshake.mjs +400 -0
  75. package/tools/{utils.js → utils.mjs} +26 -23
  76. package/tools/{web_repl.js → web_repl.mjs} +15 -13
  77. package/tools/web_repl_export.mjs +93 -0
  78. package/tree-sitter/README.md +101 -0
  79. package/tree-sitter/grammar.js +992 -0
  80. package/tree-sitter/package.json +43 -0
  81. package/tree-sitter/queries/rapydscript/highlights.scm +232 -0
  82. package/tree-sitter/queries/rapydscript/indents.scm +64 -0
  83. package/tree-sitter/queries/rapydscript/injections.scm +14 -0
  84. package/tree-sitter/queries/rapydscript/locals.scm +108 -0
  85. package/tree-sitter/src/grammar.json +4976 -0
  86. package/tree-sitter/src/node-types.json +2901 -0
  87. package/tree-sitter/src/parser.c +196465 -0
  88. package/tree-sitter/src/scanner.c +294 -0
  89. package/tree-sitter/src/tree_sitter/alloc.h +54 -0
  90. package/tree-sitter/src/tree_sitter/array.h +330 -0
  91. package/tree-sitter/src/tree_sitter/parser.h +286 -0
  92. package/tree-sitter/test/corpus/chaining.txt +99 -0
  93. package/tree-sitter/test/corpus/classes.txt +147 -0
  94. package/tree-sitter/test/corpus/comprehensions.txt +155 -0
  95. package/tree-sitter/test/corpus/containers.txt +242 -0
  96. package/tree-sitter/test/corpus/control_flow.txt +361 -0
  97. package/tree-sitter/test/corpus/decorators.txt +64 -0
  98. package/tree-sitter/test/corpus/existential.txt +102 -0
  99. package/tree-sitter/test/corpus/functions.txt +293 -0
  100. package/tree-sitter/test/corpus/imports.txt +117 -0
  101. package/tree-sitter/test/corpus/literals.txt +135 -0
  102. package/tree-sitter/test/corpus/operators.txt +296 -0
  103. package/tree-sitter/test/corpus/statements.txt +189 -0
  104. package/tree-sitter/test/corpus/strings.txt +90 -0
  105. package/tree-sitter/test/corpus/subscripts.txt +227 -0
  106. package/tree-sitter/tree-sitter.json +36 -0
  107. package/web-repl/env.js +35 -23
  108. package/web-repl/main.js +8 -8
  109. package/bin/export +0 -75
  110. package/bin/web-repl-export +0 -102
  111. package/tools/cli.js +0 -523
  112. package/tools/compile.js +0 -184
  113. package/tools/compiler.js +0 -84
  114. package/tools/test.js +0 -110
@@ -0,0 +1,279 @@
1
+ local M = {}
2
+
3
+ -- init.lua lives at <plugin>/lua/rapydscript/init.lua; 3 :h steps reach <plugin>/.
4
+ local _plugin_root = vim.fn.fnamemodify(
5
+ debug.getinfo(1, "S").source:sub(2), ":p:h:h:h"
6
+ )
7
+ -- <plugin> is at <repo>/editor-plugins/nvim/rapydscript; 3 more :h steps reach <repo>/.
8
+ local _repo_root = vim.fn.fnamemodify(_plugin_root, ":h:h:h")
9
+
10
+ -- Compile the tree-sitter parser once per nvim instance at require() time.
11
+ -- Stores the .so/.dll path on success, nil if sources are absent or compilation fails.
12
+ local _ts_so = (function()
13
+ local ts_src = _repo_root .. "/tree-sitter/src"
14
+ local parser_c = ts_src .. "/parser.c"
15
+ local scanner_c = ts_src .. "/scanner.c"
16
+ if vim.fn.filereadable(parser_c) == 0 then return nil end
17
+
18
+ local bin_dir = _plugin_root .. "/bin"
19
+ vim.fn.mkdir(bin_dir, "p")
20
+
21
+ local is_win = vim.fn.has("win32") == 1
22
+ local lib_ext = is_win and ".dll" or ".so"
23
+ local so = bin_dir .. "/rapydscript" .. lib_ext
24
+
25
+ local so_mtime = vim.fn.getftime(so)
26
+ local needs = so_mtime < 0
27
+ or vim.fn.getftime(parser_c) > so_mtime
28
+ or vim.fn.getftime(scanner_c) > so_mtime
29
+
30
+ if needs then
31
+ local cmd
32
+ if is_win then
33
+ local compiler
34
+ if vim.fn.exepath("cl") ~= "" then
35
+ compiler = "cl"
36
+ elseif vim.fn.exepath("clang-cl") ~= "" then
37
+ compiler = "clang-cl"
38
+ else
39
+ vim.notify(
40
+ "rapydscript: tree-sitter syntax highlighting requires cl or clang-cl on PATH",
41
+ vim.log.levels.ERROR
42
+ )
43
+ return nil
44
+ end
45
+ -- /LD = build DLL, /nologo = suppress banner, /O2 = optimize,
46
+ -- /I = include path, /Fe: = output DLL path
47
+ cmd = string.format(
48
+ '"%s" /LD /nologo /O2 /I"%s" /Fe:"%s" "%s" "%s"',
49
+ compiler, ts_src, so, parser_c, scanner_c
50
+ )
51
+ else
52
+ local uname = vim.fn.system("uname -s"):gsub("%s+", "")
53
+ local shared = uname == "Darwin" and "-dynamiclib" or "-shared"
54
+ cmd = table.concat({
55
+ "cc", shared, "-fPIC", "-Os",
56
+ "-I", vim.fn.shellescape(ts_src),
57
+ "-o", vim.fn.shellescape(so),
58
+ vim.fn.shellescape(parser_c),
59
+ vim.fn.shellescape(scanner_c),
60
+ }, " ")
61
+ end
62
+
63
+ vim.notify("rapydscript: compiling tree-sitter parser…", vim.log.levels.INFO)
64
+ local out = vim.fn.system(cmd)
65
+ if vim.v.shell_error ~= 0 then
66
+ vim.notify("rapydscript: tree-sitter compile failed:\n" .. out, vim.log.levels.ERROR)
67
+ return nil
68
+ end
69
+ end
70
+
71
+ return so
72
+ end)()
73
+
74
+ local function _start_treesitter(bufnr)
75
+ if not _ts_so then return end
76
+
77
+ -- Add tree-sitter dir to rtp so nvim resolves queries/rapydscript/*.scm.
78
+ local ts_root = _repo_root .. "/tree-sitter"
79
+ local rtp = vim.opt.rtp:get()
80
+ if not vim.tbl_contains(rtp, ts_root) then
81
+ vim.opt.rtp:append(ts_root)
82
+ end
83
+
84
+ local ok, err = pcall(vim.treesitter.language.add, "rapydscript", { path = _ts_so })
85
+ if not ok then
86
+ vim.notify("rapydscript: failed to load tree-sitter parser: " .. tostring(err), vim.log.levels.ERROR)
87
+ return
88
+ end
89
+
90
+ local ts_ok, ts_err = pcall(vim.treesitter.start, bufnr, "rapydscript")
91
+ if not ts_ok then
92
+ vim.notify("rapydscript: tree-sitter start failed: " .. tostring(ts_err), vim.log.levels.ERROR)
93
+ end
94
+ end
95
+
96
+ local _min_system_version = { 0, 8, 0 }
97
+
98
+ local function _parse_version(str)
99
+ local a, b, c = str:match("(%d+)%.(%d+)%.(%d+)")
100
+ if not a then return nil end
101
+ return { tonumber(a), tonumber(b), tonumber(c) }
102
+ end
103
+
104
+ local function _version_str(v)
105
+ return v and table.concat(v, ".") or "unknown"
106
+ end
107
+
108
+ local function _version_gte(v, min)
109
+ for i = 1, 3 do
110
+ if v[i] > min[i] then return true end
111
+ if v[i] < min[i] then return false end
112
+ end
113
+ return true
114
+ end
115
+
116
+ local function _query_version(bin)
117
+ local out = vim.fn.system({ bin, "--version" })
118
+ if vim.v.shell_error ~= 0 then return nil end
119
+ return _parse_version(out)
120
+ end
121
+
122
+ -- Prefer rapydscript on PATH; fall back to the copy in the repo checkout.
123
+ -- Populates M._binary_info as a side-effect.
124
+ local function _default_lsp_cmd()
125
+ local sys_path = vim.fn.exepath("rapydscript")
126
+ if sys_path ~= "" then
127
+ local ver = _query_version(sys_path)
128
+ local rejected = ver ~= nil and not _version_gte(ver, _min_system_version)
129
+ M._binary_info.system = { path = sys_path, version = ver, rejected = rejected }
130
+ if rejected then
131
+ vim.notify(
132
+ string.format(
133
+ "rapydscript: system binary v%s is too old (minimum 0.8.0); using repo binary instead",
134
+ _version_str(ver)
135
+ ),
136
+ vim.log.levels.WARN
137
+ )
138
+ else
139
+ return { "rapydscript", "lsp" }
140
+ end
141
+ end
142
+
143
+ local repo_bin = _repo_root .. "/bin/rapydscript"
144
+ if vim.fn.filereadable(repo_bin) == 1 then
145
+ local ver = _query_version(repo_bin)
146
+ M._binary_info.repo = { path = repo_bin, version = ver }
147
+ if vim.fn.has("win32") == 1 then
148
+ -- On Windows the shebang is not honoured; invoke via node explicitly.
149
+ return { "node", repo_bin, "lsp" }
150
+ end
151
+ return { repo_bin, "lsp" }
152
+ end
153
+
154
+ return { "rapydscript", "lsp" }
155
+ end
156
+
157
+ -- Expose tree-sitter compilation result for checkhealth.
158
+ M._ts_so = _ts_so
159
+
160
+ -- Populated by _default_lsp_cmd() below; read by lua/rapydscript/health.lua.
161
+ M._binary_info = { system = nil, repo = nil }
162
+
163
+ -- Expand glob patterns relative to root, keep only dirs that contain .pyj files,
164
+ -- and return them colon-separated. Returns nil when nothing matches.
165
+ local function _resolve_import_paths(root, patterns)
166
+ local seen = {}
167
+ local dirs = {}
168
+ for _, pat in ipairs(patterns) do
169
+ local matches = vim.fn.glob(root .. "/" .. pat, false, true)
170
+ for _, path in ipairs(matches) do
171
+ local norm = vim.fn.fnamemodify(path, ":p"):gsub("/$", "")
172
+ if not seen[norm] and vim.fn.isdirectory(norm) == 1 then
173
+ if #vim.fn.glob(norm .. "/*.pyj", false, true) > 0 then
174
+ seen[norm] = true
175
+ dirs[#dirs + 1] = norm
176
+ end
177
+ end
178
+ end
179
+ end
180
+ return #dirs > 0 and table.concat(dirs, ":") or nil
181
+ end
182
+
183
+ M.defaults = {
184
+ cmd = _default_lsp_cmd(),
185
+ -- Glob patterns relative to the project root; matching dirs that contain
186
+ -- .pyj files are passed automatically as --import-path to the LSP server.
187
+ import_path_patterns = { ".", "src", "src/pyj" },
188
+ line_length = nil,
189
+ preferred_quote = nil,
190
+ filetypes = { "rapydscript" },
191
+ root_markers = { ".git", "package.json", "rapydscript.json" },
192
+ }
193
+
194
+ -- Current runtime settings, kept in sync whenever update_settings() is called.
195
+ M._settings = {}
196
+
197
+ local function build_cmd(opts, import_path)
198
+ local cmd = vim.deepcopy(opts.cmd)
199
+ if import_path then
200
+ vim.list_extend(cmd, { "--import-path", import_path })
201
+ end
202
+ if opts.line_length then
203
+ vim.list_extend(cmd, { "--line-length", tostring(opts.line_length) })
204
+ end
205
+ if opts.preferred_quote then
206
+ vim.list_extend(cmd, { "--preferred-quote", opts.preferred_quote })
207
+ end
208
+ return cmd
209
+ end
210
+
211
+ local function make_capabilities()
212
+ local caps = vim.lsp.protocol.make_client_capabilities()
213
+ -- Tell the server we support dynamic registration for workspace/didChangeConfiguration
214
+ -- so it will register that notification and accept live setting updates.
215
+ caps.workspace = caps.workspace or {}
216
+ caps.workspace.didChangeConfiguration = { dynamicRegistration = true }
217
+ return caps
218
+ end
219
+
220
+ -- Send workspace/didChangeConfiguration to every active rapydscript client.
221
+ -- `new_settings` is a table with any subset of:
222
+ -- line_length (number)
223
+ -- preferred_quote (string) -- "single" | "double"
224
+ function M.update_settings(new_settings)
225
+ new_settings = new_settings or {}
226
+
227
+ -- Merge into the module-level settings table.
228
+ if new_settings.line_length ~= nil then
229
+ M._settings.lineLength = new_settings.line_length
230
+ end
231
+ if new_settings.preferred_quote ~= nil then
232
+ M._settings.preferredQuote = new_settings.preferred_quote
233
+ end
234
+
235
+ local clients = vim.lsp.get_clients({ name = "rapydscript" })
236
+ if #clients == 0 then
237
+ vim.notify("rapydscript: no active LSP client found", vim.log.levels.WARN)
238
+ return
239
+ end
240
+ for _, client in ipairs(clients) do
241
+ client.notify("workspace/didChangeConfiguration", {
242
+ settings = { rapydscript = M._settings },
243
+ })
244
+ end
245
+ end
246
+
247
+ function M.setup(opts)
248
+ opts = vim.tbl_deep_extend("force", M.defaults, opts or {})
249
+ M._active_opts = opts
250
+
251
+ -- Seed the runtime settings table from the initial opts so that partial
252
+ -- update_settings() calls later always send the full current state.
253
+ M._settings = {
254
+ lineLength = opts.line_length,
255
+ preferredQuote = opts.preferred_quote,
256
+ }
257
+
258
+ vim.api.nvim_create_autocmd("FileType", {
259
+ pattern = opts.filetypes,
260
+ callback = function(ev)
261
+ _start_treesitter(ev.buf)
262
+ local root = vim.fs.root(ev.buf, opts.root_markers)
263
+ local import_path = root
264
+ and _resolve_import_paths(root, opts.import_path_patterns)
265
+ or nil
266
+ vim.lsp.start({
267
+ name = "rapydscript",
268
+ cmd = build_cmd(opts, import_path),
269
+ root_dir = root or vim.fn.getcwd(),
270
+ capabilities = make_capabilities(),
271
+ settings = {
272
+ rapydscript = M._settings,
273
+ },
274
+ })
275
+ end,
276
+ })
277
+ end
278
+
279
+ return M
package/local-agent.md ADDED
@@ -0,0 +1,28 @@
1
+ initialize_command: bin/rapydscript self --complete
2
+ copy_resource: node_modules
3
+ copy_resource: dev
4
+ prepend_to_path: bin
5
+
6
+ # System Instructions & Project Context
7
+
8
+ ## Rules for Code Generation
9
+ - **Error Handling**: Implement explicit error handling. Avoid silent failures or empty catch blocks.
10
+ - **Dependency Minimization**: Use existing project utilities and native standard libraries before suggesting new external packages.
11
+ - **Local Context**: Search the codebase for existing patterns before writing boilerplate structure from scratch.
12
+
13
+ ## Project Execution Workflows
14
+
15
+ You both build and run the test suite by simply executing:
16
+
17
+ ./build
18
+
19
+ The newly built tools are placed in the bin directory.
20
+
21
+ The test suite runs very fast so dont bother trying to run specific tests, just
22
+ run the entire suite.
23
+
24
+ ## Verification Pipeline
25
+
26
+ Before declaring a task complete, you must follow this exact verification lifecycle:
27
+ 1. Run the local **Build and Test Command** to guarantee zero compilation or compilation-stage errors and no test failures
28
+ 2. If errors occur, analyze the stdout logs completely before writing a fix. Do not guess.
package/package.json CHANGED
@@ -8,16 +8,16 @@
8
8
  "language",
9
9
  "compiler"
10
10
  ],
11
- "main": "tools/compiler.js",
11
+ "main": "tools/compiler.mjs",
12
12
  "scripts": {
13
13
  "test": "node bin/rapydscript self --complete --test",
14
14
  "start": "node bin/rapydscript",
15
15
  "build-self": "node bin/rapydscript self --complete"
16
16
  },
17
- "version": "0.7.24",
17
+ "version": "0.8.0",
18
18
  "license": "BSD-2-Clause",
19
19
  "engines": {
20
- "node": ">=0.12.0"
20
+ "node": ">=0.14.0"
21
21
  },
22
22
  "maintainers": [
23
23
  {
@@ -30,8 +30,7 @@
30
30
  "url": "https://github.com/kovidgoyal/rapydscript-ng.git"
31
31
  },
32
32
  "dependencies": {
33
- "regenerator": ">= 0.12.1",
34
- "uglify-js": ">= 3.0.15"
33
+ "terser": ">=5.49.0"
35
34
  },
36
35
  "optionalDependencies": {
37
36
  "v8-profiler": ">= 5.2.9"