hotwatch only responds once

This commit is contained in:
me 2025-12-21 14:28:49 +02:00
parent 2640ceef41
commit c89b06fb31
8 changed files with 670 additions and 13 deletions

258
Cargo.lock generated
View file

@ -40,6 +40,12 @@ dependencies = [
"log", "log",
] ]
[[package]]
name = "anes"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
[[package]] [[package]]
name = "anstream" name = "anstream"
version = "0.6.21" version = "0.6.21"
@ -110,6 +116,7 @@ name = "ayin-lang"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"chumsky", "chumsky",
"criterion",
"env_logger", "env_logger",
"gamepads", "gamepads",
"hotwatch", "hotwatch",
@ -150,6 +157,12 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cast"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.2.49" version = "1.2.49"
@ -186,6 +199,58 @@ dependencies = [
"unicode-segmentation", "unicode-segmentation",
] ]
[[package]]
name = "ciborium"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e"
dependencies = [
"ciborium-io",
"ciborium-ll",
"serde",
]
[[package]]
name = "ciborium-io"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757"
[[package]]
name = "ciborium-ll"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
dependencies = [
"ciborium-io",
"half",
]
[[package]]
name = "clap"
version = "4.5.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
version = "4.5.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00"
dependencies = [
"anstyle",
"clap_lex",
]
[[package]]
name = "clap_lex"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
[[package]] [[package]]
name = "color_quant" name = "color_quant"
version = "1.1.0" version = "1.1.0"
@ -235,6 +300,39 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "criterion"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1c047a62b0cc3e145fa84415a3191f628e980b194c2755aa12300a4e6cbd928"
dependencies = [
"anes",
"cast",
"ciborium",
"clap",
"criterion-plot",
"itertools",
"num-traits",
"oorandom",
"plotters",
"rayon",
"regex",
"serde",
"serde_json",
"tinytemplate",
"walkdir",
]
[[package]]
name = "criterion-plot"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b1bcc0dc7dfae599d84ad0b1a55f80cde8af3725da8313b528da95ef783e338"
dependencies = [
"cast",
"itertools",
]
[[package]] [[package]]
name = "crossbeam-channel" name = "crossbeam-channel"
version = "0.5.15" version = "0.5.15"
@ -244,12 +342,43 @@ dependencies = [
"crossbeam-utils", "crossbeam-utils",
] ]
[[package]]
name = "crossbeam-deque"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
dependencies = [
"crossbeam-utils",
]
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.21" version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "crunchy"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]] [[package]]
name = "encode_unicode" name = "encode_unicode"
version = "1.0.0" version = "1.0.0"
@ -416,6 +545,17 @@ version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e05e7e6723e3455f4818c7b26e855439f7546cf617ef669d1adedb8669e5cb9" checksum = "9e05e7e6723e3455f4818c7b26e855439f7546cf617ef669d1adedb8669e5cb9"
[[package]]
name = "half"
version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b"
dependencies = [
"cfg-if",
"crunchy",
"zerocopy",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.15.5" version = "0.15.5"
@ -509,6 +649,21 @@ version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
[[package]]
name = "itertools"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010"
[[package]] [[package]]
name = "jiff" name = "jiff"
version = "0.2.16" version = "0.2.16"
@ -778,6 +933,12 @@ version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
[[package]]
name = "oorandom"
version = "11.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e"
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.12.5" version = "0.12.5"
@ -807,6 +968,34 @@ version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]]
name = "plotters"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747"
dependencies = [
"num-traits",
"plotters-backend",
"plotters-svg",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "plotters-backend"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a"
[[package]]
name = "plotters-svg"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670"
dependencies = [
"plotters-backend",
]
[[package]] [[package]]
name = "png" name = "png"
version = "0.17.16" version = "0.17.16"
@ -869,6 +1058,26 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "rayon"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
dependencies = [
"crossbeam-deque",
"crossbeam-utils",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.5.18" version = "0.5.18"
@ -939,6 +1148,12 @@ version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "ryu"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62049b2877bf12821e8f9ad256ee38fdc31db7387ec2d3b3f403024de2034aea"
[[package]] [[package]]
name = "same-file" name = "same-file"
version = "1.0.6" version = "1.0.6"
@ -984,6 +1199,19 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "serde_json"
version = "1.0.145"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
"serde_core",
]
[[package]] [[package]]
name = "shlex" name = "shlex"
version = "1.3.0" version = "1.3.0"
@ -1052,6 +1280,16 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "tinytemplate"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
dependencies = [
"serde",
"serde_json",
]
[[package]] [[package]]
name = "ttf-parser" name = "ttf-parser"
version = "0.21.1" version = "0.21.1"
@ -1485,3 +1723,23 @@ name = "windows_x86_64_msvc"
version = "0.53.1" version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
[[package]]
name = "zerocopy"
version = "0.8.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

View file

@ -16,6 +16,10 @@ path = "src/lib.rs"
name = "ayin" name = "ayin"
path = "src/main.rs" path = "src/main.rs"
[[bench]]
name = "benchmark"
harness = false
[dependencies] [dependencies]
thiserror = "1" thiserror = "1"
env_logger = "0.11.8" env_logger = "0.11.8"
@ -28,6 +32,7 @@ hotwatch = "0.5.0"
[dev-dependencies] [dev-dependencies]
insta = "1.44.3" insta = "1.44.3"
criterion = { version = "0.7" }
[workspace.lints.clippy] [workspace.lints.clippy]
all = { level = "warn", priority = -1 } all = { level = "warn", priority = -1 }

View file

@ -12,7 +12,8 @@ test:
.PHONY: run .PHONY: run
run: run:
RUST_BACKTRACE=1 cargo run -- colorgame.ayin # RUST_BACKTRACE=1 cargo run -- game.ayin
cargo run -- game.ayin
.PHONY: review .PHONY: review
review: review:

208
benches/benchmark.rs Normal file
View file

@ -0,0 +1,208 @@
use criterion::{Criterion, criterion_group, criterion_main};
use std::hint::black_box;
fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("minimal", |b| {
b.iter(|| {
let program = "
let main = fn() {
1
}
";
ayin::run_main(black_box(program))
})
});
c.bench_function("game", |b| {
b.iter(|| {
let program = "
let main = fn() {
setup()
}
let screen_size = 360
let shoot_timer = 60
let dim = {
.w: 16,
.h: 16,
}
let bullet_dim = {
.w: dim.w / 4,
.h: dim.h / 4,
}
let migrate = fn(state) {
return setup();
state
}
let setup = fn() {
return {
.player: {
.pos: {
.x: (screen_size - dim.w) - dim.w,
.y: dim.h,
},
.speed: 360,
},
.enemy: {
.pos: {
.x: dim.w,
.y: dim.h,
},
.speed: 20,
.timer: shoot_timer,
},
.bullets: {
.pos: {
.x: dim.w,
.y: dim.h,
},
.movement: {
.x: 0,
.y: 0,
},
.speed: 180,
},
.timer: 0,
.status: \"ongoing\",
};
}
let move_player = fn(state, input) {
let delta = get_frame_time();
let dpad_x = if input.gamepad1.dpad.right { 1 } else { 0 } + if input.gamepad1.dpad.left { -1 } else { 0 };
let dpad_y = if input.gamepad1.dpad.down { 1 } else { 0 } + if input.gamepad1.dpad.up { -1 } else { 0 };
let movement = {
.x: input.gamepad1.sticks.left.x + dpad_x,
.y: input.gamepad1.sticks.left.y + dpad_y,
};
state.player.pos.x =
max(0,
min( state.player.pos.x + (delta * state.player.speed * movement.x)
, screen_size - dim.w
)
);
state.player.pos.y =
max(0,
min( state.player.pos.y + (delta * state.player.speed * movement.y)
, screen_size - dim.w
)
);
}
let update = fn(state, input) {
let delta = get_frame_time();
state.timer = state.timer + delta;
move_player(state, input);
let enemy_movement = {
.x: if abs(state.enemy.pos.x - state.player.pos.x) < 5 { 0 } else { if state.enemy.pos.x < state.player.pos.x { 1 } else { -1 } },
.y: if abs(state.enemy.pos.y - state.player.pos.y) < 5 { 0 } else { if state.enemy.pos.y < state.player.pos.y { 1 } else { -1 } },
};
state.enemy.pos.x =
max(0,
min( state.enemy.pos.x + (delta * state.enemy.speed * enemy_movement.x)
, screen_size - dim.w
)
);
state.enemy.pos.y =
max(0,
min( state.enemy.pos.y + (delta * state.enemy.speed * enemy_movement.y)
, screen_size - dim.w
)
);
state.enemy.timer = state.enemy.timer - 1;
if state.enemy.timer == 0 {
state.enemy.timer = shoot_timer;
state.bullets.pos.x = state.enemy.pos.x + (dim.w * enemy_movement.x);
state.bullets.pos.y = state.enemy.pos.y + (dim.h * enemy_movement.y);
state.bullets.movement.x = enemy_movement.x;
state.bullets.movement.y = enemy_movement.y;
};
state.bullets.pos.x =
state.bullets.pos.x + (delta * state.bullets.speed * state.bullets.movement.x);
state.bullets.pos.y =
state.bullets.pos.y + (delta * state.bullets.speed * state.bullets.movement.y);
return state;
}
let draw = fn(state) {
frame_clear(0, 0, 0);
let player_rect = {
.x: state.player.pos.x,
.y: state.player.pos.y,
.w: dim.w,
.h: dim.h,
};
let color = { .r: 155, .g: 205, .b: 255 };
draw_rectangle(player_rect, color);
let enemy_rect = {
.x: state.enemy.pos.x,
.y: state.enemy.pos.y,
.w: dim.w,
.h: dim.h,
};
let color = { .r: 255, .g: 155, .b: 255 };
draw_rectangle(enemy_rect, color);
let bullet_rect = {
.x: state.bullets.pos.x,
.y: state.bullets.pos.y,
.w: bullet_dim.w,
.h: bullet_dim.h,
};
let color = { .r: 255, .g: 255, .b: 255 };
draw_rectangle(bullet_rect, color);
draw_text(\"RUN!!!\", 20, 50, 50, { .r: 255, .g: 55, .b: 55 });
}
let min = fn(a,b) {
if a < b {
a
} else {
b
}
}
let max = fn(a,b) {
if a < b {
b
} else {
a
}
}
let abs = fn(a) {
if a >= 0 { a } else { 0 - a }
}
let is_touching = fn(rect1, rect2) {
if ((rect1.x < rect2.x) && ((rect1.x + rect1.w) > rect2.x))
&& ((rect1.y < rect2.y) && ((rect1.y + rect1.h) > rect2.y)) {
true
} else {
false
}
}
";
ayin::run_main(black_box(program))
})
});
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);

178
game.ayin Normal file
View file

@ -0,0 +1,178 @@
let screen_size = 360
let shoot_timer = 60
let dim = {
.w: 16,
.h: 16,
}
let bullet_dim = {
.w: dim.w / 4,
.h: dim.h / 4,
}
let migrate = fn(state) {
return setup();
state
}
let setup = fn() {
return {
.player: {
.pos: {
.x: (screen_size - dim.w) - dim.w,
.y: dim.h,
},
.speed: 360,
},
.enemy: {
.pos: {
.x: dim.w,
.y: dim.h,
},
.speed: 20,
.timer: shoot_timer,
},
.bullets: {
.pos: {
.x: dim.w,
.y: dim.h,
},
.movement: {
.x: 0,
.y: 0,
},
.speed: 180,
},
.timer: 0,
.status: "ongoing",
};
}
let move_player = fn(state, input) {
let delta = get_frame_time();
let dpad_x = if input.gamepad1.dpad.right { 1 } else { 0 } + if input.gamepad1.dpad.left { -1 } else { 0 };
let dpad_y = if input.gamepad1.dpad.down { 1 } else { 0 } + if input.gamepad1.dpad.up { -1 } else { 0 };
let movement = {
.x: input.gamepad1.sticks.left.x + dpad_x,
.y: input.gamepad1.sticks.left.y + dpad_y,
};
state.player.pos.x =
max(0,
min( state.player.pos.x + (delta * state.player.speed * movement.x)
, screen_size - dim.w
)
);
state.player.pos.y =
max(0,
min( state.player.pos.y + (delta * state.player.speed * movement.y)
, screen_size - dim.w
)
);
}
let update = fn(state, input) {
let delta = get_frame_time();
state.timer = state.timer + delta;
move_player(state, input);
let enemy_movement = {
.x: if abs(state.enemy.pos.x - state.player.pos.x) < 5 { 0 } else { if state.enemy.pos.x < state.player.pos.x { 1 } else { -1 } },
.y: if abs(state.enemy.pos.y - state.player.pos.y) < 5 { 0 } else { if state.enemy.pos.y < state.player.pos.y { 1 } else { -1 } },
};
state.enemy.pos.x =
max(0,
min( state.enemy.pos.x + (delta * state.enemy.speed * enemy_movement.x)
, screen_size - dim.w
)
);
state.enemy.pos.y =
max(0,
min( state.enemy.pos.y + (delta * state.enemy.speed * enemy_movement.y)
, screen_size - dim.w
)
);
state.enemy.timer = state.enemy.timer - 1;
if state.enemy.timer == 0 {
state.enemy.timer = shoot_timer;
state.bullets.pos.x = state.enemy.pos.x + (dim.w * enemy_movement.x);
state.bullets.pos.y = state.enemy.pos.y + (dim.h * enemy_movement.y);
state.bullets.movement.x = enemy_movement.x;
state.bullets.movement.y = enemy_movement.y;
};
state.bullets.pos.x =
state.bullets.pos.x + (delta * state.bullets.speed * state.bullets.movement.x);
state.bullets.pos.y =
state.bullets.pos.y + (delta * state.bullets.speed * state.bullets.movement.y);
return state;
}
let draw = fn(state) {
frame_clear(0, 0, 0);
let player_rect = {
.x: state.player.pos.x,
.y: state.player.pos.y,
.w: dim.w,
.h: dim.h,
};
let color = { .r: 155, .g: 205, .b: 255 };
draw_rectangle(player_rect, color);
let enemy_rect = {
.x: state.enemy.pos.x,
.y: state.enemy.pos.y,
.w: dim.w,
.h: dim.h,
};
let color = { .r: 255, .g: 155, .b: 255 };
draw_rectangle(enemy_rect, color);
let bullet_rect = {
.x: state.bullets.pos.x,
.y: state.bullets.pos.y,
.w: bullet_dim.w,
.h: bullet_dim.h,
};
let color = { .r: 255, .g: 255, .b: 255 };
draw_rectangle(bullet_rect, color);
draw_text("RUN!!!", 20, 50, 50, { .r: 255, .g: 55, .b: 55 });
}
let min = fn(a,b) {
if a < b {
a
} else {
b
}
}
let max = fn(a,b) {
if a < b {
b
} else {
a
}
}
let abs = fn(a) {
if a >= 0 { a } else { 0 - a }
}
let is_touching = fn(rect1, rect2) {
if ((rect1.x < rect2.x) && ((rect1.x + rect1.w) > rect2.x))
&& ((rect1.y < rect2.y) && ((rect1.y + rect1.h) > rect2.y)) {
true
} else {
false
}
}

View file

@ -56,7 +56,11 @@ impl std::fmt::Display for Error {
) )
} }
Error::DuplicateNames(a, b) => write!(f, "Duplicate names: {a:?}\n{b}"), Error::DuplicateNames(a, b) => write!(f, "Duplicate names: {a:?}\n{b}"),
Error::NameNotFound(a, e, b) => write!(f, "Name not found: {a:?} in {e:#?}\n{b}"), Error::NameNotFound(a, e, b) => write!(
f,
"Name not found: {a:?} in {:#?}\n{b}",
e.env.keys().collect::<Vec<_>>()
),
Error::FieldNotFound(a, b) => write!(f, "Field not found: {a:?}\n{b}"), Error::FieldNotFound(a, b) => write!(f, "Field not found: {a:?}\n{b}"),
Error::EnvNotFound(a, b) => write!(f, "Env not found: {a:?}\n{b}"), Error::EnvNotFound(a, b) => write!(f, "Env not found: {a:?}\n{b}"),
Error::LastStatementNotAnExpr(a) => { Error::LastStatementNotAnExpr(a) => {

View file

@ -1,5 +1,8 @@
use ayin::runtime::*; use ayin::runtime::*;
use hotwatch; use hotwatch::{
self,
notify::event::{DataChange, ModifyKind},
};
use macroquad::prelude::*; use macroquad::prelude::*;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
@ -30,7 +33,7 @@ async fn main() {
let mut hotwatch = hotwatch::Hotwatch::new().expect("hotwatch failed to initialize!"); let mut hotwatch = hotwatch::Hotwatch::new().expect("hotwatch failed to initialize!");
hotwatch hotwatch
.watch(file.clone(), move |event: hotwatch::Event| { .watch(file.clone(), move |event: hotwatch::Event| {
if let hotwatch::EventKind::Modify(_) = event.kind { if let hotwatch::EventKind::Modify(ModifyKind::Data(DataChange::Content)) = event.kind {
match std::fs::read_to_string(file.clone()) { match std::fs::read_to_string(file.clone()) {
Err(err) => println!("Error: {err:#?}"), Err(err) => println!("Error: {err:#?}"),
Ok(txt) => match ayin::parser::parse_file(txt) { Ok(txt) => match ayin::parser::parse_file(txt) {

View file

@ -171,17 +171,17 @@ pub fn fetch_events(state: &mut State) -> Input {
pub fn draw(state: &mut State) { pub fn draw(state: &mut State) {
clear_background(Color::from_hex(0x081829)); clear_background(Color::from_hex(0x081829));
set_default_camera(); // set_default_camera();
let (w, h) = (SCREEN_WIDTH as f32 / 2., 400.0); // let (w, h) = (SCREEN_WIDTH as f32 / 2., 400.0);
set_camera(&Camera2D { // set_camera(&Camera2D {
zoom: vec2(2.2 / w, 2.2 / h), // zoom: vec2(2.2 / w, 2.2 / h),
target: Vec2 { x: w / 2.2, y: 0.0 }, // target: Vec2 { x: w / 2.2, y: 0.0 },
viewport: Some((0, 0, w as i32, h as i32)), // viewport: Some((0, 0, w as i32, h as i32)),
..Default::default() // ..Default::default()
}); // });
set_default_camera(); // set_default_camera();
match interpret::interpret( match interpret::interpret(
&mut state.state, &mut state.state,