plum

#treesitter#compiler#wasm

git clone https://git.pyrossh.dev/plum

A statically typed, imperative programming language inspired by rust, python


984357bPeter John 2026-09-05T21:35:44+05:30
rename folders
Files changed (70) hide show
  1. .vscode/launch.json +1 -1
  2. README.md +5 -5
  3. plum-checker/Cargo.toml +1 -1
  4. plum-checker/tests/examples_test.rs +3 -3
  5. plum-cli/Cargo.toml +1 -1
  6. plum-cli/src/editor.rs +9 -9
  7. plum-core/Cargo.toml +1 -1
  8. plum-core/src/formatter.rs +1 -1
  9. {examples → plum-examples}/basics.plum +6 -3
  10. {examples → plum-examples}/closures.plum +0 -0
  11. {examples → plum-examples}/control_flow.plum +0 -0
  12. {examples → plum-examples}/dop_visitor.plum +0 -0
  13. {examples → plum-examples}/functions.plum +0 -0
  14. {examples → plum-examples}/io.plum +0 -0
  15. {examples → plum-examples}/match.plum +0 -0
  16. {examples → plum-examples}/methods.plum +0 -0
  17. {examples → plum-examples}/numbers.plum +0 -0
  18. {examples → plum-examples}/oop_visitor.plum +0 -0
  19. {examples → plum-examples}/strings.plum +0 -0
  20. {examples → plum-examples}/testing.plum +0 -0
  21. {examples → plum-examples}/types.plum +0 -0
  22. {tooling → plum-tooling}/tree-sitter-plum/.gitattributes +0 -0
  23. {tooling → plum-tooling}/tree-sitter-plum/.gitignore +0 -0
  24. {tooling → plum-tooling}/tree-sitter-plum/.helix/languages.toml +1 -1
  25. {tooling → plum-tooling}/tree-sitter-plum/.recall/.capture.json +0 -0
  26. {tooling → plum-tooling}/tree-sitter-plum/.recall/history.md +0 -0
  27. {tooling → plum-tooling}/tree-sitter-plum/Cargo.lock +0 -0
  28. {tooling → plum-tooling}/tree-sitter-plum/Cargo.toml +0 -0
  29. {tooling → plum-tooling}/tree-sitter-plum/LICENSE +0 -0
  30. {tooling → plum-tooling}/tree-sitter-plum/Makefile +0 -0
  31. {tooling → plum-tooling}/tree-sitter-plum/bindings/rust/build.rs +0 -0
  32. {tooling → plum-tooling}/tree-sitter-plum/bindings/rust/lib.rs +0 -0
  33. {tooling → plum-tooling}/tree-sitter-plum/grammar.js +0 -0
  34. {tooling → plum-tooling}/tree-sitter-plum/queries/plum/format.scm +0 -0
  35. {tooling → plum-tooling}/tree-sitter-plum/queries/plum/highlights.scm +0 -0
  36. {tooling → plum-tooling}/tree-sitter-plum/queries/plum/indents.scm +0 -0
  37. {tooling → plum-tooling}/tree-sitter-plum/queries/plum/injections.scm +0 -0
  38. {tooling → plum-tooling}/tree-sitter-plum/queries/plum/tags.scm +0 -0
  39. {tooling → plum-tooling}/tree-sitter-plum/queries/plum/textobjects.scm +0 -0
  40. {tooling → plum-tooling}/tree-sitter-plum/src/grammar.json +0 -0
  41. {tooling → plum-tooling}/tree-sitter-plum/src/node-types.json +0 -0
  42. {tooling → plum-tooling}/tree-sitter-plum/src/parser.c +0 -0
  43. {tooling → plum-tooling}/tree-sitter-plum/src/scanner.c +0 -0
  44. {tooling → plum-tooling}/tree-sitter-plum/src/tree_sitter/alloc.h +0 -0
  45. {tooling → plum-tooling}/tree-sitter-plum/src/tree_sitter/array.h +0 -0
  46. {tooling → plum-tooling}/tree-sitter-plum/src/tree_sitter/parser.h +0 -0
  47. {tooling → plum-tooling}/tree-sitter-plum/test/aa.plum +0 -0
  48. {tooling → plum-tooling}/tree-sitter-plum/test/corpus/.recall/.capture.json +0 -0
  49. {tooling → plum-tooling}/tree-sitter-plum/test/corpus/.recall/history.md +0 -0
  50. {tooling → plum-tooling}/tree-sitter-plum/test/corpus/assert.txt +0 -0
  51. {tooling → plum-tooling}/tree-sitter-plum/test/corpus/assign.txt +0 -0
  52. {tooling → plum-tooling}/tree-sitter-plum/test/corpus/const.txt +0 -0
  53. {tooling → plum-tooling}/tree-sitter-plum/test/corpus/enum.txt +0 -0
  54. {tooling → plum-tooling}/tree-sitter-plum/test/corpus/for.txt +0 -0
  55. {tooling → plum-tooling}/tree-sitter-plum/test/corpus/function.txt +0 -0
  56. {tooling → plum-tooling}/tree-sitter-plum/test/corpus/if.txt +0 -0
  57. {tooling → plum-tooling}/tree-sitter-plum/test/corpus/literals.txt +0 -0
  58. {tooling → plum-tooling}/tree-sitter-plum/test/corpus/match.txt +0 -0
  59. {tooling → plum-tooling}/tree-sitter-plum/test/corpus/test.txt +0 -0
  60. {tooling → plum-tooling}/tree-sitter-plum/test/corpus/trait.txt +0 -0
  61. {tooling → plum-tooling}/tree-sitter-plum/test/corpus/type.txt +0 -0
  62. {tooling → plum-tooling}/tree-sitter-plum/test/corpus/while.txt +0 -0
  63. {tooling → plum-tooling}/tree-sitter-plum/test/highlight/sample.plum +0 -0
  64. {tooling → plum-tooling}/tree-sitter-plum/tree-sitter.json +0 -0
  65. {tooling → plum-tooling}/vscode-plum/language-configuration.json +0 -0
  66. {tooling → plum-tooling}/vscode-plum/package-lock.json +0 -0
  67. {tooling → plum-tooling}/vscode-plum/package.json +0 -0
  68. {tooling → plum-tooling}/vscode-plum/syntaxes/plum.tmLanguage.json +0 -0
  69. plum-wasm-codegen/Cargo.toml +1 -1
  70. plum-wasm-codegen/tests/examples_test.rs +2 -2
