You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+17-36Lines changed: 17 additions & 36 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# RustScript
2
2
3
-
RustScript is the language, VM, Lua/JavaScript frontends, standard library, examples, bytecode/AOT tooling, wasm runtime support, and debugger-facing runtime contract for the RustScript family.
3
+
RustScript is the language, VM/compiler core, standard library, examples, bytecode/AOT tooling, wasm runtime support, and debugger-facing runtime contract for the RustScript family. Compatibility language frontends now live in source-plugin crates.
4
4
5
5
## Related projects
6
6
@@ -9,6 +9,7 @@ RustScript is the language, VM, Lua/JavaScript frontends, standard library, exam
`pd-vm` is a stack-based virtual machine plus compiler toolchain used as a backend for multiple
30
-
source syntaxes (`.rss`, `.js`, `.lua`).
30
+
`pd-vm` is a stack-based virtual machine plus compiler toolchain. It includes the RustScript (`.rss`) frontend and exposes a source-plugin API for compatibility languages such as JavaScript and Lua.
31
31
32
32
## Contents
33
33
@@ -80,15 +80,10 @@ than optional hints.
80
80
Run with the VM runner binary:
81
81
82
82
```powershell
83
-
cargo run -p pd-vm --bin pd-vm-run -- --fuel 100000 examples/example.lua
83
+
cargo run -p pd-vm --bin pd-vm-run -- --fuel 100000 examples/example.rss
84
84
```
85
85
86
-
Other supported flavors:
87
-
88
-
```powershell
89
-
cargo run -p pd-vm --bin pd-vm-run -- examples/example.js
90
-
cargo run -p pd-vm --bin pd-vm-run -- examples/example.rss
91
-
```
86
+
Compatibility frontends such as JavaScript and Lua are provided by source-plugin crates. Use `CompileSourceFileOptions::with_source_plugin(...)` when compiling those files from an embedding crate.
1. Frontend lowering (built-in `rustscript`, plus any registered source plugins)
477
472
1. Frontend-independent IR
478
473
1. Type-consistency validation on legalized IR (for example rejecting known `if`/`else` branch mismatches)
479
474
1. Lifetime/liveness lowering plus type metadata collection
@@ -504,8 +499,7 @@ monomorphic runtime fast paths, not to provide a full source-language static typ
504
499
505
500
#### Compiler APIs
506
501
507
-
Use `compile_source()` for RustScript, or `compile_source_file()` for extension-based flavor
508
-
selection (`.rss`, `.js`, `.lua`).
502
+
Use `compile_source()` for RustScript, or `compile_source_file()` for built-in `.rss` path loading. For compatibility languages, build options with `CompileSourceFileOptions::with_source_plugin(...)` and call `compile_source_file_with_options(...)`.
509
503
510
504
```text
511
505
fn print(x);
@@ -526,23 +520,17 @@ let add = |value| value + base;
526
520
add(5);
527
521
```
528
522
529
-
Lua closure equivalent lowered by frontend:
530
-
531
-
```lua
532
-
localadd=function(value) returnvalue+baseend
533
-
```
523
+
Compatibility frontends can lower equivalent closure forms through the source-plugin API.
- JavaScript: `import * as runtime from "runtime";`, `import * as http from "http";`
545
-
- Lua: `require("runtime")`, `require("http")`
533
+
- Compatibility frontends own their import syntax through `SourcePlugin::parse_imports(...)` and `SourcePlugin::strip_imports(...)`.
546
534
547
535
#### Assembler API
548
536
@@ -633,18 +621,11 @@ Module/source loading:
633
621
634
622
-`crate::...` module paths are not supported in RustScript source loading; use relative module paths
635
623
636
-
JavaScript frontend:
637
-
638
-
- arrow closures with block bodies are not supported (expression-body arrows only)
639
-
-`return <expr>;` is lowered to `<expr>;` (function results still follow final-expression semantics)
640
-
641
-
Lua frontend:
624
+
Source plugins:
642
625
643
-
- Lua pattern API string methods (`:match`, `:gsub`, etc.) are not supported
644
-
- function literal bodies are limited to `function(...) end`, `function(...) return end`, or `function(...) return <expr[, expr...]> end`
645
-
- direct `function`/`local function` bodies are still minimal: empty/fallthrough, `return`, `return <expr[, expr...]>`, or a single return-only `if`/`elseif`/`else` chain
646
-
-`pcall(...)` / `xpcall(...)` lower with success-only semantics and always prefix `true` before the callee return values
647
-
- multi-return unpacking is currently limited to compiler-known Lua function/closure return shapes; extra return values are dropped, missing locals are filled with `null`, but plain assignment destructuring and arbitrary host-call unpacking are not supported
626
+
- Compatibility-language parsing, lowering, and source import scanning belong in plugin crates.
627
+
-`pd-vm` exposes `SourcePlugin`, `FrontendIr`, parser dialect helpers, and IR builder types for plugin authors.
628
+
-`compile_source_file()` without options only handles built-in `.rss`; use `compile_source_file_with_options()` for plugin-backed extensions.
Copy file name to clipboardExpand all lines: docs/blog/v07-why-rustscript.md
+8-8Lines changed: 8 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,9 +6,9 @@
6
6
7
7
## The Starting Point
8
8
9
-
pd-vm already runs four source-language frontends on the same stack-based VM with the same bytecode. All four lower into a shared `FrontendIr` before compilation, and all four run on a runtime that uses no garbage collector and relies on deterministic ownership for memory management.
9
+
pd-vm runs RustScript on a stack-based VM with bytecode that plugin frontends can also target. Built-in RustScript and plugin sources lower into a shared `FrontendIr` before compilation, then run on a runtime that uses no garbage collector and relies on deterministic ownership for memory management.
10
10
11
-
Given those other frontends, a fair question is: why add another one? What does a Rust-shaped scripting syntax buy a VM that already works?
11
+
Given the plugin path for compatibility languages, a fair question is: what does a Rust-shaped scripting syntax buy this VM?
12
12
13
13
The short answer is that RustScript exists because its syntax carries **intent that the compiler can act on**. Move-vs-copy distinctions, borrow annotations, and mutability declarations are not runtime features. They are compiler inputs. And they happen to be in a syntax that AI models already know well.
14
14
@@ -34,14 +34,14 @@ let b = a; // move: `a` is consumed, slot is cleared
34
34
35
35
The compiler sees the local-to-local rebind of a non-copyable value, lowers it as a consuming load (`MoveVar` in the IR), and emits the null-clear sequence. Using `a` after this point is a compile-time error, not a runtime surprise.
36
36
37
-
Compare the same logic in the JavaScript frontend:
37
+
Compare the same logic in a copy-by-default compatibility frontend:
38
38
39
39
```javascript
40
40
let a = [1, 2, 3];
41
41
let b = a; // copy: both `a` and `b` share the array
42
42
```
43
43
44
-
Both programs compile to valid bytecode on the same VM. The difference is what the compiler knows at the point of the assignment. RustScript's syntax tells it "this is a transfer of ownership." The JS frontend's syntax tells it nothing, so it defaults to shared copy.
44
+
Both programs compile to valid bytecode on the same VM. The difference is what the compiler knows at the point of the assignment. RustScript's syntax tells it "this is a transfer of ownership." A copy-by-default plugin syntax tells it nothing, so it defaults to shared copy.
45
45
46
46
### `.copy()` and Borrows
47
47
@@ -70,7 +70,7 @@ The core of RustScript's value is the availability analysis in `availability.rs`
70
70
71
71
When `enable_local_move_semantics` is active (RustScript only), the pass enforces stricter rules:
| Local-to-local rebind of a collection | Move source, reject reuse | Copy (shared ownership) |
76
76
| Local read after move | Compile error | N/A (no moves) |
@@ -113,7 +113,7 @@ The capture binding modes are:
113
113
|**BorrowMut**|`&mut x` in capture position | Non-consuming; mutation tracked |
114
114
|**Move**|`x` (default for non-copyable) | Outer local consumed |
115
115
116
-
In the JS and Lua frontends, all captures degrade to `Copy` mode. The capture slot still gets a value, but the outer scope keeps its own copy unconditionally.
116
+
Compatibility frontends can choose to degrade captures to `Copy` mode. The capture slot still gets a value, but the outer scope keeps its own copy unconditionally.
117
117
118
118
## Type Inference and the Ownership Surface
119
119
@@ -128,12 +128,12 @@ These are all DX-layer decisions. They catch mistakes before bytecode is generat
128
128
129
129
## The AI Angle: Syntax Proximity to Rust
130
130
131
-
There is a practical benefit that was not part of the original design but became increasingly clear as the project grew: **AI code-generation models produce better RustScript than they produce JavaScript or Lua for this VM**.
131
+
There is a practical benefit that was not part of the original design but became increasingly clear as the project grew: **AI code-generation models produce better RustScript than they produce compatibility languages for this VM**.
132
132
133
133
The reason is corpus proximity. Large language models trained on significant amounts of Rust code have internalized Rust's ownership patterns, borrow semantics, and idiomatic structures. When asked to write RustScript for pd-vm — which lives in the same repository as the Rust runtime — the model:
134
134
135
135
1.**Naturally uses ownership-aware patterns.** It writes `let b = a;` as a move and `let b = a.copy();` when it needs the source to survive. It does not try to share mutable state through aliasing.
136
-
2.**Avoids GC-dependent patterns.** Rust-trained models do not reach for garbage-collected idioms like long-lived closures over mutable state or circular references. Those patterns would be valid in the JS frontend but counterproductive for a GC-free runtime.
136
+
2.**Avoids GC-dependent patterns.** Rust-trained models do not reach for garbage-collected idioms like long-lived closures over mutable state or circular references. Those patterns can be natural in compatibility-language frontends but counterproductive for a GC-free runtime.
137
137
3.**Matches the surrounding code style.** The pd-vm runtime is Rust. The compiler is Rust. The test harness is Rust. When the scripting language is also Rust-shaped, the model does not need to context-switch between two different programming idioms within the same codebase.
138
138
4.**Produces more accurate type annotations.** Because the model knows Rust's type annotation syntax, it generates valid RustScript type hints that feed into the compiler's inference pipeline rather than leaving locals at `Unknown`.
0 commit comments