plum

#treesitter#compiler#wasm

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

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


ad7c5e8 — Peter John 2026-11-02T15:01:27+05:30
style: cargo fmt
plum-checker/tests/checker_tests.rs CHANGED
@@ -878,14 +878,18 @@ fn checkDiscard(body: &str) -> Result<(), Vec<CheckError>> {
878
878
  fn discardedNonUnitCallIsError() {
879
879
  let t = errText(checkDiscard("fun f(b: Bag) =\n b.push(1)\n b.bump()\n"));
880
880
  assert!(
881
+ t.contains(
881
- t.contains("result of 'push' is unused (Bag); assign it, or discard it explicitly with '_ := ...'"),
882
+ "result of 'push' is unused (Bag); assign it, or discard it explicitly with '_ := ...'"
883
+ ),
882
884
  "{t}"
883
885
  );
884
886
  let t = errText(checkDiscard("fun f() =\n five()\n five()\n"));
885
887
  assert!(t.contains("result of 'five' is unused (Int)"), "{t}");
886
888
  let t = errText(checkDiscard("fun f() =\n Util.two()\n five()\n"));
887
889
  assert!(t.contains("result of 'two' is unused (Int)"), "{t}");
890
+ let t = errText(checkDiscard(
888
- let t = errText(checkDiscard("fun f() =\n g := |x| x + 1\n g(2)\n five()\n"));
891
+ "fun f() =\n g := |x| x + 1\n g(2)\n five()\n",
892
+ ));
889
893
  assert!(t.contains("result of 'g' is unused"), "{t}");
890
894
  }
891
895
 
@@ -922,5 +926,8 @@ fn underscoreDiscardIsAccepted() {
922
926
 
923
927
  #[test]
924
928
  fn discardTargetTwiceInOneScopeIsFine() {
929
+ assert!(
925
- assert!(checkDiscard("fun f() =\n _ := five()\n _ := five()\n _ = five()\n _ := five()\n").is_ok());
930
+ checkDiscard("fun f() =\n _ := five()\n _ := five()\n _ = five()\n _ := five()\n")
931
+ .is_ok()
932
+ );
926
933
  }
plum-cli/src/game.rs CHANGED
@@ -126,7 +126,9 @@ fn buildHostWasm() -> Result<PathBuf> {
126
126
  /// Every file under `dir` (dotfiles skipped), as `/`-separated paths relative to it, sorted.
127
127
  fn listFiles(dir: &Path) -> Result<Vec<String>> {
128
128
  fn walk(dir: &Path, prefix: &str, out: &mut Vec<String>) -> Result<()> {
129
+ for entry in
129
- for entry in fs::read_dir(dir).with_context(|| format!("failed to read {}", dir.display()))? {
130
+ fs::read_dir(dir).with_context(|| format!("failed to read {}", dir.display()))?
131
+ {
130
132
  let entry = entry?;
131
133
  let name = format!("{prefix}{}", entry.file_name().to_string_lossy());
132
134
  if entry.file_name().to_string_lossy().starts_with('.') {
@@ -151,7 +153,11 @@ fn writeWeb(wasm: &[u8], dist: &Path, assets: &Path) -> Result<()> {
151
153
  let bundle = jsBundle()?;
152
154
 
153
155
  // The whole asset directory (if there is one) is bundled and preloaded.
154
- let files = if assets.is_dir() { listFiles(assets)? } else { Vec::new() };
156
+ let files = if assets.is_dir() {
157
+ listFiles(assets)?
158
+ } else {
159
+ Vec::new()
160
+ };
155
161
 
156
162
  fs::create_dir_all(dist)?;
157
163
  let web = repoRoot().join("plum-game/web");
@@ -163,7 +169,10 @@ fn writeWeb(wasm: &[u8], dist: &Path, assets: &Path) -> Result<()> {
163
169
  fs::copy(&hostWasm, dist.join("plum-game.wasm"))
164
170
  .with_context(|| format!("failed to copy {}", hostWasm.display()))?;
165
171
  fs::write(dist.join("plum.wasm"), wasm)?;
172
+ fs::write(
173
+ dist.join("preload.txt"),
166
- fs::write(dist.join("preload.txt"), files.iter().map(|f| format!("{f}\n")).collect::<String>())?;
174
+ files.iter().map(|f| format!("{f}\n")).collect::<String>(),
175
+ )?;
167
176
  for rel in &files {
168
177
  let to = dist.join("assets").join(rel);
169
178
  fs::create_dir_all(to.parent().expect("asset has a parent"))?;