.vscode/launch.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "type": "extensionHost",
11
11
  "request": "launch",
12
12
  "args": [
13
- "--extensionDevelopmentPath=${workspaceFolder}/tooling/vscode-plum"
13
+ "--extensionDevelopmentPath=${workspaceFolder}/plum-tooling/vscode-plum"
14
14
  ]
15
15
  }
16
16
  ]
README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A statically typed, imperative programming language with algebraic data types, inspired by Rust and Gleam.
4
4
 
5
- - Built on a [tree-sitter](tooling/tree-sitter-plum) grammar, with syntax highlighting for Helix and Zed out of the box
5
+ - Built on a [tree-sitter](plum-tooling/tree-sitter-plum) grammar, with syntax highlighting for Helix and Zed out of the box
6
6
  - Compiles to WebAssembly today, with plans to target amd64, arm64, and riscv64 via QBE (C-ABI compatible)
7
7
 
8
8
  ## Requirements
@@ -162,7 +162,7 @@ test "add works"
162
162
  ```
163
163
 
164
164
  ```sh
165
- $ plum test examples/testing.plum
165
+ $ plum test plum-examples/testing.plum
166
166
  └─ add works ✔
167
167
 
168
168
  1 passed, 0 failed
@@ -299,10 +299,10 @@ fun greet(name: Str) -> Str =
299
299
  extern fun printLn(s: Str)
300
300
  ```
301
301
 
302
- `extern fun` declares a function backed by a host-provided wasm import, with no Plum body. `libs/std/os.plum` declares `printLn` for use via `import std/os`.
302
+ `extern fun` declares a function backed by a host-provided wasm import, with no Plum body. `plum-std/Os.plum` declares `printLn` for use via `import std/os`.
303
303
 
304
304
  ```sh
305
- $ plum run examples/io.plum
305
+ $ plum run plum-examples/io.plum
306
306
  hello from plum
