plum
git clone https://git.pyrossh.dev/plum
A statically typed, imperative programming language inspired by rust, python
98bcd99
— Peter John
2026-09-04T20:50:43+05:30
chore: fix stale Bool/Str doc comments and test fixture breakage
- examples/io.plum +6 -3
- plum-cli/tests/compile_tests.rs +28 -9
- plum-wasm-codegen/src/lib.rs +9 -6
examples/io.plum
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import std/Str
|
|
2
2
|
import std/Bool
|
|
3
3
|
|
|
4
|
-
# `printLn` mirrors `libs/std/os.plum`'s declaration; redeclared locally
|
|
4
|
+
# `printLn` mirrors `libs/std/os.plum`'s declaration; redeclared locally
|
|
5
|
-
# than `import std/os`) so this stays
|
|
5
|
+
# (rather than `import std/os`) so this stays the SMALLEST possible example
|
|
6
|
+
# — `import std/os` pulls in every other filesystem extern os.plum declares
|
|
6
|
-
#
|
|
7
|
+
# too, which the Rust-level `ioExampleCompilesAndRunsCorrectly` test (which
|
|
8
|
+
# actually RUNS this module under wasmtime, providing real host imports)
|
|
9
|
+
# would then all need stubs for.
|
|
7
10
|
extern fun printLn(s: Str)
|
|
8
11
|
|
|
9
12
|
fun main() =
|
plum-cli/tests/compile_tests.rs
CHANGED
|
@@ -11,13 +11,24 @@ fn plumBin() -> std::path::PathBuf {
|
|
|
11
11
|
path
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
/// A fresh subdirectory under the system temp dir, named for this test run
|
|
15
|
+
/// (so parallel test binaries don't collide) — these tests write their own
|
|
16
|
+
/// minimal fixture files here rather than depending on anything checked into
|
|
17
|
+
/// the repo, so they stay self-contained regardless of what `test/` holds.
|
|
18
|
+
fn freshTempDir(name: &str) -> std::path::PathBuf {
|
|
19
|
+
let dir = std::env::temp_dir().join(format!("plum_{}_{}", name, std::process::id()));
|
|
20
|
+
std::fs::create_dir_all(&dir).expect("failed to create temp dir");
|
|
21
|
+
dir
|
|
22
|
+
}
|
|
23
|
+
|
|
14
24
|
#[test]
|
|
15
25
|
fn compileSimpleAddProducesWasm() {
|
|
26
|
+
let dir = freshTempDir("simple_add");
|
|
16
|
-
let src_path =
|
|
27
|
+
let src_path = dir.join("simple_add.plum");
|
|
28
|
+
std::fs::write(&src_path, "fun add(a: Int, b: Int) -> Int =\n a + b\n").unwrap();
|
|
17
|
-
let out_path =
|
|
29
|
+
let out_path = dir.join("simple_add.wasm");
|
|
18
|
-
let out_path_str = out_path.to_str().unwrap();
|
|
19
30
|
let status = Command::new(plumBin())
|
|
20
|
-
.args(["compile", src_path, "-o",
|
|
31
|
+
.args(["compile", src_path.to_str().unwrap(), "-o", out_path.to_str().unwrap()])
|
|
21
32
|
.status()
|
|
22
33
|
.expect("failed to run plum compile");
|
|
23
34
|
assert!(status.success(), "plum compile exited with: {}", status);
|
|
@@ -27,12 +38,20 @@ fn compileSimpleAddProducesWasm() {
|
|
|
27
38
|
|
|
28
39
|
#[test]
|
|
29
40
|
fn compileWithImportResolvesViaLibPath() {
|
|
30
|
-
let
|
|
41
|
+
let dir = freshTempDir("import_fixtures");
|
|
31
|
-
|
|
42
|
+
std::fs::write(dir.join("helper.plum"), "fun helperValue() -> Int =\n 42\n").unwrap();
|
|
32
|
-
let
|
|
43
|
+
let src_path = dir.join("main.plum");
|
|
44
|
+
std::fs::write(&src_path, "module fixtures\n\nimport helper\n\nfun main() -> Int =\n helperValue()\n").unwrap();
|
|
33
|
-
let
|
|
45
|
+
let out_path = dir.join("main.wasm");
|
|
34
46
|
let status = Command::new(plumBin())
|
|
47
|
+
.args([
|
|
48
|
+
"compile",
|
|
49
|
+
src_path.to_str().unwrap(),
|
|
35
|
-
|
|
50
|
+
"--lib-path",
|
|
51
|
+
dir.to_str().unwrap(),
|
|
52
|
+
"-o",
|
|
53
|
+
out_path.to_str().unwrap(),
|
|
54
|
+
])
|
|
36
55
|
.status()
|
|
37
56
|
.expect("failed to run plum compile");
|
|
38
57
|
assert!(status.success(), "plum compile exited with: {}", status);
|
plum-wasm-codegen/src/lib.rs
CHANGED
|
@@ -614,14 +614,16 @@ pub struct GcTypeRegistry {
|
|
|
614
614
|
/// Concrete class/struct name -> its one wasm-gc `struct` type index.
|
|
615
615
|
pub class_type_idx: HashMap<String, u32>,
|
|
616
616
|
/// Enum name -> its abstract supertype `struct` type index (every variant
|
|
617
|
-
/// subtypes this) —
|
|
617
|
+
/// subtypes this) — including `Bool` (`enum Bool = | True | False` in
|
|
618
|
-
/// `ast::Item::Enum` of its own (`buildGlobalTables` hardcodes its
|
|
619
|
-
/// `
|
|
618
|
+
/// `libs/std/Bool.plum`), an ordinary enum like any other, present only
|
|
619
|
+
/// if actually imported.
|
|
620
620
|
pub enum_super_type_idx: HashMap<String, u32>,
|
|
621
621
|
/// Variant name (flat namespace, matching `EnumVariants`) -> its concrete
|
|
622
622
|
/// subtype `struct` type index.
|
|
623
623
|
pub variant_type_idx: HashMap<String, u32>,
|
|
624
|
-
/// The single shared `array<i8>` type index
|
|
624
|
+
/// The single shared `array<i8>` type index `[]Byte`/`Buffer`'s own
|
|
625
|
+
/// `data` field use — NOT `Str`'s own representation (`Str` is an
|
|
626
|
+
/// ordinary class, `data: Buffer`; see `libs/std/Str.plum`'s header).
|
|
625
627
|
pub byte_array_type_idx: u32,
|
|
626
628
|
/// The single shared closure-value struct type index — `{table_idx: i32, env:
|
|
627
629
|
/// anyref}` — every closure (and zero-capture "trampoline") uses regardless of
|
|
@@ -694,8 +696,9 @@ fn plumTypeToGcValtype(t: &PlumType, registry: &GcTypeRegistry) -> ValType {
|
|
|
694
696
|
}
|
|
695
697
|
}
|
|
696
698
|
|
|
697
|
-
/// Builds the wasm-gc type registry for every concrete class/enum
|
|
699
|
+
/// Builds the wasm-gc type registry for every concrete class/enum actually declared
|
|
700
|
+
/// in `source` (`Bool`/`Str`/etc included, but only if imported — no builtin is
|
|
698
|
-
///
|
|
701
|
+
/// hardcoded here), plus the shared raw byte-array type, and declares them all as
|
|
699
702
|
/// ONE `rec` group via `module.addGcTypes` — a single group sidesteps every ordering
|
|
700
703
|
/// question about mutual/self-references (a class field of another class's type, an
|
|
701
704
|
/// enum variant field referencing its own enum, `Node.next: Option[Node]`, etc.),
|