plum
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 +10 -3
- plum-cli/src/game.rs +12 -3
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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() {
|
|
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
|
-
|
|
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"))?;
|