307
307
  ```
308
308
 
@@ -316,4 +316,4 @@ hello from plum
316
316
  - **`Map[K: Hashable, V]`** (`import std/Map`) — a real bucketed hash table
317
317
  - **`List[T]`** (`import std/List`) — a singly-linked list with `get`/`add`/`set`/`removeAt`/`remove`/`each`/`map`/`reduce`/`sort`/`join`/`chunk`/`partition`
318
318
 
319
- See [`examples/`](examples) for a runnable file per feature above, and [`libs/std/`](libs/std) for the standard library source.
319
+ See [`plum-examples/`](plum-examples) for a runnable file per feature above, and [`plum-std/`](plum-std) for the standard library source.
plum-checker/Cargo.toml CHANGED
@@ -8,4 +8,4 @@ plum-core = { path = "../plum-core" }
8
8
 
9
9
  [dev-dependencies]
10
10
  tree-sitter = "0.26"
11
- tree-sitter-plum = { path = "../tooling/tree-sitter-plum" }
11
+ tree-sitter-plum = { path = "../plum-tooling/tree-sitter-plum" }
plum-checker/tests/examples_test.rs CHANGED
@@ -2,7 +2,7 @@
2
2
  use plum_checker::checkSource;
3
3
 
4
4
  fn examplesDir() -> std::path::PathBuf {
5
- std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../examples")
5
+ std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../plum-examples")
6
6
  }
7
7
 
8
8
  fn libPath() -> std::path::PathBuf {
@@ -11,13 +11,13 @@ fn libPath() -> std::path::PathBuf {
11
11
 
12
12
  fn exampleFiles() -> Vec<std::path::PathBuf> {
13
13
  let mut files: Vec<_> = std::fs::read_dir(examplesDir())
14
- .expect("examples/ directory should exist")
14
+ .expect("plum-examples/ directory should exist")
15
15
  .filter_map(|e| e.ok())
16
16
  .map(|e| e.path())
17
17
  .filter(|p| p.extension().and_then(|e| e.to_str()) == Some("plum"))
18
18
  .collect();
19
19
  files.sort();
20
- assert!(!files.is_empty(), "examples/ should contain at least one .plum file");
20
+ assert!(!files.is_empty(), "plum-examples/ should contain at least one .plum file");
21
21
  files
22
22
  }
23
23
 
plum-cli/Cargo.toml CHANGED
@@ -14,7 +14,7 @@ plum-wasm-codegen = { path = "../plum-wasm-codegen" }
14
14
  clap = { version = "4", features = ["derive"] }
15
15
  anyhow = "1"
16
16
  tree-sitter = "0.26"
17
- tree-sitter-plum = { path = "../tooling/tree-sitter-plum" }
17
+ tree-sitter-plum = { path = "../plum-tooling/tree-sitter-plum" }
18
18
  toml_edit = "0.22"
19
19
  wasmtime = "47"
20
20
  ureq = "2.10"
plum-cli/src/editor.rs CHANGED
@@ -21,11 +21,11 @@ pub enum EditorType {
21
21
  // ---- embedded VSCode extension assets -------------------------------------
22
22
 
23
23
  const VSCODE_PACKAGE_JSON: &str =
24
- include_str!("../../tooling/vscode-plum/package.json");
24
+ include_str!("../../plum-tooling/vscode-plum/package.json");
25
25
  const VSCODE_LANGUAGE_CONFIG: &str =
26
- include_str!("../../tooling/vscode-plum/language-configuration.json");
26
+ include_str!("../../plum-tooling/vscode-plum/language-configuration.json");
27
27
  const VSCODE_TMLANGUAGE: &str =
28
- include_str!("../../tooling/vscode-plum/syntaxes/plum.tmLanguage.json");
28
+ include_str!("../../plum-tooling/vscode-plum/syntaxes/plum.tmLanguage.json");
29
29
 
30
30
  const VSCODE_PUBLISHER: &str = "plum-lang";
31
31
  const VSCODE_EXTENSION_NAME: &str = "plum";
@@ -34,15 +34,15 @@ const VSCODE_EXTENSION_VERSION: &str = "0.0.1";
34
34
  // ---- embedded Helix / tree-sitter query assets ----------------------------
35
35
 
36
36
  const HELIX_HIGHLIGHTS: &str =
37
- include_str!("../../tooling/tree-sitter-plum/queries/plum/highlights.scm");
37
+ include_str!("../../plum-tooling/tree-sitter-plum/queries/plum/highlights.scm");
38
38
  const HELIX_INDENTS: &str =
39
- include_str!("../../tooling/tree-sitter-plum/queries/plum/indents.scm");
39
+ include_str!("../../plum-tooling/tree-sitter-plum/queries/plum/indents.scm");
40
40
  const HELIX_INJECTIONS: &str =
41
- include_str!("../../tooling/tree-sitter-plum/queries/plum/injections.scm");
41
+ include_str!("../../plum-tooling/tree-sitter-plum/queries/plum/injections.scm");
42
42
  const HELIX_TAGS: &str =
43
- include_str!("../../tooling/tree-sitter-plum/queries/plum/tags.scm");
43
+ include_str!("../../plum-tooling/tree-sitter-plum/queries/plum/tags.scm");
44
44
  const HELIX_TEXTOBJECTS: &str =
45
- include_str!("../../tooling/tree-sitter-plum/queries/plum/textobjects.scm");
45
+ include_str!("../../plum-tooling/tree-sitter-plum/queries/plum/textobjects.scm");
46
46
 
47
47
  /// The absolute path to the `tree-sitter-plum` grammar crate on the machine that
48
48
  /// *built* this `plum` binary. Baked in at compile time so a contributor running
@@ -50,7 +50,7 @@ const HELIX_TEXTOBJECTS: &str =
50
50
  /// languages.toml entry that actually resolves, instead of a hand-copied path
51
51
  /// that goes stale the moment the repo moves.
52
52
  const TREE_SITTER_PLUM_DIR: &str =
53
- concat!(env!("CARGO_MANIFEST_DIR"), "/../tooling/tree-sitter-plum");
53
+ concat!(env!("CARGO_MANIFEST_DIR"), "/../plum-tooling/tree-sitter-plum");
54
54
 
55
55
  /// [`TREE_SITTER_PLUM_DIR`] with the `..` component resolved away, for a tidier
56
56
  /// `languages.toml`. Falls back to the raw (still-correct, just uglier) path if
plum-core/Cargo.toml CHANGED
@@ -5,7 +5,7 @@ edition = "2021"
5
5
 
6
6
  [dependencies]
7
7
  tree-sitter = "0.26"
8
- tree-sitter-plum = { path = "../tooling/tree-sitter-plum" }
8
+ tree-sitter-plum = { path = "../plum-tooling/tree-sitter-plum" }
9
9
  topiary-core = "0.7.3"
10
10
  topiary-tree-sitter-facade = "0.7.3"
11
11
 
plum-core/src/formatter.rs CHANGED
@@ -4,7 +4,7 @@ use std::io::Cursor;
4
4
  use topiary_core::{formatter, Language, Operation, TopiaryQuery};
5
5
 
6
6
  const FORMAT_QUERY: &str =
7
- include_str!("../../tooling/tree-sitter-plum/queries/plum/format.scm");
7
+ include_str!("../../plum-tooling/tree-sitter-plum/queries/plum/format.scm");
8
8
 
9
9
  #[derive(Debug)]
10
10
  pub enum FormatterError {
{examples → plum-examples}/basics.plum RENAMED
@@ -10,7 +10,8 @@ GREETING = "hello"
10
10
  fun main() =
11
11
  dec := 42
12
12
  hex := 0xFF
13
- bin := 0b1010
13
+ bin := 0b1
14
+ 010
14
15
  big := 1_000_000
15
16
  flt := 3.14
16
17
  flt2 := 12.0f
@@ -18,9 +19,11 @@ fun main() =
18
19
  name := "plum"
19
20
  yes := True
20
21
  no := False
21
-
22
22
  sum := 1 + 2 * 3 - 4 / 2
23
+ bits := 0b1
23
- bits := 0b1100 & 0b1010 | 0b0001
24
+ 100 & 0b1
25
+ 010 | 0b0
26
+ 001
24
27
  shifted := 1 << 4
25
28
  cmp := sum > 0 && bits != 0 || False
26
29
  grouped := {1 + 2} * {3 - 1}
{examples → plum-examples}/closures.plum RENAMED
File without changes
{examples → plum-examples}/control_flow.plum RENAMED
File without changes
{examples → plum-examples}/dop_visitor.plum RENAMED
File without changes
{examples → plum-examples}/functions.plum RENAMED
File without changes
{examples → plum-examples}/io.plum RENAMED
File without changes
{examples → plum-examples}/match.plum RENAMED
File without changes
{examples → plum-examples}/methods.plum RENAMED
File without changes
{examples → plum-examples}/numbers.plum RENAMED
File without changes
{examples → plum-examples}/oop_visitor.plum RENAMED
File without changes
{examples → plum-examples}/strings.plum RENAMED
File without changes
{examples → plum-examples}/testing.plum RENAMED
File without changes
{examples → plum-examples}/types.plum RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/.gitattributes RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/.gitignore RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/.helix/languages.toml RENAMED
@@ -8,4 +8,4 @@ indent = { tab-width = 2, unit = " " }
8
8
 
9
9
  [[grammar]]
10
10
  name = "plum"
11
- source.path = "/Users/pyrossh/Code/plum/tooling/tree-sitter-plum"
11
+ source.path = "/Users/pyrossh/Code/plum/plum-tooling/tree-sitter-plum"
{tooling → plum-tooling}/tree-sitter-plum/.recall/.capture.json RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/.recall/history.md RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/Cargo.lock RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/Cargo.toml RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/LICENSE RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/Makefile RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/bindings/rust/build.rs RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/bindings/rust/lib.rs RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/grammar.js RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/queries/plum/format.scm RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/queries/plum/highlights.scm RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/queries/plum/indents.scm RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/queries/plum/injections.scm RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/queries/plum/tags.scm RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/queries/plum/textobjects.scm RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/src/grammar.json RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/src/node-types.json RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/src/parser.c RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/src/scanner.c RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/src/tree_sitter/alloc.h RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/src/tree_sitter/array.h RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/src/tree_sitter/parser.h RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/test/aa.plum RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/test/corpus/.recall/.capture.json RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/test/corpus/.recall/history.md RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/test/corpus/assert.txt RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/test/corpus/assign.txt RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/test/corpus/const.txt RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/test/corpus/enum.txt RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/test/corpus/for.txt RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/test/corpus/function.txt RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/test/corpus/if.txt RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/test/corpus/literals.txt RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/test/corpus/match.txt RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/test/corpus/test.txt RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/test/corpus/trait.txt RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/test/corpus/type.txt RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/test/corpus/while.txt RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/test/highlight/sample.plum RENAMED
File without changes
{tooling → plum-tooling}/tree-sitter-plum/tree-sitter.json RENAMED
File without changes
{tooling → plum-tooling}/vscode-plum/language-configuration.json RENAMED
File without changes
{tooling → plum-tooling}/vscode-plum/package-lock.json RENAMED
File without changes
{tooling → plum-tooling}/vscode-plum/package.json RENAMED
File without changes
{tooling → plum-tooling}/vscode-plum/syntaxes/plum.tmLanguage.json RENAMED
File without changes
plum-wasm-codegen/Cargo.toml CHANGED
@@ -11,5 +11,5 @@ plum-checker = { path = "../plum-checker" }
11
11
  [dev-dependencies]
12
12
  wasmparser = "0.220"
13
13
  tree-sitter = "0.26"
14
- tree-sitter-plum = { path = "../tooling/tree-sitter-plum" }
14
+ tree-sitter-plum = { path = "../plum-tooling/tree-sitter-plum" }
15
15
  wasmtime = "47"
plum-wasm-codegen/tests/examples_test.rs CHANGED
@@ -2,7 +2,7 @@
2
2
  use plum_wasm_codegen::compileSource;
3
3
 
4
4
  fn examplesDir() -> std::path::PathBuf {
5
- std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../examples")
5
+ std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../plum-examples")
6
6
  }
7
7
 
8
8
  fn libPath() -> std::path::PathBuf {
@@ -64,7 +64,7 @@ fn typesCompiles() {
64
64
 
65
65
  // methods.plum/match.plum/closures.plum's actual runtime-correctness checks
66
66
  // now live as native `test`/`expect` blocks inside those example files
67
- // themselves (run via `plum test examples/<name>.plum`, see
67
+ // themselves (run via `plum test plum-examples/<name>.plum`, see
68
68
  // scripts/test-plum.sh) — `assertCompiles` below still exercises that each
69
69
  // still compiles to valid wasm via this crate's direct (non-CLI) path.
70
70
  #[test]