From ae9c28afdd2d05830c569ff811b70669fa9b87cb Mon Sep 17 00:00:00 2001 From: zxq5 Date: Thu, 26 Jun 2025 23:47:51 +0100 Subject: [PATCH] deleted files for doc --- Cargo.lock | 4262 ----------------- Cargo.toml | 17 - README.md | 1 - assembler/Cargo.toml | 18 - assembler/brainf.bf | 29 - assembler/brainf.dsb | Bin 3000 -> 0 bytes assembler/src/assembler/assembler.rs | 264 - assembler/src/assembler/codegen.rs | 348 -- assembler/src/assembler/expand.rs | 368 -- assembler/src/assembler/lexer.rs | 173 - assembler/src/assembler/macros.rs | 138 - assembler/src/assembler/mod.rs | 266 - assembler/src/assembler/model.rs | 438 -- assembler/src/assembler/parser.rs | 368 -- assembler/src/assembler/resolver.rs | 156 - assembler/src/image_builder/mod.rs | 0 assembler/src/lib.rs | 28 - assembler/src/main.rs | 64 - assembler/src/tooling/brainf.rs | 280 -- assembler/src/tooling/mod.rs | 2 - assembler/src/tooling/project.rs | 93 - assembler/src/util/logging.rs | 108 - assembler/src/util/mod.rs | 13 - common/Cargo.toml | 7 - common/src/instructions.rs | 517 -- common/src/instructions/args.rs | 208 - common/src/instructions/encode.rs | 72 - common/src/instructions/encode/tests.rs | 98 - common/src/instructions/errors.rs | 56 - common/src/instructions/tests.rs | 215 - common/src/lib.rs | 22 - dsa_editor/Cargo.lock | 3985 --------------- dsa_editor/Cargo.toml | 23 - dsa_editor/src/highlighting.rs | 253 - dsa_editor/src/lib.rs | 296 -- dsa_editor/src/syntax/dsa.rs | 29 - dsa_editor/src/syntax/mod.rs | 204 - dsa_editor/src/themes/mod.rs | 147 - dsa_editor/src/themes/theme.rs | 22 - emulator/Cargo.toml | 42 - emulator/src/emulator/config.rs | 38 - emulator/src/emulator/misc/mod.rs | 1 - emulator/src/emulator/misc/rpc.rs | 221 - emulator/src/emulator/mod.rs | 5 - emulator/src/emulator/system/emulator.rs | 245 - emulator/src/emulator/system/memory.rs | 170 - emulator/src/emulator/system/mod.rs | 4 - emulator/src/emulator/system/model.rs | 327 -- emulator/src/emulator/system/processor/mod.rs | 507 -- .../src/emulator/system/processor/tests.rs | 695 --- emulator/src/emulator/ui/control_unit.rs | 197 - emulator/src/emulator/ui/display.rs | 92 - emulator/src/emulator/ui/editor.rs | 545 --- emulator/src/emulator/ui/history.rs | 84 - emulator/src/emulator/ui/interface.rs | 128 - emulator/src/emulator/ui/loader.rs | 294 -- emulator/src/emulator/ui/memory_inspector.rs | 162 - emulator/src/emulator/ui/menu.rs | 30 - emulator/src/emulator/ui/mod.rs | 9 - emulator/src/emulator/ui/stack_inspector.rs | 79 - emulator/src/lib.rs | 132 - emulator/src/main.rs | 39 - resources/dsa/bf.dsa | 224 - resources/dsa/lib/collections/stack.dsa | 0 resources/dsa/lib/error/handlers.dsa | 34 - resources/dsa/lib/io/print.dsa | 244 - resources/dsa/lib/maths/core.dsa | 60 - resources/dsa/lib/maths/fib.dsa | 31 - resources/dsa/main.dsa | 80 - resources/dsa/testprint.dsa | 80 - resources/dsb/bf.dsb | Bin 4 -> 0 bytes resources/dsb/test.dsb | Bin 4 -> 0 bytes resources/emulator/AndroidManifest.xml | 35 - resources/emulator/AppIcon.png | Bin 2449 -> 0 bytes resources/emulator/build_android.ps1 | 74 - resources/emulator/build_android.sh | 46 - src/main.rs | 53 - 77 files changed, 18595 deletions(-) delete mode 100644 Cargo.lock delete mode 100644 Cargo.toml delete mode 100644 README.md delete mode 100644 assembler/Cargo.toml delete mode 100644 assembler/brainf.bf delete mode 100644 assembler/brainf.dsb delete mode 100644 assembler/src/assembler/assembler.rs delete mode 100644 assembler/src/assembler/codegen.rs delete mode 100644 assembler/src/assembler/expand.rs delete mode 100644 assembler/src/assembler/lexer.rs delete mode 100644 assembler/src/assembler/macros.rs delete mode 100644 assembler/src/assembler/mod.rs delete mode 100644 assembler/src/assembler/model.rs delete mode 100644 assembler/src/assembler/parser.rs delete mode 100644 assembler/src/assembler/resolver.rs delete mode 100644 assembler/src/image_builder/mod.rs delete mode 100644 assembler/src/lib.rs delete mode 100644 assembler/src/main.rs delete mode 100644 assembler/src/tooling/brainf.rs delete mode 100644 assembler/src/tooling/mod.rs delete mode 100644 assembler/src/tooling/project.rs delete mode 100644 assembler/src/util/logging.rs delete mode 100644 assembler/src/util/mod.rs delete mode 100644 common/Cargo.toml delete mode 100644 common/src/instructions.rs delete mode 100644 common/src/instructions/args.rs delete mode 100644 common/src/instructions/encode.rs delete mode 100644 common/src/instructions/encode/tests.rs delete mode 100644 common/src/instructions/errors.rs delete mode 100644 common/src/instructions/tests.rs delete mode 100644 common/src/lib.rs delete mode 100644 dsa_editor/Cargo.lock delete mode 100644 dsa_editor/Cargo.toml delete mode 100644 dsa_editor/src/highlighting.rs delete mode 100644 dsa_editor/src/lib.rs delete mode 100644 dsa_editor/src/syntax/dsa.rs delete mode 100644 dsa_editor/src/syntax/mod.rs delete mode 100644 dsa_editor/src/themes/mod.rs delete mode 100644 dsa_editor/src/themes/theme.rs delete mode 100644 emulator/Cargo.toml delete mode 100644 emulator/src/emulator/config.rs delete mode 100644 emulator/src/emulator/misc/mod.rs delete mode 100644 emulator/src/emulator/misc/rpc.rs delete mode 100644 emulator/src/emulator/mod.rs delete mode 100644 emulator/src/emulator/system/emulator.rs delete mode 100644 emulator/src/emulator/system/memory.rs delete mode 100644 emulator/src/emulator/system/mod.rs delete mode 100644 emulator/src/emulator/system/model.rs delete mode 100644 emulator/src/emulator/system/processor/mod.rs delete mode 100644 emulator/src/emulator/system/processor/tests.rs delete mode 100644 emulator/src/emulator/ui/control_unit.rs delete mode 100644 emulator/src/emulator/ui/display.rs delete mode 100644 emulator/src/emulator/ui/editor.rs delete mode 100644 emulator/src/emulator/ui/history.rs delete mode 100644 emulator/src/emulator/ui/interface.rs delete mode 100644 emulator/src/emulator/ui/loader.rs delete mode 100644 emulator/src/emulator/ui/memory_inspector.rs delete mode 100644 emulator/src/emulator/ui/menu.rs delete mode 100644 emulator/src/emulator/ui/mod.rs delete mode 100644 emulator/src/emulator/ui/stack_inspector.rs delete mode 100644 emulator/src/lib.rs delete mode 100644 emulator/src/main.rs delete mode 100644 resources/dsa/bf.dsa delete mode 100644 resources/dsa/lib/collections/stack.dsa delete mode 100644 resources/dsa/lib/error/handlers.dsa delete mode 100644 resources/dsa/lib/io/print.dsa delete mode 100644 resources/dsa/lib/maths/core.dsa delete mode 100644 resources/dsa/lib/maths/fib.dsa delete mode 100644 resources/dsa/main.dsa delete mode 100644 resources/dsa/testprint.dsa delete mode 100644 resources/dsb/bf.dsb delete mode 100644 resources/dsb/test.dsb delete mode 100644 resources/emulator/AndroidManifest.xml delete mode 100644 resources/emulator/AppIcon.png delete mode 100644 resources/emulator/build_android.ps1 delete mode 100644 resources/emulator/build_android.sh delete mode 100644 src/main.rs diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index a84889a..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,4262 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "ab_glyph" -version = "0.2.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3672c180e71eeaaac3a541fbbc5f5ad4def8b747c595ad30d674e43049f7b0" -dependencies = [ - "ab_glyph_rasterizer", - "owned_ttf_parser", -] - -[[package]] -name = "ab_glyph_rasterizer" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" - -[[package]] -name = "accesskit" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3d3b8f9bae46a948369bc4a03e815d4ed6d616bd00de4051133a5019dc31c5a" - -[[package]] -name = "accesskit_atspi_common" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c5dd55e6e94949498698daf4d48fb5659e824d7abec0d394089656ceaf99d4f" -dependencies = [ - "accesskit", - "accesskit_consumer", - "atspi-common", - "serde", - "thiserror 1.0.69", - "zvariant", -] - -[[package]] -name = "accesskit_consumer" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f47983a1084940ba9a39c077a8c63e55c619388be5476ac04c804cfbd1e63459" -dependencies = [ - "accesskit", - "hashbrown", - "immutable-chunkmap", -] - -[[package]] -name = "accesskit_macos" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7329821f3bd1101e03a7d2e03bd339e3ac0dc64c70b4c9f9ae1949e3ba8dece1" -dependencies = [ - "accesskit", - "accesskit_consumer", - "hashbrown", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "accesskit_unix" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcee751cc20d88678c33edaf9c07e8b693cd02819fe89053776f5313492273f5" -dependencies = [ - "accesskit", - "accesskit_atspi_common", - "async-channel", - "async-executor", - "async-task", - "atspi", - "futures-lite", - "futures-util", - "serde", - "zbus", -] - -[[package]] -name = "accesskit_windows" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24fcd5d23d70670992b823e735e859374d694a3d12bfd8dd32bd3bd8bedb5d81" -dependencies = [ - "accesskit", - "accesskit_consumer", - "hashbrown", - "paste", - "static_assertions", - "windows", - "windows-core", -] - -[[package]] -name = "accesskit_winit" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6a48dad5530b6deb9fc7a52cc6c3bf72cdd9eb8157ac9d32d69f2427a5e879" -dependencies = [ - "accesskit", - "accesskit_macos", - "accesskit_unix", - "accesskit_windows", - "raw-window-handle", - "winit", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - -[[package]] -name = "ahash" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" -dependencies = [ - "cfg-if", - "getrandom 0.3.3", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "android-activity" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" -dependencies = [ - "android-properties", - "bitflags 2.9.1", - "cc", - "cesu8", - "jni", - "jni-sys", - "libc", - "log", - "ndk", - "ndk-context", - "ndk-sys 0.6.0+11769913", - "num_enum", - "thiserror 1.0.69", -] - -[[package]] -name = "android-properties" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "arboard" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1df21f715862ede32a0c525ce2ca4d52626bb0007f8c18b87a384503ac33e70" -dependencies = [ - "clipboard-win", - "image", - "log", - "objc2 0.6.1", - "objc2-app-kit 0.3.1", - "objc2-core-foundation", - "objc2-core-graphics", - "objc2-foundation 0.3.1", - "parking_lot", - "percent-encoding", - "windows-sys 0.59.0", - "x11rb", -] - -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" - -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - -[[package]] -name = "as-raw-xcb-connection" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" - -[[package]] -name = "ash" -version = "0.38.0+1.3.281" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" -dependencies = [ - "libloading", -] - -[[package]] -name = "assembler" -version = "0.2.0" -dependencies = [ - "common", - "num_cpus", - "threadpool", -] - -[[package]] -name = "async-broadcast" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" -dependencies = [ - "event-listener", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-channel" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-executor" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb812ffb58524bdd10860d7d974e2f01cc0950c2438a74ee5ec2e2280c6c4ffa" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "pin-project-lite", - "slab", -] - -[[package]] -name = "async-fs" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" -dependencies = [ - "async-lock", - "blocking", - "futures-lite", -] - -[[package]] -name = "async-io" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1237c0ae75a0f3765f58910ff9cdd0a12eeb39ab2f4c7de23262f337f0aacbb3" -dependencies = [ - "async-lock", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix 1.0.7", - "slab", - "tracing", - "windows-sys 0.59.0", -] - -[[package]] -name = "async-lock" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" -dependencies = [ - "event-listener", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-process" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde3f4e40e6021d7acffc90095cbd6dc54cb593903d1de5832f435eb274b85dc" -dependencies = [ - "async-channel", - "async-io", - "async-lock", - "async-signal", - "async-task", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "rustix 1.0.7", - "tracing", -] - -[[package]] -name = "async-recursion" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "async-signal" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7605a4e50d4b06df3898d5a70bf5fde51ed9059b0434b73105193bc27acce0d" -dependencies = [ - "async-io", - "async-lock", - "atomic-waker", - "cfg-if", - "futures-core", - "futures-io", - "rustix 1.0.7", - "signal-hook-registry", - "slab", - "windows-sys 0.59.0", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - -[[package]] -name = "async-trait" -version = "0.1.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "atspi" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be534b16650e35237bb1ed189ba2aab86ce65e88cc84c66f4935ba38575cecbf" -dependencies = [ - "atspi-common", - "atspi-connection", - "atspi-proxies", -] - -[[package]] -name = "atspi-common" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1909ed2dc01d0a17505d89311d192518507e8a056a48148e3598fef5e7bb6ba7" -dependencies = [ - "enumflags2", - "serde", - "static_assertions", - "zbus", - "zbus-lockstep", - "zbus-lockstep-macros", - "zbus_names", - "zvariant", -] - -[[package]] -name = "atspi-connection" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "430c5960624a4baaa511c9c0fcc2218e3b58f5dbcc47e6190cafee344b873333" -dependencies = [ - "atspi-common", - "atspi-proxies", - "futures-lite", - "zbus", -] - -[[package]] -name = "atspi-proxies" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e6c5de3e524cf967569722446bcd458d5032348554d9a17d7d72b041ab7496" -dependencies = [ - "atspi-common", - "serde", - "zbus", - "zvariant", -] - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "bit-set" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" -dependencies = [ - "serde", -] - -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block2" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" -dependencies = [ - "objc2 0.5.2", -] - -[[package]] -name = "blocking" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" -dependencies = [ - "async-channel", - "async-task", - "futures-io", - "futures-lite", - "piper", -] - -[[package]] -name = "bumpalo" -version = "3.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" - -[[package]] -name = "bytemuck" -version = "1.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" -dependencies = [ - "bytemuck_derive", -] - -[[package]] -name = "bytemuck_derive" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "byteorder-lite" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" - -[[package]] -name = "bytes" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" - -[[package]] -name = "calloop" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" -dependencies = [ - "bitflags 2.9.1", - "log", - "polling", - "rustix 0.38.44", - "slab", - "thiserror 1.0.69", -] - -[[package]] -name = "calloop-wayland-source" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" -dependencies = [ - "calloop", - "rustix 0.38.44", - "wayland-backend", - "wayland-client", -] - -[[package]] -name = "cc" -version = "1.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" -dependencies = [ - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - -[[package]] -name = "cfg-if" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "cgl" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" -dependencies = [ - "libc", -] - -[[package]] -name = "clipboard-win" -version = "5.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892" -dependencies = [ - "error-code", -] - -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - -[[package]] -name = "colorful" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb474a9c3219a8254ead020421ecf1b90427f29b55f6aae9a2471fa62c126ef" - -[[package]] -name = "combine" -version = "4.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" -dependencies = [ - "bytes", - "memchr", -] - -[[package]] -name = "common" -version = "0.2.0" - -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "core-graphics" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "core-graphics-types", - "foreign-types", - "libc", -] - -[[package]] -name = "core-graphics-types" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "libc", -] - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "cursor-icon" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "dirs" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.60.2", -] - -[[package]] -name = "discord-presence" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91d7c2fc01ffdc327e2b66d65dd59b8bd3f31a17e88811ce0540412fa0b84c1" -dependencies = [ - "byteorder", - "bytes", - "cfg-if", - "crossbeam-channel", - "log", - "num-derive", - "num-traits", - "parking_lot", - "paste", - "quork", - "serde", - "serde_json", - "thiserror 2.0.12", - "uuid", -] - -[[package]] -name = "dispatch" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" - -[[package]] -name = "dispatch2" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" -dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", -] - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dlib" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" -dependencies = [ - "libloading", -] - -[[package]] -name = "document-features" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" -dependencies = [ - "litrs", -] - -[[package]] -name = "downcast-rs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" - -[[package]] -name = "dpi" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" - -[[package]] -name = "dsa_editor" -version = "0.1.0" -dependencies = [ - "colorful", - "eframe", - "egui", - "serde", -] - -[[package]] -name = "dyn-clone" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005" - -[[package]] -name = "ecolor" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc4feb366740ded31a004a0e4452fbf84e80ef432ecf8314c485210229672fd1" -dependencies = [ - "bytemuck", - "emath", -] - -[[package]] -name = "eframe" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0dfe0859f3fb1bc6424c57d41e10e9093fe938f426b691e42272c2f336d915c" -dependencies = [ - "ahash", - "bytemuck", - "document-features", - "egui", - "egui-wgpu", - "egui-winit", - "egui_glow", - "glow", - "glutin", - "glutin-winit", - "image", - "js-sys", - "log", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", - "parking_lot", - "percent-encoding", - "profiling", - "raw-window-handle", - "static_assertions", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "web-time", - "winapi", - "windows-sys 0.59.0", - "winit", -] - -[[package]] -name = "egui" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd34cec49ab55d85ebf70139cb1ccd29c977ef6b6ba4fe85489d6877ee9ef3" -dependencies = [ - "accesskit", - "ahash", - "bitflags 2.9.1", - "emath", - "epaint", - "log", - "nohash-hasher", - "profiling", -] - -[[package]] -name = "egui-wgpu" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d319dfef570f699b6e9114e235e862a2ddcf75f0d1a061de9e1328d92146d820" -dependencies = [ - "ahash", - "bytemuck", - "document-features", - "egui", - "epaint", - "log", - "profiling", - "thiserror 1.0.69", - "type-map", - "web-time", - "wgpu", - "winit", -] - -[[package]] -name = "egui-winit" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d9dfbb78fe4eb9c3a39ad528b90ee5915c252e77bbab9d4ebc576541ab67e13" -dependencies = [ - "accesskit_winit", - "ahash", - "arboard", - "bytemuck", - "egui", - "log", - "profiling", - "raw-window-handle", - "smithay-clipboard", - "web-time", - "webbrowser", - "winit", -] - -[[package]] -name = "egui_file" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e7289fecaa1af3f4944a7ac6e1c187d0700e32716c2a4c76d6bad7ffd255d72" -dependencies = [ - "dyn-clone", - "egui", -] - -[[package]] -name = "egui_glow" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "910906e3f042ea6d2378ec12a6fd07698e14ddae68aed2d819ffe944a73aab9e" -dependencies = [ - "ahash", - "bytemuck", - "egui", - "glow", - "log", - "memoffset", - "profiling", - "wasm-bindgen", - "web-sys", - "winit", -] - -[[package]] -name = "emath" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e4cadcff7a5353ba72b7fea76bf2122b5ebdbc68e8155aa56dfdea90083fe1b" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "emulator" -version = "0.1.0" -dependencies = [ - "assembler", - "common", - "dirs", - "discord-presence", - "dsa_editor", - "eframe", - "egui", - "egui_file", - "serde", - "toml", - "winit", -] - -[[package]] -name = "endi" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" - -[[package]] -name = "enumflags2" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" -dependencies = [ - "enumflags2_derive", - "serde", -] - -[[package]] -name = "enumflags2_derive" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "epaint" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fcc0f5a7c613afd2dee5e4b30c3e6acafb8ad6f0edb06068811f708a67c562" -dependencies = [ - "ab_glyph", - "ahash", - "bytemuck", - "ecolor", - "emath", - "epaint_default_fonts", - "log", - "nohash-hasher", - "parking_lot", - "profiling", -] - -[[package]] -name = "epaint_default_fonts" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7e7a64c02cf7a5b51e745a9e45f60660a286f151c238b9d397b3e923f5082f" - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" -dependencies = [ - "libc", - "windows-sys 0.60.2", -] - -[[package]] -name = "error-code" -version = "3.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" - -[[package]] -name = "event-listener" -version = "5.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" -dependencies = [ - "event-listener", - "pin-project-lite", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "fdeflate" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" -dependencies = [ - "simd-adler32", -] - -[[package]] -name = "flate2" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "foreign-types" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" -dependencies = [ - "foreign-types-macros", - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "foreign-types-shared" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-lite" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - -[[package]] -name = "futures-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "gethostname" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" -dependencies = [ - "libc", - "windows-targets 0.48.5", -] - -[[package]] -name = "getrandom" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.1+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasi 0.14.2+wasi-0.2.4", -] - -[[package]] -name = "gl_generator" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" -dependencies = [ - "khronos_api", - "log", - "xml-rs", -] - -[[package]] -name = "glow" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" -dependencies = [ - "js-sys", - "slotmap", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "glutin" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12124de845cacfebedff80e877bb37b5b75c34c5a4c89e47e1cdd67fb6041325" -dependencies = [ - "bitflags 2.9.1", - "cfg_aliases", - "cgl", - "dispatch2", - "glutin_egl_sys", - "glutin_glx_sys", - "glutin_wgl_sys", - "libloading", - "objc2 0.6.1", - "objc2-app-kit 0.3.1", - "objc2-core-foundation", - "objc2-foundation 0.3.1", - "once_cell", - "raw-window-handle", - "wayland-sys", - "windows-sys 0.52.0", - "x11-dl", -] - -[[package]] -name = "glutin-winit" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" -dependencies = [ - "cfg_aliases", - "glutin", - "raw-window-handle", - "winit", -] - -[[package]] -name = "glutin_egl_sys" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4680ba6195f424febdc3ba46e7a42a0e58743f2edb115297b86d7f8ecc02d2" -dependencies = [ - "gl_generator", - "windows-sys 0.52.0", -] - -[[package]] -name = "glutin_glx_sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7bb2938045a88b612499fbcba375a77198e01306f52272e692f8c1f3751185" -dependencies = [ - "gl_generator", - "x11-dl", -] - -[[package]] -name = "glutin_wgl_sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" -dependencies = [ - "gl_generator", -] - -[[package]] -name = "gpu-alloc" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" -dependencies = [ - "bitflags 2.9.1", - "gpu-alloc-types", -] - -[[package]] -name = "gpu-alloc-types" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" -dependencies = [ - "bitflags 2.9.1", -] - -[[package]] -name = "gpu-descriptor" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" -dependencies = [ - "bitflags 2.9.1", - "gpu-descriptor-types", - "hashbrown", -] - -[[package]] -name = "gpu-descriptor-types" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" -dependencies = [ - "bitflags 2.9.1", -] - -[[package]] -name = "hashbrown" -version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" -dependencies = [ - "foldhash", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hexf-parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" - -[[package]] -name = "icu_collections" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" - -[[package]] -name = "icu_properties" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "potential_utf", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" - -[[package]] -name = "icu_provider" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" -dependencies = [ - "displaydoc", - "icu_locale_core", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "idna" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "image" -version = "0.25.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" -dependencies = [ - "bytemuck", - "byteorder-lite", - "num-traits", - "png", - "tiff", -] - -[[package]] -name = "immutable-chunkmap" -version = "2.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f97096f508d54f8f8ab8957862eee2ccd628847b6217af1a335e1c44dee578" -dependencies = [ - "arrayvec", -] - -[[package]] -name = "indexmap" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "itoa" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" - -[[package]] -name = "jni" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" -dependencies = [ - "cesu8", - "cfg-if", - "combine", - "jni-sys", - "log", - "thiserror 1.0.69", - "walkdir", - "windows-sys 0.45.0", -] - -[[package]] -name = "jni-sys" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" - -[[package]] -name = "jobserver" -version = "0.1.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" -dependencies = [ - "getrandom 0.3.3", - "libc", -] - -[[package]] -name = "jpeg-decoder" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07" - -[[package]] -name = "js-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "khronos-egl" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" -dependencies = [ - "libc", - "libloading", - "pkg-config", -] - -[[package]] -name = "khronos_api" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" - -[[package]] -name = "libc" -version = "0.2.174" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" - -[[package]] -name = "libloading" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" -dependencies = [ - "cfg-if", - "windows-targets 0.53.2", -] - -[[package]] -name = "libredox" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" -dependencies = [ - "bitflags 2.9.1", - "libc", - "redox_syscall 0.5.13", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[package]] -name = "linux-raw-sys" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" - -[[package]] -name = "litemap" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" - -[[package]] -name = "litrs" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" - -[[package]] -name = "lock_api" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" - -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - -[[package]] -name = "memchr" -version = "2.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" - -[[package]] -name = "memmap2" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" -dependencies = [ - "libc", -] - -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "metal" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f569fb946490b5743ad69813cb19629130ce9374034abe31614a36402d18f99e" -dependencies = [ - "bitflags 2.9.1", - "block", - "core-graphics-types", - "foreign-types", - "log", - "objc", - "paste", -] - -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", - "simd-adler32", -] - -[[package]] -name = "naga" -version = "24.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e380993072e52eef724eddfcde0ed013b0c023c3f0417336ed041aa9f076994e" -dependencies = [ - "arrayvec", - "bit-set", - "bitflags 2.9.1", - "cfg_aliases", - "codespan-reporting", - "hexf-parse", - "indexmap", - "log", - "rustc-hash 1.1.0", - "spirv", - "strum", - "termcolor", - "thiserror 2.0.12", - "unicode-xid", -] - -[[package]] -name = "ndk" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" -dependencies = [ - "bitflags 2.9.1", - "jni-sys", - "log", - "ndk-sys 0.6.0+11769913", - "num_enum", - "raw-window-handle", - "thiserror 1.0.69", -] - -[[package]] -name = "ndk-context" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" - -[[package]] -name = "ndk-sys" -version = "0.5.0+25.2.9519653" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" -dependencies = [ - "jni-sys", -] - -[[package]] -name = "ndk-sys" -version = "0.6.0+11769913" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" -dependencies = [ - "jni-sys", -] - -[[package]] -name = "nix" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" -dependencies = [ - "bitflags 2.9.1", - "cfg-if", - "cfg_aliases", - "libc", - "memoffset", -] - -[[package]] -name = "nohash-hasher" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" - -[[package]] -name = "num-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "num_enum" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" -dependencies = [ - "num_enum_derive", - "rustversion", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - -[[package]] -name = "objc-sys" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" - -[[package]] -name = "objc2" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" -dependencies = [ - "objc-sys", - "objc2-encode", -] - -[[package]] -name = "objc2" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88c6597e14493ab2e44ce58f2fdecf095a51f12ca57bec060a11c57332520551" -dependencies = [ - "objc2-encode", -] - -[[package]] -name = "objc2-app-kit" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" -dependencies = [ - "bitflags 2.9.1", - "block2", - "libc", - "objc2 0.5.2", - "objc2-core-data", - "objc2-core-image", - "objc2-foundation 0.2.2", - "objc2-quartz-core", -] - -[[package]] -name = "objc2-app-kit" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" -dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", - "objc2-core-foundation", - "objc2-core-graphics", - "objc2-foundation 0.3.1", -] - -[[package]] -name = "objc2-cloud-kit" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" -dependencies = [ - "bitflags 2.9.1", - "block2", - "objc2 0.5.2", - "objc2-core-location", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-contacts" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" -dependencies = [ - "block2", - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-core-data" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" -dependencies = [ - "bitflags 2.9.1", - "block2", - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-core-foundation" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" -dependencies = [ - "bitflags 2.9.1", - "dispatch2", - "objc2 0.6.1", -] - -[[package]] -name = "objc2-core-graphics" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" -dependencies = [ - "bitflags 2.9.1", - "dispatch2", - "objc2 0.6.1", - "objc2-core-foundation", - "objc2-io-surface", -] - -[[package]] -name = "objc2-core-image" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" -dependencies = [ - "block2", - "objc2 0.5.2", - "objc2-foundation 0.2.2", - "objc2-metal", -] - -[[package]] -name = "objc2-core-location" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" -dependencies = [ - "block2", - "objc2 0.5.2", - "objc2-contacts", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-encode" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" - -[[package]] -name = "objc2-foundation" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" -dependencies = [ - "bitflags 2.9.1", - "block2", - "dispatch", - "libc", - "objc2 0.5.2", -] - -[[package]] -name = "objc2-foundation" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" -dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-io-surface" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c" -dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-link-presentation" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" -dependencies = [ - "block2", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-metal" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" -dependencies = [ - "bitflags 2.9.1", - "block2", - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-quartz-core" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" -dependencies = [ - "bitflags 2.9.1", - "block2", - "objc2 0.5.2", - "objc2-foundation 0.2.2", - "objc2-metal", -] - -[[package]] -name = "objc2-symbols" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" -dependencies = [ - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-ui-kit" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" -dependencies = [ - "bitflags 2.9.1", - "block2", - "objc2 0.5.2", - "objc2-cloud-kit", - "objc2-core-data", - "objc2-core-image", - "objc2-core-location", - "objc2-foundation 0.2.2", - "objc2-link-presentation", - "objc2-quartz-core", - "objc2-symbols", - "objc2-uniform-type-identifiers", - "objc2-user-notifications", -] - -[[package]] -name = "objc2-uniform-type-identifiers" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" -dependencies = [ - "block2", - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-user-notifications" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" -dependencies = [ - "bitflags 2.9.1", - "block2", - "objc2 0.5.2", - "objc2-core-location", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "orbclient" -version = "0.3.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba0b26cec2e24f08ed8bb31519a9333140a6599b867dac464bb150bdb796fd43" -dependencies = [ - "libredox", -] - -[[package]] -name = "ordered-float" -version = "4.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" -dependencies = [ - "num-traits", -] - -[[package]] -name = "ordered-stream" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" -dependencies = [ - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "owned_ttf_parser" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4" -dependencies = [ - "ttf-parser", -] - -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "parking_lot" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.5.13", - "smallvec", - "windows-targets 0.52.6", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pin-project" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "piper" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - -[[package]] -name = "png" -version = "0.17.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" -dependencies = [ - "bitflags 1.3.2", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", -] - -[[package]] -name = "polling" -version = "3.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b53a684391ad002dd6a596ceb6c74fd004fdce75f4be2e3f615068abbea5fd50" -dependencies = [ - "cfg-if", - "concurrent-queue", - "hermit-abi", - "pin-project-lite", - "rustix 1.0.7", - "tracing", - "windows-sys 0.59.0", -] - -[[package]] -name = "potential_utf" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" -dependencies = [ - "zerovec", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro-crate" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" -dependencies = [ - "toml_edit", -] - -[[package]] -name = "proc-macro-error-attr2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] -name = "proc-macro-error2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" -dependencies = [ - "proc-macro-error-attr2", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "proc-macro2" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "profiling" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" - -[[package]] -name = "quick-xml" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "quick-xml" -version = "0.37.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" -dependencies = [ - "memchr", -] - -[[package]] -name = "quork" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bd9640e0addc098a3481fd53bdc23970e5dd0edf6b349403aa680fb576c8f83" -dependencies = [ - "cfg-if", - "nix", - "quork-proc", - "thiserror 2.0.12", - "windows-sys 0.59.0", -] - -[[package]] -name = "quork-proc" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "860d36740d9412e39fff90f57010e9870b15c2b48e5325295a6f5a824a480439" -dependencies = [ - "proc-macro-crate", - "proc-macro-error2", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "quote" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", -] - -[[package]] -name = "raw-window-handle" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" - -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" -dependencies = [ - "bitflags 2.9.1", -] - -[[package]] -name = "redox_users" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" -dependencies = [ - "getrandom 0.2.16", - "libredox", - "thiserror 2.0.12", -] - -[[package]] -name = "renderdoc-sys" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags 2.9.1", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustix" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" -dependencies = [ - "bitflags 2.9.1", - "errno", - "libc", - "linux-raw-sys 0.9.4", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustversion" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" - -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "sctk-adwaita" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" -dependencies = [ - "ab_glyph", - "log", - "memmap2", - "smithay-client-toolkit", - "tiny-skia", -] - -[[package]] -name = "serde" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.140" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" -dependencies = [ - "libc", -] - -[[package]] -name = "simd-adler32" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - -[[package]] -name = "slab" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" - -[[package]] -name = "slotmap" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" -dependencies = [ - "version_check", -] - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "smithay-client-toolkit" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" -dependencies = [ - "bitflags 2.9.1", - "calloop", - "calloop-wayland-source", - "cursor-icon", - "libc", - "log", - "memmap2", - "rustix 0.38.44", - "thiserror 1.0.69", - "wayland-backend", - "wayland-client", - "wayland-csd-frame", - "wayland-cursor", - "wayland-protocols", - "wayland-protocols-wlr", - "wayland-scanner", - "xkeysym", -] - -[[package]] -name = "smithay-clipboard" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc8216eec463674a0e90f29e0ae41a4db573ec5b56b1c6c1c71615d249b6d846" -dependencies = [ - "libc", - "smithay-client-toolkit", - "wayland-backend", -] - -[[package]] -name = "smol_str" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" -dependencies = [ - "serde", -] - -[[package]] -name = "spirv" -version = "0.3.0+sdk-1.3.268.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" -dependencies = [ - "bitflags 2.9.1", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "strict-num" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" - -[[package]] -name = "strum" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn", -] - -[[package]] -name = "syn" -version = "2.0.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tempfile" -version = "3.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" -dependencies = [ - "fastrand", - "getrandom 0.3.3", - "once_cell", - "rustix 1.0.7", - "windows-sys 0.59.0", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - -[[package]] -name = "thiserror" -version = "2.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" -dependencies = [ - "thiserror-impl 2.0.12", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "threadpool" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" -dependencies = [ - "num_cpus", -] - -[[package]] -name = "tiff" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" -dependencies = [ - "flate2", - "jpeg-decoder", - "weezl", -] - -[[package]] -name = "tiny-skia" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" -dependencies = [ - "arrayref", - "arrayvec", - "bytemuck", - "cfg-if", - "log", - "tiny-skia-path", -] - -[[package]] -name = "tiny-skia-path" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" -dependencies = [ - "arrayref", - "bytemuck", - "strict-num", -] - -[[package]] -name = "tinystr" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", - "winnow", -] - -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - -[[package]] -name = "tracing" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" -dependencies = [ - "once_cell", -] - -[[package]] -name = "ttf-parser" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" - -[[package]] -name = "type-map" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90" -dependencies = [ - "rustc-hash 2.1.1", -] - -[[package]] -name = "typenum" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" - -[[package]] -name = "uds_windows" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" -dependencies = [ - "memoffset", - "tempfile", - "winapi", -] - -[[package]] -name = "unicode-ident" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - -[[package]] -name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - -[[package]] -name = "url" -version = "2.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "uuid" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" -dependencies = [ - "getrandom 0.3.3", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" -dependencies = [ - "wit-bindgen-rt", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" -dependencies = [ - "cfg-if", - "js-sys", - "once_cell", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "wayland-backend" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe770181423e5fc79d3e2a7f4410b7799d5aab1de4372853de3c6aa13ca24121" -dependencies = [ - "cc", - "downcast-rs", - "rustix 0.38.44", - "scoped-tls", - "smallvec", - "wayland-sys", -] - -[[package]] -name = "wayland-client" -version = "0.31.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978fa7c67b0847dbd6a9f350ca2569174974cd4082737054dbb7fbb79d7d9a61" -dependencies = [ - "bitflags 2.9.1", - "rustix 0.38.44", - "wayland-backend", - "wayland-scanner", -] - -[[package]] -name = "wayland-csd-frame" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" -dependencies = [ - "bitflags 2.9.1", - "cursor-icon", - "wayland-backend", -] - -[[package]] -name = "wayland-cursor" -version = "0.31.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a65317158dec28d00416cb16705934070aef4f8393353d41126c54264ae0f182" -dependencies = [ - "rustix 0.38.44", - "wayland-client", - "xcursor", -] - -[[package]] -name = "wayland-protocols" -version = "0.32.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "779075454e1e9a521794fed15886323ea0feda3f8b0fc1390f5398141310422a" -dependencies = [ - "bitflags 2.9.1", - "wayland-backend", - "wayland-client", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols-plasma" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fd38cdad69b56ace413c6bcc1fbf5acc5e2ef4af9d5f8f1f9570c0c83eae175" -dependencies = [ - "bitflags 2.9.1", - "wayland-backend", - "wayland-client", - "wayland-protocols", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols-wlr" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cb6cdc73399c0e06504c437fe3cf886f25568dd5454473d565085b36d6a8bbf" -dependencies = [ - "bitflags 2.9.1", - "wayland-backend", - "wayland-client", - "wayland-protocols", - "wayland-scanner", -] - -[[package]] -name = "wayland-scanner" -version = "0.31.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "896fdafd5d28145fce7958917d69f2fd44469b1d4e861cb5961bcbeebc6d1484" -dependencies = [ - "proc-macro2", - "quick-xml 0.37.5", - "quote", -] - -[[package]] -name = "wayland-sys" -version = "0.31.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbcebb399c77d5aa9fa5db874806ee7b4eba4e73650948e8f93963f128896615" -dependencies = [ - "dlib", - "log", - "once_cell", - "pkg-config", -] - -[[package]] -name = "web-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webbrowser" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf4f3c0ba838e82b4e5ccc4157003fb8c324ee24c058470ffb82820becbde98" -dependencies = [ - "core-foundation 0.10.1", - "jni", - "log", - "ndk-context", - "objc2 0.6.1", - "objc2-foundation 0.3.1", - "url", - "web-sys", -] - -[[package]] -name = "weezl" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3" - -[[package]] -name = "wgpu" -version = "24.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b0b3436f0729f6cdf2e6e9201f3d39dc95813fad61d826c1ed07918b4539353" -dependencies = [ - "arrayvec", - "bitflags 2.9.1", - "cfg_aliases", - "document-features", - "js-sys", - "log", - "parking_lot", - "profiling", - "raw-window-handle", - "smallvec", - "static_assertions", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "wgpu-core", - "wgpu-hal", - "wgpu-types", -] - -[[package]] -name = "wgpu-core" -version = "24.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f0aa306497a238d169b9dc70659105b4a096859a34894544ca81719242e1499" -dependencies = [ - "arrayvec", - "bit-vec", - "bitflags 2.9.1", - "cfg_aliases", - "document-features", - "indexmap", - "log", - "naga", - "once_cell", - "parking_lot", - "profiling", - "raw-window-handle", - "rustc-hash 1.1.0", - "smallvec", - "thiserror 2.0.12", - "wgpu-hal", - "wgpu-types", -] - -[[package]] -name = "wgpu-hal" -version = "24.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f112f464674ca69f3533248508ee30cb84c67cf06c25ff6800685f5e0294e259" -dependencies = [ - "android_system_properties", - "arrayvec", - "ash", - "bitflags 2.9.1", - "bytemuck", - "cfg_aliases", - "core-graphics-types", - "glow", - "glutin_wgl_sys", - "gpu-alloc", - "gpu-descriptor", - "js-sys", - "khronos-egl", - "libc", - "libloading", - "log", - "metal", - "naga", - "ndk-sys 0.5.0+25.2.9519653", - "objc", - "once_cell", - "ordered-float", - "parking_lot", - "profiling", - "raw-window-handle", - "renderdoc-sys", - "rustc-hash 1.1.0", - "smallvec", - "thiserror 2.0.12", - "wasm-bindgen", - "web-sys", - "wgpu-types", - "windows", -] - -[[package]] -name = "wgpu-types" -version = "24.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50ac044c0e76c03a0378e7786ac505d010a873665e2d51383dcff8dd227dc69c" -dependencies = [ - "bitflags 2.9.1", - "js-sys", - "log", - "web-sys", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" -dependencies = [ - "windows-core", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-result", - "windows-strings", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-implement" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-interface" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-result" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-strings" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" -dependencies = [ - "windows-result", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.2", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" -dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - -[[package]] -name = "winit" -version = "0.30.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4409c10174df8779dc29a4788cac85ed84024ccbc1743b776b21a520ee1aaf4" -dependencies = [ - "ahash", - "android-activity", - "atomic-waker", - "bitflags 2.9.1", - "block2", - "bytemuck", - "calloop", - "cfg_aliases", - "concurrent-queue", - "core-foundation 0.9.4", - "core-graphics", - "cursor-icon", - "dpi", - "js-sys", - "libc", - "memmap2", - "ndk", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", - "objc2-ui-kit", - "orbclient", - "percent-encoding", - "pin-project", - "raw-window-handle", - "redox_syscall 0.4.1", - "rustix 0.38.44", - "sctk-adwaita", - "smithay-client-toolkit", - "smol_str", - "tracing", - "unicode-segmentation", - "wasm-bindgen", - "wasm-bindgen-futures", - "wayland-backend", - "wayland-client", - "wayland-protocols", - "wayland-protocols-plasma", - "web-sys", - "web-time", - "windows-sys 0.52.0", - "x11-dl", - "x11rb", - "xkbcommon-dl", -] - -[[package]] -name = "winnow" -version = "0.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" -dependencies = [ - "memchr", -] - -[[package]] -name = "wit-bindgen-rt" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.1", -] - -[[package]] -name = "writeable" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" - -[[package]] -name = "x11-dl" -version = "2.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" -dependencies = [ - "libc", - "once_cell", - "pkg-config", -] - -[[package]] -name = "x11rb" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" -dependencies = [ - "as-raw-xcb-connection", - "gethostname", - "libc", - "libloading", - "once_cell", - "rustix 0.38.44", - "x11rb-protocol", -] - -[[package]] -name = "x11rb-protocol" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" - -[[package]] -name = "xcursor" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "635887f4315a33cb714eb059bdbd7c1c92bfa71bc5b9d5115460502f788c2ab5" - -[[package]] -name = "xdg-home" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "xkbcommon-dl" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" -dependencies = [ - "bitflags 2.9.1", - "dlib", - "log", - "once_cell", - "xkeysym", -] - -[[package]] -name = "xkeysym" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" - -[[package]] -name = "xml-rs" -version = "0.8.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62ce76d9b56901b19a74f19431b0d8b3bc7ca4ad685a746dfd78ca8f4fc6bda" - -[[package]] -name = "yoke" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zbus" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725" -dependencies = [ - "async-broadcast", - "async-executor", - "async-fs", - "async-io", - "async-lock", - "async-process", - "async-recursion", - "async-task", - "async-trait", - "blocking", - "enumflags2", - "event-listener", - "futures-core", - "futures-sink", - "futures-util", - "hex", - "nix", - "ordered-stream", - "rand", - "serde", - "serde_repr", - "sha1", - "static_assertions", - "tracing", - "uds_windows", - "windows-sys 0.52.0", - "xdg-home", - "zbus_macros", - "zbus_names", - "zvariant", -] - -[[package]] -name = "zbus-lockstep" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca2c5dceb099bddaade154055c926bb8ae507a18756ba1d8963fd7b51d8ed1d" -dependencies = [ - "zbus_xml", - "zvariant", -] - -[[package]] -name = "zbus-lockstep-macros" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "709ab20fc57cb22af85be7b360239563209258430bccf38d8b979c5a2ae3ecce" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "zbus-lockstep", - "zbus_xml", - "zvariant", -] - -[[package]] -name = "zbus_macros" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", - "zvariant_utils", -] - -[[package]] -name = "zbus_names" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" -dependencies = [ - "serde", - "static_assertions", - "zvariant", -] - -[[package]] -name = "zbus_xml" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3f374552b954f6abb4bd6ce979e6c9b38fb9d0cd7cc68a7d796e70c9f3a233" -dependencies = [ - "quick-xml 0.30.0", - "serde", - "static_assertions", - "zbus_names", - "zvariant", -] - -[[package]] -name = "zerocopy" -version = "0.8.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerotrie" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zvariant" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe" -dependencies = [ - "endi", - "enumflags2", - "serde", - "static_assertions", - "zvariant_derive", -] - -[[package]] -name = "zvariant_derive" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", - "zvariant_utils", -] - -[[package]] -name = "zvariant_utils" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index d5039da..0000000 --- a/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -cargo-features = ["codegen-backend"] - -[workspace] -members = ["emulator", "common", "assembler", "dsa_editor"] -resolver = "3" - -[workspace.package] -version = "0.2.0" -edition = "2024" -authors = ["zxq5", "nullndvoid"] - -[profile.dev] -codegen-backend = "cranelift" -panic = "abort" # Cranelift does not support stack unwinds. -lto = false -debug = true -incremental = false # sccache does not support caching incremental crates. diff --git a/README.md b/README.md deleted file mode 100644 index 98498f8..0000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -We failing DSA with this one \ No newline at end of file diff --git a/assembler/Cargo.toml b/assembler/Cargo.toml deleted file mode 100644 index 676d37d..0000000 --- a/assembler/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "assembler" -version.workspace = true -edition.workspace = true -authors.workspace = true - -[[bin]] -name = "assembler_runner" -path = "src/main.rs" - -[lib] -name = "assembler" -path = "src/lib.rs" - -[dependencies] -common = { path = "../common" } -num_cpus = "1.17.0" -threadpool = "1.8.1" diff --git a/assembler/brainf.bf b/assembler/brainf.bf deleted file mode 100644 index 4adf535..0000000 --- a/assembler/brainf.bf +++ /dev/null @@ -1,29 +0,0 @@ -++++++++++++++++++++++++++++++++++++++++++++ ->++++++++++++++++++++++++++++++++ ->++++++++++++++++ -> ->+ -<< -[ ->> -> ->++++++++++ -<< -[->+>-[>+>>]>[+[-<+>]>+>>]<<<<<<] ->[<+>-] ->[-] ->> ->++++++++++ -< -[->-[>+>>]>[+[-<+>]>+>>]<<<<<] ->[-] ->>[++++++++++++++++++++++++++++++++++++++++++++++++.[-]] -<[++++++++++++++++++++++++++++++++++++++++++++++++.[-]] -<<<++++++++++++++++++++++++++++++++++++++++++++++++.[-] -<<<<<<<.>. ->>[>>+<<-] ->[>+<<+>-] ->[<+>-] -<<<- -] -<<++... diff --git a/assembler/brainf.dsb b/assembler/brainf.dsb deleted file mode 100644 index 885a8c58464e52c7204808f3ecd083063309f49a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3000 zcmdT`y-or_5dMJW_>sm&ERaZNPzj)cgo0Qb3$^ePD<6T*#s{!OgC<(}06qYPg@uK0 za26I8mX;m z#(#S9N#JT1YGogP&U=oaFw(|a8sezLjRv63(4)V*-i&M~$3$WQrZy)3z~UN*kL{ID_YxB)y~Ift>O z9+TRJ#|dMyR;HJC_H!+pA8T6oB5jWC$51Kqi@2^GCwr7O)e7>+o;B}ii)%_e=1}w0 z6!TX@<{!1@ADv+SYKr-*U(a99Ts7=D80{WdI~^Cjx8tOyI>+(%Nsw91bIffCD!&N- zcl`pWcnghe1-LFjnLc0owQ-(lZFG8Lo%pQioH)oo&wU5sHeQ>UfB*9tt9vnjPiSqN z?=#QZ$TKVLAYA4-X1q>`O#dEA`1hmKU{>}hE>wf>>7a2kNAK;V-;4B1o90C8K{M~| zlZ1b!WS+r3, - modules: Vec, - tasks: Vec, - logger: Logger, -} - -impl Program { - #[must_use] - pub fn new() -> Self { - Self { - registry: HashSet::new(), - modules: Vec::new(), - tasks: Vec::new(), - main_path: PathBuf::new(), - logger: Logger::new(), - } - } - - pub fn add_task(&mut self, task: Task) { - self.tasks.push(task); - } -} - -impl Default for Program { - fn default() -> Self { - Self::new() - } -} - -pub struct ProgramRef { - program: Arc>, -} - -impl ProgramRef { - #[must_use] - pub fn new(program: Program) -> Self { - Self { - program: Arc::new(Mutex::new(program)), - } - } - - pub fn register(&self, path: &Path) { - self.program - .lock() - .expect("Failed to acquire program lock") - .registry - .insert(quick_hash(path)); - } - - #[must_use] - pub fn is_registered(&self, path: &Path) -> bool { - self.program - .lock() - .expect("Failed to acquire program lock") - .registry - .contains(&quick_hash(path)) - } - - // pub fn get_tasks(&self) -> Vec<&Task> { - // self.program.lock().unwrap().tasks.iter().collect() - // } - - pub fn add_task(&self, task: Task) { - self.program - .lock() - .expect("Failed to acquire program lock") - .add_task(task); - } - - pub fn add_module(&self, module: Module) { - self.program - .lock() - .expect("Failed to acquire program lock") - .modules - .push(module); - } - - pub fn log(&self, message: &str) { - self.program - .lock() - .expect("Failed to acquire program lock") - .logger - .log(message); - } -} - -impl Clone for ProgramRef { - fn clone(&self) -> Self { - Self { - program: self.program.clone(), - } - } -} - -pub struct Module { - pub path: PathBuf, - pub hash: u64, - pub nodes: Vec, - program: ProgramRef, -} - -impl Module { - #[must_use] - pub const fn new( - path: PathBuf, - hash: u64, - nodes: Vec, - program: ProgramRef, - ) -> Self { - Self { - path, - hash, - nodes, - program, - } - } - - pub fn build(path: PathBuf, program: ProgramRef) -> Result { - // Spawn a thread that creates the main function and executes the lexer and parser. - let handle = thread::spawn(move || { - let mut module = - Self::new(path.clone(), quick_hash(&path), Vec::new(), program.clone()); - - match module.lex() { - Ok(tokens) => { - module.parse(tokens); - module.expand(); - module.prepare_dependencies(); - module - } - Err(why) => { - eprintln!( - "Error building program at path `{}`: {why}", - path.display() - ); - - // TODO: Find a way to make this work without panicking. - unreachable!() - } - } - }); - - Ok(Task { module: handle }) - } - - fn lex(&self) -> Result, AssembleError> { - if let Ok(path) = self.path.canonicalize() { - self.program.log(&format!( - "{:20} {:20} [{}]", - "Building", - self.get_filename(), - path.display() - )); - } - - let src = fs::read_to_string(&self.path) - .map_err(|_| AssembleError::InvalidFile(self.path.clone()))?; - - let file_hash = quick_hash(&self.path); - - self.program - .log(&format!("{:20} {:20}", "Tokenising", self.get_filename())); - - lexer::lexer(src, file_hash) - } - - fn parse(&mut self, tokens: Vec) -> Result<(), AssembleError> { - self.program - .log(&format!("{:20} {:20}", "Parsing", self.get_filename())); - - let parsed = Parser::parse_nodes(tokens)?; - self.nodes = parsed; - - Ok(()) - } - - fn expand(&mut self) -> Result<(), AssembleError> { - self.program - .log(&format!("{:20} {:20}", "Expanding", self.get_filename())); - - let expanded = expand_pseudo_ops(self.nodes.clone(), self.hash)?; - self.nodes = expanded; - - Ok(()) - } - - fn prepare_dependencies(&self) -> Result<(), AssembleError> { - let nodes = resolve_dependencies( - self.nodes.clone(), - self.path.parent().expect("File should have a parent path!"), - )?; - - let dependencies = Parser::get_dependencies(&nodes, &self.path)?; - - for dep in dependencies { - if self.program.is_registered(&dep) { - // we have already built this module! - continue; - } - - self.program.register(&dep); - - // create new module - // add the task to the program - - match Self::build(dep, self.program.clone()) { - Ok(task) => self.program.add_task(task), - Err(why) => { - eprintln!("Error building program: {why}"); - } - } - } - - Ok(()) - } - - /// Gets the filename from a [`PathBuf`]. - fn get_filename(&self) -> &str { - self.path - .file_name() - .and_then(|f| f.to_str()) - .unwrap_or_default() - } - - /// Gets the parent filepath from a [`PathBuf`]. - fn get_parent(&self) -> &str { - self.path - .parent() - .and_then(|f| f.to_str()) - .unwrap_or_default() - } -} - -pub struct Task { - module: JoinHandle, -} diff --git a/assembler/src/assembler/codegen.rs b/assembler/src/assembler/codegen.rs deleted file mode 100644 index 3e34281..0000000 --- a/assembler/src/assembler/codegen.rs +++ /dev/null @@ -1,348 +0,0 @@ -use common::{args, prelude::*}; - -use crate::assembler::model::{Node, Opcode}; -use crate::{assembler::AssembleError, expect_token}; - -fn log(message: &str) { - println!("\x1b[32mINFO:\x1b[0m {message}"); -} - -pub fn codegen(nodes: Vec) -> Result, AssembleError> { - let mut instructions = vec![]; - - for node in nodes { - instructions.push(build_instruction(&node)?); - } - - println!("------------------------"); - log("Compilation Success ✅"); - - Ok(instructions) -} - -fn build_instruction(node: &Node) -> Result { - let opcode = node.opcode(); - let args = node.args(); - - match opcode { - Opcode::Nop => Ok(Instruction::Nop), - Opcode::Mov | Opcode::Movs => build_mov_instruction(opcode, &args), - Opcode::Ldb - | Opcode::Ldw - | Opcode::Ldh - | Opcode::Ldbs - | Opcode::Ldhs - | Opcode::Stb - | Opcode::Stw - | Opcode::Sth => build_memory_instruction(opcode, &args), - Opcode::Lli | Opcode::Lui => build_load_immediate_instruction(opcode, &args), - Opcode::Jmp - | Opcode::Jeq - | Opcode::Jne - | Opcode::Jgt - | Opcode::Jge - | Opcode::Jlt - | Opcode::Jle => build_jump_instruction(opcode, &args), - Opcode::Cmp => build_compare_instruction(&args), - Opcode::Inc | Opcode::Dec => build_inc_dec_instruction(opcode, &args), - Opcode::Shl | Opcode::Shr => build_shift_instruction(opcode, &args), - Opcode::Add - | Opcode::Sub - | Opcode::And - | Opcode::Or - | Opcode::Xor - | Opcode::Nand - | Opcode::Nor - | Opcode::Xnor => build_arithmetic_instruction(opcode, &args), - Opcode::AddI | Opcode::SubI => { - build_arithmetic_immediate_instruction(opcode, &args) - } - Opcode::Not => build_not_instruction(&args), - Opcode::Int => build_interrupt_instruction(&args), - Opcode::Irt => Ok(Instruction::IntReturn), - Opcode::Hlt => Ok(Instruction::Halt), - Opcode::Data => build_data_instruction(&args), - Opcode::Segment => build_segment_instruction(&args), - // These pseudo-instructions should have been expanded! - Opcode::Db - | Opcode::Dh - | Opcode::Dw - | Opcode::Resb - | Opcode::Resh - | Opcode::Resw - | Opcode::Push - | Opcode::Pop - | Opcode::Lwi - | Opcode::Include - | Opcode::Call - | Opcode::Return - | Opcode::Pusha - | Opcode::Popa => Err(AssembleError::InvalidArg), - } -} - -fn build_mov_instruction( - opcode: Opcode, - args: &[crate::assembler::model::Token], -) -> Result { - let Some(src_token) = args.first() else { - return Err(AssembleError::MissingArgument(0)); - }; - let Some(dest_token) = args.get(1) else { - return Err(AssembleError::MissingArgument(1)); - }; - - let src = expect_token!(src_token, Register)?; - let dest = expect_token!(dest_token, Register)?; - - match opcode { - Opcode::Mov => Ok(Instruction::Mov(args!(R, sr1: src, dr: dest))), - Opcode::Movs => Ok(Instruction::MovSigned(args!(R, sr1: src, dr: dest))), - _ => unreachable!(), - } -} - -fn build_memory_instruction( - opcode: Opcode, - args: &[crate::assembler::model::Token], -) -> Result { - let Some(base_token) = args.first() else { - return Err(AssembleError::MissingArgument(0)); - }; - let Some(dest_token) = args.get(1) else { - return Err(AssembleError::MissingArgument(1)); - }; - let Some(offset_token) = args.get(2) else { - return Err(AssembleError::MissingArgument(2)); - }; - - let base = expect_token!(base_token, Register)?; - let dest = expect_token!(dest_token, Register)?; - let offset = expect_token!(offset_token, Immediate)?; - let instruction_args = args!(I, immediate: offset as u16, r1: base, r2: dest); - - match opcode { - Opcode::Ldb => Ok(Instruction::LoadByte(instruction_args)), - Opcode::Ldw => Ok(Instruction::LoadWord(instruction_args)), - Opcode::Ldh => Ok(Instruction::LoadHalfword(instruction_args)), - Opcode::Ldbs => Ok(Instruction::LoadByteSigned(instruction_args)), - Opcode::Ldhs => Ok(Instruction::LoadHalfwordSigned(instruction_args)), - Opcode::Stb => Ok(Instruction::StoreByte(instruction_args)), - Opcode::Stw => Ok(Instruction::StoreWord(instruction_args)), - Opcode::Sth => Ok(Instruction::StoreHalfword(instruction_args)), - _ => unreachable!(), - } -} - -fn build_load_immediate_instruction( - opcode: Opcode, - args: &[crate::assembler::model::Token], -) -> Result { - let Some(value_token) = args.first() else { - return Err(AssembleError::MissingArgument(0)); - }; - let Some(dest_token) = args.get(1) else { - return Err(AssembleError::MissingArgument(1)); - }; - - let value = expect_token!(value_token, Immediate)?; - let dest = expect_token!(dest_token, Register)?; - - match opcode { - Opcode::Lli => { - let instruction_args = args!(I, immediate: value as u16, r1: dest); - Ok(Instruction::LoadLowerImmediate(instruction_args)) - } - Opcode::Lui => { - let upper_value = value >> 16; - let instruction_args = args!(I, immediate: upper_value as u16, r1: dest); - Ok(Instruction::LoadUpperImmediate(instruction_args)) - } - _ => unreachable!(), - } -} - -fn build_jump_instruction( - opcode: Opcode, - args: &[crate::assembler::model::Token], -) -> Result { - let Some(address_token) = args.first() else { - return Err(AssembleError::MissingArgument(0)); - }; - let Some(offset_token) = args.get(1) else { - return Err(AssembleError::MissingArgument(1)); - }; - - let address = expect_token!(address_token, Immediate)?; - let offset = expect_token!(offset_token, Register)?; - let instruction_args = args!(I, immediate: address as u16, r1: offset); - - match opcode { - Opcode::Jmp => Ok(Instruction::Jump(instruction_args)), - Opcode::Jeq => Ok(Instruction::JumpEq(instruction_args)), - Opcode::Jne => Ok(Instruction::JumpNeq(instruction_args)), - Opcode::Jgt => Ok(Instruction::JumpGt(instruction_args)), - Opcode::Jge => Ok(Instruction::JumpGe(instruction_args)), - Opcode::Jlt => Ok(Instruction::JumpLt(instruction_args)), - Opcode::Jle => Ok(Instruction::JumpLe(instruction_args)), - _ => unreachable!(), - } -} - -fn build_compare_instruction( - args: &[crate::assembler::model::Token], -) -> Result { - let Some(left_token) = args.first() else { - return Err(AssembleError::MissingArgument(0)); - }; - let Some(right_token) = args.get(1) else { - return Err(AssembleError::MissingArgument(1)); - }; - - let left = expect_token!(left_token, Register)?; - let right = expect_token!(right_token, Register)?; - Ok(Instruction::Compare(args!(R, sr1: left, sr2: right))) -} - -fn build_inc_dec_instruction( - opcode: Opcode, - args: &[crate::assembler::model::Token], -) -> Result { - let Some(reg_token) = args.first() else { - return Err(AssembleError::MissingArgument(0)); - }; - - let reg = expect_token!(reg_token, Register)?; - match opcode { - Opcode::Inc => Ok(Instruction::Increment(args!(R, sr1: reg))), - Opcode::Dec => Ok(Instruction::Decrement(args!(R, sr1: reg))), - _ => unreachable!(), - } -} - -fn build_shift_instruction( - opcode: Opcode, - args: &[crate::assembler::model::Token], -) -> Result { - let Some(reg_token) = args.first() else { - return Err(AssembleError::MissingArgument(0)); - }; - let Some(amount_token) = args.get(1) else { - return Err(AssembleError::MissingArgument(1)); - }; - - let reg = expect_token!(reg_token, Register)?; - let amount = expect_token!(amount_token, Immediate)? as u8; - - match opcode { - Opcode::Shl => Ok(Instruction::ShiftLeft(args!(R, sr1: reg, shamt: amount))), - Opcode::Shr => Ok(Instruction::ShiftRight(args!(R, sr1: reg, shamt: amount))), - _ => unreachable!(), - } -} - -fn build_arithmetic_instruction( - opcode: Opcode, - args: &[crate::assembler::model::Token], -) -> Result { - let Some(left_token) = args.first() else { - return Err(AssembleError::MissingArgument(0)); - }; - let Some(right_token) = args.get(1) else { - return Err(AssembleError::MissingArgument(1)); - }; - let Some(dest_token) = args.get(2) else { - return Err(AssembleError::MissingArgument(2)); - }; - - let left = expect_token!(left_token, Register)?; - let right = expect_token!(right_token, Register)?; - let dest = expect_token!(dest_token, Register)?; - let instruction_args = args!(R, sr1: left, sr2: right, dr: dest); - - match opcode { - Opcode::Add => Ok(Instruction::Add(instruction_args)), - Opcode::Sub => Ok(Instruction::Sub(instruction_args)), - Opcode::And => Ok(Instruction::And(instruction_args)), - Opcode::Or => Ok(Instruction::Or(instruction_args)), - Opcode::Xor => Ok(Instruction::Xor(instruction_args)), - Opcode::Nand => Ok(Instruction::Nand(instruction_args)), - Opcode::Nor => Ok(Instruction::Nor(instruction_args)), - Opcode::Xnor => Ok(Instruction::Xnor(instruction_args)), - _ => unreachable!(), - } -} - -fn build_arithmetic_immediate_instruction( - opcode: Opcode, - args: &[crate::assembler::model::Token], -) -> Result { - let Some(reg_token) = args.first() else { - return Err(AssembleError::MissingArgument(0)); - }; - let Some(immediate_token) = args.get(1) else { - return Err(AssembleError::MissingArgument(1)); - }; - let Some(dest_token) = args.get(2) else { - return Err(AssembleError::MissingArgument(2)); - }; - - let reg = expect_token!(reg_token, Register)?; - let immediate = expect_token!(immediate_token, Immediate)? as u16; - let dest = expect_token!(dest_token, Register)?; - let instruction_args = args!(I, immediate: immediate, r1: reg, r2: dest); - - match opcode { - Opcode::AddI => Ok(Instruction::AddImmediate(instruction_args)), - Opcode::SubI => Ok(Instruction::SubImmediate(instruction_args)), - _ => unreachable!(), - } -} - -fn build_not_instruction( - args: &[crate::assembler::model::Token], -) -> Result { - let Some(reg_token) = args.first() else { - return Err(AssembleError::MissingArgument(0)); - }; - let Some(dest_token) = args.get(1) else { - return Err(AssembleError::MissingArgument(1)); - }; - - let reg = expect_token!(reg_token, Register)?; - let dest = expect_token!(dest_token, Register)?; - Ok(Instruction::Not(args!(R, sr1: reg, dr: dest))) -} - -fn build_interrupt_instruction( - args: &[crate::assembler::model::Token], -) -> Result { - let Some(code_token) = args.first() else { - return Err(AssembleError::MissingArgument(0)); - }; - - let code = expect_token!(code_token, Immediate)? as u8; - Ok(Instruction::Interrupt(Interrupt::Software(code))) -} - -fn build_data_instruction( - args: &[crate::assembler::model::Token], -) -> Result { - let Some(immediate_token) = args.first() else { - return Err(AssembleError::MissingArgument(0)); - }; - - let immediate = expect_token!(immediate_token, Immediate)?; - Ok(Instruction::Data(immediate)) -} - -fn build_segment_instruction( - args: &[crate::assembler::model::Token], -) -> Result { - let Some(immediate_token) = args.first() else { - return Err(AssembleError::MissingArgument(0)); - }; - - let immediate = expect_token!(immediate_token, Immediate)?; - Ok(Instruction::Segment(immediate)) -} diff --git a/assembler/src/assembler/expand.rs b/assembler/src/assembler/expand.rs deleted file mode 100644 index ed25bd3..0000000 --- a/assembler/src/assembler/expand.rs +++ /dev/null @@ -1,368 +0,0 @@ -use common::prelude::Register; - -use crate::assembler::model::{Node, Opcode, Token}; -use crate::{assembler::AssembleError, expect_token, expect_type, node}; - -pub fn expand_pseudo_ops( - mut nodes: Vec, - module: u64, -) -> Result, AssembleError> { - let mut result = Vec::::with_capacity(nodes.len()); - - for node in &mut nodes { - if try_expand(node.clone(), &mut result, module).is_err() { - result.push(node.clone()); - } - } - - Ok(result) -} - -fn try_expand( - node: Node, - result: &mut Vec, - _module: u64, -) -> Result<(), AssembleError> { - match node.opcode() { - Opcode::Push => expand_push(&node, result)?, - Opcode::Pop => expand_pop(&node, result)?, - Opcode::Pusha => expand_pusha(&node, result)?, - Opcode::Popa => expand_popa(&node, result)?, - Opcode::Call => expand_call(&node, result)?, - Opcode::Return => expand_return(&node, result), - Opcode::Ldb | Opcode::Ldbs | Opcode::Ldh | Opcode::Ldhs | Opcode::Ldw => { - expand_ldx(&node, result)?; - } - Opcode::Stb | Opcode::Sth | Opcode::Stw => expand_stx(&node, result)?, - - Opcode::Lwi => expand_lwi(&node, result)?, - Opcode::Resb | Opcode::Resh | Opcode::Resw => expand_resx(&node, result)?, - Opcode::Db | Opcode::Dh | Opcode::Dw => expand_dx(&node, result)?, - _ => result.push(node), - } - Ok(()) -} - -fn expand_push(current: &Node, nodes: &mut Vec) -> Result<(), AssembleError> { - let label = current.label(); - let Ok(arg0) = current.arg(0) else { - return Err(AssembleError::Generic); - }; - - let reg = expect_type!(arg0, Register)?; - let spr = Token::Register(Register::Spr); - - nodes.extend(vec![ - node!(label, Opcode::SubI, spr, 4, spr), - node!(None, Opcode::Stw, reg, spr, 0), - ]); - - Ok(()) -} - -fn expand_pusha(current: &Node, nodes: &mut Vec) -> Result<(), AssembleError> { - let label = current.label(); - let Ok(arg0) = current.arg(0) else { - return Err(AssembleError::Generic); - }; - - let count = expect_token!(arg0, Immediate)?; - let spr = Token::Register(Register::Spr); - let registers: Vec = Register::general(); - - nodes.push(node!( - label, - Opcode::SubI, - spr, - Token::Immediate(count * 4), - spr - )); - - nodes.extend((0..count).rev().map(|i| { - node!( - None, - Opcode::Stw, - Token::Register(registers[i as usize]), - spr, - Token::Immediate(i * 4) - ) - })); - - Ok(()) -} - -fn expand_popa(current: &Node, nodes: &mut Vec) -> Result<(), AssembleError> { - let label = current.label(); - - let Ok(arg0) = current.arg(0) else { - return Err(AssembleError::Generic); - }; - - let count = expect_token!(arg0, Immediate)?; - let spr = Token::Register(Register::Spr); - let registers: Vec = Register::general(); - - nodes.extend((0..count).rev().map(|i| { - node!( - { if i == 0 { label.clone() } else { None } }, - Opcode::Ldw, - spr, - Token::Register(registers[i as usize]), - Token::Immediate(i * 4) - ) - })); - - nodes.push(node!( - None, - Opcode::AddI, - spr, - Token::Immediate(count * 4), - spr - )); - - Ok(()) -} - -fn expand_call(current: &Node, nodes: &mut Vec) -> Result<(), AssembleError> { - let label = current.label(); - - let Ok(arg0) = current.arg(0) else { - return Err(AssembleError::Generic); - }; - - let addr = expect_type!(arg0, Symbol)?; - let spr = Token::Register(Register::Spr); - let pcx = Token::Register(Register::Pcx); - let zero = Token::Register(Register::Zero); - - nodes.extend(vec![ - node!(label, Opcode::SubI, spr, 4, spr), - node!(None, Opcode::Stw, pcx, spr, 0), - node!(None, Opcode::Jmp, addr, zero), - ]); - - Ok(()) -} - -fn expand_return(current: &Node, nodes: &mut Vec) { - let label = current.label(); - let spr = Token::Register(Register::Spr); - let ret = Token::Register(Register::Ret); - - nodes.extend(vec![ - node!(label, Opcode::Ldw, spr, ret, 0), - node!(None, Opcode::AddI, spr, 4, spr), - node!(None, Opcode::Jmp, 4, ret), - ]); -} - -fn expand_pop(current: &Node, nodes: &mut Vec) -> Result<(), AssembleError> { - let label = current.label(); - - let Ok(arg0) = current.arg(0) else { - return Err(AssembleError::Generic); - }; - - let reg = expect_type!(arg0, Register)?; - let spr = Token::Register(Register::Spr); - - nodes.extend(vec![ - node!(label, Opcode::Ldw, spr, reg, 0), - node!(None, Opcode::AddI, spr, 4, spr), - ]); - - Ok(()) -} - -fn expand_ldx(current: &Node, nodes: &mut Vec) -> Result<(), AssembleError> { - let opcode = current.opcode(); - let args: Vec = current.args().into_iter().take(3).collect(); - - let Some(name) = args.first() else { - return Err(AssembleError::MissingArgument(0)); - }; - - let Some(reg) = args.get(1) else { - return Err(AssembleError::MissingArgument(1)); - }; - - let Some(offset) = args.get(2) else { - return Err(AssembleError::MissingArgument(2)); - }; - - let name = expect_type!(name, Symbol)?; - let reg = expect_type!(reg, Register)?; - let offset = expect_type!(offset, Immediate)?; - - nodes.extend(vec![ - node!(current.label(), Opcode::Lli, name, reg), - node!(None, Opcode::Lui, name, reg), - node!(None, opcode, reg, reg, offset), - ]); - - Ok(()) -} - -fn expand_stx(current: &Node, nodes: &mut Vec) -> Result<(), AssembleError> { - let opcode = current.opcode(); - - let args: Vec = current.args().into_iter().take(3).collect(); - - let Some(base) = args.first() else { - return Err(AssembleError::MissingArgument(0)); - }; - - let Some(dest) = args.get(1) else { - return Err(AssembleError::MissingArgument(1)); - }; - - let Some(offset) = args.get(2) else { - return Err(AssembleError::MissingArgument(2)); - }; - - let base = expect_type!(base, Register)?; - let dest = expect_type!(dest, Symbol)?; - let offset = expect_type!(offset, Immediate)?; - let temp = Token::Register(Register::Acc); - - nodes.extend(vec![ - node!(current.label(), Opcode::Lli, dest, temp), - node!(None, Opcode::Lui, dest, temp), - node!(None, opcode, base, temp, offset), - ]); - - Ok(()) -} - -fn expand_lwi(current: &Node, nodes: &mut Vec) -> Result<(), AssembleError> { - let Ok(val) = current.arg(0) else { - return Err(AssembleError::MissingArgument(0)); - }; - - let Ok(reg) = current.arg(1) else { - return Err(AssembleError::MissingArgument(1)); - }; - - let val = expect_type!(val, Symbol, Immediate)?; - let reg = expect_type!(reg, Register)?; - - nodes.extend(vec![ - node!(current.label(), Opcode::Lli, val, reg), - node!(None, Opcode::Lui, val, reg), - ]); - - Ok(()) -} - -fn expand_resx(current: &Node, nodes: &mut Vec) -> Result<(), AssembleError> { - let Ok(region_label) = current.arg(0) else { - return Err(AssembleError::MissingArgument(0)); - }; - - let Ok(size) = current.arg(1) else { - return Err(AssembleError::MissingArgument(1)); - }; - - let region_label = expect_token!(region_label, Symbol)?; - let size = expect_token!(size, Immediate)?; - - let units_per = match current.opcode() { - Opcode::Resb => 4, - Opcode::Resh => 2, - Opcode::Resw => 1, - _ => unreachable!(), - }; - - let mut buffer = vec![]; - // push the inital node with the label - for _ in 0..size.div_ceil(units_per) { - // push the rest of the nodes - buffer.push(node!(None, Opcode::Data, 0)); - } - buffer[0].symbol = Some(region_label); - nodes.extend(buffer); - - Ok(()) -} - -fn expand_dx(current: &Node, nodes: &mut Vec) -> Result<(), AssembleError> { - let Ok(region_label) = current.arg(0) else { - return Err(AssembleError::MissingArgument(0)); - }; - - let region_label = expect_token!(region_label, Symbol)?; - let size = match current.opcode() { - Opcode::Db => 4, - Opcode::Dh => 2, - Opcode::Dw => 1, - _ => unreachable!(), - }; - - let mut buffer = vec![]; - - let mut args = current.args(); - let _label = args.remove(0); - - for word in process_dx_data(args, size)? { - buffer.push(node!(None, Opcode::Data, Token::Immediate(word))); - } - buffer[0].symbol = Some(region_label); - - nodes.extend(buffer); - Ok(()) -} - -fn process_dx_data(args: Vec, size: usize) -> Result, AssembleError> { - assert!(matches!(size, 1 | 2 | 4)); - - let mut buffer = Vec::::new(); - - // Process each token - for token in args { - match token { - Token::StringLit(mut s) => { - s.push('\0'); - // Split string into chars and write as bytes - for ch in s.chars() { - // Convert char to bytes (UTF-8 encoding) - let mut char_buf = [0u8; 4]; - let char_bytes = ch.encode_utf8(&mut char_buf); - buffer.extend_from_slice(char_bytes.as_bytes()); - } - } - Token::Immediate(value) => { - // Split u32 into bytes (little-endian) - buffer.extend_from_slice(&value.to_be_bytes()); - } - _ => { - return Err(AssembleError::Generic); - } - } - - // Pad buffer to alignment boundary with zeros - let remainder = buffer.len() % size; - if remainder != 0 { - let padding = size - remainder; - buffer.resize(buffer.len() + padding, 0); - } - } - - // Convert byte buffer to u32 chunks - // Pad final buffer to u32 boundary if needed - let remainder = buffer.len() % 4; - if remainder != 0 { - let padding = 4 - remainder; - buffer.resize(buffer.len() + padding, 0); - } - - // Convert bytes to u32s efficiently using chunks_exact - let result = buffer - .chunks_exact(4) - .map(|chunk| { - // Convert 4 bytes to u32 (little-endian) - u32::from_be_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]) - }) - .collect(); - - Ok(result) -} diff --git a/assembler/src/assembler/lexer.rs b/assembler/src/assembler/lexer.rs deleted file mode 100644 index 442d9b3..0000000 --- a/assembler/src/assembler/lexer.rs +++ /dev/null @@ -1,173 +0,0 @@ -use std::str::FromStr; - -use crate::assembler::AssembleError; -use crate::assembler::model::{Module, Opcode, Symbol, Token}; -use common::prelude::Register; - -pub fn lexer(mut program: String, module: u64) -> Result, AssembleError> { - let mut tokens = Vec::new(); - - let lines = program.lines(); - let mut literal = String::new(); - - for line in lines { - for (i, token) in line.split_whitespace().enumerate() { - if token.starts_with("//") { - break; - } - - if let Some(stripped) = token.strip_prefix('"') { - literal.push_str(stripped); - } - - if !literal.is_empty() { - if !token.starts_with('"') { - if i > 0 { - literal.push(' '); - } - literal.push_str(token); - } - - if token.ends_with('"') { - literal.pop(); // remove the closing quote - - tokens.push(Token::StringLit(literal)); - literal = String::new(); - } - - continue; - } - - let token = token.trim_end_matches(','); - if token.is_empty() { - continue; - } - - if let Some(token) = parse_register(token)? { - tokens.push(token); - } else if let Some(token) = parse_opcode(token)? { - tokens.push(token); - } else if let Some(token) = parse_hex(token)? { - tokens.push(token); - } else if let Some(token) = parse_octal(token)? { - tokens.push(token); - } else if let Some(token) = parse_binary(token)? { - tokens.push(token); - } else if let Some(token) = parse_decimal(token)? { - tokens.push(token); - } else if let Some(token) = parse_label(token, module)? { - tokens.push(token); - } else if let Some(token) = parse_symbol(token, module)? { - tokens.push(token); - } else { - return Err(AssembleError::Generic); - } - } - } - - println!("{:#?}", tokens); - - Ok(tokens) -} -pub fn parse_register(token: &str) -> Result, AssembleError> { - Ok(Register::try_from(token).map(Token::Register).ok()) -} - -pub fn parse_opcode(token: &str) -> Result, AssembleError> { - if Opcode::OPCODES.contains(&token) { - Ok(Some(Token::Opcode(Opcode::from_str(token).expect( - "Opcode::from_str failed for a valid opcode token", - )))) - } else { - Ok(None) - } -} - -pub fn parse_hex(token: &str) -> Result, AssembleError> { - if (token.len() < 3) | !token.starts_with("0x") { - return Ok(None); - } - - let Some(lit) = &token.get(2..) else { - return Err(AssembleError::InvalidArg); - }; - - u32::from_str_radix(lit, 16).map_or(Err(AssembleError::Generic), |value| { - Ok(Some(Token::Immediate(value))) - }) -} - -pub fn parse_octal(token: &str) -> Result, AssembleError> { - if (token.len() < 3) | !token.starts_with("0o") { - return Ok(None); - } - - let Some(lit) = &token.get(2..) else { - return Err(AssembleError::InvalidArg); - }; - - u32::from_str_radix(lit, 8).map_or(Err(AssembleError::Generic), |value| { - Ok(Some(Token::Immediate(value))) - }) -} - -pub fn parse_binary(token: &str) -> Result, AssembleError> { - if (token.len() < 3) | !token.starts_with("0b") { - return Ok(None); - } - - let Some(lit) = &token.get(2..) else { - return Err(AssembleError::InvalidArg); - }; - - u32::from_str_radix(lit, 2).map_or(Err(AssembleError::Generic), |value| { - Ok(Some(Token::Immediate(value))) - }) -} - -pub fn parse_decimal(token: &str) -> Result, AssembleError> { - let Ok(tok) = token.parse::() else { - return Ok(None); - }; - - Ok(Some(Token::Immediate(tok))) -} - -pub fn parse_label(token: &str, module: u64) -> Result, AssembleError> { - if token.ends_with(':') { - Ok(Some(Token::Symbol(Symbol { - name: token[0..token.len() - 1].to_string(), - module: Module::Resolved(module), - }))) - } else { - Ok(None) - } -} - -pub fn parse_symbol(token: &str, module: u64) -> Result, AssembleError> { - let Some(tokc) = token.chars().next() else { - return Err(AssembleError::Generic); // TODO: What is this error? - }; - - if tokc.is_numeric() { - return Ok(None); - } - - let mut split = token.splitn(2, "::"); - let Some(symbol1) = split.next() else { - return Err(AssembleError::InvalidArg); - }; - let symbol1 = symbol1.to_string(); - - if let Some(symbol2) = split.next() { - Ok(Some(Token::Symbol(Symbol { - name: symbol2.to_string(), - module: Module::Unresolved(symbol1), - }))) - } else { - Ok(Some(Token::Symbol(Symbol { - name: symbol1, - module: Module::Resolved(module), - }))) - } -} diff --git a/assembler/src/assembler/macros.rs b/assembler/src/assembler/macros.rs deleted file mode 100644 index 592ef32..0000000 --- a/assembler/src/assembler/macros.rs +++ /dev/null @@ -1,138 +0,0 @@ -//! Macros used throughout the assembler - -use crate::assembler::model::{Node, Opcode, Symbol, Token}; -/// Parse DSA assembly code with optional formatting -/// -/// # Examples -/// ``` -/// // With formatting: -/// let nodes = dsa!(hash, "mov r1, {}", 42)?; -/// -/// // Without formatting: -/// let nodes = dsa!(hash, "mov r1, 42")?; -/// ``` -#[macro_export] -macro_rules! dsa { - // Version with formatting arguments - ($hash:expr, $input:expr, $($args:expr),+) => {{ - let input = format!($input, $($args),+); - let tokens = $crate::lexer::lexer(input, $hash)?; - let parsed = $crate::parser::Parser::parse_nodes(tokens)?; - parsed - }}; - // Version without formatting - ($hash:expr, $input:expr) => {{ - let input = String::from($input); - let tokens = $crate::lexer::lexer(input, $hash)?; - let parsed = $crate::parser::Parser::parse_nodes(tokens)?; - parsed - }}; -} - -/// Creates a new Node with the given symbol, opcode, and tokens -#[macro_export] -macro_rules! node { - ($symbol: expr, $opcode: expr, args: $tokens: expr) => { - $crate::assembler::model::Node::new($symbol.clone(), $opcode.clone(), $tokens.clone()) - }; - - ($symbol: expr, $opcode: expr, $($tokens: expr),+) => { - $crate::assembler::model::Node::new( - $symbol.clone(), - $opcode.clone(), - vec![$(node!(@convert_token $tokens)),+] - ) - }; - - ($symbol: expr, $opcode: expr) => { - $crate::assembler::model::Node::new( - $symbol.clone(), - $opcode.clone(), - Vec::new() - ) - }; - - (@convert_token $token: literal) => { - $crate::assembler::model::Token::Immediate($token) - }; - - (@convert_token $token: expr) => { - $token.clone() - }; -} - -/// Extracts a specific token type from a token -#[macro_export] -macro_rules! expect_token { - ($token:expr, Symbol) => { - match $token { - $crate::assembler::model::Token::Symbol(value) => Ok(value.clone()), - other => Err($crate::assembler::AssembleError::UnexpectedToken( - other.clone(), - $crate::assembler::model::TokenType::Symbol, - )), - } - }; - ($token:expr, Register) => { - match $token { - $crate::assembler::model::Token::Register(value) => Ok(value.clone()), - other => Err($crate::assembler::AssembleError::UnexpectedToken( - other.clone(), - $crate::assembler::model::TokenType::Register, - )), - } - }; - ($token:expr, Immediate) => { - match $token { - $crate::assembler::model::Token::Immediate(value) => Ok(value.clone()), - other => Err($crate::assembler::AssembleError::UnexpectedToken( - other.clone(), - $crate::assembler::model::TokenType::Immediate, - )), - } - }; - ($token:expr, StringLit) => { - match $token { - $crate::assembler::model::Token::StringLit(value) => Ok(value.clone()), - other => Err($crate::assembler::AssembleError::UnexpectedToken( - other.clone(), - $crate::assembler::model::TokenType::StringLit, - )), - } - }; - ($token:expr, Opcode) => { - match $token { - $crate::assembler::model::Token::Opcode(value) => Ok(value.clone()), - other => Err($crate::assembler::AssembleError::UnexpectedToken( - other.clone(), - $crate::assembler::model::TokenType::Opcode, - )), - } - }; -} - -/// Checks if a token matches any of the specified types -#[macro_export] -macro_rules! expect_type { - ($token:expr, $($variant:ident),+) => {{ - let token = $token; - match &token { - $( - $crate::assembler::model::Token::$variant(_) => Ok(token.clone()), - )+ - other => { - let expected_type = expect_type!(@get_first_type $($variant),+); - Err($crate::assembler::AssembleError::UnexpectedToken( - other.clone().clone(), - expected_type, - )) - } - } - }}; - - (@get_first_type Symbol $(, $rest:ident)*) => { $crate::assembler::model::TokenType::Symbol }; - (@get_first_type Register $(, $rest:ident)*) => { $crate::assembler::model::TokenType::Register }; - (@get_first_type Immediate $(, $rest:ident)*) => { $crate::assembler::model::TokenType::Immediate }; - (@get_first_type StringLit $(, $rest:ident)*) => { $crate::assembler::model::TokenType::StringLit }; - (@get_first_type Opcode $(, $rest:ident)*) => { $crate::assembler::model::TokenType::Opcode }; -} diff --git a/assembler/src/assembler/mod.rs b/assembler/src/assembler/mod.rs deleted file mode 100644 index 26fd801..0000000 --- a/assembler/src/assembler/mod.rs +++ /dev/null @@ -1,266 +0,0 @@ -#![allow(dead_code, unused)] - -use std::{ - collections::HashSet, - fmt, fs, - hash::{DefaultHasher, Hash, Hasher}, - path::{Path, PathBuf}, - sync::{Arc, Mutex, mpsc}, - thread, -}; - -use common::prelude::Instruction; - -// TODO: Use an actual logging or tracing library for pretty (scoped) output. -fn log(message: &str) { - println!("\x1b[32mINFO:\x1b[0m {message}"); -} - -// Module declarations -#[macro_use] -pub mod macros; - -#[allow(clippy::module_inception)] -pub mod assembler; -pub mod codegen; -pub mod expand; -pub mod lexer; -pub mod model; -pub mod parser; -pub mod resolver; - -// Re-exports -pub use self::{ - codegen::codegen, - expand::expand_pseudo_ops, - lexer::lexer, - model::{Module, Node, Opcode, Symbol, Token, TokenType}, - parser::{Parser, Program}, - resolver::{create_sections, resolve_dependencies, resolve_symbols}, -}; - -use crate::util::logging::{Entry, Logger}; - -pub struct CompilerEngine { - result_tx: mpsc::Sender, AssembleError>>, - result_rx: Option, AssembleError>>>, - is_running: bool, -} - -impl CompilerEngine { - #[must_use] - pub fn new() -> Self { - let (tx, rx) = mpsc::channel(); - Self { - result_tx: tx, - result_rx: Some(rx), - is_running: false, - } - } - - /// Start the compilation process in a separate thread - pub fn start_compilation(&mut self, src: &Path) { - if self.is_running { - return; - } - - let src = src.to_path_buf(); - let tx = self.result_tx.clone(); - - thread::spawn(move || { - let result = assemble(&src); - tx.send(result) - .expect("Failed to send compilation result from worker thread"); - }); - - self.is_running = true; - } - - /// Check if compilation is complete and get the result - pub fn try_get_result(&mut self) -> Option, AssembleError>> { - if !self.is_running { - return None; - } - - match self - .result_rx - .as_ref() - .expect("result_rx should be Some while compilation is running") - .try_recv() - { - Ok(result) => { - self.is_running = false; - Some(result) - } - Err(mpsc::TryRecvError::Empty) => None, - Err(mpsc::TryRecvError::Disconnected) => { - self.is_running = false; - Some(Err(AssembleError::Generic)) - } - } - } - - /// Block until compilation is complete and return the result - pub fn wait_for_result(&mut self) -> Result, AssembleError> { - if !self.is_running { - return Err(AssembleError::Generic); - } - - if let Ok(result) = self - .result_rx - .take() - .expect("result_rx should be Some while waiting for compilation result") - .recv() - { - self.is_running = false; - result - } else { - self.is_running = false; - Err(AssembleError::Generic) - } - } -} - -fn assemble(src: &Path) -> Result, AssembleError> { - let mut modules = HashSet::new(); - let mut program = Program::new(); - - let hash = quick_hash(src); - - if modules.contains(&hash) { - return Ok(vec![]); - } - - prepare_dependency(src, &mut modules, &mut program)?; - - let mut nodes = program.nodes.clone(); - - create_sections(&mut nodes)?; - resolve_symbols(&mut nodes)?; - - let instructions = codegen(nodes)?; - Ok(instructions) -} - -impl Default for CompilerEngine { - fn default() -> Self { - Self::new() - } -} - -fn prepare_dependency( - path: &Path, - modules: &mut HashSet, - program: &mut Program, -) -> Result<(), AssembleError> { - let filename = path - .file_name() - .and_then(|n| n.to_str()) - .expect("Failed to get file name from path"); - - if let Ok(path) = path.canonicalize() { - log(&format!( - "{:20} {:20} [{}]", - "Building", - filename, - path.display() - )); - } - - let src = fs::read_to_string(path) - .map_err(|_| AssembleError::InvalidFile(path.to_path_buf()))?; - let file_hash = quick_hash(path); - - log(&format!("{:20} {:20}", "Tokenising", filename)); - let tokens = lexer::lexer(src, file_hash)?; - - log(&format!("{:20} {:20}", "Parsing", filename)); - let parsed = Parser::parse_nodes(tokens)?; - - log(&format!("{:20} {:20}", "Resolving Deps", filename)); - // Get the parent directory of the source file to use as the base directory - let base_dir = path - .parent() - .ok_or_else(|| AssembleError::InvalidFile(path.to_path_buf()))?; - let mut nodes = expand_pseudo_ops(parsed, file_hash)?; - nodes = resolve_dependencies(nodes, base_dir)?; - - let deps = Parser::get_dependencies(&nodes, path)?; - - log(&format!( - "{:20} {:20}", - "Expanding PseudoInstructions", filename - )); - - // add a section instruction - nodes.insert( - 0, - node!(None, Opcode::Segment, Token::Immediate(file_hash as u32)), - ); - - for n in &nodes { - println!("{n}"); - } - - program.add_module(nodes); - - for dep in deps { - log(&format!( - "{:20} {:20}", - "Including", - dep.file_name() - .and_then(|f| f.to_str()) - .expect("Dependency path has no file name or is not valid UTF-8") - )); - - let dep_hash = quick_hash(&dep); - if modules.insert(dep_hash) { - prepare_dependency(dep.as_path(), modules, program)?; - } - } - - Ok(()) -} - -#[derive(Debug, Clone)] -pub enum AssembleError { - Generic, - UnexpectedEof, - InvalidFile(PathBuf), - UnexpectedToken(Token, TokenType), - InvalidArg, - UndefinedSymbol(Symbol), - /// Contains the nth element missing from the instruction. - MissingArgument(u8), -} - -impl fmt::Display for AssembleError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Generic => write!(f, "Generic error"), - Self::UnexpectedToken(tok, expected) => { - write!(f, "Unexpected token {tok:?}, expected {expected:?}") - } - Self::UnexpectedEof => write!(f, "Unexpected end of file"), - Self::InvalidFile(path) => write!(f, "Invalid file `{}`", path.display()), - Self::InvalidArg => write!(f, "Invalid argument"), - Self::UndefinedSymbol(symbol) => { - write!(f, "Undefined symbol {symbol}") - } - Self::MissingArgument(n) => { - write!(f, "Missing argument #{n} from instruction arguments.") - } - } - } -} - -fn quick_hash(value: &Path) -> u64 { - let mut hasher = DefaultHasher::new(); - value - .canonicalize() - .expect("Failed to canonicalize path for quick_hash") - .to_str() - .hash(&mut hasher); - - hasher.finish() -} diff --git a/assembler/src/assembler/model.rs b/assembler/src/assembler/model.rs deleted file mode 100644 index 059884d..0000000 --- a/assembler/src/assembler/model.rs +++ /dev/null @@ -1,438 +0,0 @@ -use std::{fmt, str::FromStr}; - -use common::prelude::Register; - -use crate::assembler::AssembleError; - -#[derive(Debug, Clone)] -pub struct Node { - pub symbol: Option, - pub opcode: Opcode, - pub tokens: Vec, -} - -impl Node { - #[must_use] - pub const fn new(symbol: Option, opcode: Opcode, tokens: Vec) -> Self { - Self { - symbol, - opcode, - tokens, - } - } - - #[must_use] - pub fn label(&self) -> Option { - self.symbol.clone() - } - - #[must_use] - pub const fn opcode(&self) -> Opcode { - self.opcode - } - - #[must_use] - pub fn args(&self) -> Vec { - self.tokens.clone() - } - - pub fn arg(&self, index: usize) -> Result { - self.args() - .get(index) - .cloned() - .ok_or(AssembleError::InvalidArg) - } -} - -impl fmt::Display for Node { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let symbol = self - .label() - .as_ref() - .map_or_else(String::new, |symbol| format!("{symbol}:\n")); - - let args = self - .args() - .into_iter() - .map(|arg| arg.to_string()) - .collect::>() - .join(" "); - - write!( - f, - "\x1b[93m{} \t\x1b[94m{} \x1b[37m{} \x1b[0m", - symbol, - self.opcode(), - args, - ) - } -} - -impl fmt::Display for Symbol { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} [ID:{}]", self.name, self.module) - } -} - -impl fmt::Display for Module { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::Unresolved(name) => write!(f, "{name}"), - Self::Resolved(name) => write!(f, "{name}"), - } - } -} - -impl fmt::Display for Opcode { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::Nop => write!(f, "nop"), - Self::Mov => write!(f, "mov"), - Self::Movs => write!(f, "movs"), - Self::Ldb => write!(f, "ldb"), - Self::Ldbs => write!(f, "ldbs"), - Self::Ldh => write!(f, "ldh"), - Self::Ldhs => write!(f, "ldhs"), - Self::Ldw => write!(f, "ldw"), - Self::Stb => write!(f, "stb"), - Self::Sth => write!(f, "sth"), - Self::Stw => write!(f, "stw"), - Self::Lli => write!(f, "lli"), - Self::Lui => write!(f, "lui"), - Self::Jmp => write!(f, "jmp"), - Self::Jeq => write!(f, "jeq"), - Self::Jne => write!(f, "jne"), - Self::Jgt => write!(f, "jgt"), - Self::Jge => write!(f, "jge"), - Self::Jlt => write!(f, "jlt"), - Self::Jle => write!(f, "jle"), - Self::Cmp => write!(f, "cmp"), - Self::Inc => write!(f, "inc"), - Self::Dec => write!(f, "dec"), - Self::Shl => write!(f, "shl"), - Self::Shr => write!(f, "shr"), - Self::Add => write!(f, "add"), - Self::Sub => write!(f, "sub"), - Self::And => write!(f, "and"), - Self::Or => write!(f, "or"), - Self::Not => write!(f, "not"), - Self::Xor => write!(f, "xor"), - Self::Nand => write!(f, "nand"), - Self::Nor => write!(f, "nor"), - Self::Xnor => write!(f, "xnor"), - Self::Int => write!(f, "int"), - Self::Irt => write!(f, "irt"), - Self::Hlt => write!(f, "hlt"), - Self::AddI => write!(f, "addi"), - Self::SubI => write!(f, "subi"), - Self::Db => write!(f, "db"), - Self::Dh => write!(f, "dh"), - Self::Dw => write!(f, "dw"), - Self::Resb => write!(f, "resb"), - Self::Resh => write!(f, "resh"), - Self::Resw => write!(f, "resw"), - Self::Push => write!(f, "push"), - Self::Pop => write!(f, "pop"), - Self::Lwi => write!(f, "lwi"), - Self::Call => write!(f, "call"), - Self::Return => write!(f, "return"), - Self::Pusha => write!(f, "pusha"), - Self::Popa => write!(f, "popa"), - - // meta instructions - Self::Include => write!(f, "include"), - Self::Data => write!(f, "data"), - Self::Segment => write!(f, "[SEGMENT]"), - } - } -} - -#[derive(Debug, Clone, Eq)] -pub struct Symbol { - pub name: String, - pub module: Module, -} - -impl std::hash::Hash for Symbol { - fn hash(&self, state: &mut H) { - self.name.hash(state); - self.module.hash(state); - } -} - -impl PartialEq for Symbol { - fn eq(&self, other: &Self) -> bool { - self.name == other.name && self.module == other.module - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum Module { - Resolved(u64), - Unresolved(String), -} - -#[derive(Debug, Clone)] -pub enum Token { - Symbol(Symbol), - Register(Register), - Immediate(u32), - StringLit(String), - Opcode(Opcode), -} - -impl fmt::Display for Token { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Symbol(symbol) => write!(f, "{}", symbol), - Self::Register(register) => write!(f, "{}", register), - Self::Immediate(immediate) => write!(f, "{}", immediate), - Self::StringLit(string_lit) => write!(f, "{}", string_lit), - Self::Opcode(opcode) => write!(f, "{}", opcode), - } - } -} - -#[derive(Debug, PartialEq, Eq, Copy, Clone)] -pub enum TokenType { - Symbol, - Register, - Immediate, - StringLit, - Opcode, -} - -impl TokenType { - #[must_use] - pub const fn from_token(token: &Token) -> Self { - match token { - Token::Symbol(_) => Self::Symbol, - Token::Register(_) => Self::Register, - Token::Immediate(_) => Self::Immediate, - Token::StringLit(_) => Self::StringLit, - Token::Opcode(_) => Self::Opcode, - } - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Opcode { - // Real instructions (0x00-0x26) - Nop, - Mov, - Movs, - Ldb, - Ldbs, - Ldh, - Ldhs, - Ldw, - Stb, - Sth, - Stw, - Lli, - Lui, - Jmp, - Jeq, - Jne, - Jgt, - Jge, - Jlt, - Jle, - Cmp, - Inc, - Dec, - Shl, - Shr, - Add, - Sub, - And, - Or, - Not, - Xor, - Nand, - Nor, - Xnor, - Int, - Irt, - Hlt, - AddI, - SubI, - - // Pseudo-instructions - Db, - Dh, - Dw, - Resb, - Resh, - Resw, - Push, - Pop, - Pusha, - Popa, - Lwi, - Call, - Return, - - // meta instructions (these aren't present in the binary as instructions) - Include, - Data, - Segment, -} - -#[derive(Debug)] -pub enum OpcodeFromStrError { - InvalidRegister(&'static str), - InvalidOpcode(String), -} - -impl std::fmt::Display for OpcodeFromStrError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::InvalidRegister(reg) => write!(f, "register does not exist: {reg}"), - Self::InvalidOpcode(op) => write!(f, "instruction does not exist: {op}"), - } - } -} - -impl std::error::Error for OpcodeFromStrError {} - -impl FromStr for Opcode { - type Err = OpcodeFromStrError; - - fn from_str(s: &str) -> Result { - match s.to_lowercase().as_str() { - "nop" => Ok(Self::Nop), - "mov" => Ok(Self::Mov), - "movs" => Ok(Self::Movs), - "ldb" => Ok(Self::Ldb), - "ldbs" => Ok(Self::Ldbs), - "ldh" => Ok(Self::Ldh), - "ldhs" => Ok(Self::Ldhs), - "ldw" => Ok(Self::Ldw), - "stb" => Ok(Self::Stb), - "sth" => Ok(Self::Sth), - "stw" => Ok(Self::Stw), - "lli" => Ok(Self::Lli), - "lui" => Ok(Self::Lui), - "jmp" => Ok(Self::Jmp), - "jeq" => Ok(Self::Jeq), - "jne" => Ok(Self::Jne), - "jgt" => Ok(Self::Jgt), - "jge" => Ok(Self::Jge), - "jlt" => Ok(Self::Jlt), - "jle" => Ok(Self::Jle), - "cmp" => Ok(Self::Cmp), - "inc" => Ok(Self::Inc), - "dec" => Ok(Self::Dec), - "shl" => Ok(Self::Shl), - "shr" => Ok(Self::Shr), - "add" => Ok(Self::Add), - "sub" => Ok(Self::Sub), - "and" => Ok(Self::And), - "or" => Ok(Self::Or), - "not" => Ok(Self::Not), - "xor" => Ok(Self::Xor), - "nand" => Ok(Self::Nand), - "nor" => Ok(Self::Nor), - "xnor" => Ok(Self::Xnor), - "int" => Ok(Self::Int), - "irt" => Ok(Self::Irt), - "hlt" => Ok(Self::Hlt), - "addi" => Ok(Self::AddI), - "subi" => Ok(Self::SubI), - "db" => Ok(Self::Db), - "dh" => Ok(Self::Dh), - "dw" => Ok(Self::Dw), - "resb" => Ok(Self::Resb), - "resh" => Ok(Self::Resh), - "resw" => Ok(Self::Resw), - "push" => Ok(Self::Push), - "pop" => Ok(Self::Pop), - "lwi" => Ok(Self::Lwi), - "include" => Ok(Self::Include), - "call" => Ok(Self::Call), - "return" => Ok(Self::Return), - "pusha" => Ok(Self::Pusha), - "popa" => Ok(Self::Popa), - _ => Err(OpcodeFromStrError::InvalidOpcode(s.to_string())), - } - } -} - -impl Opcode { - pub const OPCODES: &[&str] = &[ - // Real instructions (0x00-0x26) - "nop", "mov", "movs", "ldb", "ldbs", "ldh", "ldhs", "ldw", "stb", "sth", "stw", - "lli", "lui", "jmp", "jeq", "jne", "jgt", "jge", "jlt", "jle", "cmp", "inc", - "dec", "shl", "shr", "add", "sub", "and", "or", "not", "xor", "nand", "nor", - "xnor", "int", "irt", "hlt", "addi", "subi", // Pseudo-instructions - "db", "dh", "dw", "resb", "resh", "resw", "push", "pop", "lwi", "call", "return", - "pusha", "popa", // meta instructions - "include", - ]; - - #[must_use] - pub const fn to_opcode_value(&self) -> Option { - match self { - Self::Nop => Some(0x00), - Self::Mov => Some(0x01), - Self::Movs => Some(0x02), - Self::Ldb => Some(0x03), - Self::Ldbs => Some(0x04), - Self::Ldh => Some(0x05), - Self::Ldhs => Some(0x06), - Self::Ldw => Some(0x07), - Self::Stb => Some(0x08), - Self::Sth => Some(0x09), - Self::Stw => Some(0x0A), - Self::Lli => Some(0x0B), - Self::Lui => Some(0x0C), - Self::Jmp => Some(0x0D), - Self::Jeq => Some(0x0E), - Self::Jne => Some(0x0F), - Self::Jgt => Some(0x10), - Self::Jge => Some(0x11), - Self::Jlt => Some(0x12), - Self::Jle => Some(0x13), - Self::Cmp => Some(0x14), - Self::Inc => Some(0x15), - Self::Dec => Some(0x16), - Self::Shl => Some(0x17), - Self::Shr => Some(0x18), - Self::Add => Some(0x19), - Self::Sub => Some(0x1A), - Self::And => Some(0x1B), - Self::Or => Some(0x1C), - Self::Not => Some(0x1D), - Self::Xor => Some(0x1E), - Self::Nand => Some(0x1F), - Self::Nor => Some(0x20), - Self::Xnor => Some(0x21), - Self::Int => Some(0x22), - Self::Irt => Some(0x23), - Self::Hlt => Some(0x24), - Self::AddI => Some(0x25), - Self::SubI => Some(0x26), - Self::Segment => Some(0x27), - - // Pseudo-instructions don't have opcode values - _ => None, - } - } - - #[must_use] - pub const fn is_pseudo_instruction(&self) -> bool { - matches!( - self, - Self::Db - | Self::Dh - | Self::Dw - | Self::Resb - | Self::Resh - | Self::Resw - | Self::Push - | Self::Pop - | Self::Lwi - ) - } -} diff --git a/assembler/src/assembler/parser.rs b/assembler/src/assembler/parser.rs deleted file mode 100644 index 7ac26b2..0000000 --- a/assembler/src/assembler/parser.rs +++ /dev/null @@ -1,368 +0,0 @@ -use std::path::{Path, PathBuf}; - -use crate::{assembler::AssembleError, expect_token, expect_type, node}; - -use crate::assembler::model::{Node, Opcode, Token}; -use common::prelude::*; - -pub struct Parser { - tokens: Vec, - nodes: Vec, -} - -#[derive(Debug)] -pub struct Program { - pub nodes: Vec, -} - -impl Program { - #[must_use] - pub const fn new() -> Self { - Self { nodes: vec![] } - } - - pub fn add_module(&mut self, module: Vec) { - self.nodes.extend(module); - } - - pub fn parser(&mut self) -> Parser { - Parser { - tokens: vec![], - nodes: self.nodes.clone(), - } - } -} - -impl Default for Program { - fn default() -> Self { - Self::new() - } -} - -impl Parser { - pub fn parse_nodes(tokens: Vec) -> Result, AssembleError> { - let mut self_ = Self { - tokens: tokens.into_iter().rev().collect(), - nodes: vec![], - }; - - while !self_.tokens.is_empty() { - let ins = self_.parse_instruction()?; - self_.nodes.push(ins); - } - - Ok(self_.nodes.clone()) - } - - pub fn get_dependencies( - nodes: &Vec, - source_path: &Path, - ) -> Result, AssembleError> { - let mut dependencies = Vec::new(); - // Get the parent directory of the source file to use as the base directory - let base_dir = source_path - .parent() - .ok_or_else(|| AssembleError::InvalidFile(source_path.to_path_buf()))?; - - for node in nodes { - if node.opcode() == Opcode::Include { - let path_str = expect_token!( - node.args().get(1).ok_or(AssembleError::Generic)?, - StringLit - )?; - let path = PathBuf::from(path_str); - - // If the path is not absolute, make it relative to the base directory - let full_path = if path.is_absolute() { - path - } else { - base_dir.join(path) - }; - - dependencies.push(full_path); - } - } - Ok(dependencies) - } - - #[expect(clippy::too_many_lines, clippy::cognitive_complexity)] - fn parse_instruction(&mut self) -> Result { - if self.tokens.is_empty() { - unreachable!(); - } - - // check if the Node starts with a label - let label = expect_token!(self.peek_next()?, Symbol).ok(); - if label.is_some() { - self.tokens.pop(); - } - - let opcode = expect_token!(self.next()?, Opcode)?; - let args: Vec; - - match opcode { - // R-type instructions - Opcode::Mov | Opcode::Movs => { - let reg1 = expect_type!(self.next()?, Register, Symbol)?; - let reg2 = expect_type!(self.next()?, Register, Symbol)?; - args = vec![reg1, reg2]; - } - - Opcode::Ldb | Opcode::Ldbs | Opcode::Ldh | Opcode::Ldhs | Opcode::Ldw => { - let base = expect_type!(self.next()?, Register, Symbol)?; - let dest = expect_type!(self.next()?, Register)?; - - let mut offset = Token::Immediate(0); - if let Ok(next) = self.peek_next() - && expect_type!(next, Immediate).is_ok() { - offset = self.next()?; - } - - args = vec![base, dest, offset]; - } - Opcode::Stb | Opcode::Sth | Opcode::Stw => { - let base = expect_type!(self.next()?, Register)?; - let dest = expect_type!(self.next()?, Register, Symbol)?; - let mut offset = Token::Immediate(0); - if let Ok(next) = self.peek_next() - && expect_type!(next, Immediate).is_ok() { - offset = self.next()?; - } - args = vec![base, dest, offset]; - } - - Opcode::Add - | Opcode::Sub - | Opcode::And - | Opcode::Or - | Opcode::Xor - | Opcode::Nand - | Opcode::Nor - | Opcode::Xnor => { - let src1 = expect_type!(self.next()?, Register, Symbol)?; - let src2 = expect_type!(self.next()?, Register, Symbol)?; - let dest = expect_type!(self.next()?, Register, Symbol)?; - args = vec![src1, src2, dest]; - } - - Opcode::Not | Opcode::Cmp => { - let reg1 = expect_type!(self.next()?, Register, Symbol)?; - let reg2 = expect_type!(self.next()?, Register, Symbol)?; - args = vec![reg1, reg2]; - } - - Opcode::Shl | Opcode::Shr => { - let reg = expect_type!(self.next()?, Register, Symbol)?; - let num = expect_type!(self.next()?, Immediate)?; - args = vec![reg, num]; - } - - Opcode::Inc | Opcode::Dec => { - let reg = expect_type!(self.next()?, Register, Symbol)?; - args = vec![reg]; - } - - Opcode::Include => { - let mod_name = expect_type!(self.next()?, Symbol)?; - let path = expect_type!(self.next()?, StringLit)?; - args = vec![mod_name, path]; - } - - // J-type instructions - Opcode::Jmp - | Opcode::Jeq - | Opcode::Jne - | Opcode::Jgt - | Opcode::Jge - | Opcode::Jlt - | Opcode::Jle => { - let imm = expect_type!(self.next()?, Immediate, Symbol)?; - let offset = match self.peek_next() { - Ok(token) => { - if expect_type!(token, Register).is_ok() { - self.next()? - } else { - Token::Register(Register::Zero) - } - } - Err(_) => Token::Register(Register::Zero), - }; - args = vec![imm, offset]; - } - - Opcode::Call => { - let addr = expect_type!(self.next()?, Symbol)?; - args = vec![addr]; - } - - // I-type instructions - Opcode::Lui | Opcode::Lli | Opcode::Lwi => { - let imm = expect_type!(self.next()?, Immediate, Symbol)?; - let reg = expect_type!(self.next()?, Register)?; - args = vec![imm, reg]; - } - - // Immediate Arithmetic - Opcode::AddI | Opcode::SubI => { - let reg = expect_type!(self.next()?, Register)?; - let imm = expect_type!(self.next()?, Immediate)?; - let reg2 = if expect_type!(self.peek_next()?, Register).is_ok() { - self.next()? - } else { - reg.clone() - }; - args = vec![reg, imm, reg2]; - } - - // D-type pseudoinstructions (data definition) - Opcode::Resb | Opcode::Resh | Opcode::Resw => { - let name = expect_type!(self.next()?, Symbol)?; - let num = expect_type!(self.next()?, Immediate)?; - args = vec![name, num]; - } - - Opcode::Db | Opcode::Dh | Opcode::Dw => { - args = self.parse_data_definition(opcode)?; - } - - // E-type pseudoinstructions (stack operations) - Opcode::Push | Opcode::Pop => { - let reg = expect_type!(self.next()?, Register, Symbol)?; - args = vec![reg]; - } - - Opcode::Pusha | Opcode::Popa => { - let count = - expect_type!(self.next()?, Immediate).unwrap_or(Token::Immediate(8)); - args = vec![count]; - } - - // Special instructions - Opcode::Int => { - let val = expect_type!(self.next()?, Immediate)?; - args = vec![val]; - } - - // Instructions with no arguments - Opcode::Hlt | Opcode::Nop | Opcode::Irt | Opcode::Return => { - args = vec![]; - } - - Opcode::Data | Opcode::Segment => { - return Err(AssembleError::Generic); - } - } - - Ok(node!(label, opcode, args: args)) - } - - fn parse_data_definition( - &mut self, - opcode: Opcode, - ) -> Result, AssembleError> { - let mut values = Vec::new(); - - let name = expect_type!(self.next()?, Symbol)?; - values.push(name); - - match opcode { - Opcode::Db => { - // db can take string literals or u8 immediates - while !self.tokens.is_empty() { - let token = self - .tokens - .last() - .expect("Expected a token for data definition, but found none"); - - match token { - Token::StringLit(_) => { - values.push(self.tokens.pop().expect( - "Expected a token for data definition, but found none", - )); - } - Token::Immediate(val) if u8::try_from(*val).is_ok() => { - values.push(self.tokens.pop().expect( - "Expected a token for data definition, but found none", - )); - } - _ => break, - } - } - } - - Opcode::Dh => { - // dh can take u16 immediates - while !self.tokens.is_empty() { - let token = self - .tokens - .last() - .expect("Expected a token for data definition, but found none"); - - match token { - Token::StringLit(_) => { - values.push(self.tokens.pop().expect( - "Expected a token for data definition, but found none", - )); - } - Token::Immediate(val) if u16::try_from(*val).is_ok() => { - values.push(self.tokens.pop().expect( - "Expected a token for data definition, but found none", - )); - } - _ => break, - } - } - } - - Opcode::Dw => { - // dw can take u32 immediates - while !self.tokens.is_empty() { - match self - .tokens - .last() - .expect("Expected a token for data definition, but found none") - { - Token::StringLit(_) => { - values.push(self.tokens.pop().expect( - "Expected a token for data definition, but found none", - )); - } - Token::Immediate(val) => { - values.push(self.tokens.pop().expect( - "Expected a token for data definition, but found none", - )); - } - _ => break, - } - } - } - - _ => unreachable!(), - } - - Ok(values) - } - - fn next(&mut self) -> Result { - if self.tokens.is_empty() { - Err(AssembleError::UnexpectedEof) - } else { - Ok(self - .tokens - .pop() - .expect("tokens vector was unexpectedly empty in next()")) - } - } - - fn peek_next(&self) -> Result { - if self.tokens.is_empty() { - Err(AssembleError::UnexpectedEof) - } else { - Ok(self - .tokens - .last() - .expect("peek_next called on empty tokens vector") - .clone()) - } - } -} diff --git a/assembler/src/assembler/resolver.rs b/assembler/src/assembler/resolver.rs deleted file mode 100644 index 626a045..0000000 --- a/assembler/src/assembler/resolver.rs +++ /dev/null @@ -1,156 +0,0 @@ -use std::{ - collections::HashMap, - fs::canonicalize, - path::{Path, PathBuf}, -}; - -use common::prelude::Register; - -use crate::assembler::quick_hash; -use crate::assembler::{ - log, - model::{Module, Node, Opcode, Symbol, Token}, -}; -use crate::{assembler::AssembleError, node}; - -pub fn resolve_symbols(nodes: &mut [Node]) -> Result<(), AssembleError> { - let symbol_table = generate_symbol_table(nodes); - - for node in nodes.iter_mut() { - match node.opcode() { - Opcode::Jmp - | Opcode::Jeq - | Opcode::Jne - | Opcode::Jgt - | Opcode::Jge - | Opcode::Jlt - | Opcode::Jle - | Opcode::Lli - | Opcode::Lui => { - if let Token::Symbol(symbol) = node - .arg(0) - .expect("Expected argument 0 for jump-like opcode") - { - if let Some(address) = symbol_table.get(&symbol) { - node.tokens[0] = Token::Immediate(*address); - } else { - return Err(AssembleError::UndefinedSymbol(symbol)); - } - } - } - _ => (), - } - } - - Ok(()) -} - -fn generate_symbol_table(nodes: &[Node]) -> HashMap { - let mut table = HashMap::new(); - - for (i, node) in nodes.iter().enumerate() { - if let Some(symbol) = node.label() { - table.insert(symbol, 4 * i as u32); - } - } - - table -} - -pub fn resolve_dependencies( - mut nodes: Vec, - base_dir: &Path, -) -> Result, AssembleError> { - // First we get a list of imports. - let mut dependencies = Vec::new(); - for node in &nodes { - if node.opcode() == Opcode::Include { - // we want the path, and the name - let name = if let Token::Symbol(name) = node - .arg(0) - .expect("Expected argument #0 for Include directive.") - { - name.name.clone() - } else { - unreachable!() - }; //node.2.get(0).unwrap() - - let Ok(Token::StringLit(path)) = node.arg(1) else { - unreachable!() - }; - - let full_path = base_dir.join(path); - let canonical_path = full_path - .canonicalize() - .map_err(|_| AssembleError::InvalidFile(full_path.clone()))?; - - let hash = quick_hash(&canonical_path); - - dependencies.push((name, hash)); - } - } - - let mut changes = Vec::<(u32, u32, Symbol)>::new(); - // now we resolve the symbols on all the nodes - // we need to check all operands for unresolved signals - for (i, node) in nodes.clone().iter().enumerate() { - let Node { - tokens: operands, .. - } = node; - for (j, token) in operands.iter().enumerate() { - if let Token::Symbol(symbol) = token { - for d in &dependencies { - if let Module::Unresolved(name) = symbol.module.clone() { - if name != d.0 { - continue; - } - - let symbol = Symbol { - name: symbol.name.clone(), - module: Module::Resolved(d.1), - }; - changes.push((i as u32, j as u32, symbol)); - } - } - } - } - } - - for (i, j, symbol) in changes { - nodes[i as usize].tokens[j as usize] = Token::Symbol(symbol); - } - - Ok(nodes) -} - -pub fn create_sections(nodes: &mut Vec) -> Result<(), AssembleError> { - let mut res = Vec::::with_capacity(nodes.len()); - - res.push(node!(None, Opcode::Segment, Token::Immediate(0))); - - for n in nodes.iter() { - if n.opcode() == Opcode::Data { - res.push(n.clone()); - } - } - - let start = res.len() + 1; - res.insert( - 0, - node!( - None, - Opcode::Jmp, - Token::Immediate(start as u32 * 4), - Token::Register(Register::Zero) - ), - ); - for n in nodes.iter() { - if !matches!(n.opcode(), Opcode::Data | Opcode::Include) { - res.push(n.clone()); - } - } - - *nodes = res; - - Ok(()) -} diff --git a/assembler/src/image_builder/mod.rs b/assembler/src/image_builder/mod.rs deleted file mode 100644 index e69de29..0000000 diff --git a/assembler/src/lib.rs b/assembler/src/lib.rs deleted file mode 100644 index d40c38a..0000000 --- a/assembler/src/lib.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![deny( - clippy::unwrap_used, - clippy::nursery, - clippy::perf, - clippy::pedantic, - clippy::complexity -)] -#![allow( - clippy::cast_possible_truncation, - clippy::missing_panics_doc, - clippy::missing_errors_doc, - clippy::match_wildcard_for_single_variants -)] - -pub mod assembler; -pub mod image_builder; -pub mod tooling; -mod util; - -pub mod prelude { - pub use crate::assembler::CompilerEngine; - pub use crate::image_builder; - pub use crate::tooling::brainf; - pub use crate::tooling::project; -} - -use num_cpus as _; -use threadpool as _; diff --git a/assembler/src/main.rs b/assembler/src/main.rs deleted file mode 100644 index 53d9d84..0000000 --- a/assembler/src/main.rs +++ /dev/null @@ -1,64 +0,0 @@ -use common as _; -use num_cpus as _; -use threadpool as _; - -use assembler::{ - prelude::*, - tooling::{brainf, project}, -}; -use std::{fs, io::Write, path::PathBuf}; - -fn main() { - // Parse command line arguments - let args: Vec = std::env::args().collect(); - - if args.len() == 2 && args[1] == "init" { - project::tool_libcreate(); - std::process::exit(0); - } - - if args.len() == 2 && args[1] == "brainf" { - let src = PathBuf::from("brainf.bf"); - let result = brainf::build(&src); - - let mut file = match fs::File::create("brainf.dsb") { - Err(e) => { - eprintln!("Failed to create output file: {e}"); - std::process::exit(1); - } - Ok(file) => file, - }; - - for instruction in result { - if let Err(e) = file.write(&instruction.encode().to_be_bytes()) { - eprintln!("Failed to write to output file: {e}"); - std::process::exit(1); - } - } - - std::process::exit(0); - } - - if args.len() != 5 || args[1] != "-i" || args[3] != "-o" { - eprintln!("Usage: {} -i input_path -o output_path", args[0]); - std::process::exit(1); - } - - let input_path = &args[2]; - let output_path = &args[4]; - let src = PathBuf::from(input_path); - - // Initialize the compiler engine - let mut compiler = CompilerEngine::new(); - compiler.start_compilation(&src); - - // Or block until done - let result = compiler.wait_for_result().unwrap(); - - for instruction in result { - if let Err(e) = fs::write(output_path, instruction.encode().to_be_bytes()) { - eprintln!("Failed to write to output file: {e}"); - std::process::exit(1); - } - } -} diff --git a/assembler/src/tooling/brainf.rs b/assembler/src/tooling/brainf.rs deleted file mode 100644 index b8a0f77..0000000 --- a/assembler/src/tooling/brainf.rs +++ /dev/null @@ -1,280 +0,0 @@ -use std::{fs, path::Path}; - -use common::prelude::*; - -use crate::{ - assembler::{ - Module, Node, Opcode, Symbol, Token, codegen, create_sections, expand_pseudo_ops, - resolve_symbols, - }, - node, -}; - -#[must_use] -pub fn build(src: &Path) -> Vec { - let src = fs::read_to_string(src).expect("Failed to read source file"); - let mut nodes = parse(&src); - - // we need to expand pseudoinstructions etc now - nodes = expand_pseudo_ops(nodes, 0).expect("Failed to expand pseudo-operations"); - - create_sections(&mut nodes).expect("Failed to create sections"); - - for n in &nodes { - println!("{n}"); - } - - resolve_symbols(&mut nodes).expect("Failed to resolve symbols"); - - codegen(nodes).expect("Failed to generate code from nodes") -} - -#[must_use] -#[expect(clippy::too_many_lines)] -pub fn parse(src: &str) -> Vec { - let stack = Token::Immediate(0x10000); - let acc = Token::Register(Register::Acc); - let rga = Token::Register(Register::Rga); - - let bpr = Token::Register(Register::Bpr); - let spr = Token::Register(Register::Spr); - let mut nodes = Vec::::new(); - - // Define symbols - let print_start = Symbol { - name: "print".to_string(), - module: Module::Resolved(0), - }; - - let tokens = lex(src); - - // let _id = 0; - let mut idstack = Vec::::new(); - - nodes.extend(vec![ - // set up a stack - node!(None, Opcode::Lwi, stack, bpr), - node!(None, Opcode::Mov, bpr, spr), - // set up the data pointer - node!( - Some(Symbol { - name: "main".to_string(), - module: Module::Resolved(0) - }), - Opcode::Lwi, - Token::Immediate(0x30000), - rga - ), - ]); - - for (id, tok) in tokens.iter().enumerate() { - match tok { - BfToken::Inc => { - // inc acc - nodes.extend(vec![node!(None, Opcode::Inc, acc)]); - } - BfToken::Dec => { - // dec acc - nodes.extend(vec![node!(None, Opcode::Dec, acc)]); - } - BfToken::IncPtr => { - // stb acc, rga - // add rga, 4 - // ldb rga, acc - nodes.extend(vec![ - node!(None, Opcode::Stw, acc, rga, 0), - node!(None, Opcode::AddI, rga, 4, rga), - node!(None, Opcode::Ldw, rga, acc, 0), - ]); - } - BfToken::DecPtr => { - // stb acc, rga - // sub rga, 4 - // ldb rga, acc - nodes.extend(vec![ - node!(None, Opcode::Stw, acc, rga, 0), - node!(None, Opcode::SubI, rga, 4, rga), - node!(None, Opcode::Ldw, rga, acc, 0), - ]); - } - BfToken::Out => { - // push rga - // call print - // pop zero - nodes.extend(vec![ - node!(None, Opcode::Push, acc), - node!(None, Opcode::Call, Token::Symbol(print_start.clone())), - node!(None, Opcode::Pop, Token::Register(Register::Zero)), - ]); - } - BfToken::In => { - // Read a byte from input and store it at the current data pointer - // Assuming we have an input function mapped to a specific memory location or I/O port - nodes.extend(vec![ - // Read input (assuming input is mapped to memory address 0x40000) - node!(None, Opcode::Ldw, Token::Immediate(0x40000), acc, 0), - // Store the input byte at the current data pointer - ]); - } - BfToken::Forward => { - // Start of loop [ - let loop_start = format!("loop_start_{id}"); - let loop_end = format!("loop_end_{id}"); - - // Push the current position for the matching ] - idstack.push(id as u32); - - // Load current cell value and check if zero - nodes.extend(vec![ - // Compare with zero - node!(None, Opcode::Cmp, acc, Token::Register(Register::Zero)), - // If zero, jump to end of loop - node!( - None, - Opcode::Jeq, - Token::Symbol(Symbol { - name: loop_end, - module: Module::Resolved(0), - }), - Token::Register(Register::Zero) - ), - ]); - - // Add label for loop start - nodes.push(node!( - Some(Symbol { - name: loop_start, - module: Module::Resolved(0), - }), - Opcode::Nop - )); - } - BfToken::Back => { - // End of loop ] - if let Some(start_id) = idstack.pop() { - let loop_start = format!("loop_start_{start_id}"); - let loop_end = format!("loop_end_{start_id}"); - - // Jump back to the start of the loop - nodes.extend(vec![ - // Compare with zero - node!(None, Opcode::Cmp, acc, Token::Register(Register::Zero)), - // If not zero, jump back to start of loop - node!( - None, - Opcode::Jne, - Token::Symbol(Symbol { - name: loop_start, - module: Module::Resolved(0), - }), - Token::Register(Register::Zero) - ), - // Add label for loop end - node!( - Some(Symbol { - name: loop_end, - module: Module::Resolved(0), - }), - Opcode::Nop - ), - ]); - } else { - // Unmatched closing bracket - could add error handling here - eprintln!("Warning: Unmatched ']' at position {id}"); - } - } - } - } - - nodes.push(node!(None, Opcode::Hlt)); - - insert_lib(&mut nodes); - - nodes -} - -fn insert_lib(nodes: &mut Vec) { - let bpr = Token::Register(Register::Bpr); - let spr = Token::Register(Register::Spr); - let rg0 = Token::Register(Register::Rg0); - let rg1 = Token::Register(Register::Rg1); - - let print_start = Symbol { - name: "print".to_string(), - module: Module::Resolved(0), - }; - let current = Symbol { - name: "current".to_string(), - module: Module::Resolved(0), - }; - // set up the program framework. - nodes.extend(vec![ - // set display to 0x20000 - node!( - None, - Opcode::Dw, - Token::Symbol(current.clone()), - Token::Immediate(0x20000) - ), - // print function - // initialisation - node!(Some(print_start), Opcode::Push, bpr), - node!(None, Opcode::Mov, spr, bpr), - // function body - node!(None, Opcode::Ldw, bpr, rg0, Token::Immediate(8)), - node!( - None, - Opcode::Ldw, - Token::Symbol(current.clone()), // Load address of current - rg1, - Token::Immediate(0) - ), - node!(None, Opcode::Stb, rg0, rg1, Token::Immediate(0)), - node!(None, Opcode::AddI, rg1, Token::Immediate(1), rg1), - // function return according to spec. - node!( - None, - Opcode::Stw, - rg1, - Token::Symbol(current), // Store back to current - Token::Immediate(0) - ), - node!(None, Opcode::Mov, bpr, spr), - node!(None, Opcode::Pop, bpr), - node!(None, Opcode::Return), - ]); -} - -enum BfToken { - Inc, - Dec, - IncPtr, - DecPtr, - Out, - In, - Forward, - Back, -} - -fn lex(src: &str) -> Vec { - src.chars() - .filter_map(|c| match c { - '+' => Some(BfToken::Inc), - '-' => Some(BfToken::Dec), - '>' => Some(BfToken::IncPtr), - '<' => Some(BfToken::DecPtr), - '.' => Some(BfToken::Out), - ',' => Some(BfToken::In), - '[' => Some(BfToken::Forward), - ']' => Some(BfToken::Back), - _ => None, - }) - .collect() -} - -fn _create_symbol(id: u32) -> Symbol { - Symbol { - name: format!("label_{id}"), - module: Module::Resolved(0), - } -} diff --git a/assembler/src/tooling/mod.rs b/assembler/src/tooling/mod.rs deleted file mode 100644 index 294e630..0000000 --- a/assembler/src/tooling/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod brainf; -pub mod project; diff --git a/assembler/src/tooling/project.rs b/assembler/src/tooling/project.rs deleted file mode 100644 index bdab388..0000000 --- a/assembler/src/tooling/project.rs +++ /dev/null @@ -1,93 +0,0 @@ -use crate::util::input; - -pub fn tool_libcreate() { - let mut ptype: String; - loop { - ptype = input("Enter project type (bin|lib)"); - if ptype == "bin" || ptype == "lib" { - break; - } - } - - let project_name = input("Enter project name"); - let project_path = input("Enter Directory to create project in"); - - println!("[ Creating new {ptype} project {project_name} in {project_path} ]"); - - let template = match ptype.as_str() { - "bin" => generate_bin_template(&project_name), - "lib" => generate_lib_template(&project_name), - _ => panic!("Invalid project type"), - }; - - let path = format!("{project_path}/{project_name}.dsa"); - std::fs::write(path, template).expect("Unable to write file"); -} - -fn generate_lib_template(module_name: &str) -> String { - format!( - r#"// {module_name}.dsa -// usage: -// -// include {module_name} "" -// -// usage for {module_name}_main: -// push (arg1) -// push (arg0) -// call {module_name}::{module_name}_main -// pop (arg0) -// pop (arg1) - -// Example data declarations -// dw example_data: 0x0000 - -// Main function template -{module_name}_main: - // the correct way to start a function as defined by the calling convention - push bpr - mov spr, bpr - - // explanation of how to access args - ldw bpr, rg0, 8 // arg 0 - ldw bpr, rg0, 12 // arg 1 - - // your code goes here - // Example: load example_data into rg1 - // ldw example_data, rg1 - - // the correct way to end a function as defined by the calling convention - mov bpr, spr - pop bpr - return -"#, - ) -} - -fn generate_bin_template(project_name: &str) -> String { - format!( - r#"// {project_name}.dsa -// Binary executable project - -// Example Dependencies -// include math "libs/math/math.dsa" -include print "../resources/dsa/print.dsa" - -// Data declarations - It is best practice to include these before any code! -dw message: "Hello from {project_name}.dsa!" // strings are automatically null terminated! - -// Program entry point - execution starts at the first non-definition line -{project_name}: - // Getting started: Calling external functions - // Syntax: push (arg1), push (arg0), call namespace::function, pop (arg0), pop (arg1) - - // Example: Print a string (if print library is included) - ldw message, rg0 // load address of message - push rg0 // push argument - call print::print // call the print function - pop rg0 // clean up stack - - // Program must end with halt instruction - halt -"#, - ) -} diff --git a/assembler/src/util/logging.rs b/assembler/src/util/logging.rs deleted file mode 100644 index 93c37e1..0000000 --- a/assembler/src/util/logging.rs +++ /dev/null @@ -1,108 +0,0 @@ -#![allow(dead_code)] -#![allow(unused)] -use std::{fmt, sync::mpsc::Sender}; - -pub struct Logger {} - -impl Logger { - pub const fn new() -> Self { - Self {} - } - - pub fn log(&self, message: &str) { - _ = self; - println!("\x1b[32mINFO:\x1b[0m {message}"); - } -} - -// #[derive(Debug)]= -// pub struct Logger { -// pub sender: Sender, -// } - -// impl Logger { -// pub fn new(sender: Sender) -> Self { -// Self { sender } -// } - -// pub fn debug(&self, message: T) { -// self.sender -// .send(Entry { -// etype: EntryType::Debug, -// message: message.to_string(), -// }) -// .unwrap(); -// } - -// pub fn info(&self, message: T) { -// self.sender -// .send(Entry { -// etype: EntryType::Info, -// message: message.to_string(), -// }) -// .unwrap(); -// } - -// pub fn warn(&self, message: T) { -// self.sender -// .send(Entry { -// etype: EntryType::Warn, -// message: message.to_string(), -// }) -// .unwrap(); -// } - -// pub fn error(&self, message: T) { -// self.sender -// .send(Entry { -// etype: EntryType::Error, -// message: message.to_string(), -// }) -// .unwrap(); -// } - -// pub fn fatal(&self, message: T) { -// self.sender -// .send(Entry { -// etype: EntryType::Fatal, -// message: message.to_string(), -// }) -// .unwrap(); -// } -// } - -pub struct Entry { - etype: EntryType, - pub message: String, -} - -#[derive(Copy, Clone, Eq, PartialEq)] -enum EntryType { - Debug, - Info, - Warn, - Error, - Fatal, -} - -impl fmt::Display for EntryType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "{:<5}", - match self { - Self::Debug => "DEBUG", - Self::Info => "INFO", - Self::Warn => "WARN", - Self::Error => "ERROR", - Self::Fatal => "FATAL", - } - ) - } -} - -impl fmt::Display for Entry { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}: {}", self.etype, self.message) - } -} diff --git a/assembler/src/util/mod.rs b/assembler/src/util/mod.rs deleted file mode 100644 index c8746e4..0000000 --- a/assembler/src/util/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -pub mod logging; - -use std::io::Write; - -pub fn input(prompt: &str) -> String { - print!("{prompt}\n > "); - std::io::stdout().flush().expect("Failed to flush stdout"); - let mut input = String::new(); - std::io::stdin() - .read_line(&mut input) - .expect("Failed to read line from stdin"); - input.trim().to_string() -} diff --git a/common/Cargo.toml b/common/Cargo.toml deleted file mode 100644 index 6d649a5..0000000 --- a/common/Cargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "common" -version.workspace = true -edition.workspace = true -authors.workspace = true - -[dependencies] diff --git a/common/src/instructions.rs b/common/src/instructions.rs deleted file mode 100644 index 032e4ae..0000000 --- a/common/src/instructions.rs +++ /dev/null @@ -1,517 +0,0 @@ -use crate::{instructions::encode::Encode, prelude::*}; - -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum Interrupt { - Software(u8), - Breakpoint, - HardFault, -} - -pub type Address = u32; - -impl Interrupt { - // someone tell clippy to stfu. - #[allow(clippy::must_use_candidate)] - pub const fn as_u8(self) -> u8 { - match self { - Self::Breakpoint => 0, - Self::HardFault => 1, - Self::Software(code) => code, - } - } -} - -// TODO: This should be TryFrom. -impl From for Interrupt { - #[allow(unreachable_code)] - fn from(code: u8) -> Self { - match code { - 0 => Self::Breakpoint, - 1 => Self::HardFault, - _ => Self::Software(code), - } - } -} - -/// Whether an [`Instruction`] is an I-type or R-type instruction. -#[non_exhaustive] -pub enum InstructionType { - Register, - Immediate, -} - -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[non_exhaustive] -pub enum Register { - // general purpose registers - Rg0, - Rg1, - Rg2, - Rg3, - Rg4, - Rg5, - Rg6, - Rg7, - Rg8, - Rg9, - Rga, - Rgb, - Rgc, - Rgd, - Rge, - Rgf, - - // special purpose registers - Acc, - Spr, - Bpr, - Ret, - Idr, - Mmr, - Zero, - NoReg, - - // system registers - can't be written to by instructions. - Mar, - Mdr, - Sts, - Cir, - Pcx, -} - -impl Register { - // this is here so clippy shuts up about the must_use tag. - #[allow(clippy::must_use_candidate)] - pub fn general() -> Vec { - vec![ - Self::Rg0, - Self::Rg1, - Self::Rg2, - Self::Rg3, - Self::Rg4, - Self::Rg5, - Self::Rg6, - Self::Rg7, - Self::Rg8, - Self::Rg9, - Self::Rga, - Self::Rgb, - Self::Rgc, - Self::Rgd, - Self::Rge, - Self::Rgf, - ] - } -} - -impl Default for Register { - fn default() -> Self { - Self::NoReg - } -} - -impl TryFrom for Register { - type Error = RegisterParseError; - - fn try_from(idx: u8) -> Result { - if idx > 0x1C { - return Err(RegisterParseError::InvalidIndex(idx)); - } - - Ok(match idx { - // System registers are not indexable in the reg file so they cannot be - // modified by instructions. - 0x0 => Self::Rg0, - 0x1 => Self::Rg1, - 0x2 => Self::Rg2, - 0x3 => Self::Rg3, - 0x4 => Self::Rg4, - 0x5 => Self::Rg5, - 0x6 => Self::Rg6, - 0x7 => Self::Rg7, - 0x8 => Self::Rg8, - 0x9 => Self::Rg9, - 0xA => Self::Rga, - 0xB => Self::Rgb, - 0xC => Self::Rgc, - 0xD => Self::Rgd, - 0xE => Self::Rge, - 0xF => Self::Rgf, - 0x10 => Self::Acc, - 0x11 => Self::Spr, - 0x12 => Self::Bpr, - 0x13 => Self::Ret, - 0x14 => Self::Idr, - 0x15 => Self::Mmr, - 0x16 => Self::Zero, - 0x17 => Self::NoReg, - 0x18 => Self::Mar, - 0x19 => Self::Mdr, - 0x1A => Self::Sts, - 0x1B => Self::Cir, - 0x1C => Self::Pcx, - _ => unreachable!("This is already checked for in top `if` branch."), - }) - } -} - -impl TryFrom<&str> for Register { - type Error = RegisterParseError; - - fn try_from(value: &str) -> Result { - match value.to_lowercase().as_str() { - "rg0" => Ok(Self::Rg0), - "rg1" => Ok(Self::Rg1), - "rg2" => Ok(Self::Rg2), - "rg3" => Ok(Self::Rg3), - "rg4" => Ok(Self::Rg4), - "rg5" => Ok(Self::Rg5), - "rg6" => Ok(Self::Rg6), - "rg7" => Ok(Self::Rg7), - "rg8" => Ok(Self::Rg8), - "rg9" => Ok(Self::Rg9), - "rga" => Ok(Self::Rga), - "rgb" => Ok(Self::Rgb), - "rgc" => Ok(Self::Rgc), - "rgd" => Ok(Self::Rgd), - "rge" => Ok(Self::Rge), - "rgf" => Ok(Self::Rgf), - "acc" => Ok(Self::Acc), - "spr" => Ok(Self::Spr), - "bpr" => Ok(Self::Bpr), - "ret" => Ok(Self::Ret), - "idr" => Ok(Self::Idr), - "mmr" => Ok(Self::Mmr), - "zero" => Ok(Self::Zero), - "null" => Ok(Self::NoReg), - "pcx" => Ok(Self::Pcx), - _ => Err(RegisterParseError::InvalidName(value.to_string())), - } - } -} - -impl std::fmt::Display for Register { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Rg0 => write!(f, "rg0"), - Self::Rg1 => write!(f, "rg1"), - Self::Rg2 => write!(f, "rg2"), - Self::Rg3 => write!(f, "rg3"), - Self::Rg4 => write!(f, "rg4"), - Self::Rg5 => write!(f, "rg5"), - Self::Rg6 => write!(f, "rg6"), - Self::Rg7 => write!(f, "rg7"), - Self::Rg8 => write!(f, "rg8"), - Self::Rg9 => write!(f, "rg9"), - Self::Rga => write!(f, "rga"), - Self::Rgb => write!(f, "rgb"), - Self::Rgc => write!(f, "rgc"), - Self::Rgd => write!(f, "rgd"), - Self::Rge => write!(f, "rge"), - Self::Rgf => write!(f, "rgf"), - Self::Acc => write!(f, "acc"), - Self::Spr => write!(f, "spr"), - Self::Bpr => write!(f, "bpr"), - Self::Ret => write!(f, "ret"), - Self::Idr => write!(f, "idr"), - Self::Mmr => write!(f, "mmr"), - Self::Zero => write!(f, "zero"), - Self::NoReg => write!(f, "noreg"), - Self::Mar => write!(f, "mar"), - Self::Mdr => write!(f, "mdr"), - Self::Sts => write!(f, "sts"), - Self::Cir => write!(f, "cir"), - Self::Pcx => write!(f, "pcx"), - } - } -} - -#[derive(Debug, Clone, Copy, Eq)] -#[repr(u8)] -#[non_exhaustive] -/// A list of all current instructions in the DSA. -/// -/// # Note -/// -/// This is subject to change and is therefore marked non exhaustive. -pub enum Instruction { - // No-op - Nop = 0x0, - - // Data transfer instructions - Mov(args::RTypeArgs) = 0x1, - MovSigned(args::RTypeArgs) = 0x2, - - LoadByte(args::ITypeArgs) = 0x3, - LoadByteSigned(args::ITypeArgs) = 0x4, - LoadHalfword(args::ITypeArgs) = 0x5, - LoadHalfwordSigned(args::ITypeArgs) = 0x6, - LoadWord(args::ITypeArgs) = 0x7, - - StoreByte(args::ITypeArgs) = 0x8, - StoreHalfword(args::ITypeArgs) = 0x9, - StoreWord(args::ITypeArgs) = 0xA, - - LoadLowerImmediate(args::ITypeArgs) = 0xB, - LoadUpperImmediate(args::ITypeArgs) = 0xC, - - // Jump Instructions - Jump(args::ITypeArgs) = 0xD, - JumpEq(args::ITypeArgs) = 0xE, - JumpNeq(args::ITypeArgs) = 0xF, - JumpGt(args::ITypeArgs) = 0x10, - JumpGe(args::ITypeArgs) = 0x11, - JumpLt(args::ITypeArgs) = 0x12, - JumpLe(args::ITypeArgs) = 0x13, - - // Comparison - Compare(args::RTypeArgs) = 0x14, - - // Arithmetic - Add(args::RTypeArgs) = 0x19, - Sub(args::RTypeArgs) = 0x1A, - Increment(args::RTypeArgs) = 0x15, - Decrement(args::RTypeArgs) = 0x16, - ShiftLeft(args::RTypeArgs) = 0x17, - ShiftRight(args::RTypeArgs) = 0x18, - - // Logical - And(args::RTypeArgs) = 0x1B, - Or(args::RTypeArgs) = 0x1C, - Not(args::RTypeArgs) = 0x1D, - Xor(args::RTypeArgs) = 0x1E, - Nand(args::RTypeArgs) = 0x1F, - Nor(args::RTypeArgs) = 0x20, - Xnor(args::RTypeArgs) = 0x21, - - // Misc - Interrupt(Interrupt) = 0x22, - IntReturn = 0x23, - Halt = 0x24, - - // Immediate Arithmetic - AddImmediate(args::ITypeArgs) = 0x25, - SubImmediate(args::ITypeArgs) = 0x26, - - // Fake Instructions - Data(u32) = 0x3E, - Segment(u32) = 0x3F, -} - -impl PartialEq for Instruction { - fn eq(&self, other: &Self) -> bool { - self.encode() == other.encode() - } -} - -impl Instruction { - /// Returns the opcode of an instruction. - /// - /// # Notes - /// - /// The top two bits shall be 0, opcodes are 6-bits long. - #[must_use] - pub const fn opcode(&self) -> u8 { - unsafe { *std::ptr::from_ref::(self).cast::() } - } - - /// Encodes an [`Instruction`] into a word. - #[must_use] - pub fn encode(&self) -> u32 { - Encode::encode(*self, self.opcode()) - } - - /// Decodes an [`Instruction`] from a word `data`. - pub fn decode(data: u32) -> Result { - data.try_into() - } - - /// Returns the mnemonic for a given [`Instruction`]. - #[must_use] - pub const fn mnemonic(self) -> &'static str { - match self { - Self::Add(_) => "add", - Self::Sub(_) => "sub", - Self::Increment(_) => "inc", - Self::Decrement(_) => "dec", - Self::Compare(_) => "cmp", - Self::Halt => "hlt", - Self::And(_) => "and", - Self::IntReturn => "intr", - Self::Interrupt(_) => "int", - Self::Jump(_) => "jmp", - Self::JumpEq(_) => "jeq", - Self::JumpNeq(_) => "jneq", - Self::JumpGt(_) => "jgt", - Self::JumpGe(_) => "jge", - Self::JumpLt(_) => "jlt", - Self::JumpLe(_) => "jle", - Self::Mov(_) => "mov", - Self::MovSigned(_) => "movs", - Self::LoadByte(_) => "ldb", - Self::LoadByteSigned(_) => "ldbs", - Self::LoadHalfword(_) => "ldh", - Self::LoadHalfwordSigned(_) => "ldhs", - Self::LoadWord(_) => "ldw", - Self::StoreByte(_) => "stb", - Self::StoreHalfword(_) => "sth", - Self::StoreWord(_) => "stw", - Self::LoadLowerImmediate(_) => "lli", - Self::LoadUpperImmediate(_) => "lui", - Self::ShiftLeft(_) => "shl", - Self::ShiftRight(_) => "shr", - Self::Or(_) => "or", - Self::Not(_) => "not", - Self::Nop => "nop", - Self::Xor(_) => "xor", - Self::Nand(_) => "nand", - Self::Nor(_) => "nor", - Self::Xnor(_) => "xnor", - Self::Data(_) => "data", - Self::AddImmediate(_) => "addi", - Self::SubImmediate(_) => "subi", - Self::Segment(_) => "[SEGMENT]", - } - } - - /// Returns the [`InstructionType`] for the given [`Instruction`]. - #[must_use] - pub const fn instruction_type(self) -> InstructionType { - Self::instruction_type_from_opcode(self.opcode()) - } - - /// Returns the [`InstructionType`] for the given `opcode`. - #[must_use] - pub const fn instruction_type_from_opcode(opcode: u8) -> InstructionType { - match opcode { - 0x3..=0x13 => InstructionType::Immediate, - _ => InstructionType::Register, - } - } -} - -// Instruction decoding logic goes here. -impl std::fmt::Display for Instruction { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.mnemonic())?; - - match self { - Self::Mov(args) | Self::MovSigned(args) => { - write!(f, " {}, {}", args.sr1, args.dr) - } - Self::LoadByte(args) - | Self::LoadByteSigned(args) - | Self::LoadHalfword(args) - | Self::LoadHalfwordSigned(args) - | Self::LoadWord(args) - | Self::StoreByte(args) - | Self::StoreHalfword(args) - | Self::StoreWord(args) => { - write!( - f, - " {}({:x}/{}), {}", - args.r1, args.immediate, args.immediate, args.r2 - ) - } - Self::Jump(args) - | Self::JumpEq(args) - | Self::JumpNeq(args) - | Self::JumpGt(args) - | Self::JumpGe(args) - | Self::JumpLt(args) - | Self::JumpLe(args) => { - write!(f, " 0x{:x}/{}({})", args.immediate, args.immediate, args.r1) - } - Self::LoadLowerImmediate(args) | Self::LoadUpperImmediate(args) => { - write!(f, " 0x{:x}, {}, {}", args.immediate, args.r1, args.r2) - } - Self::Compare(args) | Self::Not(args) => { - write!(f, " {}, {}", args.sr1, args.sr2) - } - - Self::Add(args) - | Self::Sub(args) - | Self::Xor(args) - | Self::Nand(args) - | Self::Nor(args) - | Self::Xnor(args) - | Self::ShiftLeft(args) - | Self::ShiftRight(args) - | Self::And(args) - | Self::Or(args) => { - write!(f, " {}, {}, {}", args.sr1, args.sr2, args.dr) - } - - Self::AddImmediate(args) | Self::SubImmediate(args) => { - write!(f, " {}, {}, {}", args.r1, args.immediate, args.r2) - } - - Self::Increment(a) | Self::Decrement(a) => write!(f, " {}", a.sr1), - Self::Interrupt(a) => write!(f, " {}", a.as_u8()), - Self::Data(a) => write!(f, " {a}"), - Self::Segment(x) => write!(f, " [SEGMENT {x}]"), - _ => Ok(()), - } - } -} - -impl TryFrom for Instruction { - type Error = InstructionDecodeError; - - /// Instruction decoding can be using using [`Instruction::try_from`] - fn try_from(data: u32) -> Result { - // Pull the opcode out so we can parse it correctly. - let opcode = ((data >> 26) & 0x3F) as u8; - - match opcode { - 0x0 => Ok(Self::Nop), - 0x1 => Ok(Self::Mov(RTypeArgs::try_from(data)?)), - 0x2 => Ok(Self::MovSigned(RTypeArgs::try_from(data)?)), - 0x3 => Ok(Self::LoadByte(ITypeArgs::try_from(data)?)), - 0x4 => Ok(Self::LoadByteSigned(ITypeArgs::try_from(data)?)), - 0x5 => Ok(Self::LoadHalfword(ITypeArgs::try_from(data)?)), - 0x6 => Ok(Self::LoadHalfwordSigned(ITypeArgs::try_from(data)?)), - 0x7 => Ok(Self::LoadWord(ITypeArgs::try_from(data)?)), - 0x8 => Ok(Self::StoreByte(ITypeArgs::try_from(data)?)), - 0x9 => Ok(Self::StoreHalfword(ITypeArgs::try_from(data)?)), - 0xA => Ok(Self::StoreWord(ITypeArgs::try_from(data)?)), - 0xB => Ok(Self::LoadLowerImmediate(ITypeArgs::try_from(data)?)), - 0xC => Ok(Self::LoadUpperImmediate(ITypeArgs::try_from(data)?)), - 0xD => Ok(Self::Jump(ITypeArgs::try_from(data)?)), - 0xE => Ok(Self::JumpEq(ITypeArgs::try_from(data)?)), - 0xF => Ok(Self::JumpNeq(ITypeArgs::try_from(data)?)), - 0x10 => Ok(Self::JumpGt(ITypeArgs::try_from(data)?)), - 0x11 => Ok(Self::JumpGe(ITypeArgs::try_from(data)?)), - 0x12 => Ok(Self::JumpLt(ITypeArgs::try_from(data)?)), - 0x13 => Ok(Self::JumpLe(ITypeArgs::try_from(data)?)), - 0x14 => Ok(Self::Compare(RTypeArgs::try_from(data)?)), - 0x15 => Ok(Self::Increment(RTypeArgs::try_from(data)?)), - 0x16 => Ok(Self::Decrement(RTypeArgs::try_from(data)?)), - 0x17 => Ok(Self::ShiftLeft(RTypeArgs::try_from(data)?)), - 0x18 => Ok(Self::ShiftRight(RTypeArgs::try_from(data)?)), - 0x19 => Ok(Self::Add(RTypeArgs::try_from(data)?)), - 0x1A => Ok(Self::Sub(RTypeArgs::try_from(data)?)), - 0x1B => Ok(Self::And(RTypeArgs::try_from(data)?)), - 0x1C => Ok(Self::Or(RTypeArgs::try_from(data)?)), - 0x1D => Ok(Self::Not(RTypeArgs::try_from(data)?)), - 0x1E => Ok(Self::Xor(RTypeArgs::try_from(data)?)), - 0x1F => Ok(Self::Nand(RTypeArgs::try_from(data)?)), - 0x20 => Ok(Self::Nor(RTypeArgs::try_from(data)?)), - 0x21 => Ok(Self::Xnor(RTypeArgs::try_from(data)?)), - 0x22 => Ok(Self::Interrupt(Interrupt::from((data & 0xFF) as u8))), - 0x23 => Ok(Self::IntReturn), - 0x24 => Ok(Self::Halt), - 0x25 => Ok(Self::AddImmediate(ITypeArgs::try_from(data)?)), - 0x26 => Ok(Self::SubImmediate(ITypeArgs::try_from(data)?)), - 0x3F => Ok(Self::Segment(u32::from(data as u8))), - _ => Err(InstructionDecodeError::InvalidOpcode(opcode)), - } - } -} - -pub mod args; -mod encode; -pub mod errors; - -#[cfg(test)] -mod tests; diff --git a/common/src/instructions/args.rs b/common/src/instructions/args.rs deleted file mode 100644 index 664c31a..0000000 --- a/common/src/instructions/args.rs +++ /dev/null @@ -1,208 +0,0 @@ -//! Various types of arguments that instructions can take, alongside encoding and decoding logic. - -use crate::{ - instructions::{RegisterParseError, encode::Encode}, - prelude::Register, -}; - -/// A list of errors that can be returned when decoding instruction arguments. -#[derive(Debug)] -pub enum ArgsDecodeError { - /// The register was not valid. - InvalidRegister(u8), -} - -impl From for ArgsDecodeError { - fn from(value: RegisterParseError) -> Self { - match value { - RegisterParseError::InvalidIndex(idx) => Self::InvalidRegister(idx), - RegisterParseError::InvalidName(_) => Self::InvalidRegister(0xFF), - } - } -} - -impl std::fmt::Display for ArgsDecodeError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::InvalidRegister(idx) => { - write!(f, "invalid register index, got {idx:x}")?; - } - } - - Ok(()) - } -} - -impl std::error::Error for ArgsDecodeError {} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -/// Used by instructions with 2 registers and an immediate argument. -pub struct ITypeArgs { - pub immediate: u16, - pub r1: Register, - /// May not actually be used by some instructions taking an immediate e.g. LUI. This is solved by making the constructor take Options. - pub r2: Register, -} - -impl ITypeArgs { - #[must_use] - /// Creates a new [`ITypeArgs`]. If r1 or r2 is unset, they will be replaced with [`Register::NoReg`]. - pub fn new(immediate: u16, r1: Option, r2: Option) -> Self { - let r1 = r1.unwrap_or_default(); - let r2 = r2.unwrap_or_default(); - - Self { immediate, r1, r2 } - } -} - -impl Encode for ITypeArgs { - /// Encodes an I-type instruction from its fields. These must have some unused high-order - /// bits set to 0 else the bit shifting logic gets fucked. - fn encode(self, opcode: u8) -> u32 { - let opcode = u32::from(opcode); - let r1 = self.r1 as u32; - let dr = self.r2 as u32; - let immediate = u32::from(self.immediate); - - (opcode << 26) | (r1 << 21) | (dr << 16) | immediate - } -} - -impl TryFrom for ITypeArgs { - type Error = ArgsDecodeError; - - fn try_from(data: u32) -> Result { - let r1 = ((data >> 21) & 0x1F) as u8; - let r2 = ((data >> 16) & 0x1F) as u8; - let immediate = data as u16; - - let r1 = r1.try_into()?; - let r2 = r2.try_into()?; - - Ok(Self { immediate, r1, r2 }) - } -} - -/// Used by instructions not using immediates (besides 5 bit shift values). -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct RTypeArgs { - pub sr1: Register, - pub sr2: Register, - pub dr: Register, - /// 5 bit shift amount. - pub shamt: u8, -} - -impl RTypeArgs { - #[must_use] - /// Creates a new [`RTypeArgs`]. If any registers are unset, they will be replaced with [`Register::NoReg`]. If `shamt` is unset, it will be set to 0. - pub fn new( - sr1: Option, - sr2: Option, - dr: Option, - shamt: Option, - ) -> Self { - let sr1 = sr1.unwrap_or_default(); - let shamt = shamt.unwrap_or_default(); - let sr2 = sr2.unwrap_or_default(); - let dr = dr.unwrap_or_default(); - - Self { - sr1, - sr2, - dr, - shamt, - } - } -} - -impl Encode for RTypeArgs { - /// Encodes an R-type instruction from its fields. These must have unused high-order - /// bits set to 0 else the bit shifting logic is fucked. - /// - /// # Arguments - /// - /// - `shamt`: The amount to shift value (used only in shift instructions, otherwise 0). - fn encode(self, opcode: u8) -> u32 { - let opcode = u32::from(opcode); - let sr1 = self.sr1 as u32; - let sr2 = self.sr2 as u32; - let dr = self.dr as u32; - let shamt = u32::from(self.shamt); - - (opcode << 26) | (sr1 << 21) | (sr2 << 16) | (dr << 11) | (shamt << 6) - } -} - -impl TryFrom for RTypeArgs { - type Error = ArgsDecodeError; - - fn try_from(data: u32) -> Result { - let sr1 = ((data >> 21) & 0x1F) as u8; - let sr2 = ((data >> 16) & 0x1F) as u8; - let dr = ((data >> 11) & 0x1F) as u8; - let shamt = ((data >> 6) & 0x1F) as u8; - - let sr1_reg = sr1.try_into()?; - let sr2_reg = sr2.try_into()?; - let dr_reg = dr.try_into()?; - - Ok(Self { - sr1: sr1_reg, - sr2: sr2_reg, - dr: dr_reg, - shamt, - }) - } -} - -#[macro_export] -macro_rules! args { - // R-type arguments - allows omitting any field - (R $(, $field:ident: $value:expr)* $(,)?) => {{ - let mut sr1: Option = None; - let mut sr2: Option = None; - let mut dr: Option = None; - let mut shamt: Option = None; - - $( - args!(@assign_r_option sr1, sr2, dr, shamt, $field, $value); - )* - - RTypeArgs::new(sr1, sr2, dr, shamt) - }}; - - // I-type arguments - requires immediate, allows omitting registers - (I, immediate: $immediate:expr $(, $field:ident: $value:expr)* $(,)?) => {{ - let mut r1: Option = None; - let mut r2: Option = None; - - $( - args!(@assign_i_option r1, r2, $field, $value); - )* - - ITypeArgs::new($immediate, r1, r2) - }}; - - // Internal helpers (same as above for R-type) - (@assign_r_option $sr1:ident, $sr2:ident, $dr:ident, $shamt:ident, sr1, $value:expr) => { - $sr1 = Some($value); - }; - (@assign_r_option $sr1:ident, $sr2:ident, $dr:ident, $shamt:ident, sr2, $value:expr) => { - $sr2 = Some($value); - }; - (@assign_r_option $sr1:ident, $sr2:ident, $dr:ident, $shamt:ident, dr, $value:expr) => { - $dr = Some($value); - }; - (@assign_r_option $sr1:ident, $sr2:ident, $dr:ident, $shamt:ident, shamt, $value:expr) => { - $shamt = Some($value); - }; - - // Internal helpers for I-type (without immediate handling) - (@assign_i_option $r1:ident, $r2:ident, r1, $value:expr) => { - $r1 = Some($value); - }; - (@assign_i_option $r1:ident, $r2:ident, r2, $value:expr) => { - $r2 = Some($value); - }; -} diff --git a/common/src/instructions/encode.rs b/common/src/instructions/encode.rs deleted file mode 100644 index 7b11a55..0000000 --- a/common/src/instructions/encode.rs +++ /dev/null @@ -1,72 +0,0 @@ -use crate::prelude::*; - -/// Not to be used directly, just call [`Instruction::encode`]. -pub trait Encode { - fn encode(self, opcode: u8) -> u32; -} - -/// Encodes a zero argument instruction. -fn encode_no_args(opcode: u8) -> u32 { - let opcode = u32::from(opcode); - let sr1 = Register::NoReg as u32; - let sr2 = Register::NoReg as u32; - let dr = Register::NoReg as u32; - let shamt = 0; - - (opcode << 26) | (sr1 << 21) | (sr2 << 16) | (dr << 11) | (shamt << 6) -} - -/// Expands to a match statement that calls encode on instructions that implement -/// [`Encode`]: -/// -/// # Usage -/// -/// ```rs -/// encode_instruction!(self, with_args: [...], no_args: [...], special: [...] ) -/// ``` -macro_rules! encode_instruction { - ($self:expr, with_args: [$($variant:ident),+ $(,)?], no_args: [$($no_arg_variant:ident),* $(,)?] $(, special: [$($special:pat => $body:expr),* $(,)?])?) => { - match $self { - $( - Instruction::$variant(args) => args.encode($self.opcode()), - )+ - $( - Instruction::$no_arg_variant => encode_no_args($self.opcode()), - )* - $($( - $special => $body, - )*)? - } - }; -} - -impl Encode for Instruction { - fn encode(self, _: u8) -> u32 { - encode_instruction!( - self, - with_args: [ - Mov, MovSigned, LoadByte, LoadByteSigned, LoadHalfword, - LoadHalfwordSigned, LoadWord, StoreByte, StoreHalfword, - StoreWord, LoadLowerImmediate, LoadUpperImmediate, Jump, - JumpEq, JumpNeq, JumpGt, JumpGe, JumpLt, JumpLe, Compare, - Add, Sub, Increment, Decrement, ShiftLeft, ShiftRight, - And, Or, Not, Xor, Nand, Nor, Xnor, AddImmediate, SubImmediate - ], - no_args: [Nop, IntReturn, Halt], - special: [ - Self::Data(data) => data, - Self::Interrupt(interrupt) => { - let opcode = u32::from(self.opcode()); - (opcode << 26) | u32::from(interrupt.as_u8()) - }, - Self::Segment(segment) => { - let opcode = u32::from(self.opcode()); - (opcode << 26) | u32::from(segment as u8) - } - ] - ) - } -} - -#[cfg(test)] -mod tests; diff --git a/common/src/instructions/encode/tests.rs b/common/src/instructions/encode/tests.rs deleted file mode 100644 index e3bc63c..0000000 --- a/common/src/instructions/encode/tests.rs +++ /dev/null @@ -1,98 +0,0 @@ -use crate::prelude::*; - -#[test] -fn test_encode_nop() { - let no_reg = Register::NoReg as u32; - let no_op = u32::from(Instruction::Nop.opcode()); - - let expected = (no_op << 26) | (no_reg << 21) | (no_reg << 16) | (no_reg << 11); - let got = Instruction::Nop.encode(); - - assert_eq!(expected, got); -} - -#[test] -fn test_encode_mov() { - let rg0 = Register::Rg0 as u32; - let rg1 = Register::Rg1 as u32; - let no_reg = Register::NoReg as u32; - - let instruction = Instruction::Mov(RTypeArgs::new( - Some(Register::Rg0), - None, - Some(Register::Rg1), - None, - )); - let mov = u32::from(instruction.opcode()); - - let expected = (mov << 26) | (rg0 << 21) | (no_reg << 16) | (rg1 << 11); - let got = instruction.encode(); - - assert_eq!(expected, got); -} - -#[test] -fn test_encode_load_byte() { - let rg0 = Register::Rg0 as u32; - let rg1 = Register::Rg1 as u32; - let immediate = 100; - - let instruction = Instruction::LoadByte(ITypeArgs::new( - immediate, - Some(Register::Rg0), - Some(Register::Rg1), - )); - let load_byte = u32::from(instruction.opcode()); - - let expected = (load_byte << 26) | (rg0 << 21) | (rg1 << 16) | u32::from(immediate); - let got = instruction.encode(); - - assert_eq!(expected, got); -} - -#[test] -fn test_encode_shift_left_shamt() { - let rg0 = Register::Rg0 as u32; - let no_reg = Register::NoReg as u32; - - let shift_amount = 5; - - let instruction = Instruction::ShiftLeft(RTypeArgs::new( - Some(Register::Rg0), - None, - None, - Some(shift_amount), - )); - let shift_left = u32::from(instruction.opcode()); - - let expected = (shift_left << 26) - | (rg0 << 21) - | (no_reg << 16) - | (no_reg << 11) - | (u32::from(shift_amount) << 6); - - let got = instruction.encode(); - - assert_eq!(expected, got); -} - -#[test] -fn test_encode_shift_left_reg() { - let rg0 = Register::Rg0 as u32; - let rg1 = Register::Rg1 as u32; - let no_reg = Register::NoReg as u32; - - let instruction = Instruction::ShiftLeft(RTypeArgs::new( - Some(Register::Rg0), - Some(Register::Rg1), - None, - None, - )); - let shift_left = u32::from(instruction.opcode()); - - let expected = (shift_left << 26) | (rg0 << 21) | (rg1 << 16) | (no_reg << 11); - - let got = instruction.encode(); - - assert_eq!(expected, got); -} diff --git a/common/src/instructions/errors.rs b/common/src/instructions/errors.rs deleted file mode 100644 index 8961ae5..0000000 --- a/common/src/instructions/errors.rs +++ /dev/null @@ -1,56 +0,0 @@ -//! All the errors that may be returned from [`instructions`]. - -use crate::prelude::*; - -#[derive(Debug)] -/// Error type for parsing register numbers. -pub enum RegisterParseError { - InvalidIndex(u8), - InvalidName(String), -} - -impl std::fmt::Display for RegisterParseError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::InvalidIndex(idx) => write!(f, "invalid index given ({idx})"), - Self::InvalidName(name) => write!(f, "invalid name given ({name})"), - } - } -} - -impl std::error::Error for RegisterParseError {} - -/// A list of errors that can be returned when decoding instructions. -#[derive(Debug)] -pub enum InstructionDecodeError { - /// Some field was incorrect. Returns an error for debugging purposes. - InvalidArgument(ArgsDecodeError), - /// Some opcode was invalid. Returns the offending opcode for debugging purposes etc. - InvalidOpcode(u8), -} - -impl From for InstructionDecodeError { - fn from(err: ArgsDecodeError) -> Self { - Self::InvalidArgument(err) - } -} - -impl std::fmt::Display for InstructionDecodeError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::InvalidOpcode(code) => write!(f, "invalid opcode, got {code:x}")?, - Self::InvalidArgument(err) => write!(f, "invalid arguments, got an error {err}")?, - } - - Ok(()) - } -} - -impl std::error::Error for InstructionDecodeError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self { - Self::InvalidArgument(err) => Some(err), - _ => None, - } - } -} diff --git a/common/src/instructions/tests.rs b/common/src/instructions/tests.rs deleted file mode 100644 index 114e7da..0000000 --- a/common/src/instructions/tests.rs +++ /dev/null @@ -1,215 +0,0 @@ -#![allow(clippy::unwrap_used)] -use crate::prelude::*; - -#[test] -fn test_opcode_nop() { - let instr = Instruction::Nop; - assert_eq!(instr.opcode(), 0x0); -} - -#[test] -fn test_opcode_data_transfer() { - let args = RTypeArgs::new(None, None, None, None); - assert_eq!(Instruction::Mov(args).opcode(), 0x1); - assert_eq!(Instruction::MovSigned(args).opcode(), 0x2); - - let iargs = ITypeArgs::new(0, None, None); - assert_eq!(Instruction::LoadByte(iargs).opcode(), 0x3); - assert_eq!(Instruction::LoadByteSigned(iargs).opcode(), 0x4); - assert_eq!(Instruction::LoadHalfword(iargs).opcode(), 0x5); - assert_eq!(Instruction::LoadHalfwordSigned(iargs).opcode(), 0x6); - assert_eq!(Instruction::LoadWord(iargs).opcode(), 0x7); - assert_eq!(Instruction::StoreByte(iargs).opcode(), 0x8); - assert_eq!(Instruction::StoreHalfword(iargs).opcode(), 0x9); - assert_eq!(Instruction::StoreWord(iargs).opcode(), 0xA); - assert_eq!(Instruction::LoadLowerImmediate(iargs).opcode(), 0xB); - assert_eq!(Instruction::LoadUpperImmediate(iargs).opcode(), 0xC); -} - -#[test] -fn test_opcode_jump_instructions() { - let args = ITypeArgs::new(0, None, None); - assert_eq!(Instruction::Jump(args).opcode(), 0xD); - assert_eq!(Instruction::JumpEq(args).opcode(), 0xE); - assert_eq!(Instruction::JumpNeq(args).opcode(), 0xF); - assert_eq!(Instruction::JumpGt(args).opcode(), 0x10); - assert_eq!(Instruction::JumpGe(args).opcode(), 0x11); - assert_eq!(Instruction::JumpLt(args).opcode(), 0x12); - assert_eq!(Instruction::JumpLe(args).opcode(), 0x13); -} - -#[test] -fn test_opcode_arithmetic() { - let args = RTypeArgs::new(None, None, None, None); - assert_eq!(Instruction::Compare(args).opcode(), 0x14); - assert_eq!(Instruction::Increment(args).opcode(), 0x15); - assert_eq!(Instruction::Decrement(args).opcode(), 0x16); - assert_eq!(Instruction::ShiftLeft(args).opcode(), 0x17); - assert_eq!(Instruction::ShiftRight(args).opcode(), 0x18); - assert_eq!(Instruction::Add(args).opcode(), 0x19); - assert_eq!(Instruction::Sub(args).opcode(), 0x1A); -} - -#[test] -fn test_opcode_logical() { - let args = RTypeArgs::new(None, None, None, None); - assert_eq!(Instruction::And(args).opcode(), 0x1B); - assert_eq!(Instruction::Or(args).opcode(), 0x1C); - assert_eq!(Instruction::Not(args).opcode(), 0x1D); - assert_eq!(Instruction::Xor(args).opcode(), 0x1E); - assert_eq!(Instruction::Nand(args).opcode(), 0x1F); - assert_eq!(Instruction::Nor(args).opcode(), 0x20); - assert_eq!(Instruction::Xnor(args).opcode(), 0x21); -} - -#[test] -fn test_opcode_misc() { - let interrupt = Interrupt::Software(5); - assert_eq!(Instruction::Interrupt(interrupt).opcode(), 0x22); - assert_eq!(Instruction::IntReturn.opcode(), 0x23); - assert_eq!(Instruction::Halt.opcode(), 0x24); -} - -#[test] -fn test_opcode_with_different_args() { - let args1 = RTypeArgs::new( - Some(Register::Rg0), - Some(Register::Rg1), - Some(Register::Rg2), - Some(5), - ); - let args2 = RTypeArgs::new( - Some(Register::Acc), - Some(Register::Spr), - Some(Register::Bpr), - Some(31), - ); - - // Opcode should be the same regardless of arguments - assert_eq!( - Instruction::Add(args1).opcode(), - Instruction::Add(args2).opcode() - ); - assert_eq!( - Instruction::Sub(args1).opcode(), - Instruction::Sub(args2).opcode() - ); -} - -#[test] -fn test_opcode_boundary_values() { - // Test highest opcode value - assert_eq!(Instruction::Halt.opcode(), 0x24); - - // Test lowest opcode value - assert_eq!(Instruction::Nop.opcode(), 0x0); -} - -#[test] -fn test_instruction_decode_nop() { - let instr = Instruction::Nop; - let encoded = instr.encode(); - let decoded = Instruction::decode(encoded).unwrap(); - assert_eq!(instr, decoded); -} - -#[test] -fn test_instruction_decode_data_transfer() { - let args = RTypeArgs::new( - Some(Register::Rg0), - Some(Register::Rg1), - Some(Register::Rg2), - Some(5), - ); - let instr = Instruction::Mov(args); - let encoded = instr.encode(); - let decoded = Instruction::decode(encoded).unwrap(); - assert_eq!(instr, decoded); - - let iargs = ITypeArgs::new(100, Some(Register::Rg3), Some(Register::Rg4)); - let instr = Instruction::LoadWord(iargs); - let encoded = instr.encode(); - let decoded = Instruction::decode(encoded).unwrap(); - assert_eq!(instr, decoded); -} - -#[test] -fn test_instruction_decode_jump() { - let args = ITypeArgs::new(200, Some(Register::Acc), Some(Register::Spr)); - let instr = Instruction::Jump(args); - let encoded = instr.encode(); - let decoded = Instruction::decode(encoded).unwrap(); - assert_eq!(instr, decoded); - - let instr = Instruction::JumpEq(args); - let encoded = instr.encode(); - let decoded = Instruction::decode(encoded).unwrap(); - assert_eq!(instr, decoded); -} - -#[test] -fn test_instruction_decode_arithmetic() { - let args = RTypeArgs::new( - Some(Register::Bpr), - Some(Register::Rg7), - Some(Register::Rgf), - Some(31), - ); - let instr = Instruction::Add(args); - let encoded = instr.encode(); - let decoded = Instruction::decode(encoded).unwrap(); - assert_eq!(instr, decoded); - - let instr = Instruction::Compare(args); - let encoded = instr.encode(); - let decoded = Instruction::decode(encoded).unwrap(); - assert_eq!(instr, decoded); -} - -#[test] -fn test_instruction_decode_logical() { - let args = RTypeArgs::new( - Some(Register::Rg8), - Some(Register::Rg9), - Some(Register::Rga), - Some(15), - ); - let instr = Instruction::And(args); - let encoded = instr.encode(); - let decoded = Instruction::decode(encoded).unwrap(); - assert_eq!(instr, decoded); - - let instr = Instruction::Xor(args); - let encoded = instr.encode(); - let decoded = Instruction::decode(encoded).unwrap(); - assert_eq!(instr, decoded); -} - -#[test] -fn test_instruction_decode_misc() { - let instr = Instruction::Halt; - let encoded = instr.encode(); - let decoded = Instruction::decode(encoded).unwrap(); - assert_eq!(instr, decoded); -} - -#[test] -fn test_instruction_decode_invalid() { - // Test with invalid opcode. - let invalid_encoded = 0xF500_0000; - let decode = Instruction::decode(invalid_encoded); - - dbg!(&decode); - - assert!(decode.is_err()); -} - -// TODO: Get interrupts working. -// #[test] -// fn test_instruction_decode_interrupt() { -// let interrupt = Interrupt::Software(10); -// let instr = Instruction::Interrupt(interrupt); -// let encoded = instr.encode(); -// let decoded = Instruction::decode(encoded).unwrap(); -// assert_eq!(instr, decoded); -// } diff --git a/common/src/lib.rs b/common/src/lib.rs deleted file mode 100644 index f1bc305..0000000 --- a/common/src/lib.rs +++ /dev/null @@ -1,22 +0,0 @@ -#![deny( - clippy::unwrap_used, - clippy::nursery, - clippy::perf, - clippy::pedantic, - clippy::complexity -)] -#![allow( - clippy::cast_possible_truncation, - clippy::missing_panics_doc, - clippy::missing_errors_doc, - clippy::match_wildcard_for_single_variants -)] - -pub mod instructions; - -pub mod prelude { - //! A collection of types you should definitely import when working with this crate. - pub use super::instructions::{ - Address, Instruction, InstructionType, Interrupt, Register, args::*, errors::*, - }; -} diff --git a/dsa_editor/Cargo.lock b/dsa_editor/Cargo.lock deleted file mode 100644 index 818de07..0000000 --- a/dsa_editor/Cargo.lock +++ /dev/null @@ -1,3985 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "ab_glyph" -version = "0.2.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3672c180e71eeaaac3a541fbbc5f5ad4def8b747c595ad30d674e43049f7b0" -dependencies = [ - "ab_glyph_rasterizer", - "owned_ttf_parser", -] - -[[package]] -name = "ab_glyph_rasterizer" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" - -[[package]] -name = "accesskit" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3d3b8f9bae46a948369bc4a03e815d4ed6d616bd00de4051133a5019dc31c5a" - -[[package]] -name = "accesskit_atspi_common" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c5dd55e6e94949498698daf4d48fb5659e824d7abec0d394089656ceaf99d4f" -dependencies = [ - "accesskit", - "accesskit_consumer", - "atspi-common", - "serde", - "thiserror 1.0.69", - "zvariant", -] - -[[package]] -name = "accesskit_consumer" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f47983a1084940ba9a39c077a8c63e55c619388be5476ac04c804cfbd1e63459" -dependencies = [ - "accesskit", - "hashbrown", - "immutable-chunkmap", -] - -[[package]] -name = "accesskit_macos" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7329821f3bd1101e03a7d2e03bd339e3ac0dc64c70b4c9f9ae1949e3ba8dece1" -dependencies = [ - "accesskit", - "accesskit_consumer", - "hashbrown", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "accesskit_unix" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcee751cc20d88678c33edaf9c07e8b693cd02819fe89053776f5313492273f5" -dependencies = [ - "accesskit", - "accesskit_atspi_common", - "async-channel", - "async-executor", - "async-task", - "atspi", - "futures-lite", - "futures-util", - "serde", - "zbus", -] - -[[package]] -name = "accesskit_windows" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24fcd5d23d70670992b823e735e859374d694a3d12bfd8dd32bd3bd8bedb5d81" -dependencies = [ - "accesskit", - "accesskit_consumer", - "hashbrown", - "paste", - "static_assertions", - "windows", - "windows-core", -] - -[[package]] -name = "accesskit_winit" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6a48dad5530b6deb9fc7a52cc6c3bf72cdd9eb8157ac9d32d69f2427a5e879" -dependencies = [ - "accesskit", - "accesskit_macos", - "accesskit_unix", - "accesskit_windows", - "raw-window-handle", - "winit", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - -[[package]] -name = "ahash" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" -dependencies = [ - "cfg-if", - "getrandom 0.3.3", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "android-activity" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" -dependencies = [ - "android-properties", - "bitflags 2.9.1", - "cc", - "cesu8", - "jni", - "jni-sys", - "libc", - "log", - "ndk", - "ndk-context", - "ndk-sys 0.6.0+11769913", - "num_enum", - "thiserror 1.0.69", -] - -[[package]] -name = "android-properties" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "arboard" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1df21f715862ede32a0c525ce2ca4d52626bb0007f8c18b87a384503ac33e70" -dependencies = [ - "clipboard-win", - "image", - "log", - "objc2 0.6.1", - "objc2-app-kit 0.3.1", - "objc2-core-foundation", - "objc2-core-graphics", - "objc2-foundation 0.3.1", - "parking_lot", - "percent-encoding", - "windows-sys 0.59.0", - "x11rb", -] - -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" - -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - -[[package]] -name = "as-raw-xcb-connection" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" - -[[package]] -name = "ash" -version = "0.38.0+1.3.281" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" -dependencies = [ - "libloading", -] - -[[package]] -name = "async-broadcast" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" -dependencies = [ - "event-listener", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-channel" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-executor" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb812ffb58524bdd10860d7d974e2f01cc0950c2438a74ee5ec2e2280c6c4ffa" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "pin-project-lite", - "slab", -] - -[[package]] -name = "async-fs" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" -dependencies = [ - "async-lock", - "blocking", - "futures-lite", -] - -[[package]] -name = "async-io" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1237c0ae75a0f3765f58910ff9cdd0a12eeb39ab2f4c7de23262f337f0aacbb3" -dependencies = [ - "async-lock", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix 1.0.7", - "slab", - "tracing", - "windows-sys 0.59.0", -] - -[[package]] -name = "async-lock" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" -dependencies = [ - "event-listener", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-process" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde3f4e40e6021d7acffc90095cbd6dc54cb593903d1de5832f435eb274b85dc" -dependencies = [ - "async-channel", - "async-io", - "async-lock", - "async-signal", - "async-task", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "rustix 1.0.7", - "tracing", -] - -[[package]] -name = "async-recursion" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "async-signal" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7605a4e50d4b06df3898d5a70bf5fde51ed9059b0434b73105193bc27acce0d" -dependencies = [ - "async-io", - "async-lock", - "atomic-waker", - "cfg-if", - "futures-core", - "futures-io", - "rustix 1.0.7", - "signal-hook-registry", - "slab", - "windows-sys 0.59.0", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - -[[package]] -name = "async-trait" -version = "0.1.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "atspi" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be534b16650e35237bb1ed189ba2aab86ce65e88cc84c66f4935ba38575cecbf" -dependencies = [ - "atspi-common", - "atspi-connection", - "atspi-proxies", -] - -[[package]] -name = "atspi-common" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1909ed2dc01d0a17505d89311d192518507e8a056a48148e3598fef5e7bb6ba7" -dependencies = [ - "enumflags2", - "serde", - "static_assertions", - "zbus", - "zbus-lockstep", - "zbus-lockstep-macros", - "zbus_names", - "zvariant", -] - -[[package]] -name = "atspi-connection" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "430c5960624a4baaa511c9c0fcc2218e3b58f5dbcc47e6190cafee344b873333" -dependencies = [ - "atspi-common", - "atspi-proxies", - "futures-lite", - "zbus", -] - -[[package]] -name = "atspi-proxies" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e6c5de3e524cf967569722446bcd458d5032348554d9a17d7d72b041ab7496" -dependencies = [ - "atspi-common", - "serde", - "zbus", - "zvariant", -] - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "bit-set" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" -dependencies = [ - "serde", -] - -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block2" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" -dependencies = [ - "objc2 0.5.2", -] - -[[package]] -name = "blocking" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" -dependencies = [ - "async-channel", - "async-task", - "futures-io", - "futures-lite", - "piper", -] - -[[package]] -name = "bumpalo" -version = "3.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" - -[[package]] -name = "bytemuck" -version = "1.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" -dependencies = [ - "bytemuck_derive", -] - -[[package]] -name = "bytemuck_derive" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "byteorder-lite" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" - -[[package]] -name = "bytes" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" - -[[package]] -name = "calloop" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" -dependencies = [ - "bitflags 2.9.1", - "log", - "polling", - "rustix 0.38.44", - "slab", - "thiserror 1.0.69", -] - -[[package]] -name = "calloop-wayland-source" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" -dependencies = [ - "calloop", - "rustix 0.38.44", - "wayland-backend", - "wayland-client", -] - -[[package]] -name = "cc" -version = "1.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" -dependencies = [ - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - -[[package]] -name = "cfg-if" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "cgl" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" -dependencies = [ - "libc", -] - -[[package]] -name = "clipboard-win" -version = "5.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892" -dependencies = [ - "error-code", -] - -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - -[[package]] -name = "colorful" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb474a9c3219a8254ead020421ecf1b90427f29b55f6aae9a2471fa62c126ef" - -[[package]] -name = "combine" -version = "4.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" -dependencies = [ - "bytes", - "memchr", -] - -[[package]] -name = "common_syntax" -version = "0.1.0" -dependencies = [ - "colorful", - "eframe", - "egui", - "serde", -] - -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "core-graphics" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "core-graphics-types", - "foreign-types", - "libc", -] - -[[package]] -name = "core-graphics-types" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "libc", -] - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "cursor-icon" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "dispatch" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" - -[[package]] -name = "dispatch2" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" -dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", -] - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dlib" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" -dependencies = [ - "libloading", -] - -[[package]] -name = "document-features" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" -dependencies = [ - "litrs", -] - -[[package]] -name = "downcast-rs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" - -[[package]] -name = "dpi" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" - -[[package]] -name = "ecolor" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc4feb366740ded31a004a0e4452fbf84e80ef432ecf8314c485210229672fd1" -dependencies = [ - "bytemuck", - "emath", -] - -[[package]] -name = "eframe" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0dfe0859f3fb1bc6424c57d41e10e9093fe938f426b691e42272c2f336d915c" -dependencies = [ - "ahash", - "bytemuck", - "document-features", - "egui", - "egui-wgpu", - "egui-winit", - "egui_glow", - "glow", - "glutin", - "glutin-winit", - "image", - "js-sys", - "log", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", - "parking_lot", - "percent-encoding", - "profiling", - "raw-window-handle", - "static_assertions", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "web-time", - "winapi", - "windows-sys 0.59.0", - "winit", -] - -[[package]] -name = "egui" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd34cec49ab55d85ebf70139cb1ccd29c977ef6b6ba4fe85489d6877ee9ef3" -dependencies = [ - "accesskit", - "ahash", - "bitflags 2.9.1", - "emath", - "epaint", - "log", - "nohash-hasher", - "profiling", -] - -[[package]] -name = "egui-wgpu" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d319dfef570f699b6e9114e235e862a2ddcf75f0d1a061de9e1328d92146d820" -dependencies = [ - "ahash", - "bytemuck", - "document-features", - "egui", - "epaint", - "log", - "profiling", - "thiserror 1.0.69", - "type-map", - "web-time", - "wgpu", - "winit", -] - -[[package]] -name = "egui-winit" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d9dfbb78fe4eb9c3a39ad528b90ee5915c252e77bbab9d4ebc576541ab67e13" -dependencies = [ - "accesskit_winit", - "ahash", - "arboard", - "bytemuck", - "egui", - "log", - "profiling", - "raw-window-handle", - "smithay-clipboard", - "web-time", - "webbrowser", - "winit", -] - -[[package]] -name = "egui_glow" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "910906e3f042ea6d2378ec12a6fd07698e14ddae68aed2d819ffe944a73aab9e" -dependencies = [ - "ahash", - "bytemuck", - "egui", - "glow", - "log", - "memoffset", - "profiling", - "wasm-bindgen", - "web-sys", - "winit", -] - -[[package]] -name = "emath" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e4cadcff7a5353ba72b7fea76bf2122b5ebdbc68e8155aa56dfdea90083fe1b" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "endi" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" - -[[package]] -name = "enumflags2" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" -dependencies = [ - "enumflags2_derive", - "serde", -] - -[[package]] -name = "enumflags2_derive" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "epaint" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fcc0f5a7c613afd2dee5e4b30c3e6acafb8ad6f0edb06068811f708a67c562" -dependencies = [ - "ab_glyph", - "ahash", - "bytemuck", - "ecolor", - "emath", - "epaint_default_fonts", - "log", - "nohash-hasher", - "parking_lot", - "profiling", -] - -[[package]] -name = "epaint_default_fonts" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7e7a64c02cf7a5b51e745a9e45f60660a286f151c238b9d397b3e923f5082f" - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "error-code" -version = "3.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" - -[[package]] -name = "event-listener" -version = "5.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" -dependencies = [ - "event-listener", - "pin-project-lite", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "fdeflate" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" -dependencies = [ - "simd-adler32", -] - -[[package]] -name = "flate2" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "foreign-types" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" -dependencies = [ - "foreign-types-macros", - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "foreign-types-shared" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-lite" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - -[[package]] -name = "futures-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "gethostname" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" -dependencies = [ - "libc", - "windows-targets 0.48.5", -] - -[[package]] -name = "getrandom" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.1+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasi 0.14.2+wasi-0.2.4", -] - -[[package]] -name = "gl_generator" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" -dependencies = [ - "khronos_api", - "log", - "xml-rs", -] - -[[package]] -name = "glow" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" -dependencies = [ - "js-sys", - "slotmap", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "glutin" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12124de845cacfebedff80e877bb37b5b75c34c5a4c89e47e1cdd67fb6041325" -dependencies = [ - "bitflags 2.9.1", - "cfg_aliases", - "cgl", - "dispatch2", - "glutin_egl_sys", - "glutin_glx_sys", - "glutin_wgl_sys", - "libloading", - "objc2 0.6.1", - "objc2-app-kit 0.3.1", - "objc2-core-foundation", - "objc2-foundation 0.3.1", - "once_cell", - "raw-window-handle", - "wayland-sys", - "windows-sys 0.52.0", - "x11-dl", -] - -[[package]] -name = "glutin-winit" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" -dependencies = [ - "cfg_aliases", - "glutin", - "raw-window-handle", - "winit", -] - -[[package]] -name = "glutin_egl_sys" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4680ba6195f424febdc3ba46e7a42a0e58743f2edb115297b86d7f8ecc02d2" -dependencies = [ - "gl_generator", - "windows-sys 0.52.0", -] - -[[package]] -name = "glutin_glx_sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7bb2938045a88b612499fbcba375a77198e01306f52272e692f8c1f3751185" -dependencies = [ - "gl_generator", - "x11-dl", -] - -[[package]] -name = "glutin_wgl_sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" -dependencies = [ - "gl_generator", -] - -[[package]] -name = "gpu-alloc" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" -dependencies = [ - "bitflags 2.9.1", - "gpu-alloc-types", -] - -[[package]] -name = "gpu-alloc-types" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" -dependencies = [ - "bitflags 2.9.1", -] - -[[package]] -name = "gpu-descriptor" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" -dependencies = [ - "bitflags 2.9.1", - "gpu-descriptor-types", - "hashbrown", -] - -[[package]] -name = "gpu-descriptor-types" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" -dependencies = [ - "bitflags 2.9.1", -] - -[[package]] -name = "hashbrown" -version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" -dependencies = [ - "foldhash", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hexf-parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" - -[[package]] -name = "icu_collections" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" - -[[package]] -name = "icu_properties" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "potential_utf", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" - -[[package]] -name = "icu_provider" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" -dependencies = [ - "displaydoc", - "icu_locale_core", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "idna" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "image" -version = "0.25.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" -dependencies = [ - "bytemuck", - "byteorder-lite", - "num-traits", - "png", - "tiff", -] - -[[package]] -name = "immutable-chunkmap" -version = "2.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f97096f508d54f8f8ab8957862eee2ccd628847b6217af1a335e1c44dee578" -dependencies = [ - "arrayvec", -] - -[[package]] -name = "indexmap" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "jni" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" -dependencies = [ - "cesu8", - "cfg-if", - "combine", - "jni-sys", - "log", - "thiserror 1.0.69", - "walkdir", - "windows-sys 0.45.0", -] - -[[package]] -name = "jni-sys" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" - -[[package]] -name = "jobserver" -version = "0.1.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" -dependencies = [ - "getrandom 0.3.3", - "libc", -] - -[[package]] -name = "jpeg-decoder" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" - -[[package]] -name = "js-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "khronos-egl" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" -dependencies = [ - "libc", - "libloading", - "pkg-config", -] - -[[package]] -name = "khronos_api" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" - -[[package]] -name = "libc" -version = "0.2.173" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8cfeafaffdbc32176b64fb251369d52ea9f0a8fbc6f8759edffef7b525d64bb" - -[[package]] -name = "libloading" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" -dependencies = [ - "cfg-if", - "windows-targets 0.53.2", -] - -[[package]] -name = "libredox" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" -dependencies = [ - "bitflags 2.9.1", - "libc", - "redox_syscall 0.5.13", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[package]] -name = "linux-raw-sys" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" - -[[package]] -name = "litemap" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" - -[[package]] -name = "litrs" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" - -[[package]] -name = "lock_api" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" - -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - -[[package]] -name = "memchr" -version = "2.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" - -[[package]] -name = "memmap2" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" -dependencies = [ - "libc", -] - -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "metal" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f569fb946490b5743ad69813cb19629130ce9374034abe31614a36402d18f99e" -dependencies = [ - "bitflags 2.9.1", - "block", - "core-graphics-types", - "foreign-types", - "log", - "objc", - "paste", -] - -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", - "simd-adler32", -] - -[[package]] -name = "naga" -version = "24.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e380993072e52eef724eddfcde0ed013b0c023c3f0417336ed041aa9f076994e" -dependencies = [ - "arrayvec", - "bit-set", - "bitflags 2.9.1", - "cfg_aliases", - "codespan-reporting", - "hexf-parse", - "indexmap", - "log", - "rustc-hash 1.1.0", - "spirv", - "strum", - "termcolor", - "thiserror 2.0.12", - "unicode-xid", -] - -[[package]] -name = "ndk" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" -dependencies = [ - "bitflags 2.9.1", - "jni-sys", - "log", - "ndk-sys 0.6.0+11769913", - "num_enum", - "raw-window-handle", - "thiserror 1.0.69", -] - -[[package]] -name = "ndk-context" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" - -[[package]] -name = "ndk-sys" -version = "0.5.0+25.2.9519653" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" -dependencies = [ - "jni-sys", -] - -[[package]] -name = "ndk-sys" -version = "0.6.0+11769913" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" -dependencies = [ - "jni-sys", -] - -[[package]] -name = "nix" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" -dependencies = [ - "bitflags 2.9.1", - "cfg-if", - "cfg_aliases", - "libc", - "memoffset", -] - -[[package]] -name = "nohash-hasher" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_enum" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - -[[package]] -name = "objc-sys" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" - -[[package]] -name = "objc2" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" -dependencies = [ - "objc-sys", - "objc2-encode", -] - -[[package]] -name = "objc2" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88c6597e14493ab2e44ce58f2fdecf095a51f12ca57bec060a11c57332520551" -dependencies = [ - "objc2-encode", -] - -[[package]] -name = "objc2-app-kit" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" -dependencies = [ - "bitflags 2.9.1", - "block2", - "libc", - "objc2 0.5.2", - "objc2-core-data", - "objc2-core-image", - "objc2-foundation 0.2.2", - "objc2-quartz-core", -] - -[[package]] -name = "objc2-app-kit" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" -dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", - "objc2-core-foundation", - "objc2-core-graphics", - "objc2-foundation 0.3.1", -] - -[[package]] -name = "objc2-cloud-kit" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" -dependencies = [ - "bitflags 2.9.1", - "block2", - "objc2 0.5.2", - "objc2-core-location", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-contacts" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" -dependencies = [ - "block2", - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-core-data" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" -dependencies = [ - "bitflags 2.9.1", - "block2", - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-core-foundation" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" -dependencies = [ - "bitflags 2.9.1", - "dispatch2", - "objc2 0.6.1", -] - -[[package]] -name = "objc2-core-graphics" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" -dependencies = [ - "bitflags 2.9.1", - "dispatch2", - "objc2 0.6.1", - "objc2-core-foundation", - "objc2-io-surface", -] - -[[package]] -name = "objc2-core-image" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" -dependencies = [ - "block2", - "objc2 0.5.2", - "objc2-foundation 0.2.2", - "objc2-metal", -] - -[[package]] -name = "objc2-core-location" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" -dependencies = [ - "block2", - "objc2 0.5.2", - "objc2-contacts", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-encode" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" - -[[package]] -name = "objc2-foundation" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" -dependencies = [ - "bitflags 2.9.1", - "block2", - "dispatch", - "libc", - "objc2 0.5.2", -] - -[[package]] -name = "objc2-foundation" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" -dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-io-surface" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c" -dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-link-presentation" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" -dependencies = [ - "block2", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-metal" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" -dependencies = [ - "bitflags 2.9.1", - "block2", - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-quartz-core" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" -dependencies = [ - "bitflags 2.9.1", - "block2", - "objc2 0.5.2", - "objc2-foundation 0.2.2", - "objc2-metal", -] - -[[package]] -name = "objc2-symbols" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" -dependencies = [ - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-ui-kit" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" -dependencies = [ - "bitflags 2.9.1", - "block2", - "objc2 0.5.2", - "objc2-cloud-kit", - "objc2-core-data", - "objc2-core-image", - "objc2-core-location", - "objc2-foundation 0.2.2", - "objc2-link-presentation", - "objc2-quartz-core", - "objc2-symbols", - "objc2-uniform-type-identifiers", - "objc2-user-notifications", -] - -[[package]] -name = "objc2-uniform-type-identifiers" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" -dependencies = [ - "block2", - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-user-notifications" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" -dependencies = [ - "bitflags 2.9.1", - "block2", - "objc2 0.5.2", - "objc2-core-location", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "orbclient" -version = "0.3.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba0b26cec2e24f08ed8bb31519a9333140a6599b867dac464bb150bdb796fd43" -dependencies = [ - "libredox", -] - -[[package]] -name = "ordered-float" -version = "4.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" -dependencies = [ - "num-traits", -] - -[[package]] -name = "ordered-stream" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" -dependencies = [ - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "owned_ttf_parser" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4" -dependencies = [ - "ttf-parser", -] - -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "parking_lot" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.5.13", - "smallvec", - "windows-targets 0.52.6", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pin-project" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "piper" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - -[[package]] -name = "png" -version = "0.17.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" -dependencies = [ - "bitflags 1.3.2", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", -] - -[[package]] -name = "polling" -version = "3.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b53a684391ad002dd6a596ceb6c74fd004fdce75f4be2e3f615068abbea5fd50" -dependencies = [ - "cfg-if", - "concurrent-queue", - "hermit-abi", - "pin-project-lite", - "rustix 1.0.7", - "tracing", - "windows-sys 0.59.0", -] - -[[package]] -name = "potential_utf" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" -dependencies = [ - "zerovec", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro-crate" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" -dependencies = [ - "toml_edit", -] - -[[package]] -name = "proc-macro2" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "profiling" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" - -[[package]] -name = "quick-xml" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "quick-xml" -version = "0.37.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" -dependencies = [ - "memchr", -] - -[[package]] -name = "quote" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", -] - -[[package]] -name = "raw-window-handle" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" - -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" -dependencies = [ - "bitflags 2.9.1", -] - -[[package]] -name = "renderdoc-sys" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags 2.9.1", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustix" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" -dependencies = [ - "bitflags 2.9.1", - "errno", - "libc", - "linux-raw-sys 0.9.4", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustversion" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "sctk-adwaita" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" -dependencies = [ - "ab_glyph", - "log", - "memmap2", - "smithay-client-toolkit", - "tiny-skia", -] - -[[package]] -name = "serde" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_repr" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" -dependencies = [ - "libc", -] - -[[package]] -name = "simd-adler32" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - -[[package]] -name = "slab" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" - -[[package]] -name = "slotmap" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" -dependencies = [ - "version_check", -] - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "smithay-client-toolkit" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" -dependencies = [ - "bitflags 2.9.1", - "calloop", - "calloop-wayland-source", - "cursor-icon", - "libc", - "log", - "memmap2", - "rustix 0.38.44", - "thiserror 1.0.69", - "wayland-backend", - "wayland-client", - "wayland-csd-frame", - "wayland-cursor", - "wayland-protocols", - "wayland-protocols-wlr", - "wayland-scanner", - "xkeysym", -] - -[[package]] -name = "smithay-clipboard" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc8216eec463674a0e90f29e0ae41a4db573ec5b56b1c6c1c71615d249b6d846" -dependencies = [ - "libc", - "smithay-client-toolkit", - "wayland-backend", -] - -[[package]] -name = "smol_str" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" -dependencies = [ - "serde", -] - -[[package]] -name = "spirv" -version = "0.3.0+sdk-1.3.268.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" -dependencies = [ - "bitflags 2.9.1", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "strict-num" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" - -[[package]] -name = "strum" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn", -] - -[[package]] -name = "syn" -version = "2.0.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tempfile" -version = "3.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" -dependencies = [ - "fastrand", - "getrandom 0.3.3", - "once_cell", - "rustix 1.0.7", - "windows-sys 0.59.0", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - -[[package]] -name = "thiserror" -version = "2.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" -dependencies = [ - "thiserror-impl 2.0.12", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tiff" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" -dependencies = [ - "flate2", - "jpeg-decoder", - "weezl", -] - -[[package]] -name = "tiny-skia" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" -dependencies = [ - "arrayref", - "arrayvec", - "bytemuck", - "cfg-if", - "log", - "tiny-skia-path", -] - -[[package]] -name = "tiny-skia-path" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" -dependencies = [ - "arrayref", - "bytemuck", - "strict-num", -] - -[[package]] -name = "tinystr" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" - -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tracing" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1ffbcf9c6f6b99d386e7444eb608ba646ae452a36b39737deb9663b610f662" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" -dependencies = [ - "once_cell", -] - -[[package]] -name = "ttf-parser" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" - -[[package]] -name = "type-map" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90" -dependencies = [ - "rustc-hash 2.1.1", -] - -[[package]] -name = "typenum" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" - -[[package]] -name = "uds_windows" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" -dependencies = [ - "memoffset", - "tempfile", - "winapi", -] - -[[package]] -name = "unicode-ident" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - -[[package]] -name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - -[[package]] -name = "url" -version = "2.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" -dependencies = [ - "wit-bindgen-rt", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" -dependencies = [ - "cfg-if", - "js-sys", - "once_cell", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "wayland-backend" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe770181423e5fc79d3e2a7f4410b7799d5aab1de4372853de3c6aa13ca24121" -dependencies = [ - "cc", - "downcast-rs", - "rustix 0.38.44", - "scoped-tls", - "smallvec", - "wayland-sys", -] - -[[package]] -name = "wayland-client" -version = "0.31.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978fa7c67b0847dbd6a9f350ca2569174974cd4082737054dbb7fbb79d7d9a61" -dependencies = [ - "bitflags 2.9.1", - "rustix 0.38.44", - "wayland-backend", - "wayland-scanner", -] - -[[package]] -name = "wayland-csd-frame" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" -dependencies = [ - "bitflags 2.9.1", - "cursor-icon", - "wayland-backend", -] - -[[package]] -name = "wayland-cursor" -version = "0.31.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a65317158dec28d00416cb16705934070aef4f8393353d41126c54264ae0f182" -dependencies = [ - "rustix 0.38.44", - "wayland-client", - "xcursor", -] - -[[package]] -name = "wayland-protocols" -version = "0.32.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "779075454e1e9a521794fed15886323ea0feda3f8b0fc1390f5398141310422a" -dependencies = [ - "bitflags 2.9.1", - "wayland-backend", - "wayland-client", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols-plasma" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fd38cdad69b56ace413c6bcc1fbf5acc5e2ef4af9d5f8f1f9570c0c83eae175" -dependencies = [ - "bitflags 2.9.1", - "wayland-backend", - "wayland-client", - "wayland-protocols", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols-wlr" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cb6cdc73399c0e06504c437fe3cf886f25568dd5454473d565085b36d6a8bbf" -dependencies = [ - "bitflags 2.9.1", - "wayland-backend", - "wayland-client", - "wayland-protocols", - "wayland-scanner", -] - -[[package]] -name = "wayland-scanner" -version = "0.31.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "896fdafd5d28145fce7958917d69f2fd44469b1d4e861cb5961bcbeebc6d1484" -dependencies = [ - "proc-macro2", - "quick-xml 0.37.5", - "quote", -] - -[[package]] -name = "wayland-sys" -version = "0.31.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbcebb399c77d5aa9fa5db874806ee7b4eba4e73650948e8f93963f128896615" -dependencies = [ - "dlib", - "log", - "once_cell", - "pkg-config", -] - -[[package]] -name = "web-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webbrowser" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf4f3c0ba838e82b4e5ccc4157003fb8c324ee24c058470ffb82820becbde98" -dependencies = [ - "core-foundation 0.10.1", - "jni", - "log", - "ndk-context", - "objc2 0.6.1", - "objc2-foundation 0.3.1", - "url", - "web-sys", -] - -[[package]] -name = "weezl" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3" - -[[package]] -name = "wgpu" -version = "24.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b0b3436f0729f6cdf2e6e9201f3d39dc95813fad61d826c1ed07918b4539353" -dependencies = [ - "arrayvec", - "bitflags 2.9.1", - "cfg_aliases", - "document-features", - "js-sys", - "log", - "parking_lot", - "profiling", - "raw-window-handle", - "smallvec", - "static_assertions", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "wgpu-core", - "wgpu-hal", - "wgpu-types", -] - -[[package]] -name = "wgpu-core" -version = "24.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f0aa306497a238d169b9dc70659105b4a096859a34894544ca81719242e1499" -dependencies = [ - "arrayvec", - "bit-vec", - "bitflags 2.9.1", - "cfg_aliases", - "document-features", - "indexmap", - "log", - "naga", - "once_cell", - "parking_lot", - "profiling", - "raw-window-handle", - "rustc-hash 1.1.0", - "smallvec", - "thiserror 2.0.12", - "wgpu-hal", - "wgpu-types", -] - -[[package]] -name = "wgpu-hal" -version = "24.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f112f464674ca69f3533248508ee30cb84c67cf06c25ff6800685f5e0294e259" -dependencies = [ - "android_system_properties", - "arrayvec", - "ash", - "bitflags 2.9.1", - "bytemuck", - "cfg_aliases", - "core-graphics-types", - "glow", - "glutin_wgl_sys", - "gpu-alloc", - "gpu-descriptor", - "js-sys", - "khronos-egl", - "libc", - "libloading", - "log", - "metal", - "naga", - "ndk-sys 0.5.0+25.2.9519653", - "objc", - "once_cell", - "ordered-float", - "parking_lot", - "profiling", - "raw-window-handle", - "renderdoc-sys", - "rustc-hash 1.1.0", - "smallvec", - "thiserror 2.0.12", - "wasm-bindgen", - "web-sys", - "wgpu-types", - "windows", -] - -[[package]] -name = "wgpu-types" -version = "24.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50ac044c0e76c03a0378e7786ac505d010a873665e2d51383dcff8dd227dc69c" -dependencies = [ - "bitflags 2.9.1", - "js-sys", - "log", - "web-sys", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" -dependencies = [ - "windows-core", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-result", - "windows-strings", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-implement" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-interface" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-result" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-strings" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" -dependencies = [ - "windows-result", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" -dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - -[[package]] -name = "winit" -version = "0.30.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4409c10174df8779dc29a4788cac85ed84024ccbc1743b776b21a520ee1aaf4" -dependencies = [ - "ahash", - "android-activity", - "atomic-waker", - "bitflags 2.9.1", - "block2", - "bytemuck", - "calloop", - "cfg_aliases", - "concurrent-queue", - "core-foundation 0.9.4", - "core-graphics", - "cursor-icon", - "dpi", - "js-sys", - "libc", - "memmap2", - "ndk", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", - "objc2-ui-kit", - "orbclient", - "percent-encoding", - "pin-project", - "raw-window-handle", - "redox_syscall 0.4.1", - "rustix 0.38.44", - "sctk-adwaita", - "smithay-client-toolkit", - "smol_str", - "tracing", - "unicode-segmentation", - "wasm-bindgen", - "wasm-bindgen-futures", - "wayland-backend", - "wayland-client", - "wayland-protocols", - "wayland-protocols-plasma", - "web-sys", - "web-time", - "windows-sys 0.52.0", - "x11-dl", - "x11rb", - "xkbcommon-dl", -] - -[[package]] -name = "winnow" -version = "0.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" -dependencies = [ - "memchr", -] - -[[package]] -name = "wit-bindgen-rt" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.1", -] - -[[package]] -name = "writeable" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" - -[[package]] -name = "x11-dl" -version = "2.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" -dependencies = [ - "libc", - "once_cell", - "pkg-config", -] - -[[package]] -name = "x11rb" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" -dependencies = [ - "as-raw-xcb-connection", - "gethostname", - "libc", - "libloading", - "once_cell", - "rustix 0.38.44", - "x11rb-protocol", -] - -[[package]] -name = "x11rb-protocol" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" - -[[package]] -name = "xcursor" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" - -[[package]] -name = "xdg-home" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "xkbcommon-dl" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" -dependencies = [ - "bitflags 2.9.1", - "dlib", - "log", - "once_cell", - "xkeysym", -] - -[[package]] -name = "xkeysym" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" - -[[package]] -name = "xml-rs" -version = "0.8.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62ce76d9b56901b19a74f19431b0d8b3bc7ca4ad685a746dfd78ca8f4fc6bda" - -[[package]] -name = "yoke" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zbus" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725" -dependencies = [ - "async-broadcast", - "async-executor", - "async-fs", - "async-io", - "async-lock", - "async-process", - "async-recursion", - "async-task", - "async-trait", - "blocking", - "enumflags2", - "event-listener", - "futures-core", - "futures-sink", - "futures-util", - "hex", - "nix", - "ordered-stream", - "rand", - "serde", - "serde_repr", - "sha1", - "static_assertions", - "tracing", - "uds_windows", - "windows-sys 0.52.0", - "xdg-home", - "zbus_macros", - "zbus_names", - "zvariant", -] - -[[package]] -name = "zbus-lockstep" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca2c5dceb099bddaade154055c926bb8ae507a18756ba1d8963fd7b51d8ed1d" -dependencies = [ - "zbus_xml", - "zvariant", -] - -[[package]] -name = "zbus-lockstep-macros" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "709ab20fc57cb22af85be7b360239563209258430bccf38d8b979c5a2ae3ecce" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "zbus-lockstep", - "zbus_xml", - "zvariant", -] - -[[package]] -name = "zbus_macros" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", - "zvariant_utils", -] - -[[package]] -name = "zbus_names" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" -dependencies = [ - "serde", - "static_assertions", - "zvariant", -] - -[[package]] -name = "zbus_xml" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3f374552b954f6abb4bd6ce979e6c9b38fb9d0cd7cc68a7d796e70c9f3a233" -dependencies = [ - "quick-xml 0.30.0", - "serde", - "static_assertions", - "zbus_names", - "zvariant", -] - -[[package]] -name = "zerocopy" -version = "0.8.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerotrie" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zvariant" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe" -dependencies = [ - "endi", - "enumflags2", - "serde", - "static_assertions", - "zvariant_derive", -] - -[[package]] -name = "zvariant_derive" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", - "zvariant_utils", -] - -[[package]] -name = "zvariant_utils" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/dsa_editor/Cargo.toml b/dsa_editor/Cargo.toml deleted file mode 100644 index adfbc95..0000000 --- a/dsa_editor/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "dsa_editor" -version = "0.1.0" -edition = "2024" -description = "a fork of a code editor egui widget adapted to work with DSA syntax." - -[dependencies] -egui = { version = "0.31", optional = true } -serde = { version = "1", optional = true } - -[lib] -name = "dsa_editor" -path = "src/lib.rs" - -[features] -default = ["egui", "editor"] -egui = ["dep:egui"] -editor = [] -serde = ["dep:serde"] - -[dev-dependencies] -eframe = "0.31" -colorful = "0.3" diff --git a/dsa_editor/src/highlighting.rs b/dsa_editor/src/highlighting.rs deleted file mode 100644 index 26380f5..0000000 --- a/dsa_editor/src/highlighting.rs +++ /dev/null @@ -1,253 +0,0 @@ -#[cfg(feature = "editor")] -use super::Editor; - -use super::syntax::{QUOTES, SEPARATORS, Syntax, TokenType}; -use std::mem; - -#[derive(Default, Debug, PartialEq, PartialOrd, Eq, Ord)] -/// Lexer and Token -pub struct Token { - ty: TokenType, - buffer: String, -} - -impl Token { - pub fn new>(ty: TokenType, buffer: S) -> Self { - Token { - ty, - buffer: buffer.into(), - } - } - pub fn ty(&self) -> TokenType { - self.ty - } - pub fn buffer(&self) -> &str { - &self.buffer - } - - fn first(&mut self, c: char, syntax: &Syntax) -> Option { - self.buffer.push(c); - let mut token = None; - self.ty = match c { - c if c.is_whitespace() => { - self.ty = TokenType::Whitespace(c); - token = self.drain(self.ty); - TokenType::Whitespace(c) - } - c if syntax.is_keyword(c.to_string().as_str()) => TokenType::Keyword, - c if syntax.is_type(c.to_string().as_str()) => TokenType::Type, - c if syntax.is_special(c.to_string().as_str()) => TokenType::Special, - c if syntax.comment == c.to_string().as_str() => TokenType::Comment(false), - c if syntax.comment_multiline[0] == c.to_string().as_str() => { - TokenType::Comment(true) - } - _ => TokenType::from(c), - }; - token - } - - fn drain(&mut self, ty: TokenType) -> Option { - let mut token = None; - if !self.buffer().is_empty() { - token = Some(Token { - buffer: mem::take(&mut self.buffer), - ty: self.ty, - }); - } - self.ty = ty; - token - } - - fn push_drain(&mut self, c: char, ty: TokenType) -> Option { - self.buffer.push(c); - self.drain(ty) - } - - fn drain_push(&mut self, c: char, ty: TokenType) -> Option { - let token = self.drain(self.ty); - self.buffer.push(c); - self.ty = ty; - token - } - - #[cfg(feature = "egui")] - /// Syntax highlighting - pub fn highlight(&mut self, editor: &T, text: &str) -> LayoutJob { - *self = Token::default(); - let mut job = LayoutJob::default(); - for c in text.chars() { - for token in self.automata(c, editor.syntax()) { - editor.append(&mut job, &token); - } - } - editor.append(&mut job, self); - job - } - - /// Lexer - pub fn tokens(&mut self, syntax: &Syntax, text: &str) -> Vec { - let mut tokens: Vec = text - .chars() - .flat_map(|c| self.automata(c, syntax)) - .collect(); - - if !self.buffer.is_empty() { - tokens.push(mem::take(self)); - } - tokens - } - - fn automata(&mut self, c: char, syntax: &Syntax) -> Vec { - use TokenType as Ty; - let mut tokens = vec![]; - match (self.ty, Ty::from(c)) { - (Ty::Comment(false), Ty::Whitespace('\n')) => { - self.buffer.push(c); - let n = self.buffer.pop(); - tokens.extend(self.drain(Ty::Whitespace(c))); - if let Some(n) = n { - tokens.extend(self.push_drain(n, self.ty)); - } - } - (Ty::Comment(false), _) => { - self.buffer.push(c); - } - (Ty::Comment(true), _) => { - self.buffer.push(c); - if self.buffer.ends_with(syntax.comment_multiline[1]) { - tokens.extend(self.drain(Ty::Unknown)); - } - } - (Ty::Literal | Ty::Punctuation(_), Ty::Whitespace(_)) => { - tokens.extend(self.drain(Ty::Whitespace(c))); - tokens.extend(self.first(c, syntax)); - } - (Ty::Hyperlink, Ty::Whitespace(_)) => { - tokens.extend(self.drain(Ty::Whitespace(c))); - tokens.extend(self.first(c, syntax)); - } - (Ty::Hyperlink, _) => { - self.buffer.push(c); - } - (Ty::Literal, _) => match c { - c if c == '(' => { - self.ty = Ty::Function; - tokens.extend(self.drain(Ty::Punctuation(c))); - tokens.extend(self.push_drain(c, Ty::Unknown)); - } - c if !c.is_alphanumeric() && !SEPARATORS.contains(&c) => { - tokens.extend(self.drain(self.ty)); - self.buffer.push(c); - self.ty = if QUOTES.contains(&c) { - Ty::Str(c) - } else { - Ty::Punctuation(c) - }; - } - _ => { - self.buffer.push(c); - self.ty = { - if self.buffer.starts_with(syntax.comment) { - Ty::Comment(false) - } else if self.buffer.starts_with(syntax.comment_multiline[0]) { - Ty::Comment(true) - } else if syntax.is_hyperlink(&self.buffer) { - Ty::Hyperlink - } else if syntax.is_keyword(&self.buffer) { - Ty::Keyword - } else if syntax.is_type(&self.buffer) { - Ty::Type - } else if syntax.is_special(&self.buffer) { - Ty::Special - } else { - Ty::Literal - } - }; - } - }, - (Ty::Numeric(false), Ty::Punctuation('.')) => { - self.buffer.push(c); - self.ty = Ty::Numeric(true); - } - (Ty::Numeric(_), Ty::Numeric(_)) => { - self.buffer.push(c); - } - (Ty::Numeric(_), Ty::Literal) => { - tokens.extend(self.drain(self.ty)); - self.buffer.push(c); - } - (Ty::Numeric(_), _) | (Ty::Punctuation(_), Ty::Literal | Ty::Numeric(_)) => { - tokens.extend(self.drain(self.ty)); - tokens.extend(self.first(c, syntax)); - } - (Ty::Punctuation(_), Ty::Str(_)) => { - tokens.extend(self.drain_push(c, Ty::Str(c))); - } - (Ty::Punctuation(_), _) => { - if !(syntax.comment.starts_with(&self.buffer) - || syntax.comment_multiline[0].starts_with(&self.buffer)) - { - tokens.extend(self.drain(self.ty)); - tokens.extend(self.first(c, syntax)); - } else { - self.buffer.push(c); - if self.buffer.starts_with(syntax.comment) { - self.ty = Ty::Comment(false); - } else if self.buffer.starts_with(syntax.comment_multiline[0]) { - self.ty = Ty::Comment(true); - } else if let Some(c) = self.buffer.pop() { - tokens.extend(self.drain(Ty::Punctuation(c))); - tokens.extend(self.first(c, syntax)); - } - } - } - (Ty::Str(q), _) => { - let control = self.buffer.ends_with('\\'); - self.buffer.push(c); - if c == q && !control { - tokens.extend(self.drain(Ty::Unknown)); - } - } - (Ty::Whitespace(_) | Ty::Unknown, _) => { - tokens.extend(self.first(c, syntax)); - } - // Keyword, Type, Special - (_reserved, Ty::Literal | Ty::Numeric(_)) => { - self.buffer.push(c); - self.ty = if syntax.is_keyword(&self.buffer) { - Ty::Keyword - } else if syntax.is_type(&self.buffer) { - Ty::Type - } else if syntax.is_special(&self.buffer) { - Ty::Special - } else { - Ty::Literal - }; - } - (reserved, _) => { - self.ty = reserved; - tokens.extend(self.drain(self.ty)); - tokens.extend(self.first(c, syntax)); - } - } - tokens - } -} - -#[cfg(feature = "egui")] -use egui::text::LayoutJob; - -#[cfg(feature = "egui")] -impl egui::util::cache::ComputerMut<(&T, &str), LayoutJob> for Token { - fn compute(&mut self, (cache, text): (&T, &str)) -> LayoutJob { - self.highlight(cache, text) - } -} - -#[cfg(feature = "egui")] -pub type HighlightCache = egui::util::cache::FrameCache; - -#[cfg(feature = "egui")] -pub fn highlight(ctx: &egui::Context, cache: &T, text: &str) -> LayoutJob { - ctx.memory_mut(|mem| mem.caches.cache::().get((cache, text))) -} diff --git a/dsa_editor/src/lib.rs b/dsa_editor/src/lib.rs deleted file mode 100644 index e9dd0ad..0000000 --- a/dsa_editor/src/lib.rs +++ /dev/null @@ -1,296 +0,0 @@ -pub mod highlighting; -mod syntax; -mod themes; - -#[cfg(feature = "egui")] -use egui::text::LayoutJob; -#[cfg(feature = "egui")] -use egui::widgets::text_edit::TextEditOutput; -pub use highlighting::Token; -#[cfg(feature = "egui")] -use highlighting::highlight; -#[cfg(feature = "editor")] -use std::hash::{Hash, Hasher}; -pub use syntax::{Syntax, TokenType}; -pub use themes::ColorTheme; -pub use themes::DEFAULT_THEMES; - -#[cfg(feature = "egui")] -pub trait Editor: Hash { - fn append(&self, job: &mut LayoutJob, token: &Token); - fn syntax(&self) -> &Syntax; -} - -#[cfg(feature = "editor")] -#[derive(Clone, Debug, PartialEq)] -/// CodeEditor struct which stores settings for highlighting. -pub struct CodeEditor { - id: String, - theme: ColorTheme, - syntax: Syntax, - numlines: bool, - numlines_shift: isize, - numlines_only_natural: bool, - fontsize: f32, - rows: usize, - stick_to_bottom: bool, - desired_width: f32, -} - -#[cfg(feature = "editor")] -impl Hash for CodeEditor { - fn hash(&self, state: &mut H) { - self.theme.hash(state); - #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)] - (self.fontsize as u32).hash(state); - self.syntax.hash(state); - } -} - -#[cfg(feature = "editor")] -impl Default for CodeEditor { - fn default() -> CodeEditor { - CodeEditor { - id: String::from("Code Editor"), - theme: ColorTheme::THEME, - syntax: Syntax::dsa(), - numlines: true, - numlines_shift: 0, - numlines_only_natural: false, - fontsize: 10.0, - rows: 10, - stick_to_bottom: false, - desired_width: f32::INFINITY, - } - } -} - -#[cfg(feature = "editor")] -impl CodeEditor { - pub fn id_source(self, id_source: impl Into) -> Self { - CodeEditor { - id: id_source.into(), - ..self - } - } - - /// Minimum number of rows to show. - /// - /// **Default: 10** - pub fn with_rows(self, rows: usize) -> Self { - CodeEditor { rows, ..self } - } - - /// Use custom Color Theme - /// - /// **Default: Gruvbox** - pub fn with_theme(self, theme: ColorTheme) -> Self { - CodeEditor { theme, ..self } - } - - /// Use custom font size - /// - /// **Default: 10.0** - pub fn with_fontsize(self, fontsize: f32) -> Self { - CodeEditor { fontsize, ..self } - } - - #[cfg(feature = "egui")] - /// Use UI font size - pub fn with_ui_fontsize(self, ui: &mut egui::Ui) -> Self { - CodeEditor { - fontsize: egui::TextStyle::Monospace.resolve(ui.style()).size, - ..self - } - } - - /// Show or hide lines numbering - /// - /// **Default: true** - pub fn with_numlines(self, numlines: bool) -> Self { - CodeEditor { numlines, ..self } - } - - /// Shift lines numbering by this value - /// - /// **Default: 0** - pub fn with_numlines_shift(self, numlines_shift: isize) -> Self { - CodeEditor { - numlines_shift, - ..self - } - } - - /// Show lines numbering only above zero, useful for enabling numbering since nth row - /// - /// **Default: false** - pub fn with_numlines_only_natural(self, numlines_only_natural: bool) -> Self { - CodeEditor { - numlines_only_natural, - ..self - } - } - - /// Use custom syntax for highlighting - /// - /// **Default: Rust** - pub fn with_syntax(self, syntax: Syntax) -> Self { - CodeEditor { syntax, ..self } - } - - /// Should the containing area shrink if the content is small? - /// - /// **Default: false** - pub fn auto_shrink(self, shrink: bool) -> Self { - CodeEditor { - desired_width: if shrink { 0.0 } else { self.desired_width }, - ..self - } - } - - /// Sets the desired width of the code editor - /// - /// **Default: `f32::INFINITY`** - pub fn desired_width(self, width: f32) -> Self { - CodeEditor { - desired_width: width, - ..self - } - } - - /// Stick to bottom - /// The scroll handle will stick to the bottom position even while the content size - /// changes dynamically. This can be useful to simulate terminal UIs or log/info scrollers. - /// The scroll handle remains stuck until user manually changes position. Once "unstuck" - /// it will remain focused on whatever content viewport the user left it on. If the scroll - /// handle is dragged to the bottom it will again become stuck and remain there until manually - /// pulled from the end position. - /// - /// **Default: false** - pub fn stick_to_bottom(self, stick_to_bottom: bool) -> Self { - CodeEditor { - stick_to_bottom, - ..self - } - } - - #[cfg(feature = "egui")] - pub fn format(&self, ty: TokenType) -> egui::text::TextFormat { - let font_id = egui::FontId::monospace(self.fontsize); - let color = self.theme.type_color(ty); - egui::text::TextFormat::simple(font_id, color) - } - - #[cfg(feature = "egui")] - fn numlines_show(&self, ui: &mut egui::Ui, text: &str) { - let total = if text.ends_with('\n') || text.is_empty() { - text.lines().count() + 1 - } else { - text.lines().count() - } - .max(self.rows) as isize; - let max_indent = total.to_string().len().max( - !self.numlines_only_natural as usize * self.numlines_shift.to_string().len(), - ); - let mut counter = (1..=total) - .map(|i| { - let num = i + self.numlines_shift; - if num <= 0 && self.numlines_only_natural { - String::new() - } else { - let label = num.to_string(); - format!( - "{}{label}", - " ".repeat(max_indent.saturating_sub(label.len())) - ) - } - }) - .collect::>() - .join("\n"); - - #[allow(clippy::cast_precision_loss)] - let width = max_indent as f32 - * self.fontsize - * 0.5 - * !(total + self.numlines_shift <= 0 && self.numlines_only_natural) as u8 - as f32; - - let mut layouter = |ui: &egui::Ui, string: &str, _wrap_width: f32| { - let layout_job = egui::text::LayoutJob::single_section( - string.to_string(), - egui::TextFormat::simple( - egui::FontId::monospace(self.fontsize), - self.theme.type_color(TokenType::Comment(true)), - ), - ); - ui.fonts(|f| f.layout_job(layout_job)) - }; - - ui.add( - egui::TextEdit::multiline(&mut counter) - .id_source(format!("{}_numlines", self.id)) - .font(egui::TextStyle::Monospace) - .interactive(false) - .frame(false) - .desired_rows(self.rows) - .desired_width(width) - .layouter(&mut layouter), - ); - } - - #[cfg(feature = "egui")] - /// Show Code Editor - pub fn show( - &mut self, - ui: &mut egui::Ui, - text: &mut dyn egui::TextBuffer, - ) -> TextEditOutput { - let mut text_edit_output: Option = None; - let code_editor = |ui: &mut egui::Ui| { - ui.horizontal_top(|h| { - self.theme.modify_style(h, self.fontsize); - if self.numlines { - self.numlines_show(h, text.as_str()); - } - egui::ScrollArea::horizontal() - .hscroll(true) - .id_salt(format!("{}_inner_scroll", self.id)) - .show(h, |ui| { - let mut layouter = - |ui: &egui::Ui, string: &str, _wrap_width: f32| { - let layout_job = highlight(ui.ctx(), self, string); - ui.fonts(|f| f.layout_job(layout_job)) - }; - let output = egui::TextEdit::multiline(text) - .id_source(&self.id) - .lock_focus(true) - .desired_rows(self.rows) - .frame(false) - .desired_width(self.desired_width) - .layouter(&mut layouter) - .show(ui); - text_edit_output = Some(output); - }); - }); - }; - - egui::ScrollArea::vertical() - .id_salt(format!("{}_outer_scroll", self.id)) - .stick_to_bottom(self.stick_to_bottom) - .show(ui, code_editor); - - text_edit_output.expect("TextEditOutput should exist at this point") - } -} - -#[cfg(feature = "editor")] -#[cfg(feature = "egui")] -impl Editor for CodeEditor { - fn append(&self, job: &mut LayoutJob, token: &Token) { - job.append(token.buffer(), 0.0, self.format(token.ty())); - } - - fn syntax(&self) -> &Syntax { - &self.syntax - } -} diff --git a/dsa_editor/src/syntax/dsa.rs b/dsa_editor/src/syntax/dsa.rs deleted file mode 100644 index 4e6815e..0000000 --- a/dsa_editor/src/syntax/dsa.rs +++ /dev/null @@ -1,29 +0,0 @@ -use super::Syntax; -use std::collections::BTreeSet; - -impl Syntax { - pub fn dsa() -> Self { - Syntax { - language: "Assembly", - case_sensitive: false, - comment: "//", - comment_multiline: ["/*", "*/"], - hyperlinks: BTreeSet::from(["http"]), - keywords: BTreeSet::from([ - "nop", "mov", "movs", "ldb", "ldbs", "ldh", "ldhs", "ldw", "stb", "sth", - "stw", "lli", "lui", "jmp", "jeq", "jne", "jgt", "jge", "jlt", "jle", - "cmp", "inc", "dec", "shl", "shr", "add", "sub", "and", "or", "not", - "xor", "nand", "nor", "xnor", "irt", "int", "hlt", - // pseduo-instructions - "db", "dh", "dw", "resb", "resh", "resw", "push", "pop", "lwi", "call", - "include", - ]), - types: BTreeSet::from([]), - special: BTreeSet::from([ - "rg0", "rg1", "rg2", "rg3", "rg4", "rg5", "rg6", "rg7", "rg8", "rg9", - "rga", "rgb", "rgc", "rgd", "rge", "rgf", "acc", "spr", "bpr", "ret", - "idr", "mmr", "zero", "null", "pcx", "mdr", "mar", "sts", "cir", - ]), - } - } -} diff --git a/dsa_editor/src/syntax/mod.rs b/dsa_editor/src/syntax/mod.rs deleted file mode 100644 index 12986f2..0000000 --- a/dsa_editor/src/syntax/mod.rs +++ /dev/null @@ -1,204 +0,0 @@ -#![allow(dead_code)] -pub mod dsa; - -use std::collections::BTreeSet; -use std::hash::{Hash, Hasher}; - -pub const SEPARATORS: [char; 1] = ['_']; -pub const QUOTES: [char; 3] = ['\'', '"', '`']; - -type MultiLine = bool; -type Float = bool; - -#[derive(Default, Clone, Copy, PartialEq, PartialOrd, Eq, Ord)] -#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] -pub enum TokenType { - Comment(MultiLine), - Function, - Keyword, - Literal, - Hyperlink, - Numeric(Float), - Punctuation(char), - Special, - Str(char), - Type, - Whitespace(char), - #[default] - Unknown, -} -impl std::fmt::Debug for TokenType { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let mut name = String::new(); - match &self { - TokenType::Comment(multiline) => { - name.push_str("Comment"); - { - if *multiline { - name.push_str(" MultiLine"); - } else { - name.push_str(" SingleLine"); - } - } - } - TokenType::Function => name.push_str("Function"), - TokenType::Keyword => name.push_str("Keyword"), - TokenType::Literal => name.push_str("Literal"), - TokenType::Hyperlink => name.push_str("Hyperlink"), - TokenType::Numeric(float) => { - name.push_str("Numeric"); - if *float { - name.push_str(" Float"); - } else { - name.push_str(" Integer"); - } - } - TokenType::Punctuation(_) => name.push_str("Punctuation"), - TokenType::Special => name.push_str("Special"), - TokenType::Str(quote) => { - name.push_str("Str "); - name.push(*quote); - } - TokenType::Type => name.push_str("Type"), - TokenType::Whitespace(c) => { - name.push_str("Whitespace"); - match c { - ' ' => name.push_str(" Space"), - '\t' => name.push_str(" Tab"), - '\n' => name.push_str(" New Line"), - _ => (), - }; - } - TokenType::Unknown => name.push_str("Unknown"), - }; - write!(f, "{name}") - } -} -impl From for TokenType { - fn from(c: char) -> Self { - match c { - c if c.is_whitespace() => TokenType::Whitespace(c), - c if QUOTES.contains(&c) => TokenType::Str(c), - c if c.is_numeric() => TokenType::Numeric(false), - c if c.is_alphabetic() || SEPARATORS.contains(&c) => TokenType::Literal, - c if c.is_ascii_punctuation() => TokenType::Punctuation(c), - _ => TokenType::Unknown, - } - } -} - -#[derive(Clone, Debug, PartialEq)] -/// Rules for highlighting. -pub struct Syntax { - pub language: &'static str, - pub case_sensitive: bool, - pub comment: &'static str, - pub comment_multiline: [&'static str; 2], - pub hyperlinks: BTreeSet<&'static str>, - pub keywords: BTreeSet<&'static str>, - pub types: BTreeSet<&'static str>, - pub special: BTreeSet<&'static str>, -} -impl Default for Syntax { - fn default() -> Self { - Syntax::dsa() - } -} -impl Hash for Syntax { - fn hash(&self, state: &mut H) { - self.language.hash(state); - } -} -impl Syntax { - pub fn new(language: &'static str) -> Self { - Syntax { - language, - ..Default::default() - } - } - pub fn with_case_sensitive(self, case_sensitive: bool) -> Self { - Syntax { - case_sensitive, - ..self - } - } - pub fn with_comment(self, comment: &'static str) -> Self { - Syntax { comment, ..self } - } - pub fn with_comment_multiline(self, comment_multiline: [&'static str; 2]) -> Self { - Syntax { - comment_multiline, - ..self - } - } - pub fn with_hyperlinks>>(self, hyperlinks: T) -> Self { - Syntax { - hyperlinks: hyperlinks.into(), - ..self - } - } - pub fn with_keywords>>(self, keywords: T) -> Self { - Syntax { - keywords: keywords.into(), - ..self - } - } - pub fn with_types>>(self, types: T) -> Self { - Syntax { - types: types.into(), - ..self - } - } - pub fn with_special>>(self, special: T) -> Self { - Syntax { - special: special.into(), - ..self - } - } - - pub fn language(&self) -> &str { - self.language - } - pub fn comment(&self) -> &str { - self.comment - } - pub fn is_hyperlink(&self, word: &str) -> bool { - self.hyperlinks.contains(word.to_ascii_lowercase().as_str()) - } - pub fn is_keyword(&self, word: &str) -> bool { - if self.case_sensitive { - self.keywords.contains(&word) - } else { - self.keywords.contains(word.to_ascii_lowercase().as_str()) - } - } - pub fn is_type(&self, word: &str) -> bool { - if self.case_sensitive { - self.types.contains(&word) - } else { - self.types.contains(word.to_ascii_lowercase().as_str()) - } - } - pub fn is_special(&self, word: &str) -> bool { - if self.case_sensitive { - self.special.contains(&word) - } else { - self.special.contains(word.to_ascii_lowercase().as_str()) - } - } -} - -impl Syntax { - pub fn simple(comment: &'static str) -> Self { - Syntax { - language: "", - case_sensitive: false, - comment, - comment_multiline: [comment; 2], - hyperlinks: BTreeSet::new(), - keywords: BTreeSet::new(), - types: BTreeSet::new(), - special: BTreeSet::new(), - } - } -} diff --git a/dsa_editor/src/themes/mod.rs b/dsa_editor/src/themes/mod.rs deleted file mode 100644 index c126748..0000000 --- a/dsa_editor/src/themes/mod.rs +++ /dev/null @@ -1,147 +0,0 @@ -#![allow(dead_code)] -pub mod theme; - -use super::syntax::TokenType; -#[cfg(feature = "egui")] -use egui::Color32; - -#[cfg(feature = "egui")] -pub const ERROR_COLOR: Color32 = Color32::from_rgb(255, 0, 255); - -/// Array of default themes. -pub const DEFAULT_THEMES: [ColorTheme; 1] = [ColorTheme::THEME]; - -#[cfg(feature = "egui")] -fn color_from_hex(hex: &str) -> Option { - if hex == "none" { - return Some(Color32::from_rgba_premultiplied(255, 0, 255, 0)); - } - let rgb = (1..hex.len()) - .step_by(2) - .filter_map(|i| u8::from_str_radix(&hex[i..i + 2], 16).ok()) - .collect::>(); - let color = Color32::from_rgb(*rgb.first()?, *rgb.get(1)?, *rgb.get(2)?); - Some(color) -} - -#[derive(Hash, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -/// Colors in hexadecimal notation as used in HTML and CSS. -pub struct ColorTheme { - pub name: &'static str, - pub dark: bool, - pub bg: &'static str, - pub cursor: &'static str, - pub selection: &'static str, - pub comments: &'static str, - pub functions: &'static str, - pub keywords: &'static str, - pub literals: &'static str, - pub numerics: &'static str, - pub punctuation: &'static str, - pub strs: &'static str, - pub types: &'static str, - pub special: &'static str, -} - -impl Default for ColorTheme { - fn default() -> Self { - ColorTheme::THEME - } -} -impl ColorTheme { - pub fn name(&self) -> &str { - self.name - } - - pub fn is_dark(&self) -> bool { - self.dark - } - - #[cfg(feature = "egui")] - pub fn bg(&self) -> Color32 { - color_from_hex(self.bg).unwrap_or(ERROR_COLOR) - } - - #[cfg(feature = "egui")] - pub fn cursor(&self) -> Color32 { - color_from_hex(self.cursor).unwrap_or(ERROR_COLOR) - } - - #[cfg(feature = "egui")] - pub fn selection(&self) -> Color32 { - color_from_hex(self.selection).unwrap_or(ERROR_COLOR) - } - - #[cfg(feature = "egui")] - pub fn modify_style(&self, ui: &mut egui::Ui, fontsize: f32) { - let style = ui.style_mut(); - style.visuals.widgets.noninteractive.bg_fill = self.bg(); - style.visuals.window_fill = self.bg(); - style.visuals.selection.stroke.color = self.cursor(); - style.visuals.selection.bg_fill = self.selection(); - style.visuals.extreme_bg_color = self.bg(); - style.override_font_id = Some(egui::FontId::monospace(fontsize)); - style.visuals.text_cursor.stroke.width = fontsize * 0.1; - } - - pub const fn type_color_str(&self, ty: TokenType) -> &'static str { - match ty { - TokenType::Comment(_) => self.comments, - TokenType::Function => self.functions, - TokenType::Keyword => self.keywords, - TokenType::Literal => self.literals, - TokenType::Hyperlink => self.special, - TokenType::Numeric(_) => self.numerics, - TokenType::Punctuation(_) => self.punctuation, - TokenType::Special => self.special, - TokenType::Str(_) => self.strs, - TokenType::Type => self.types, - TokenType::Whitespace(_) | TokenType::Unknown => self.comments, - } - } - - #[cfg(feature = "egui")] - pub fn type_color(&self, ty: TokenType) -> Color32 { - match ty { - TokenType::Comment(_) => color_from_hex(self.comments), - TokenType::Function => color_from_hex(self.functions), - TokenType::Keyword => color_from_hex(self.keywords), - TokenType::Literal => color_from_hex(self.literals), - TokenType::Hyperlink => color_from_hex(self.special), - TokenType::Numeric(_) => color_from_hex(self.numerics), - TokenType::Punctuation(_) => color_from_hex(self.punctuation), - TokenType::Special => color_from_hex(self.special), - TokenType::Str(_) => color_from_hex(self.strs), - TokenType::Type => color_from_hex(self.types), - TokenType::Whitespace(_) | TokenType::Unknown => { - color_from_hex(self.comments) - } - } - .unwrap_or(ERROR_COLOR) - } - - pub fn monocolor( - dark: bool, - bg: &'static str, - fg: &'static str, - cursor: &'static str, - selection: &'static str, - ) -> Self { - ColorTheme { - name: "monocolor", - dark, - bg, - cursor, - selection, - literals: fg, - numerics: fg, - keywords: fg, - functions: fg, - punctuation: fg, - types: fg, - strs: fg, - comments: fg, - special: fg, - } - } -} diff --git a/dsa_editor/src/themes/theme.rs b/dsa_editor/src/themes/theme.rs deleted file mode 100644 index 757264d..0000000 --- a/dsa_editor/src/themes/theme.rs +++ /dev/null @@ -1,22 +0,0 @@ -use super::ColorTheme; - -impl ColorTheme { - /// Author : Jakub Bartodziej - /// Theme uses the gruvbox dark palette with standard contrast - pub const THEME: ColorTheme = ColorTheme { - name: "Theme", - dark: true, - bg: "#1b1b1b", - cursor: "#de5252", // fg4 - selection: "#28323B", // bg2 - comments: "#444444", // gray1 - functions: "#7CCCC7", // green1 - keywords: "#6C81E0", // red1 - literals: "#A3ABFF", // fg1 - numerics: "#8A46CF", // purple1 - punctuation: "#99C9C9", // orange1 - strs: "#618c84", // aqua1 - types: "#B8B9D4", // yellow1 - special: "#de5252", // blue1 - }; -} diff --git a/emulator/Cargo.toml b/emulator/Cargo.toml deleted file mode 100644 index 23f7142..0000000 --- a/emulator/Cargo.toml +++ /dev/null @@ -1,42 +0,0 @@ -[package] -name = "emulator" -version = "0.1.0" -edition = "2024" -default-run = "emulator" - -[lib] -name = "dsa_rs" -path = "src/lib.rs" -crate-type = ["cdylib", "rlib"] - -[[bin]] -name = "emulator" -required-features = ["config"] - -[dependencies] -common = { path = "../common" } -assembler = { path = "../assembler" } -dsa_editor = { path = "../dsa_editor" } -egui = "0.31.1" -dirs = "6.0.0" -discord-presence = { version = "1.6.0", optional = true } -toml = { version = "0.8.23", optional = true } -serde = { version = "1.0.219", features = ["derive"], optional = true } -egui_file = "0.22.1" - -[features] -default = ["config"] -discord-rpc = ["dep:discord-presence"] -config = ["dep:toml", "dep:serde"] - -# Add support for Android for the fun of it. Currently crashes lol. -[target.'cfg(target_os = "android")'.dependencies] -winit = { version = "0.30.11", features = ["android-native-activity"] } -# jni = "0.21.1" - -[target.'cfg(target_os = "android")'.dependencies.eframe] -version = "0.31.1" -features = ["android-native-activity"] - -[target.'cfg(not(target_os = "android"))'.dependencies.eframe] -version = "0.31.1" diff --git a/emulator/src/emulator/config.rs b/emulator/src/emulator/config.rs deleted file mode 100644 index bf7d83a..0000000 --- a/emulator/src/emulator/config.rs +++ /dev/null @@ -1,38 +0,0 @@ -//! Loads configuration information from a TOML file in the current working directory. -//! Currently doesn't do much but this may be expanded. - -use std::path::Path; - -use serde::Deserialize; - -#[derive(Deserialize, Default)] -pub struct Config { - pub misc: MiscTable, -} - -/// For config options where you aren't sure what table it should go under. -#[derive(Deserialize, Default)] -pub struct MiscTable { - /// Whether or not we can enable Discord RPC for fun. - #[cfg(feature = "discord-rpc")] - pub use_discord_rpc: bool, -} - -impl Config { - pub fn load(path: &Path) -> Result { - let file_contents = match std::fs::read_to_string(path) { - Ok(file_contents) => file_contents, - Err(why) => { - eprintln!( - "WARN: Expected to read config file from '{}' with error '{}'. Using default settings.", - path.display(), - why - ); - - return Ok(Self::default()); - } - }; - - Self::deserialize(toml::Deserializer::new(&file_contents)) - } -} diff --git a/emulator/src/emulator/misc/mod.rs b/emulator/src/emulator/misc/mod.rs deleted file mode 100644 index 06a3fd0..0000000 --- a/emulator/src/emulator/misc/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod rpc; diff --git a/emulator/src/emulator/misc/rpc.rs b/emulator/src/emulator/misc/rpc.rs deleted file mode 100644 index 3ef47e3..0000000 --- a/emulator/src/emulator/misc/rpc.rs +++ /dev/null @@ -1,221 +0,0 @@ -//! Just for fun I thought I would add a Discord RPC client to the emulator. -//! -//! This will display information like the current value of PCX, architecture name and -//! GitHub repo links to show off the ISA. Perhaps in the future if we cross-compile to -//! WASM we could include a link to run this software in the browser. -//! -//! -//! # Configuration -//! -//! This may be disabled like so in your `.dsa.emulator.toml` file: -//! -//! ```toml -//! [misc] -//! use_discord_rpc = false -//! ``` -//! -//! Alternatively, you can hide this in your Discord settings. - -#[cfg(feature = "discord-rpc")] -use std::{path::PathBuf, sync::Arc, time::Duration}; - -use std::sync::mpsc::{Receiver, Sender}; - -#[cfg(feature = "discord-rpc")] -use discord_presence::{Client, DiscordError, models::ActivityTimestamps}; - -use crate::emulator::config::Config; - -#[derive(Debug)] -#[cfg(feature = "discord-rpc")] -pub enum RpcClientError { - Client(DiscordError), -} - -#[cfg(feature = "discord-rpc")] -impl std::fmt::Display for RpcClientError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Client(why) => write!(f, "discord RPC error: {why}"), - } - } -} - -#[cfg(feature = "discord-rpc")] -impl std::error::Error for RpcClientError {} - -#[cfg(feature = "discord-rpc")] -impl From for RpcClientError { - fn from(err: DiscordError) -> Self { - Self::Client(err) - } -} - -/// The type of activity the user is currently doing. -#[derive(Debug, Clone)] -#[cfg(feature = "discord-rpc")] -pub enum Activity { - Idle, - EditingFile(PathBuf), -} - -/// Messages to send over the wire. -#[derive(Debug)] -#[cfg(feature = "discord-rpc")] -pub enum Message { - /// Sent when we want to update the [`Context`]. - Update(Activity), - /// Sent when the main program wants to exit. - Stop, -} - -#[cfg(feature = "discord-rpc")] -unsafe impl Send for Message {} - -#[derive(Debug, Clone)] -#[cfg(feature = "discord-rpc")] -pub struct RpcClient { - /// Sends updates to [`Context`] (our state). - sender: Sender, - /// Stored for later cleanup on Drop. - thread_handle: Option>>, -} - -#[cfg(feature = "discord-rpc")] -impl RpcClient { - #[expect(clippy::unreadable_literal)] - /// Sets up the [`RpcClient`]. - pub fn new( - sender: Sender, - reciever: Receiver, - ) -> Result { - // TODO: Put client id into a .env file. - let mut client = discord_presence::Client::new(1384303074088190042); - - let thread_handle = std::thread::spawn(move || { - client.start(); - - eprintln!("INFO: Started Discord RPC client."); - - std::thread::sleep(Duration::from_millis(1000)); - - // Recieve updates and do shit. - for message in &reciever { - match message { - Message::Update(activity) => { - Self::handle_activity(&mut client, &activity); - } - Message::Stop => { - eprintln!("INFO: Stopping discord RPC client."); - if let Err(why) = client.shutdown() { - eprintln!("ERROR: Stopping discord RPC client failed: {why}"); - } - - break; - } - } - } - }); - - Ok(Self { - sender, - thread_handle: Some(Arc::new(thread_handle)), - }) - } - - fn handle_activity(client: &mut Client, activity: &Activity) { - let current_time = std::time::SystemTime::now(); - let timestamps = ActivityTimestamps::new().start( - current_time - .duration_since(std::time::UNIX_EPOCH) - .expect("Failed to get UNIX timestamp for activity.") - .as_secs(), - ); - - match activity { - Activity::Idle => { - client - .set_activity(|act| act.details("Idle").timestamps(|_| timestamps)) - .expect("TODO: Exponential backoff."); - } - Activity::EditingFile(file_path) => { - client - .set_activity(|act| { - act.details(format!("Editing file: {}", file_path.display())) - .timestamps(|_| timestamps) - }) - .expect("TODO: Exponential backoff."); - } - } - - eprintln!("INFO: RPC sent: {activity:?}"); - } - - /// Stops the [`RpcClient`]. - /// - /// # Panics - /// - /// May panic if the reciever was deallocated. This should not happen. - fn stop(&self) { - self.sender - .send(Message::Stop) - .expect("Failed to send stop message to RPC client."); - } - - /// Send an update with a given [`Activity`] to the [`RpcClient`]. - /// - /// # Panics - /// - /// May panic if the reciever was deallocated. This should not happen. - pub fn update(&self, activity: Activity) { - self.sender - .send(Message::Update(activity)) - .expect("Failed to send update to RPC client. This should not happen."); - } -} - -// Possibly unneeded but good practice. -#[cfg(feature = "discord-rpc")] -impl Drop for RpcClient { - fn drop(&mut self) { - self.stop(); - - if let Some(handle) = self.thread_handle.take() { - if let Some(handle) = Arc::into_inner(handle) { - let _ = handle.join(); - } - } - } -} - -/// Stub for when the feature is disabled. -#[cfg(not(feature = "discord-rpc"))] -pub struct RpcClient {} - -/// Stub for when the feature is disabled. -#[cfg(not(feature = "discord-rpc"))] -pub enum Message {} - -/// Stub for when the feature is disabled. -#[cfg(not(feature = "discord-rpc"))] -pub enum Activity {} - -/// Gets the discord [`RpcClient`] or returns None if this has been disabled in the config -/// options. -#[cfg(feature = "config")] -#[allow(clippy::needless_pass_by_value, unused_variables)] -pub fn get_rpc_client_or_none( - config: &Config, - rpc_sender: Sender, - rpc_reciever: Receiver, -) -> Result, Box> { - #[cfg(not(feature = "discord-rpc"))] - return Ok(None); - - #[cfg(feature = "discord-rpc")] - if config.misc.use_discord_rpc { - Ok(Some(RpcClient::new(rpc_sender, rpc_reciever)?)) - } else { - Ok(None) - } -} diff --git a/emulator/src/emulator/mod.rs b/emulator/src/emulator/mod.rs deleted file mode 100644 index 9d6cc6f..0000000 --- a/emulator/src/emulator/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -#[cfg(feature = "config")] -pub mod config; -pub mod misc; -pub mod system; -pub mod ui; diff --git a/emulator/src/emulator/system/emulator.rs b/emulator/src/emulator/system/emulator.rs deleted file mode 100644 index f6e5c0c..0000000 --- a/emulator/src/emulator/system/emulator.rs +++ /dev/null @@ -1,245 +0,0 @@ -use std::sync::Arc; -use std::sync::mpsc::{self, Receiver, Sender}; - -#[allow(unused_imports)] -use crate::emulator::misc::rpc::{Activity, RpcClient}; - -use crate::emulator::system::model::StateUpdate; -use crate::emulator::system::{ - model::{Command, Running}, - processor::Processor, -}; - -use common::prelude::*; - -#[expect(clippy::too_many_lines)] -#[allow(unused_variables)] -pub fn run_emulator( - cmd_rx: &Receiver, - state_tx: &Sender, - mut processor: Processor, - rpc_client: Option<&Arc>, -) { - println!("INFO: Starting emulator."); - - let mut running = Running::Paused; - let mut step = 0; - let mut addr; - let mut history = Vec::<(u32, Instruction)>::new(); - let size = 256; - - state_tx - .send(StateUpdate::Running(Running::Paused)) - .expect("Failed to send initial state!"); - - let mut instruction_count = 0; - let mut update = false; - - loop { - let cmd = if running == Running::Running || step > 0 { - match cmd_rx.try_recv() { - Ok(cmd) => Some(cmd), - Err(mpsc::TryRecvError::Empty) => { - update = false; - None - } - Err(mpsc::TryRecvError::Disconnected) => break, - } - } else { - match cmd_rx.recv() { - Ok(cmd) => Some(cmd), - Err(_) => break, - } - }; - - if let Some(cmd) = cmd { - match cmd { - Command::Start => { - running = Running::Running; - - // Update RPC with current state. TODO: Make this only occur on state - // changes. - #[cfg(feature = "discord-rpc")] - if let Some(rpc_client) = rpc_client { - use std::{path::PathBuf, str::FromStr}; - - rpc_client.update(Activity::EditingFile( - PathBuf::from_str("test") - .expect("This is a valid path, WTF."), - )); - } - } - Command::Stop => { - running = Running::Paused; - } - Command::Reset(x) => { - running = Running::Paused; - - match x { - 0 => { - processor.clear(); - processor.reset(); - instruction_count = 0; - } - 1 => { - processor.reset(); - instruction_count = 0; - } - 2 => { - processor.clear(); - } - _ => unreachable!(), - } - - processor.reset(); - } - Command::Step(x) => { - step = x; - } - Command::Write(offset, data) => { - update = true; - - processor - .memory - .write_range(offset, data) - .unwrap_or_else(|_| { - report_err( - state_tx, - "Failed to write memory range!", - &mut processor, - ); - }); - } - Command::Interrupt(_interrupt) => { - update = true; - - todo!("implement interrupts") - } - Command::MemRequest(new, size) if update => { - addr = new; - let _ = state_tx.send(StateUpdate::MemoryView( - processor.memory.read_range(addr, size).unwrap_or_else(|_| { - report_err( - state_tx, - "Failed to read memory range!", - &mut processor, - ); - Vec::new() - }), - )); - } - Command::DisplayRequest if update => { - let _ = state_tx.send(StateUpdate::DisplayView( - processor.display().unwrap_or_else(|_| { - report_err( - state_tx, - "Failed to read display!", - &mut processor, - ); - Vec::new() - }), - )); - } - Command::StackRequest if update => { - let _ = state_tx.send(StateUpdate::StackView( - processor.get_stack(32).unwrap_or_else(|_| { - report_err(state_tx, "Failed to read stack!", &mut processor); - Vec::new() - }), - )); - } - Command::RegisterRequest if update => { - let _ = state_tx.send(StateUpdate::Registers(processor.registers)); - } - Command::RunningRequest if update => { - let _ = state_tx.send(StateUpdate::Running(running)); - } - Command::HistoryRequest if update => { - let hsc = history.clone(); - history.clear(); - let _ = state_tx.send(StateUpdate::InstructionHistory(hsc)); - } - Command::InstructionCountRequest if update => { - let _ = state_tx.send(StateUpdate::Instructions(instruction_count)); - } - Command::WriteBlock(addr, block) => { - processor - .memory - .write_range(addr, block.to_vec()) - .unwrap_or_else(|_| { - report_err( - state_tx, - "Failed to write memory block!", - &mut processor, - ); - }); - } - - _ => {} - } - } - - if step > 0 { - step -= 1; - update = true; - running = Running::Paused; - - // Execute one cycle. - match processor.cycle() { - Ok((addr, instruction)) => { - history.push((addr, instruction)); - } - Err(why) => { - let pcx = processor - .get(Register::Pcx) - .expect("SPR should never be invalid"); - report_err( - state_tx, - &format!( - "Could not decode instruction at {pcx:x}. Reason: {why}" - ), - &mut processor, - ); - } - } - instruction_count += 1; - continue; - } - - if running == Running::Running { - update = true; - - // Execute one cycle. - let instruction = match processor.cycle() { - Ok(instruction) => instruction, - Err(why) => { - let pcx = processor - .get(Register::Pcx) - .expect("PCX should never be invalid"); - report_err( - state_tx, - &format!( - "Could not decode instruction at {pcx:x}. Reason: {why}" - ), - &mut processor, - ); - (pcx, Instruction::Nop) - } - }; - - history.push(instruction); - if matches!(instruction.1, Instruction::Halt) { - running = Running::Halted; - } - - instruction_count += 1; - } - } -} - -fn report_err(state_tx: &Sender, why: &str, processor: &mut Processor) { - processor - .begin_interrupt(Interrupt::HardFault) - .expect("What kind of goofy ahh shenanigans did you do with your fault handler? At this point, the emulator can just crash. this is on you."); - let _ = state_tx.send(StateUpdate::Error(why.to_string())); -} diff --git a/emulator/src/emulator/system/memory.rs b/emulator/src/emulator/system/memory.rs deleted file mode 100644 index b6a1425..0000000 --- a/emulator/src/emulator/system/memory.rs +++ /dev/null @@ -1,170 +0,0 @@ -use std::collections::HashMap; - -use crate::emulator::system::model::ProcessorError; - -pub trait MemoryUnit: Send + Sync { - fn reset(&mut self); - fn read_byte(&mut self, addr: u32) -> Result; - fn write_byte(&mut self, addr: u32, value: u8) -> Result<(), ProcessorError>; - fn read_word(&mut self, addr: u32) -> Result; - fn write_word(&mut self, addr: u32, value: u32) -> Result<(), ProcessorError>; - - fn read_range(&mut self, addr: u32, size: u32) -> Result, ProcessorError> { - let mut data = Vec::with_capacity(size as usize); - for i in 0..size { - data.push(self.read_byte(addr + i)?); - } - Ok(data) - } - - fn write_range(&mut self, addr: u32, value: Vec) -> Result<(), ProcessorError> { - for (i, byte) in value.into_iter().enumerate() { - self.write_byte(addr + i as u32, byte)?; - } - Ok(()) - } - - fn read_block(&mut self, addr: u32) -> Result<[u8; 256], ProcessorError> { - let mut data = [0; 256]; - for (i, byte) in data.iter_mut().enumerate() { - *byte = self.read_byte(addr + i as u32)?; - } - Ok(data) - } - - fn write_block(&mut self, addr: u32, data: [u8; 256]) -> Result<(), ProcessorError> { - for (i, byte) in data.iter().enumerate() { - self.write_byte(addr + i as u32, *byte)?; - } - Ok(()) - } -} - -pub struct MainStore { - pub data: HashMap, -} - -pub struct Block { - data: [u8; 256], -} - -impl Default for MainStore { - fn default() -> Self { - Self::new() - } -} - -impl MainStore { - #[must_use] - pub fn new() -> Self { - Self { - data: HashMap::new(), - } - } - - const fn segment_addr(addr: u32) -> (u32, u8) { - (addr / 256, (addr % 256) as u8) - } - - fn mut_block(&mut self, addr: u32) -> &mut Block { - self.data - .entry(addr) - .or_insert_with(|| Block { data: [0; 256] }); - - self.data.get_mut(&addr).map_or_else( - || panic!("Could not fetch block with address {addr:x?}"), - |block| block, - ) - } - - fn block(&mut self, addr: u32) -> &Block { - self.data - .entry(addr) - .or_insert_with(|| Block { data: [0; 256] }); - - self.data.get(&addr).map_or_else( - || panic!("Could not fetch block with address {addr:x?}"), - |block| block, - ) - } -} - -impl MemoryUnit for MainStore { - fn reset(&mut self) { - self.data.clear(); - } - - fn read_byte(&mut self, addr: u32) -> Result { - let (block_addr, offset) = Self::segment_addr(addr); - let block = self.block(block_addr); - Ok(block.data[offset as usize]) - } - - fn read_word(&mut self, addr: u32) -> Result { - if addr % 4 != 0 { - return Err(ProcessorError::BadMemoryAccess(addr)); - } - - let (block_addr, offset) = Self::segment_addr(addr); - let block = self.mut_block(block_addr); - let mut bytes = [0; 4]; - bytes[0] = block.data[offset as usize]; - bytes[1] = block.data[(offset + 1) as usize]; - bytes[2] = block.data[(offset + 2) as usize]; - bytes[3] = block.data[(offset + 3) as usize]; - Ok(u32::from_be_bytes(bytes)) - } - - fn read_range(&mut self, addr: u32, size: u32) -> Result, ProcessorError> { - let mut data = Vec::with_capacity(size as usize); - for i in 0..size { - data.push(self.read_byte(addr + i)?); - } - - Ok(data) - } - - fn write_byte(&mut self, addr: u32, value: u8) -> Result<(), ProcessorError> { - let (block_addr, offset) = Self::segment_addr(addr); - let block = self.mut_block(block_addr); - block.data[offset as usize] = value; - Ok(()) - } - - fn write_word(&mut self, addr: u32, value: u32) -> Result<(), ProcessorError> { - if addr % 4 != 0 { - return Err(ProcessorError::BadMemoryAccess(addr)); - } - - let (block_addr, offset) = Self::segment_addr(addr); - let block = self.mut_block(block_addr); - block.data[offset as usize] = (value >> 24) as u8; - block.data[(offset + 1) as usize] = (value >> 16) as u8; - block.data[(offset + 2) as usize] = (value >> 8) as u8; - block.data[(offset + 3) as usize] = value as u8; - Ok(()) - } - - fn write_range(&mut self, addr: u32, value: Vec) -> Result<(), ProcessorError> { - for (i, byte) in value.into_iter().enumerate() { - let (block_addr, offset) = Self::segment_addr(addr + i as u32); - let block = self.mut_block(block_addr); - block.data[offset as usize] = byte; - } - - Ok(()) - } - - fn read_block(&mut self, addr: u32) -> Result<[u8; 256], ProcessorError> { - let (block_addr, _) = Self::segment_addr(addr); - let block = self.block(block_addr); - Ok(block.data) - } - - fn write_block(&mut self, addr: u32, data: [u8; 256]) -> Result<(), ProcessorError> { - let (block_addr, _) = Self::segment_addr(addr); - let block = self.mut_block(block_addr); - block.data = data; - Ok(()) - } -} diff --git a/emulator/src/emulator/system/mod.rs b/emulator/src/emulator/system/mod.rs deleted file mode 100644 index e483168..0000000 --- a/emulator/src/emulator/system/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod emulator; -pub mod memory; -pub mod model; -pub mod processor; diff --git a/emulator/src/emulator/system/model.rs b/emulator/src/emulator/system/model.rs deleted file mode 100644 index 2d49a94..0000000 --- a/emulator/src/emulator/system/model.rs +++ /dev/null @@ -1,327 +0,0 @@ -use std::sync::mpsc::{self, Receiver, Sender}; - -use common::prelude::*; - -#[derive(PartialEq, Eq, Debug, Clone, Copy)] -pub enum Running { - Running, - Paused, - Halted, -} - -pub trait IODevice: Send + Sync { - fn read_byte(&mut self, addr: u32) -> u8; - fn write_byte(&mut self, addr: u32, value: u8); - fn read_range(&mut self, addr: u32, size: u32) -> Vec; - fn write_range(&mut self, addr: u32, value: Vec); -} - -#[derive(PartialEq, Eq, Debug, Clone)] -pub enum Command { - // set emulator state. - Start, - Stop, - Step(usize), - Reset(usize), - Interrupt(Interrupt), - Write(Address, Vec), - WriteBlock(Address, Box<[u8; 256]>), - - // request emulator state. - MemRequest(Address, u32), - DisplayRequest, - StackRequest, - RegisterRequest, - RunningRequest, - HistoryRequest, - InstructionCountRequest, -} - -#[derive(Debug)] -pub enum ProcessorError { - InvalidInstruction(u32), - InvalidRegister(u8), - BadMemoryAccess(u32), -} - -impl std::error::Error for ProcessorError {} - -impl std::fmt::Display for ProcessorError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::InvalidInstruction(instruction) => { - write!(f, "Invalid instruction: {instruction}") - } - Self::InvalidRegister(register) => { - write!(f, "Invalid register: {register}") - } - Self::BadMemoryAccess(address) => { - write!(f, "Bad memory access: {address}") - } - } - } -} - -pub struct State { - pub state_receiver: Receiver, - pub cmd_sender: Sender, - - // Processor state - pub reg_file: RegFile, - pub running: Running, - pub instructions: usize, - - // Memory access views - pub stack_view: Vec, - pub memory_view: Vec, - pub display_view: Vec, - - pub error_log: Vec, - - pub instruction_history: Vec<(u32, Instruction)>, -} - -impl State { - #[must_use] - pub fn new(sender: Sender, receiver: Receiver) -> Self { - Self { - state_receiver: receiver, - cmd_sender: sender, - reg_file: RegFile::default(), - running: Running::Paused, - instructions: 0, - stack_view: vec![], - memory_view: vec![], - display_view: vec![], - error_log: vec![], - instruction_history: vec![], - } - } - - pub fn send(&mut self, cmd: Command) { - if let Err(e) = self.cmd_sender.send(cmd) { - self.error_log.push(e.to_string()); - } - } - - pub fn update(&mut self) -> Result<(), mpsc::TryRecvError> { - while let Ok(update) = self.state_receiver.try_recv() { - match update { - StateUpdate::Registers(reg_file) => self.reg_file = reg_file, - StateUpdate::Running(running) => self.running = running, - StateUpdate::Instructions(instructions) => { - self.instructions = instructions; - } - StateUpdate::StackView(stack_view) => self.stack_view = stack_view, - StateUpdate::MemoryView(memory_view) => self.memory_view = memory_view, - StateUpdate::DisplayView(display_view) => { - self.display_view = display_view; - } - StateUpdate::Error(err_state) => self.error_log.push(err_state), - StateUpdate::InstructionHistory(history) => { - self.instruction_history.extend(history); - } - } - - if self.error_log.len() > 256 { - self.error_log.drain(0..self.error_log.len() - 256); - } - - if self.instruction_history.len() > 1024 { - self.instruction_history - .drain(0..self.instruction_history.len() - 1024); - } - } - - if let Err(e) = self.state_receiver.try_recv() { - match e { - mpsc::TryRecvError::Empty => {} - mpsc::TryRecvError::Disconnected => { - return Err(e); - } - } - } - - Ok(()) - } -} - -pub enum StateUpdate { - Registers(RegFile), - Running(Running), - Instructions(usize), - StackView(Vec), - MemoryView(Vec), - DisplayView(Vec), - Error(String), - InstructionHistory(Vec<(u32, Instruction)>), -} - -#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] -pub struct RegFile { - // General Purpose Registers - rg0: u32, - rg1: u32, - rg2: u32, - rg3: u32, - rg4: u32, - rg5: u32, - rg6: u32, - rg7: u32, - rg8: u32, - rg9: u32, - rga: u32, - rgb: u32, - rgc: u32, - rgd: u32, - rge: u32, - rgf: u32, - - // Special Purpose Registers - acc: u32, - spr: u32, - bpr: u32, - ret: u32, - idr: u32, - mmr: u32, - - // System Registers - mar: u32, - mdr: u32, - sts: u32, - cir: u32, - pcx: u32, -} - -impl RegFile { - #[must_use] - pub fn all(&self) -> Vec<(&str, u32)> { - vec![ - ("Rg0", self.rg0), - ("Rg1", self.rg1), - ("Rg2", self.rg2), - ("Rg3", self.rg3), - ("Rg4", self.rg4), - ("Rg5", self.rg5), - ("Rg6", self.rg6), - ("Rg7", self.rg7), - ("Rg8", self.rg8), - ("Rg9", self.rg9), - ("Rga", self.rga), - ("Rgb", self.rgb), - ("Rgc", self.rgc), - ("Rgd", self.rgd), - ("Rge", self.rge), - ("Rgf", self.rgf), - ("Acc", self.acc), - ("Spr", self.spr), - ("Bpr", self.bpr), - ("Ret", self.ret), - ("Idr", self.idr), - ("Mmr", self.mmr), - ("Mar", self.mar), - ("Mdr", self.mdr), - ("Sts", self.sts), - ("Cir", self.cir), - ("Pcx", self.pcx), - ] - } - - pub const fn reset(&mut self) { - self.rg0 = 0; - self.rg1 = 0; - self.rg2 = 0; - self.rg3 = 0; - self.rg4 = 0; - self.rg5 = 0; - self.rg6 = 0; - self.rg7 = 0; - self.rg8 = 0; - self.rg9 = 0; - self.rga = 0; - self.rgb = 0; - self.rgc = 0; - self.rgd = 0; - self.rge = 0; - self.rgf = 0; - self.acc = 0; - self.spr = 0; - self.bpr = 0; - self.ret = 0; - self.idr = 0; - self.mmr = 0; - self.mar = 0; - self.mdr = 0; - self.sts = 0; - self.cir = 0; - self.pcx = 0; - } - - pub const fn reg(&mut self, reg: Register) -> Result<&mut u32, ProcessorError> { - Ok(match reg { - Register::Rg0 => &mut self.rg0, - Register::Rg1 => &mut self.rg1, - Register::Rg2 => &mut self.rg2, - Register::Rg3 => &mut self.rg3, - Register::Rg4 => &mut self.rg4, - Register::Rg5 => &mut self.rg5, - Register::Rg6 => &mut self.rg6, - Register::Rg7 => &mut self.rg7, - Register::Rg8 => &mut self.rg8, - Register::Rg9 => &mut self.rg9, - Register::Rga => &mut self.rga, - Register::Rgb => &mut self.rgb, - Register::Rgc => &mut self.rgc, - Register::Rgd => &mut self.rgd, - Register::Rge => &mut self.rge, - Register::Rgf => &mut self.rgf, - Register::Acc => &mut self.acc, - Register::Spr => &mut self.spr, - Register::Bpr => &mut self.bpr, - Register::Ret => &mut self.ret, - Register::Idr => &mut self.idr, - Register::Mmr => &mut self.mmr, - Register::Mar => &mut self.mar, - Register::Mdr => &mut self.mdr, - Register::Sts => &mut self.sts, - Register::Cir => &mut self.cir, - Register::Pcx => &mut self.pcx, - _ => return Err(ProcessorError::InvalidRegister(Register::NoReg as u8)), - }) - } - - #[must_use] - pub const fn get(&self, reg: Register) -> Result { - Ok(match reg { - Register::Rg0 => self.rg0, - Register::Rg1 => self.rg1, - Register::Rg2 => self.rg2, - Register::Rg3 => self.rg3, - Register::Rg4 => self.rg4, - Register::Rg5 => self.rg5, - Register::Rg6 => self.rg6, - Register::Rg7 => self.rg7, - Register::Rg8 => self.rg8, - Register::Rg9 => self.rg9, - Register::Rga => self.rga, - Register::Rgb => self.rgb, - Register::Rgc => self.rgc, - Register::Rgd => self.rgd, - Register::Rge => self.rge, - Register::Rgf => self.rgf, - Register::Acc => self.acc, - Register::Spr => self.spr, - Register::Bpr => self.bpr, - Register::Ret => self.ret, - Register::Idr => self.idr, - Register::Mmr => self.mmr, - Register::Mar => self.mar, - Register::Mdr => self.mdr, - Register::Sts => self.sts, - Register::Cir => self.cir, - Register::Pcx => self.pcx, - Register::Zero => 0, - _ => return Err(ProcessorError::InvalidRegister(Register::NoReg as u8)), - }) - } -} diff --git a/emulator/src/emulator/system/processor/mod.rs b/emulator/src/emulator/system/processor/mod.rs deleted file mode 100644 index d48b80d..0000000 --- a/emulator/src/emulator/system/processor/mod.rs +++ /dev/null @@ -1,507 +0,0 @@ -use std::{ - cmp::{max, min}, - sync::Arc, -}; - -use crate::emulator::system::{ - memory::MemoryUnit, - model::{IODevice, ProcessorError, RegFile}, -}; - -use common::instructions::{Instruction, Interrupt, Register}; - -pub struct Processor { - pub memory: Box, - pub registers: RegFile, - pub halted: bool, - pub io_devices: Vec>, - - pub void: u32, -} - -fn log(message: &str) { - println!("\x1b[32mINFO:\x1b[0m {message}"); -} - -impl Processor { - #[must_use] - pub fn new(memory: Box, io_devices: Vec>) -> Self { - Self { - memory, - registers: RegFile::default(), - halted: false, - io_devices, - void: 0, - } - } - - pub const fn reset(&mut self) { - // set all registers to zero - // run memory.reset() - self.registers.reset(); - } - - pub fn clear(&mut self) { - self.memory.reset(); - } - - pub fn cycle(&mut self) -> Result<(u32, Instruction), ProcessorError> { - self.halted = false; - - // Get value from PCX. - let addr = self.fetch()?; - // Increment PCX. - self.advance(); - - // Set MAR to the previous value of PCX. - *self.reg(Register::Mar)? = addr; - let val = self.memory.read_word(addr)?; - - // Set CIR to the value of RAM[MAR]. - *self.reg(Register::Mar)? = val; - - // Decode and execute the instruction. - let instruction = Instruction::decode(val) - .map_err(|_| ProcessorError::InvalidInstruction(val))?; - - instruction.execute(self)?; - Ok((addr, instruction)) - } - - const fn fetch(&self) -> Result { - self.get(Register::Pcx) - } - - pub const fn get(&self, reg: Register) -> Result { - self.registers.get(reg) - } - - pub const fn reg(&mut self, reg: Register) -> Result<&mut u32, ProcessorError> { - match reg { - Register::Zero => Ok(&mut self.void), - _ => self.registers.reg(reg), - } - } - - pub fn display(&mut self) -> Result, ProcessorError> { - self.memory.read_range(0x20000, 2000) - } - - pub fn cmp(&mut self, a: u32, b: u32) { - self.set_flag(Flag::Equal, a == b); - self.set_flag(Flag::GreaterThan, a > b); - self.set_flag(Flag::LessThan, a < b); - } - - // functions to set new state - fn set_flag(&mut self, flag: Flag, value: bool) { - if value { - *self - .reg(Register::Sts) - .expect("STS should never be invalid") |= flag as u32; - } else { - *self - .reg(Register::Sts) - .expect("STS should never be invalid") &= !(flag as u32); - } - } - - fn get_flag(&self, flag: Flag) -> Result { - Ok(self.get(Register::Sts)? & (flag as u32) != 0) - } - - fn advance(&mut self) -> Result<(), ProcessorError> { - // increment PCX - *self.reg(Register::Pcx)? += 4; - Ok(()) - } - - fn jump(&mut self, reg: Register, offset: u16) -> Result<(), ProcessorError> { - *self.reg(Register::Pcx)? = self.get(reg)? + u32::from(offset); - Ok(()) - } - - pub fn begin_interrupt( - &mut self, - interrupt: Interrupt, - ) -> Result<(), ProcessorError> { - let idt = self.get(Register::Idr)?; - - let addr = self - .memory - .read_word(idt + u32::from(interrupt.as_u8()) * 4)?; - println!("INFO: Interrupt {interrupt:?} addr: {addr}"); - - self.push(self.get(Register::Pcx)?)?; - *self.reg(Register::Pcx)? = addr; - Ok(()) - } - - fn push(&mut self, val: u32) -> Result<(), ProcessorError> { - *self.reg(Register::Spr)? -= 4; - let reg = *self.reg(Register::Spr)?; - self.memory.write_word(reg, val) - } - - fn pop(&mut self) -> Result { - let reg = *self.reg(Register::Spr)?; - let val = self.memory.read_word(reg)?; - *self.reg(Register::Spr)? += 4; - Ok(val) - } - - // TODO: remove this once implemented - #[allow(clippy::needless_pass_by_ref_mut)] - fn end_interrupt(&mut self) -> Result<(), ProcessorError> { - let ret = self.pop()?; - *self.reg(Register::Ret)? = ret; - *self.reg(Register::Pcx)? = ret; - Ok(()) - } - - pub fn get_stack(&mut self, n: u32) -> Result, ProcessorError> { - let addr = self.get(Register::Spr)?; - let size = n * 4; - // returns the stack - self.memory.read_range( - max(addr, 0), // ensures that we cannot read from a negative address - min(size, addr), // ensures we don't read above the top of the stack - ) - } -} - -#[derive(Debug)] -#[expect(dead_code)] -enum Flag { - Equal = 1, - GreaterThan = 2, - LessThan = 4, - Zero = 8, - Positive = 16, - Negative = 32, - Carry = 64, - UserMode = 128, - InterruptsEnabled = 256, -} - -trait Executable { - fn execute(self, cpu: &mut Processor) -> Result<(), ProcessorError>; -} - -impl Executable for Instruction { - #[allow(clippy::too_many_lines)] - fn execute(self, cpu: &mut Processor) -> Result<(), ProcessorError> { - match self { - // No operation - a blank line. - // Copies from SrcReg to a.drReg. - Self::Mov(a) => { - *cpu.reg(a.dr)? = cpu.get(a.sr1)?; - } - - // Copies from SrcReg to a.drReg, sign extending the value to take up a full - // word. - Self::MovSigned(a) => { - *cpu.reg(a.dr)? = sign_extend(cpu.get(a.sr1)?); - } - - // Loads a byte from memory address (base + offset) into a.drReg. The - // effective address must be byte-aligned. - Self::LoadByte(a) => { - *cpu.reg(a.r2)? = u32::from( - cpu.memory - .read_byte(cpu.get(a.r1)? + u32::from(a.immediate))?, - ); - } - - // Loads a sign-extended byte from memory address (base + offset) into - // a.drReg. The effective address must be byte-aligned. - Self::LoadByteSigned(a) => { - *cpu.reg(a.r2)? = sign_extend(u32::from( - cpu.memory - .read_byte(cpu.get(a.r1)? + u32::from(a.immediate))?, - )); - } - - // Loads a half-word from memory address (base + offset) into a.drReg. The - // effective address must be 2-byte-aligned. - Self::LoadHalfword(a) => { - // we read an entire word, then right shift so we only get the first half - // of the word - *cpu.reg(a.r2)? = cpu - .memory - .read_word(cpu.get(a.r1)? + u32::from(a.immediate))? - >> 16; - } - - // Loads a sign-extended half-word from memory address (base + offset) into - // a.drReg. The effective address must be 2-byte-aligned. - Self::LoadHalfwordSigned(a) => { - *cpu.reg(a.r2)? = sign_extend( - cpu.memory - .read_word(cpu.get(a.r1)? + u32::from(a.immediate))? - >> 16, - ); - } - - // Loads a word from memory address (base + offset) into a.drReg. The - // effective address must be 4-byte-aligned. - Self::LoadWord(a) => { - *cpu.reg(a.r2)? = cpu - .memory - .read_word(cpu.get(a.r1)? + u32::from(a.immediate))?; - } - - // Stores a byte from SrcReg in memory address (base + offset) The effective - // address must be byte-aligned. - Self::StoreByte(a) => { - cpu.memory.write_byte( - cpu.get(a.r2)? + u32::from(a.immediate), - cpu.get(a.r1)? as u8, - )?; - } - - // Stores a half-word from SrcReg in memory address (base + offset) The - // effective address must be 2-byte-aligned. - Self::StoreHalfword(a) => { - // split the value into bytes and then write two bytes - let bytes = (cpu.get(a.r1)? as u16).to_le_bytes(); - cpu.memory - .write_byte(cpu.get(a.r2)? + u32::from(a.immediate), bytes[0])?; - cpu.memory - .write_byte(cpu.get(a.r2)? + u32::from(a.immediate) + 1, bytes[1])?; - } - - // Stores a word from SrcReg in memory address (base + offset) The effective - // address must be 4-byte-aligned. - Self::StoreWord(a) => { - cpu.memory.write_word( - cpu.get(a.r2)? + u32::from(a.immediate), - cpu.get(a.r1)?, - )?; - } - - // Loads a 16-bit literal value into reg, setting the bottom 16 bits of the - // word. To populate the upper 16 bits, see LUI. - Self::LoadLowerImmediate(a) => { - *cpu.reg(a.r1)? = u32::from(a.immediate); - } - - // Loads a 16-bit literal value into reg, setting the top 16 bits of the word. - // To populate the lower 16 bits, see LLI. - Self::LoadUpperImmediate(a) => { - *cpu.reg(a.r1)? = - (cpu.get(a.r1)? & 0x0000_FFFF) | (u32::from(a.immediate) << 16); - } - - // Unconditionally jumps to the calculated address or direct address - Self::Jump(a) => cpu.jump(a.r1, a.immediate)?, - - // Jumps to the calculated address or direct address if equal flag set. - Self::JumpEq(a) => { - if cpu.get_flag(Flag::Equal)? { - cpu.jump(a.r1, a.immediate)?; - } - } - - // Jumps to the calculated address or direct address if equal flag not set. - Self::JumpNeq(a) => { - if !cpu.get_flag(Flag::Equal)? { - cpu.jump(a.r1, a.immediate)?; - } - } - - // Jumps to the calculated address or direct address if greater than flag set. - Self::JumpGt(a) => { - if cpu.get_flag(Flag::GreaterThan)? { - cpu.jump(a.r1, a.immediate)?; - } - } - - // Jumps to the calculated address or direct address if greater than flag or - // equal flag set. - Self::JumpGe(a) => { - if cpu.get_flag(Flag::GreaterThan)? || cpu.get_flag(Flag::Equal)? { - cpu.jump(a.r1, a.immediate)?; - } - } - - // Jumps to the calculated address or direct address if less than flag set. - Self::JumpLt(a) => { - if cpu.get_flag(Flag::LessThan)? { - cpu.jump(a.r1, a.immediate)?; - } - } - - // Jumps to the calculated address or direct address if less than flag or - // equal flag set. - Self::JumpLe(a) => { - if cpu.get_flag(Flag::LessThan)? || cpu.get_flag(Flag::Equal)? { - cpu.jump(a.r1, a.immediate)?; - } - } - - // Increments the value in the given register - Self::Increment(a) => *cpu.reg(a.sr1)? = inc(cpu.get(a.sr1)?), - - // Decrements the value in the given register - Self::Decrement(a) => *cpu.reg(a.sr1)? = dec(cpu.get(a.sr1)?), - - // Left shifts the value in Reg by the given amount (either a register, or a - // literal value) - Self::ShiftLeft(a) => { - let reg = cpu.get(a.sr1)?; - let val = a.shamt; - *cpu.reg(a.sr1)? = shl(reg, val); - } - - // Right shifts the value in Reg by the given amount (either a register, or a - // literal value). - Self::ShiftRight(a) => { - let regval = cpu.get(a.sr1)?; - let val = a.shamt; - *cpu.reg(a.sr1)? = shr(regval, val); - } - - // Adds the value of Src2 to Src1 and writes the result to a.dr - Self::Add(a) => { - *cpu.reg(a.dr)? = add(cpu.get(a.sr1)?, cpu.get(a.sr2)?); - } - - // Subtracts the value of Src2 from Src1 and writes the result to a.dr - Self::Sub(a) => { - *cpu.reg(a.dr)? = sub(cpu.get(a.sr1)?, cpu.get(a.sr2)?); - } - - Self::AddImmediate(a) => { - *cpu.reg(a.r2)? = add(cpu.get(a.r1)?, u32::from(a.immediate)); - } - - Self::SubImmediate(a) => { - *cpu.reg(a.r2)? = sub(cpu.get(a.r1)?, u32::from(a.immediate)); - } - - // Performs bitwise AND on Src1 and Src2 storing the result in a.dr - Self::And(a) => *cpu.reg(a.dr)? = and(cpu.get(a.sr1)?, cpu.get(a.sr2)?), - - // Performs bitwise OR on Src1 and Src2 storing the result in a.dr - Self::Or(a) => *cpu.reg(a.dr)? = or(cpu.get(a.sr1)?, cpu.get(a.sr2)?), - - // Performs bitwise NOT on Src storing the result in a.dr - Self::Not(a) => *cpu.reg(a.dr)? = not(cpu.get(a.sr1)?), - - // Performs bitwise XOR on Src1 and Src2 storing the result in a.dr - Self::Xor(a) => *cpu.reg(a.dr)? = xor(cpu.get(a.sr1)?, cpu.get(a.sr2)?), - - // Performs bitwise NAND on Src1 and Src2 storing the result in a.dr - Self::Nand(a) => *cpu.reg(a.dr)? = nand(cpu.get(a.sr1)?, cpu.get(a.sr2)?), - - // Performs bitwise NOR on Src1 and Src2 storing the result in a.dr - Self::Nor(a) => *cpu.reg(a.dr)? = nor(cpu.get(a.sr1)?, cpu.get(a.sr2)?), - - // Performs bitwise XNOR on Src1 and Src2 storing the result in a.dr - Self::Xnor(a) => *cpu.reg(a.dr)? = xnor(cpu.get(a.sr1)?, cpu.get(a.sr2)?), - - // Compares the value of Reg1 to the value in Reg2. The results of the - // comparisons are set in the Status register. - Self::Compare(a) => { - cpu.cmp(cpu.get(a.sr1)?, cpu.get(a.sr2)?); - } - - // Initiates an interrupt with the given 8 bit interrupt code. - // Triggering an interrupt invokes the following behaviour: - // - The return address is saved to the RET register. - // - The stack base ptr is set to the kernel stack. - Self::Interrupt(interrupt_code) => { - cpu.begin_interrupt(interrupt_code)?; - } - - // Returns from an interrupt, - Self::IntReturn => { - cpu.end_interrupt()?; - } - - // Halts the processor. - Self::Halt => { - cpu.halted = true; - } - - Self::Segment(_) | Self::Nop | Self::Data(_) => {} - _ => { - eprintln!("WARN: unimplemented instruction: {self}"); - todo!() - } - } - Ok(()) - } -} - -// mathematical and logical functions & other operations -const fn add(a: u32, b: u32) -> u32 { - a.wrapping_add(b) -} - -const fn sub(a: u32, b: u32) -> u32 { - a.wrapping_sub(b) -} - -const fn and(a: u32, b: u32) -> u32 { - a & b -} - -const fn inc(a: u32) -> u32 { - a.wrapping_add(1) -} - -const fn dec(a: u32) -> u32 { - a.wrapping_sub(1) -} - -const fn shl(a: u32, amount: u8) -> u32 { - a << amount -} - -const fn shr(a: u32, amount: u8) -> u32 { - a >> amount -} - -const fn or(a: u32, b: u32) -> u32 { - a | b -} - -const fn not(a: u32) -> u32 { - !a -} - -const fn xor(a: u32, b: u32) -> u32 { - a ^ b -} - -const fn nand(a: u32, b: u32) -> u32 { - !(a & b) -} - -const fn nor(a: u32, b: u32) -> u32 { - !(a | b) -} - -const fn xnor(a: u32, b: u32) -> u32 { - !(a ^ b) -} - -const fn sign_extend(val: u32) -> u32 { - let (mask, sign_bit): (u32, u8) = match val { - 0..=0xFF => (0xFFFF_FF00, 7), - // I presume this was the intended behaviour? - 0x100..=0xFFFF => (0xFFFF_0000, 15), - _ => (0x0000_0000, 31), - }; - - if val & (1 << sign_bit) != 0 { - val | mask - } else { - val - } -} - -#[cfg(test)] -mod tests; diff --git a/emulator/src/emulator/system/processor/tests.rs b/emulator/src/emulator/system/processor/tests.rs deleted file mode 100644 index 6381e3a..0000000 --- a/emulator/src/emulator/system/processor/tests.rs +++ /dev/null @@ -1,695 +0,0 @@ -use super::*; -use crate::emulator::system::memory::*; - -use common::prelude::*; - -fn create_test_processor() -> Processor { - let memory = Box::new(MainStore::new()); - Processor::new(memory, Vec::new()) -} - -#[test] -fn test_nop_instruction() { - let mut cpu = create_test_processor(); - let initial_state = cpu.registers; - - Instruction::Nop.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - - assert_eq!( - cpu.registers - .get(Register::Rg0) - .expect("Failed to get register Rg0"), - initial_state - .get(Register::Rg0) - .expect("Failed to get register Rg0") - ); - assert_eq!( - cpu.registers - .get(Register::Acc) - .expect("Failed to get register Acc"), - initial_state - .get(Register::Acc) - .expect("Failed to get register Acc") - ); -} - -#[test] -fn test_mov_instruction() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 0x1234_5678; - - let mov_instr = Instruction::Mov(RTypeArgs::new( - Some(Register::Rg1), - None, - Some(Register::Rg2), - None, - )); - - mov_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg2).expect("Failed to get register Rg2"), - 0x1234_5678 - ); -} - -#[test] -fn test_mov_signed_instruction() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 0x0000_00FF; - - let mov_signed_instr = Instruction::MovSigned(RTypeArgs::new( - Some(Register::Rg1), - None, - Some(Register::Rg2), - None, - )); - - mov_signed_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg2).expect("Failed to get register Rg2"), - 0xFFFF_FFFF - ); -} - -#[test] -fn test_load_byte_instruction() { - let mut cpu = create_test_processor(); - let addr = 0x100; - cpu.memory - .write_byte(addr, 0xAB) - .expect("Failed to write byte to memory"); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = addr - 4; - - let load_byte_instr = Instruction::LoadByte(ITypeArgs::new( - 4, - Some(Register::Rg1), - Some(Register::Rg2), - )); - - load_byte_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg2).expect("Failed to get register Rg2"), - 0x0000_00AB - ); -} - -#[test] -fn test_load_byte_signed_instruction() { - let mut cpu = create_test_processor(); - let addr = 0x100; - cpu.memory - .write_byte(addr, 0xFF) - .expect("Failed to write byte to memory"); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = addr; - - let load_byte_signed_instr = Instruction::LoadByteSigned(ITypeArgs::new( - 0, - Some(Register::Rg1), - Some(Register::Rg2), - )); - - load_byte_signed_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg2).expect("Failed to get register Rg2"), - 0xFFFF_FFFF - ); -} - -#[test] -fn test_load_halfword_instruction() { - let mut cpu = create_test_processor(); - let addr = 0x100; - cpu.memory - .write_word(addr, 0x1234_5678) - .expect("Failed to write word to memory"); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = addr; - - let load_halfword_instr = Instruction::LoadHalfword(ITypeArgs::new( - 0, - Some(Register::Rg1), - Some(Register::Rg2), - )); - - load_halfword_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg2).expect("Failed to get register Rg2"), - 0x0000_1234 - ); -} - -#[test] -fn test_load_word_instruction() { - let mut cpu = create_test_processor(); - let addr = 0x100; - cpu.memory - .write_word(addr, 0x1234_5678) - .expect("Failed to write word to memory"); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = addr; - - let load_word_instr = Instruction::LoadWord(ITypeArgs::new( - 0, - Some(Register::Rg1), - Some(Register::Rg2), - )); - - load_word_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg2).expect("Failed to get register Rg2"), - 0x1234_5678 - ); -} - -#[test] -fn test_store_byte_instruction() { - let mut cpu = create_test_processor(); - let addr = 0x100; - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = addr; - *cpu.reg(Register::Rg2).expect("Failed to get register Rg2") = 0xAB; - - let store_byte_instr = Instruction::StoreByte(ITypeArgs::new( - 0, - Some(Register::Rg2), - Some(Register::Rg1), - )); - - store_byte_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!(cpu.memory.read_byte(addr).expect("Emulator was slain by losing the game while attempting to execute instruction"), 0xAB); -} - -#[test] -fn test_store_word_instruction() { - let mut cpu = create_test_processor(); - let addr = 0x100; - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = addr; - *cpu.reg(Register::Rg2).expect("Failed to get register Rg2") = 0x1234_5678; - - let store_word_instr = Instruction::StoreWord(ITypeArgs::new( - 0, - Some(Register::Rg2), - Some(Register::Rg1), - )); - - store_word_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!(cpu.memory.read_word(addr).expect("Emulator was slain by losing the game while attempting to execute instruction"), 0x1234_5678); -} - -#[test] -fn test_add_instruction() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 15; - *cpu.reg(Register::Rg2).expect("Failed to get register Rg2") = 25; - - let add_instr = Instruction::Add(RTypeArgs::new( - Some(Register::Rg1), - Some(Register::Rg2), - Some(Register::Rg3), - None, - )); - - add_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg3).expect("Failed to get register Rg3"), - 40 - ); -} - -#[test] -fn test_sub_instruction() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 50; - *cpu.reg(Register::Rg2).expect("Failed to get register Rg2") = 20; - - let sub_instr = Instruction::Sub(RTypeArgs::new( - Some(Register::Rg1), - Some(Register::Rg2), - Some(Register::Rg3), - None, - )); - - sub_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg3).expect("Failed to get register Rg3"), - 30 - ); -} - -#[test] -fn test_and_instruction() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 0b1100; - *cpu.reg(Register::Rg2).expect("Failed to get register Rg2") = 0b1010; - - let and_instr = Instruction::And(RTypeArgs::new( - Some(Register::Rg1), - Some(Register::Rg2), - Some(Register::Rg3), - None, - )); - - and_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg3).expect("Failed to get register Rg3"), - 0b1000 - ); -} - -#[test] -fn test_or_instruction() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 0b1100; - *cpu.reg(Register::Rg2).expect("Failed to get register Rg2") = 0b1010; - - let or_instr = Instruction::Or(RTypeArgs::new( - Some(Register::Rg1), - Some(Register::Rg2), - Some(Register::Rg3), - None, - )); - - or_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg3).expect("Failed to get register Rg3"), - 0b1110 - ); -} - -#[test] -fn test_xor_instruction() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 0b1100; - *cpu.reg(Register::Rg2).expect("Failed to get register Rg2") = 0b1010; - - let xor_instr = Instruction::Xor(RTypeArgs::new( - Some(Register::Rg1), - Some(Register::Rg2), - Some(Register::Rg3), - None, - )); - - xor_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg3).expect("Failed to get register Rg3"), - 0b0110 - ); -} - -#[test] -fn test_not_instruction() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 0x0F0F_0F0F; - - let not_instr = Instruction::Not(RTypeArgs::new( - Some(Register::Rg1), - None, - Some(Register::Rg2), - None, - )); - - not_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg2).expect("Failed to get register Rg2"), - 0xF0F0_F0F0 - ); -} - -#[test] -fn test_compare_equal() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 42; - *cpu.reg(Register::Rg2).expect("Failed to get register Rg2") = 42; - - let cmp_instr = Instruction::Compare(RTypeArgs::new( - Some(Register::Rg1), - Some(Register::Rg2), - None, - None, - )); - - cmp_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - - assert!(cpu.get_flag(Flag::Equal).expect("Failed to get flag Equal")); - assert!( - !cpu.get_flag(Flag::GreaterThan) - .expect("Failed to get flag GreaterThan") - ); - assert!( - !cpu.get_flag(Flag::LessThan) - .expect("Failed to get flag LessThan") - ); -} - -#[test] -fn test_compare_greater_than() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 50; - *cpu.reg(Register::Rg2).expect("Failed to get register Rg2") = 30; - - let cmp_instr = Instruction::Compare(RTypeArgs::new( - Some(Register::Rg1), - Some(Register::Rg2), - None, - None, - )); - - cmp_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - - assert!(!cpu.get_flag(Flag::Equal).expect("Failed to get flag Equal")); - assert!( - cpu.get_flag(Flag::GreaterThan) - .expect("Failed to get flag GreaterThan") - ); - assert!( - !cpu.get_flag(Flag::LessThan) - .expect("Failed to get flag LessThan") - ); -} - -#[test] -fn test_compare_less_than() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 20; - *cpu.reg(Register::Rg2).expect("Failed to get register Rg2") = 30; - - let cmp_instr = Instruction::Compare(RTypeArgs::new( - Some(Register::Rg1), - Some(Register::Rg2), - None, - None, - )); - - cmp_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - - assert!(!cpu.get_flag(Flag::Equal).expect("Failed to get flag Equal")); - assert!( - !cpu.get_flag(Flag::GreaterThan) - .expect("Failed to get flag GreaterThan") - ); - assert!( - cpu.get_flag(Flag::LessThan) - .expect("Failed to get flag LessThan") - ); -} - -#[test] -fn test_increment_instruction() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 42; - - let inc_instr = - Instruction::Increment(RTypeArgs::new(Some(Register::Rg1), None, None, None)); - - inc_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg1).expect("Failed to get register Rg1"), - 43 - ); -} - -#[test] -fn test_decrement_instruction() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 42; - - let dec_instr = - Instruction::Decrement(RTypeArgs::new(Some(Register::Rg1), None, None, None)); - - dec_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg1).expect("Failed to get register Rg1"), - 41 - ); -} - -#[test] -fn test_shift_left_with_shamt() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 0b1010; - - let shl_instr = Instruction::ShiftLeft(RTypeArgs::new( - Some(Register::Rg1), - Some(Register::Zero), - None, - Some(2), - )); - - shl_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg1).expect("Failed to get register Rg1"), - 0b10_1000 - ); -} - -#[test] -fn test_shift_right_with_shamt() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 0b10_1000; - - let shr_instr = Instruction::ShiftRight(RTypeArgs::new( - Some(Register::Rg1), - Some(Register::Zero), - None, - Some(2), - )); - - shr_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg1).expect("Failed to get register Rg1"), - 0b1010 - ); -} - -// #[test] -// fn test_shift_left_with_register() { -// let mut cpu = create_test_processor(); -// *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 0b1010; - -// let shl_instr = -// Instruction::ShiftLeft(RTypeArgs::new(Some(Register::Rg1), None, None, -// Some(3))); - -// shl_instr.execute(&mut cpu).expect( -// "Emulator was slain by losing the game while attempting to execute -// instruction", ); -// assert_eq!( -// cpu.get(Register::Rg1).expect("Failed to get register Rg1"), -// 0b101_0000 -// ); -// } - -#[test] -fn test_load_lower_immediate() { - let mut cpu = create_test_processor(); - - let lli_instr = Instruction::LoadLowerImmediate(ITypeArgs::new( - 0x1234, - Some(Register::Rg1), - None, - )); - - lli_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg1).expect("Failed to get register Rg1"), - 0x0000_1234 - ); -} - -#[test] -fn test_load_upper_immediate() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 0x0000_5678; - - let lui_instr = Instruction::LoadUpperImmediate(ITypeArgs::new( - 0x1234, - Some(Register::Rg1), - None, - )); - - lui_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg1).expect("Failed to get register Rg1"), - 0x1234_5678 - ); -} - -#[test] -fn test_jump_unconditional() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 0x1000; - let initial_pc = cpu.get(Register::Pcx).expect("Failed to get register Pcx"); - - let jump_instr = Instruction::Jump(ITypeArgs::new(0x100, Some(Register::Rg1), None)); - - jump_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Pcx).expect("Failed to get register Pcx"), - 0x1100 - ); - assert_ne!( - cpu.get(Register::Pcx).expect("Failed to get register Pcx"), - initial_pc - ); -} - -#[test] -fn test_jump_equal_when_flag_set() { - let mut cpu = create_test_processor(); - cpu.set_flag(Flag::Equal, true); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 0x1000; - - let jump_eq_instr = - Instruction::JumpEq(ITypeArgs::new(0x100, Some(Register::Rg1), None)); - - jump_eq_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Pcx).expect("Failed to get register Pcx"), - 0x1100 - ); -} - -#[test] -fn test_jump_equal_when_flag_not_set() { - let mut cpu = create_test_processor(); - cpu.set_flag(Flag::Equal, false); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 0x1000; - let initial_pc = cpu.get(Register::Pcx).expect("Failed to get register Pcx"); - - let jump_eq_instr = - Instruction::JumpEq(ITypeArgs::new(0x100, Some(Register::Rg1), None)); - - jump_eq_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Pcx).expect("Failed to get register Pcx"), - initial_pc - ); -} - -#[test] -fn test_halt_instruction() { - let mut cpu = create_test_processor(); - assert!(!cpu.halted); - - Instruction::Halt.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert!(cpu.halted); -} - -#[test] -fn test_nand_instruction() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 0b1100; - *cpu.reg(Register::Rg2).expect("Failed to get register Rg2") = 0b1010; - - let nand_instr = Instruction::Nand(RTypeArgs::new( - Some(Register::Rg1), - Some(Register::Rg2), - Some(Register::Rg3), - None, - )); - - nand_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg3).expect("Failed to get register Rg3"), - !0b1000 - ); -} - -#[test] -fn test_nor_instruction() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 0b1100; - *cpu.reg(Register::Rg2).expect("Failed to get register Rg2") = 0b1010; - - let nor_instr = Instruction::Nor(RTypeArgs::new( - Some(Register::Rg1), - Some(Register::Rg2), - Some(Register::Rg3), - None, - )); - - nor_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg3).expect("Failed to get register Rg3"), - !0b1110 - ); -} - -#[test] -fn test_xnor_instruction() { - let mut cpu = create_test_processor(); - *cpu.reg(Register::Rg1).expect("Failed to get register Rg1") = 0b1100; - *cpu.reg(Register::Rg2).expect("Failed to get register Rg2") = 0b1010; - - let xnor_instr = Instruction::Xnor(RTypeArgs::new( - Some(Register::Rg1), - Some(Register::Rg2), - Some(Register::Rg3), - None, - )); - - xnor_instr.execute(&mut cpu).expect( - "Emulator was slain by losing the game while attempting to execute instruction", - ); - assert_eq!( - cpu.get(Register::Rg3).expect("Failed to get register Rg3"), - !0b0110 - ); -} diff --git a/emulator/src/emulator/ui/control_unit.rs b/emulator/src/emulator/ui/control_unit.rs deleted file mode 100644 index 2cee3bb..0000000 --- a/emulator/src/emulator/ui/control_unit.rs +++ /dev/null @@ -1,197 +0,0 @@ -use crate::emulator::{ - system::model::{Command, Running, State}, - ui::interface::Component, -}; - -use common::{instructions::Register, prelude::Instruction}; - -pub struct ControlPanel { - visible: bool, - step_amount_input: String, - step_amount: usize, -} - -impl ControlPanel { - #[allow(clippy::must_use_candidate)] - pub fn new() -> Self { - Self { - visible: false, - step_amount_input: String::from("1"), - step_amount: 1, - } - } -} - -impl Default for ControlPanel { - fn default() -> Self { - Self::new() - } -} - -impl Component for ControlPanel { - fn category(&self) -> super::interface::Category { - super::interface::Category::Control - } - - fn visible(&mut self) -> &mut bool { - &mut self.visible - } - - fn name(&self) -> &'static str { - "Control Panel" - } - - fn render(&mut self, state: &mut State, ui: &mut egui::Ui, ctx: &egui::Context) { - ui.horizontal(|ui| { - // Pause / Run - if ui - .button(if state.running == Running::Running { - "Pause" - } else { - "Run" - }) - .clicked() - { - if state.running == Running::Running { - state.cmd_sender.send(Command::Stop).unwrap_or_else(|_| { - state.error_log.push("Failed to send command".to_string()); - }); - } else { - state.cmd_sender.send(Command::Start).unwrap_or_else(|_| { - state.error_log.push("Failed to send command".to_string()); - }); - } - } - - // Step - if ui.button("Step").clicked() { - state - .cmd_sender - .send(Command::Step(self.step_amount)) - .unwrap_or_else(|_| { - state.error_log.push("Failed to send command".to_string()); - }); - } - - // Resets the emulator and all attached devices - if ui.button("Reset All").clicked() { - state - .cmd_sender - .send(Command::Reset(0)) - .unwrap_or_else(|_| { - state.error_log.push("Failed to send command".to_string()); - }); - } - - // Resets the emulator and all attached devices - if ui.button("Clear Registers").clicked() { - state - .cmd_sender - .send(Command::Reset(1)) - .unwrap_or_else(|_| { - state.error_log.push("Failed to send command".to_string()); - }); - } - - // Resets the emulator and all attached devices - if ui.button("Clear RAM").clicked() { - state - .cmd_sender - .send(Command::Reset(2)) - .unwrap_or_else(|_| { - state.error_log.push("Failed to send command".to_string()); - }); - } - - ui.separator(); - - state.send(Command::RegisterRequest); - state.send(Command::RunningRequest); - state.send(Command::InstructionCountRequest); - - if ui - .text_edit_singleline(&mut self.step_amount_input) - .changed() - { - self.step_amount = if let Ok(amount) = self.step_amount_input.parse() { - amount - } else { - state - .error_log - .push("Unable to parse step amount".to_string()); - 1 - } - } - - // Status info - ui.label(format!( - "Status: {}", - match state.running { - Running::Running => "Running", - Running::Paused => "Paused", - Running::Halted => "Halted", - } - )); - - let pcx = state - .reg_file - .get(Register::Pcx) - .expect("PCX should never be invalid"); - let instructions = state.instructions; - - ui.label(format!("Instructions: {instructions}")); - ui.label(format!("PC: 0x{pcx:08X}")); - - let instruction = Instruction::decode( - state - .reg_file - .get(Register::Cir) - .expect("CIR should never be invalid"), - ) - .map_or_else( - |_| "Invalid Instruction".to_string(), - |instruction| instruction.to_string(), - ); - - ui.label(format!("Instruction: {instruction}")); - }); - - render_register_table(state, ui, ctx); - } -} - -fn render_register_table(state: &State, ui: &mut egui::Ui, _ctx: &egui::Context) { - // Left column - Registers - ui.vertical(|ui| { - ui.heading("Registers"); - - egui::ScrollArea::vertical() - .id_salt("register_inspector_scroll") - .show(ui, |ui| { - egui::Grid::new("registers_grid") - .num_columns(8) - .spacing([40.0, 4.0]) - .striped(true) - .show(ui, |ui| { - ui.label("Register"); - ui.label("Value"); - ui.label("Register"); - ui.label("Value"); - ui.label("Register"); - ui.label("Value"); - ui.label("Register"); - ui.label("Value"); - ui.end_row(); - - // iterate over state.reg_file.iter() in chunks of 4 registers - for chunk in state.reg_file.all().chunks(4) { - for reg in chunk { - ui.label(reg.0.to_string()); - ui.label(format!("0x{:08X} ({})", reg.1, reg.1,)); - } - ui.end_row(); - } - }); - }) - }); -} diff --git a/emulator/src/emulator/ui/display.rs b/emulator/src/emulator/ui/display.rs deleted file mode 100644 index 90ee4a9..0000000 --- a/emulator/src/emulator/ui/display.rs +++ /dev/null @@ -1,92 +0,0 @@ -use crate::emulator::{ - system::model::{Command, State}, - ui::interface::{Category, Component}, -}; - -use eframe::egui; -use egui::{Color32, FontId, Vec2}; - -const VGA_WIDTH: usize = 80; -const VGA_HEIGHT: usize = 25; - -pub struct Display { - visible: bool, -} - -impl Display { - #[must_use] - pub const fn new() -> Self { - Self { visible: false } - } -} - -impl Default for Display { - fn default() -> Self { - Self::new() - } -} - -impl Component for Display { - fn name(&self) -> &'static str { - "Display" - } - - fn category(&self) -> Category { - Category::IO - } - - fn visible(&mut self) -> &mut bool { - &mut self.visible - } - - fn render(&mut self, state: &mut State, ui: &mut egui::Ui, _ctx: &egui::Context) { - state.send(Command::DisplayRequest); - - let display: Vec = state.display_view.clone(); - let font_id = FontId::monospace(12.0); - - let char_width = ui.fonts(|f| f.glyph_width(&font_id, 'W')); - let line_height = ui.fonts(|f| f.row_height(&font_id)); - - #[expect(clippy::cast_precision_loss)] - let display_size = Vec2::new( - char_width * VGA_WIDTH as f32, - line_height * VGA_HEIGHT as f32, - ); - - let (rect, _response) = ui.allocate_exact_size(display_size, egui::Sense::all()); - - // Fill background - // ui.painter().rect_filled(rect, 0.0, Color32::BLACK); - - // Draw text - for y in 0..VGA_HEIGHT { - let mut row_text = String::with_capacity(VGA_WIDTH); - for x in 0..VGA_WIDTH { - let index = y * VGA_WIDTH + x; - if index < display.len() { - let byte = display[index]; - let ch = if (32..=126).contains(&byte) { - byte as char - } else { - ' ' - }; - row_text.push(ch); - } else { - row_text.push(' '); - } - } - - #[expect(clippy::cast_precision_loss)] - let text_pos = rect.min + Vec2::new(0.0, y as f32 * line_height); - - ui.painter().text( - text_pos, - egui::Align2::LEFT_TOP, - row_text, - font_id.clone(), - Color32::WHITE, - ); - } - } -} diff --git a/emulator/src/emulator/ui/editor.rs b/emulator/src/emulator/ui/editor.rs deleted file mode 100644 index e49ad85..0000000 --- a/emulator/src/emulator/ui/editor.rs +++ /dev/null @@ -1,545 +0,0 @@ -use std::fmt::Write; -use std::{ - ffi::OsStr, - fs, - path::{Path, PathBuf}, -}; - -use common::prelude::Instruction; -use egui::{Align, Context, Key, Layout, Ui}; - -use dsa_editor::{CodeEditor, ColorTheme, Syntax}; -use egui_file::FileDialog; - -use crate::emulator::{ - system::model::{Command, State}, - ui::interface::Component, -}; - -use assembler::prelude::*; - -#[derive(Default)] -pub struct Editor { - // editor state - path: Option, - unsaved: bool, - text: String, - buffer: String, - - // output / loading - output: Vec, - load_offset: u32, - offset_str: String, - - // cursor - currently unused - cursor_col: usize, - cursor_line: usize, - - // file dialogs - open_file_dialog: Option, - save_file_dialog: Option, - - // other - visible: bool, - error: Option, -} - -impl Component for Editor { - fn name(&self) -> &'static str { - "Editor" - } - - fn visible(&mut self) -> &mut bool { - &mut self.visible - } - - fn category(&self) -> super::interface::Category { - super::interface::Category::Programming - } - - fn render(&mut self, state: &mut State, ui: &mut Ui, ctx: &Context) { - if self.buffer != self.text { - self.unsaved = true; - } - - ui.vertical(|ui| { - // Top bar - - if ui.input(|i| i.key_pressed(Key::S) && i.modifiers.ctrl) { - self.save(); - } - - self.render_toolbar(state, ui, ctx); - - ui.add_space(4.0); // Add some spacing instead of just a separator - ui.separator(); - - let remaining_height = f32::max(ui.available_height() - 100.0, 100.0); - - ui.allocate_ui_with_layout( - egui::Vec2::new(ui.available_width(), remaining_height), - Layout::left_to_right(Align::Min), - |ui| { - self.render_editor(state, ui, ctx); - ui.separator(); - self.render_output(state, ui, ctx); - }, - ); - - self.render_bottom_bar(state, ui, ctx); - }); - } -} - -impl Editor { - #[must_use] - pub const fn new() -> Self { - Self { - path: None, - text: String::new(), - buffer: String::new(), - output: Vec::new(), - unsaved: true, - cursor_col: 1, - cursor_line: 1, - visible: false, - load_offset: 0, - offset_str: String::new(), - error: None, - open_file_dialog: None, - save_file_dialog: None, - } - } - - fn filename(&self) -> &str { - if let Some(path) = &self.path { - return path - .file_name() - .unwrap_or_else(|| OsStr::new("Unnamed!")) - .to_str() - .map_or_else( - || unreachable!("File name should be valid UTF-8."), - |ext| ext, - ); - } - "Unnamed!" - } - - fn extension(&self) -> &str { - if let Some(path) = &self.path { - return path - .extension() - .map_or_else(|| OsStr::new("Unknown!"), |ext| ext) - .to_str() - .map_or_else( - || unreachable!("File name should be valid UTF-8."), - |ext| ext, - ); - } - "Unknown!" - } - - fn save(&mut self) { - if self.open_file_dialog.is_some() { - // TODO: Flash an error stating you can only have one menu open at once. - self.open_file_dialog = None; - } - - if let Some(path) = &self.path { - // Save to existing path - self.buffer = self.text.clone(); - - let text = if path.extension().is_some_and(|ext| ext == "dsb") { - let mut res = Vec::new(); - for line in self.text.lines() { - for line in line.split_whitespace() { - match u32::from_str_radix(line, 16) { - Ok(num) => res.push(num), - Err(e) => { - self.error = Some(format!("Failed to parse file: {e}")); - return; - } - } - } - } - res.into_iter() - .flat_map(u32::to_be_bytes) - .collect::>() - } else { - self.text.as_bytes().to_vec() - }; - - if let Err(why) = std::fs::write(path, text) { - self.error = Some(format!("Failed to save file: {why}")); - } else { - self.unsaved = false; - } - } else { - // Open the save dialog. - let work_dir = std::env::current_dir().unwrap_or_else(|_| { - dirs::home_dir().expect( - "Couldn't get your current working directory or your home directory.", - ) - }); - - if self.save_file_dialog.is_none() { - let mut dialog = FileDialog::save_file(Some(work_dir)); - dialog.open(); - self.save_file_dialog = Some(dialog); - } - } - } - - fn open(&mut self) { - let work_dir = std::env::current_dir().unwrap_or_else(|_| { - dirs::home_dir().expect( - "Couldn't get your current working directory or your home directory.", - ) - }); - - if self.save_file_dialog.is_some() { - // TODO: Flash an error stating you can only have one menu open at once. - self.save_file_dialog = None; - } - - if self.open_file_dialog.is_none() { - if let Some(p) = &self.path { - let path = p.parent().map(Path::to_path_buf); - let mut dialog = FileDialog::open_file(path); - dialog.open(); - self.open_file_dialog = Some(dialog); - } else { - let mut dialog = FileDialog::open_file(Some(work_dir)); - dialog.open(); - self.open_file_dialog = Some(dialog); - } - } - } - - fn handle_file_dialogs(&mut self, ctx: &egui::Context) { - // Handle open dialog - if let Some(dialog) = &mut self.open_file_dialog - && dialog.show(ctx).selected() - { - if let Some(file) = dialog.path() { - // check if the file is a binary file - if file.extension().is_some_and(|ext| ext == "dsb") { - match std::fs::read(file) { - Ok(content) => { - let mut res = String::new(); - for (i, b) in content.iter().enumerate() { - _ = write!(res, "{b:02x}"); - if i % 4 == 3 { - res.push('\n'); - } - } - self.text = res.clone(); - self.buffer = res; - self.path = Some(file.to_path_buf()); - self.unsaved = false; - self.error = None; - } - Err(e) => { - self.error = Some(format!("Failed to read file: {e}")); - } - } - } else { - match std::fs::read_to_string(file) { - Ok(content) => { - self.text = content.clone(); - self.buffer = content; - self.path = Some(file.to_path_buf()); - self.unsaved = false; - self.error = None; - } - Err(e) => { - self.error = Some(format!("Failed to read file: {e}")); - } - } - } - } - self.open_file_dialog = None; - } - - // Handle save dialog - if let Some(dialog) = &mut self.save_file_dialog - && dialog.show(ctx).selected() - { - if let Some(file) = dialog.path() { - self.buffer = self.text.clone(); - - let content = if file.extension().is_some_and(|ext| ext == "dsb") { - let mut res = Vec::new(); - for line in self.text.lines() { - for line in line.split_whitespace() { - match u32::from_str_radix(line, 16) { - Ok(num) => res.push(num), - Err(e) => { - self.error = - Some(format!("Failed to parse file: {e}")); - return; - } - } - } - } - res.into_iter() - .flat_map(u32::to_be_bytes) - .collect::>() - } else { - self.text.clone().as_bytes().to_vec() - }; - - match std::fs::write(file, content) { - Ok(()) => { - self.path = Some(file.to_path_buf()); - self.unsaved = false; - self.error = None; - } - Err(e) => { - self.error = Some(format!("Failed to save file: {e}")); - } - } - } - self.save_file_dialog = None; - } - } - - fn render_output(&self, _state: &mut State, ui: &mut Ui, _ctx: &Context) { - // Output area with synchronized scrolling - egui::ScrollArea::vertical() - .id_salt("output_scroll") - .max_width(400.0) - .show(ui, |ui| { - if self.output.is_empty() { - ui.label( - egui::RichText::new("No output data") - .font(egui::FontId::monospace(12.0)) - .color(egui::Color32::GRAY), - ); - return; - } - - egui::Grid::new("output_grid") - .spacing([5.0, 2.0]) // Horizontal and vertical spacing - .num_columns(4) - .striped(false) - .show(ui, |ui| { - // Process bytes in chunks of 4 - for (line_num, chunk) in self.output.chunks(4).enumerate() { - let address = line_num * 4; - - // Convert chunk to u32 (little-endian) - let mut bytes = [0u8; 4]; - for (i, &byte) in chunk.iter().enumerate() { - if i < 4 { - bytes[i] = byte; - } - } - let value = u32::from_be_bytes(bytes); - - // Address column - ui.with_layout( - egui::Layout::left_to_right(egui::Align::Center), - |ui| { - ui.set_min_width(80.0); - let style = ui.style_mut(); - style.visuals.widgets.inactive.bg_fill = - egui::Color32::from_gray(30); - ui.label( - egui::RichText::new(format!("0x{address:04X}")) - .font(egui::FontId::monospace(12.0)), - ); - }, - ); - - // Individual bytes column - let byte_str = chunk - .iter() - .map(|b| format!("{b:02X}")) - .collect::>() - .join(" "); - - ui.label( - egui::RichText::new(format!("{byte_str:<11}")) - .font(egui::FontId::monospace(12.0)) - .color(egui::Color32::from_rgb(200, 200, 255)), - ); - - // Hex column - ui.label( - egui::RichText::new(format!("0x{value:08X}")) - .font(egui::FontId::monospace(12.0)) - .color(egui::Color32::from_rgb(255, 200, 200)), - ); - - // Instruction column - let instruction = Instruction::decode(value).map_or_else( - |_| format!("{value:10}"), - |instruction| instruction.to_string(), - ); - - ui.label( - egui::RichText::new(instruction) - .font(egui::FontId::monospace(12.0)) - .color(egui::Color32::from_rgb(200, 255, 200)), - ); - - ui.end_row(); - } - }); - }); - } - - fn render_editor(&mut self, _state: &mut State, ui: &mut Ui, _ctx: &Context) { - let available_width = ui.available_width(); - let syntax = match self.extension() { - "dsa" => Some(Syntax::new("dsa")), - _ => None, - }; - - let ed = CodeEditor::default() - .id_source("editor") - .with_fontsize(12.0) - .with_rows(0) - .with_theme(ColorTheme::default()) - .with_syntax(Syntax::dsa()) - .with_numlines(true) - .desired_width(available_width - 500.0); - - let mut editor = ed.clone(); - - if let Some(syntax) = syntax { - editor = ed.with_syntax(syntax); - } - - editor.show(ui, &mut self.text); - } - - fn render_bottom_bar(&self, _state: &mut State, ui: &mut Ui, _ctx: &Context) { - ui.horizontal(|ui| { - // error display - ui.label( - egui::RichText::new(self.error.clone().unwrap_or_default()) - .color(egui::Color32::RED), - ); - - // line and col - ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { - ui.label(format!("Ln {}, Col {}", self.cursor_line, self.cursor_col)); - }); - }); - } - - fn build(&mut self) { - if let Some(path) = &self.path { - match path.extension().and_then(|ext| ext.to_str()) { - Some("dsa") => { - let mut compiler = CompilerEngine::new(); - compiler.start_compilation(path); - - // Or block until done - let instructions = match compiler.wait_for_result() { - Ok(instructions) => instructions, - Err(e) => { - self.error = Some(e.to_string()); - return; - } - }; - - self.output = instructions - .iter() - .flat_map(|i| i.encode().to_be_bytes().to_vec()) - .collect(); - } - Some("dsb") => { - if let Ok(bytes) = fs::read(path) { - self.output = bytes; - } else { - self.error = Some("Failed to read file".to_string()); - } - } - _ => { - self.error = Some(format!("Invalid file type: {}", self.filename())); - } - } - } - } - - fn render_toolbar(&mut self, state: &State, ui: &mut Ui, ctx: &Context) { - self.handle_file_dialogs(ctx); - - ui.horizontal(|ui| { - ui.label(format!("File type: {}", self.extension())); - ui.label(format!("Filename: {}", self.filename())); - ui.label(format!("Unsaved: {}", self.unsaved)); - - // number of lines in the file - ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { - let line_count = self.text.lines().count(); - ui.label(format!("Lines: {line_count}")); - }); - }); - - ui.horizontal(|ui| { - ui.spacing_mut().button_padding = egui::vec2(8.0, 4.0); - ui.spacing_mut().item_spacing.x = 6.0; - - // Opens a file - if ui.button("Open").clicked() { - self.open(); - } - - // Saves the current file - if ui.button("Save").clicked() { - self.save(); - } - - // builds the current file - if ui.button("Build").clicked() && !self.unsaved { - self.build(); - } - - // Loads the generated binary into the assembler at the provided offset - if ui.button("Load").clicked() { - if self.error.is_some() { - self.error = - Some("Can't load program at invalid offset!".to_string()); - } - - state - .cmd_sender - .send(Command::Write(self.load_offset, self.output.clone())) - .unwrap_or_else(|_| { - self.error = Some("Failed to send command".to_string()); - }); - } - - // Entry widget to enter a load offset - if ui.text_edit_singleline(&mut self.offset_str).changed() { - if let Some(offset) = parse_address(&self.offset_str) { - self.load_offset = offset; - self.error = None; - } else { - self.error = Some("Invalid offset".to_string()); - } - } - }); - } -} - -fn parse_address(address: &str) -> Option { - address.strip_prefix("0x").map_or_else( - || { - address.strip_prefix("0b").map_or_else( - || { - address.strip_prefix("0o").map_or_else( - || address.parse::().ok(), - |oct| u32::from_str_radix(oct, 8).ok(), - ) - }, - |bin| u32::from_str_radix(bin, 2).ok(), - ) - }, - |hex| u32::from_str_radix(hex, 16).ok(), - ) -} diff --git a/emulator/src/emulator/ui/history.rs b/emulator/src/emulator/ui/history.rs deleted file mode 100644 index 64be793..0000000 --- a/emulator/src/emulator/ui/history.rs +++ /dev/null @@ -1,84 +0,0 @@ -use egui::{Context, Ui}; - -use crate::emulator::{ - system::model::{Command, State}, - ui::interface::Component, -}; - -pub struct History { - visible: bool, -} - -impl Component for History { - fn name(&self) -> &'static str { - "Instruction History" - } - - fn visible(&mut self) -> &mut bool { - &mut self.visible - } - - fn category(&self) -> super::interface::Category { - super::interface::Category::Control - } - - fn render(&mut self, state: &mut State, ui: &mut Ui, _ctx: &Context) { - state.send(Command::HistoryRequest); - - egui::ScrollArea::vertical() - .id_salt("output_scroll") - .max_width(400.0) - .show(ui, |ui| { - if state.instruction_history.is_empty() { - ui.label( - egui::RichText::new("No output data") - .font(egui::FontId::monospace(12.0)) - .color(egui::Color32::GRAY), - ); - return; - } - - egui::Grid::new("output_grid") - .spacing([5.0, 2.0]) // Horizontal and vertical spacing - .num_columns(4) - .striped(false) - .show(ui, |ui| { - // Process bytes in chunks of 4 - for (idx, instruction) in - state.instruction_history.iter().enumerate() - { - ui.label(format!("{idx}: ")); - - // Hex column - let addr = instruction.0; - ui.label( - egui::RichText::new(format!("0x{addr:08X}")) - .font(egui::FontId::monospace(12.0)) - .color(egui::Color32::from_rgb(255, 200, 200)), - ); - - ui.label( - egui::RichText::new(instruction.1.to_string()) - .font(egui::FontId::monospace(12.0)) - .color(egui::Color32::from_rgb(200, 255, 200)), - ); - - ui.end_row(); - } - }); - }); - } -} - -impl Default for History { - fn default() -> Self { - Self::new() - } -} - -impl History { - #[must_use] - pub const fn new() -> Self { - Self { visible: false } - } -} diff --git a/emulator/src/emulator/ui/interface.rs b/emulator/src/emulator/ui/interface.rs deleted file mode 100644 index f5b85c9..0000000 --- a/emulator/src/emulator/ui/interface.rs +++ /dev/null @@ -1,128 +0,0 @@ -use crate::emulator::system::model::{Command, Running, State, StateUpdate}; -use std::sync::mpsc::{Receiver, Sender}; - -pub trait Component { - fn render(&mut self, state: &mut State, ui: &mut egui::Ui, ctx: &egui::Context); - fn visible(&mut self) -> &mut bool; - fn name(&self) -> &'static str; - fn category(&self) -> Category; -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Category { - Control, - Memory, - IO, - Programming, -} - -impl Category { - #[must_use] - pub const fn as_str(&self) -> &'static str { - match self { - Self::Control => "Control Systems", - Self::Memory => "Memory Systems", - Self::IO => "I/O Systems", - Self::Programming => "Programming", - } - } - - #[must_use] - pub fn list() -> Vec { - vec![Self::Control, Self::Memory, Self::IO, Self::Programming] - } -} - -pub struct EmulatorUI { - pub state: State, - pub components: Vec>, -} - -impl EmulatorUI { - #[must_use] - pub fn new(sender: Sender, receiver: Receiver) -> Self { - Self { - state: State::new(sender, receiver), - components: vec![], - } - } - - pub fn add_component(&mut self, component: Box) { - self.components.push(component); - } -} - -impl eframe::App for EmulatorUI { - fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { - if let Err(e) = self.state.update() { - self.state.error_log.push(e.to_string()); - } - - if self.state.running == Running::Running { - ctx.request_repaint(); - } - - egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { - ui.with_layout( - egui::Layout::top_down_justified(egui::Align::Center) - .with_main_align(egui::Align::Min), - |ui| { - ui.allocate_space(egui::vec2(0.0, 15.0)); - ui.heading("DSA Simulator (Damn Simple Architecture 🔥)"); - ui.allocate_space(egui::vec2(0.0, 15.0)); - }, - ); - }); - - egui::CentralPanel::default().show(ctx, |ui| { - ui.with_layout(egui::Layout::left_to_right(egui::Align::Center), |_ui| { - egui::Window::new("Main Menu") - .resizable(false) - .default_width(300.0) - .show(ctx, |ui| { - super::menu::render_menu(self, ui, ctx); - }); - - for c in &mut self.components { - let mut visible = *c.visible(); - if visible { - egui::Window::new(c.name()) - .open(&mut visible) - .show(ctx, |ui| { - c.render(&mut self.state, ui, ctx); - }); - } - *c.visible() = visible; - } - }); - }); - - egui::TopBottomPanel::bottom("bottom_panel").show(ctx, |ui| { - ui.horizontal_centered(|ui| { - ui.group(|ui| { - ui.add_space(10.0); - ui.strong("Authors:"); - ui.add_space(5.0); - ui.label("zxq5"); - ui.label("nullndvoid"); - ui.add_space(10.0); - ui.separator(); - ui.add_space(10.0); - ui.strong("Version"); - ui.add_space(5.0); - ui.label("1.0.0"); - ui.add_space(10.0); - ui.separator(); - ui.add_space(10.0); - ui.strong("Source:"); - ui.add_space(5.0); - ui.hyperlink_to( - "https://git.zxq5.dev/LowLevelDevs/damn_simple_architecture", - "https://git.zxq5.dev/LowLevelDevs/damn_simple_architecture", - ); - ui.add_space(10.0); - }); - }); - }); - } -} diff --git a/emulator/src/emulator/ui/loader.rs b/emulator/src/emulator/ui/loader.rs deleted file mode 100644 index 75b2bdd..0000000 --- a/emulator/src/emulator/ui/loader.rs +++ /dev/null @@ -1,294 +0,0 @@ -use std::{ - ffi::OsStr, - path::{Path, PathBuf}, -}; - -use common::prelude::Instruction; -use egui::{Context, Ui}; -use egui_file::FileDialog; - -use crate::emulator::{ - system::model::{Command, State}, - ui::interface::Component, -}; - -#[derive(Default)] -pub struct Loader { - path: Option, - output: Vec, - load_offset: u32, - offset_str: String, - - // file dialogs - open_file_dialog: Option, - - // other - visible: bool, - error: Option, -} - -impl Component for Loader { - fn name(&self) -> &'static str { - "Loader" - } - - fn visible(&mut self) -> &mut bool { - &mut self.visible - } - - fn category(&self) -> super::interface::Category { - super::interface::Category::Programming - } - - fn render(&mut self, state: &mut State, ui: &mut Ui, ctx: &Context) { - ui.vertical(|ui| { - self.render_toolbar(state, ui, ctx); - - ui.add_space(4.0); // Add some spacing instead of just a separator - ui.separator(); - - egui::ScrollArea::vertical() - .auto_shrink([false; 2]) - .max_height(ui.available_height() - 100.0) - .show(ui, |ui| { - self.render_output(state, ui, ctx); - }); - - self.render_bottom_bar(state, ui, ctx); - }); - } -} - -impl Loader { - #[must_use] - pub const fn new() -> Self { - Self { - path: None, - output: Vec::new(), - visible: false, - load_offset: 0, - offset_str: String::new(), - error: None, - open_file_dialog: None, - } - } - - fn filename(&self) -> &str { - if let Some(path) = &self.path { - return path - .file_name() - .unwrap_or_else(|| OsStr::new("Unnamed!")) - .to_str() - .map_or_else( - || unreachable!("File name should be valid UTF-8."), - |ext| ext, - ); - } - "Unnamed!" - } - - fn open(&mut self) { - let work_dir = std::env::current_dir().unwrap_or_else(|_| { - dirs::home_dir().expect( - "Couldn't get your current working directory or your home directory.", - ) - }); - - if self.open_file_dialog.is_some() { - // TODO: Flash an error stating you can only have one menu open at once. - self.open_file_dialog = None; - } - - if self.open_file_dialog.is_none() { - if let Some(p) = &self.path { - let path = p.parent().map(Path::to_path_buf); - let mut dialog = FileDialog::open_file(path); - dialog.open(); - self.open_file_dialog = Some(dialog); - } else { - let mut dialog = FileDialog::open_file(Some(work_dir)); - dialog.open(); - self.open_file_dialog = Some(dialog); - } - } - } - - fn handle_file_dialogs(&mut self, ctx: &egui::Context) { - // Handle open dialog - if let Some(dialog) = &mut self.open_file_dialog - && dialog.show(ctx).selected() - { - if let Some(file) = dialog.path() { - // check if the file is a binary file - if file.extension().is_some_and(|ext| ext == "dsb") { - match std::fs::read(file) { - Ok(content) => { - self.output = content; - self.error = None; - } - Err(e) => { - self.error = Some(format!("Failed to read file: {e}")); - } - } - } - } - self.open_file_dialog = None; - } - } - - fn render_output(&self, _state: &mut State, ui: &mut Ui, _ctx: &Context) { - // Output area with synchronized scrolling - egui::ScrollArea::vertical() - .id_salt("output_scroll") - .max_width(400.0) - .show(ui, |ui| { - if self.output.is_empty() { - ui.label( - egui::RichText::new("No output data") - .font(egui::FontId::monospace(12.0)) - .color(egui::Color32::GRAY), - ); - return; - } - - egui::Grid::new("output_grid") - .spacing([5.0, 2.0]) // Horizontal and vertical spacing - .num_columns(4) - .striped(false) - .show(ui, |ui| { - // Process bytes in chunks of 4 - for (line_num, chunk) in self.output.chunks(4).enumerate() { - let address = line_num * 4; - - // Convert chunk to u32 (little-endian) - let mut bytes = [0u8; 4]; - for (i, &byte) in chunk.iter().enumerate() { - if i < 4 { - bytes[i] = byte; - } - } - let value = u32::from_be_bytes(bytes); - - // Address column - ui.with_layout( - egui::Layout::left_to_right(egui::Align::Center), - |ui| { - ui.set_min_width(80.0); - let style = ui.style_mut(); - style.visuals.widgets.inactive.bg_fill = - egui::Color32::from_gray(30); - ui.label( - egui::RichText::new(format!("0x{address:04X}")) - .font(egui::FontId::monospace(12.0)), - ); - }, - ); - - // Individual bytes column - let byte_str = chunk - .iter() - .map(|b| format!("{b:02X}")) - .collect::>() - .join(" "); - - ui.label( - egui::RichText::new(format!("{byte_str:<11}")) - .font(egui::FontId::monospace(12.0)) - .color(egui::Color32::from_rgb(200, 200, 255)), - ); - - // Hex column - ui.label( - egui::RichText::new(format!("0x{value:08X}")) - .font(egui::FontId::monospace(12.0)) - .color(egui::Color32::from_rgb(255, 200, 200)), - ); - - // Instruction column - let instruction = Instruction::decode(value).map_or_else( - |_| format!("{value:10}"), - |instruction| instruction.to_string(), - ); - - ui.label( - egui::RichText::new(instruction) - .font(egui::FontId::monospace(12.0)) - .color(egui::Color32::from_rgb(200, 255, 200)), - ); - - ui.end_row(); - } - }); - }); - } - - fn render_bottom_bar(&self, _state: &mut State, ui: &mut Ui, _ctx: &Context) { - ui.horizontal(|ui| { - // error display - ui.label( - egui::RichText::new(self.error.clone().unwrap_or_default()) - .color(egui::Color32::RED), - ); - }); - } - - fn render_toolbar(&mut self, state: &State, ui: &mut Ui, ctx: &Context) { - self.handle_file_dialogs(ctx); - - ui.horizontal(|ui| { - ui.label(format!("Filename: {}", self.filename())); - }); - - ui.horizontal(|ui| { - ui.spacing_mut().button_padding = egui::vec2(8.0, 4.0); - ui.spacing_mut().item_spacing.x = 6.0; - - // Opens a file - if ui.button("Open").clicked() { - self.open(); - } - - // Loads the generated binary into the assembler at the provided offset - if ui.button("Load").clicked() { - if self.error.is_some() { - self.error = - Some("Can't load program at invalid offset!".to_string()); - } - - state - .cmd_sender - .send(Command::Write(self.load_offset, self.output.clone())) - .unwrap_or_else(|_| { - self.error = Some("Failed to send command".to_string()); - }); - } - - // Entry widget to enter a load offset - if ui.text_edit_singleline(&mut self.offset_str).changed() { - if let Some(offset) = parse_address(&self.offset_str) { - self.load_offset = offset; - self.error = None; - } else { - self.error = Some("Invalid offset".to_string()); - } - } - }); - } -} - -fn parse_address(address: &str) -> Option { - address.strip_prefix("0x").map_or_else( - || { - address.strip_prefix("0b").map_or_else( - || { - address.strip_prefix("0o").map_or_else( - || address.parse::().ok(), - |oct| u32::from_str_radix(oct, 8).ok(), - ) - }, - |bin| u32::from_str_radix(bin, 2).ok(), - ) - }, - |hex| u32::from_str_radix(hex, 16).ok(), - ) -} diff --git a/emulator/src/emulator/ui/memory_inspector.rs b/emulator/src/emulator/ui/memory_inspector.rs deleted file mode 100644 index d6206d1..0000000 --- a/emulator/src/emulator/ui/memory_inspector.rs +++ /dev/null @@ -1,162 +0,0 @@ -use std::num::ParseIntError; - -use common::prelude::Instruction; - -use crate::emulator::{ - system::model::{Command, State}, - ui::interface::Component, -}; - -#[derive(Default)] -pub struct MemoryInspector { - view_size: u32, - view_addr: u32, - visible: bool, - addr_input: String, -} - -impl MemoryInspector { - #[must_use] - pub const fn new() -> Self { - Self { - view_size: 256, - view_addr: 0, - visible: false, - addr_input: String::new(), - } - } -} - -impl Component for MemoryInspector { - fn category(&self) -> super::interface::Category { - super::interface::Category::Memory - } - - fn name(&self) -> &'static str { - "Memory Inspector" - } - - fn visible(&mut self) -> &mut bool { - &mut self.visible - } - - fn render(&mut self, state: &mut State, ui: &mut egui::Ui, ctx: &egui::Context) { - // Right column - Memory - ui.vertical(|ui| { - ui.heading("Memory Inspector"); - ui.add_space(10.0); - - // Address input section - ui.horizontal(|ui| { - ui.label("Address:"); - - let address_response = ui.add( - egui::TextEdit::singleline(&mut self.addr_input) - .hint_text("0x1000 or 4096") - .desired_width(150.0), - ); - - ui.add_space(10.0); - - // Search button - let search_clicked = ui.button("🔍 Search").clicked(); - - // Handle Enter key in text field - let enter_pressed = address_response.lost_focus() - && ctx.input(|i| i.key_pressed(egui::Key::Enter)); - - if search_clicked || enter_pressed { - if let Ok(new) = parse_address(&self.addr_input) { - self.view_addr = new; - } else { - state.error_log.push("Invalid address".to_string()); - } - } - - let _ = state - .cmd_sender - .send(Command::MemRequest(self.view_addr, self.view_size)); - - ui.label("(hex or decimal)"); - }); - - // Show input error if any - if let Some(error) = state.error_log.last() { - ui.colored_label(egui::Color32::RED, format!("Error: {error}")); - } - - ui.add_space(10.0); - - // Memory table - egui::ScrollArea::vertical() - .auto_shrink(true) - .id_salt("memory_inspector_scroll") - .show(ui, |ui| { - egui::Grid::new("memory_grid") - .spacing([12.0, 2.0]) - .min_col_width(5.0) - .striped(true) - .show(ui, |ui| { - // Header - ui.strong("Address"); - - for i in 0..4 { - ui.strong(format!("{i:X}")); - } - - ui.strong("Decimal"); - ui.strong("Instruction"); - - ui.end_row(); - - // Memory data (8 bytes per row) - for (row, chunk) in (0u32..).zip(state.memory_view.chunks(4)) - { - let row_address = self.view_addr + (row * 4); - ui.monospace(format!( - "0x{row_address:08X} ({row_address})" - )); - for &byte in chunk { - ui.monospace(format!("{byte:02X}")); - } - - // Fill remaining columns if last row is incomplete - for _ in chunk.len()..4 { - ui.label(""); - } - - // combine all 4 bytes in the chunk into a u32 - let combined = chunk.iter().fold(0u32, |acc, &byte| { - (acc << 8) | u32::from(byte) - }); - - ui.monospace(format!("{combined}")); - ui.monospace(format!( - "{}", - Instruction::decode(combined) - .unwrap_or(Instruction::Nop) - )); - - ui.end_row(); - } - }); - }); - }); - } -} - -fn parse_address(address: &str) -> Result { - if let Some(hex_part) = address.strip_prefix("0x") { - return u32::from_str_radix(hex_part, 16); - } - - if let Some(bin_part) = address.strip_prefix("0b") { - return u32::from_str_radix(bin_part, 2); - } - - if let Some(oct_part) = address.strip_prefix("0o") { - return u32::from_str_radix(oct_part, 8); - } - - address.parse::() -} diff --git a/emulator/src/emulator/ui/menu.rs b/emulator/src/emulator/ui/menu.rs deleted file mode 100644 index edd5008..0000000 --- a/emulator/src/emulator/ui/menu.rs +++ /dev/null @@ -1,30 +0,0 @@ -use crate::emulator::ui::interface::{Category, EmulatorUI}; - -pub fn render_menu(state: &mut EmulatorUI, ui: &mut egui::Ui, _ctx: &egui::Context) { - ui.with_layout( - egui::Layout::top_down_justified(egui::Align::Center), - |ui| { - ui.set_max_width(300.0); - ui.set_min_width(300.0); - ui.spacing_mut().button_padding = egui::vec2(10.0, 5.0); - - for cat in Category::list() { - ui.add_space(10.0); - ui.heading(cat.as_str()); - ui.add_space(10.0); - - for comp in &mut state.components { - let name = comp.name(); - if comp.category() == cat { - ui.toggle_value(comp.visible(), name); - } - } - - ui.add_space(10.0); - ui.separator(); - } - - ui.add_space(10.0); - }, - ); -} diff --git a/emulator/src/emulator/ui/mod.rs b/emulator/src/emulator/ui/mod.rs deleted file mode 100644 index 9e0cf7e..0000000 --- a/emulator/src/emulator/ui/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub mod control_unit; -pub mod display; -pub mod editor; -pub mod history; -pub mod interface; -pub mod loader; -pub mod memory_inspector; -pub mod menu; -pub mod stack_inspector; diff --git a/emulator/src/emulator/ui/stack_inspector.rs b/emulator/src/emulator/ui/stack_inspector.rs deleted file mode 100644 index b89f4f0..0000000 --- a/emulator/src/emulator/ui/stack_inspector.rs +++ /dev/null @@ -1,79 +0,0 @@ -use crate::emulator::{ - system::model::{Command, State}, - ui::interface::Component, -}; - -use common::instructions::Register; - -pub struct StackInspector { - visible: bool, -} - -impl Default for StackInspector { - fn default() -> Self { - Self::new() - } -} - -impl StackInspector { - #[must_use] - pub const fn new() -> Self { - Self { visible: false } - } -} - -impl Component for StackInspector { - fn visible(&mut self) -> &mut bool { - &mut self.visible - } - - fn name(&self) -> &'static str { - "Stack Inspector" - } - - fn category(&self) -> super::interface::Category { - super::interface::Category::Memory - } - - fn render(&mut self, state: &mut State, ui: &mut egui::Ui, _ctx: &egui::Context) { - state.send(Command::StackRequest); - - ui.vertical(|ui| { - ui.heading("Stack Inspector"); - egui::ScrollArea::vertical() - .id_salt("stack_inspector_scroll") - .show(ui, |ui| { - egui::Grid::new("stack_grid") - .num_columns(2) - .spacing([40.0, 4.0]) - .striped(true) - .show(ui, |ui| { - ui.label("Address"); - ui.label("Value"); - ui.end_row(); - - for (i, value) in - state.stack_view.chunks(4).take(32).enumerate() - { - let value = u32::from_be_bytes(value.try_into().expect( - "Could not read 4 byte instruction or data! Something is wrong.", - )); - ui.label(format!( - "{} [{}]", - i, - state.reg_file.get(Register::Spr).expect("SPR should never be invalid") - i as u32 * 4 - )); - ui.label(format!("0x{value:08X} ({value})")); - ui.end_row(); - } - - if state.stack_view.is_empty() { - ui.label("(empty)"); - ui.label("-"); - ui.end_row(); - } - }); - }); - }); - } -} diff --git a/emulator/src/lib.rs b/emulator/src/lib.rs deleted file mode 100644 index 32ce805..0000000 --- a/emulator/src/lib.rs +++ /dev/null @@ -1,132 +0,0 @@ -#![deny( - clippy::unwrap_used, - clippy::nursery, - clippy::perf, - clippy::pedantic, - clippy::complexity -)] -#![allow( - clippy::cast_possible_truncation, - clippy::missing_panics_doc, - clippy::missing_errors_doc, - clippy::match_wildcard_for_single_variants -)] - -pub mod emulator; - -use std::{ - sync::{ - Arc, - mpsc::{Receiver, Sender}, - }, - thread, -}; - -#[cfg(target_os = "android")] -use winit::platform::android::{EventLoopBuilderExtAndroid, activity::AndroidApp}; - -use crate::emulator::{ - misc::rpc::RpcClient, - system::{ - emulator::run_emulator, - memory::MainStore, - model::{Command, StateUpdate}, - processor::Processor, - }, - ui::{ - control_unit::ControlPanel, display::Display, editor::Editor, - interface::EmulatorUI, memory_inspector::MemoryInspector, - stack_inspector::StackInspector, - }, -}; - -#[cfg(target_os = "android")] -#[unsafe(no_mangle)] -pub fn android_main(app: AndroidApp) -> Result<(), Box> { - use crate::emulator::{config::Config, misc::rpc::get_rpc_client_or_none}; - use std::path::Path; - - // Initialize channels and read in configuration. - let (cmd_sender, cmd_receiver) = std::sync::mpsc::channel(); - let (state_sender, state_reciever) = std::sync::mpsc::channel(); - let config = Config::load(Path::new(".dsa.emulator.toml"))?; - - // Setup RPC if enabled. - let (rpc_sender, rpc_reciever) = std::sync::mpsc::channel(); - - let rpc_client = - get_rpc_client_or_none(&config, rpc_sender, rpc_reciever)?.map(Arc::new); - - setup_emulator(cmd_receiver, state_sender, rpc_client); - - let ui = setup_ui(cmd_sender, state_reciever); - - // Run UI. - #[allow(unused_variables)] - let options = eframe::NativeOptions { - viewport: egui::ViewportBuilder::default().with_inner_size([800.0, 600.0]), - event_loop_builder: Some(Box::new(move |builder| { - #[cfg(target_os = "android")] - builder.with_android_app(app); - })), - ..Default::default() - }; - - eframe::run_native( - "DSA Simulator (Damn Simple Architecture 🔥)", - options, - Box::new(move |cc| { - cc.egui_ctx.set_visuals(egui::Visuals::default()); - Ok(Box::new(ui)) - }), - )?; - - Ok(()) -} - -pub fn setup_emulator( - cmd_receiver: Receiver, - state_sender: Sender, - rpc_client: Option>, -) { - let main_store = MainStore::new(); - let processor = Processor::new(Box::new(main_store), vec![]); - - thread::spawn(move || { - run_emulator(&cmd_receiver, &state_sender, processor, rpc_client.as_ref()); - }); -} - -/// Creates the [`EmulatorUI`]. -#[must_use] -pub fn setup_ui( - cmd_sender: Sender, - state_reciever: Receiver, -) -> EmulatorUI { - let mut ui = EmulatorUI::new(cmd_sender, state_reciever); - - // Create UI modules. - let control_unit = ControlPanel::new(); - - ui.add_component(Box::new(control_unit)); - - let mem_inspector = MemoryInspector::new(); - ui.add_component(Box::new(mem_inspector)); - - let stack_inspector = StackInspector::new(); - ui.add_component(Box::new(stack_inspector)); - - let editor = Editor::new(); - ui.add_component(Box::new(editor)); - - let display = Display::new(); - ui.add_component(Box::new(display)); - - let history = emulator::ui::history::History::new(); - ui.add_component(Box::new(history)); - - let loader = emulator::ui::loader::Loader::new(); - ui.add_component(Box::new(loader)); - - ui -} diff --git a/emulator/src/main.rs b/emulator/src/main.rs deleted file mode 100644 index b074df9..0000000 --- a/emulator/src/main.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::path::Path; -use std::sync::Arc; - -use dsa_rs::emulator::{config::Config, misc::rpc::get_rpc_client_or_none}; - -fn main() -> Result<(), Box> { - // Initialize channels and read in configuration. - let (cmd_sender, cmd_receiver) = std::sync::mpsc::channel(); - let (state_sender, state_reciever) = std::sync::mpsc::channel(); - let config = Config::load(Path::new(".dsa.emulator.toml"))?; - - // Setup RPC if enabled. - let (rpc_sender, rpc_reciever) = std::sync::mpsc::channel(); - - let rpc_client = - get_rpc_client_or_none(&config, rpc_sender, rpc_reciever)?.map(Arc::new); - - dsa_rs::setup_emulator(cmd_receiver, state_sender, rpc_client); - - let ui = dsa_rs::setup_ui(cmd_sender, state_reciever); - - // Run UI. - #[allow(unused_variables)] - let options = eframe::NativeOptions { - viewport: egui::ViewportBuilder::default().with_inner_size([800.0, 600.0]), - ..Default::default() - }; - - eframe::run_native( - "DSA Simulator (Damn Simple Architecture 🔥)", - options, - Box::new(move |cc| { - cc.egui_ctx.set_visuals(egui::Visuals::default()); - Ok(Box::new(ui)) - }), - )?; - - Ok(()) -} diff --git a/resources/dsa/bf.dsa b/resources/dsa/bf.dsa deleted file mode 100644 index 57e39d9..0000000 --- a/resources/dsa/bf.dsa +++ /dev/null @@ -1,224 +0,0 @@ - -// a simple brainf##k interpreter, -// because I already wrote a compiler lol. - -include print "./lib/io/print.dsa" - -// "print hello world" -db program: "++++++++++++++++++++++++++++++++++++++++++++ ->++++++++++++++++++++++++++++++++ ->++++++++++++++++ -> ->+ -<< -[ ->> -> ->++++++++++ -<< -[->+>-[>+>>]>[+[-<+>]>+>>]<<<<<<] ->[<+>-] ->[-] ->> ->++++++++++ -< -[->-[>+>>]>[+[-<+>]>+>>]<<<<<] ->[-] ->>[++++++++++++++++++++++++++++++++++++++++++++++++.[-]] -<[++++++++++++++++++++++++++++++++++++++++++++++++.[-]] -<<<++++++++++++++++++++++++++++++++++++++++++++++++.[-] -<<<<<<<.>. ->>[>>+<<-] ->[>+<<+>-] ->[<+>-] -<<<- -] -<<++..." - -db error: "Invalid Instruction!" -dw stack: 0x10000 -dw input: 0x30000 -resb data: 1024 - -// set up a stack so we can call functions -_init_stack: - ldw stack, bpr - mov bpr, spr - -start: - // load the start of the program into rg0 - lwi program, rg0 - lwi data, rg1 - - // rg0 is our instruction pointer - // rg1 is our data pointer - // rg2 is the value at the data pointer - // rg3 stores the current instruction - // rg4 is the expression nesting level. - - lli 43, rg8 // + = 43 increment - lli 45, rg9 // - = 45 decrement - lli 62, rga // > = 62 increment pointer - lli 60, rgb // < = 60 decrement pointer - lli 46, rgc // . = 46 output - lli 44, rgd // , = 44 input - lli 91, rge // [ = 91 loop start - lli 93, rgf // ] = 93 loop end - -loop_start: - // load the current instruction into rg3 - ldb rg0, rg3 - - // switch on the instruction - // all cases will return to either loop_start or loop_end - cmp rg3, rg8 - jeq increment - cmp rg3, rg9 - jeq decrement - cmp rg3, rga - jeq inc_ptr - cmp rg3, rgb - jeq dec_ptr - cmp rg3, rgc - jeq output - cmp rg3, rgd - jeq input - cmp rg3, rge - jeq expr_start - cmp rg3, rgf - jeq expr_end - cmp rg3, zero - jeq end - - // if we get here, we don't know what the instruction is - lwi error, rg2 - pusha 2 - push rg2 - call print::print - pop zero - popa 2 - -end: - hlt - -loop_end: - inc rg0 - jmp loop_start - -// ------------------------------------------ -// increment the current cell -increment: - inc rg2 - jmp loop_end - -// ------------------------------------------ -// decrement the current cell -decrement: - dec rg2 - jmp loop_end - -// ------------------------------------------ -// increment the pointer -inc_ptr: - stw rg2, rg1 - addi rg1, 4 - ldw rg1, rg2 - jmp loop_end - -// ------------------------------------------ -// decrement the pointer -dec_ptr: - stw rg2, rg1 - subi rg1, 4 - ldw rg1, rg2 - jmp loop_end - -// ------------------------------------------ -// print the byte in the current cell -output: - pusha 2 - push rg2 - call print::print_byte - pop zero - popa 2 - jmp loop_end - -// ------------------------------------------ -// read a byte into the current cell -input: - ldw input, rg2 - jmp loop_end - -// ------------------------------------------ -// handle an open bracket instruction -expr_start: - cmp rg2, zero - jne loop_end - -_traverse_right_start: - // push a register that definitely has a nonzero value - // when we pop this value from the stack - // we know we've finished traversing. - push rg8 - -_traverse_right: - inc rg0 - ldb rg0, rg3 - - cmp rg3, rge - jeq open_right - cmp rg3, rgf - jeq close_right - cmp rg3, zero - jeq end - jmp _traverse_right - -open_right: - // push zero to the stack - push zero - jmp _traverse_right - -close_right: - // check if we've reached the bottom of the stack - pop rg4 - cmp rg4, zero - jeq _traverse_right - - // go to next instruction after closing bracket - inc rg0 - jmp loop_start - -// ------------------------------------------ -// handle the close bracket instruction -expr_end: - cmp rg2, zero - jeq loop_end - -_traverse_left_start: - push rg8 -_traverse_left: - dec rg0 - ldb rg0, rg3 - - cmp rg3, rge - jeq open_left - cmp rg3, rgf - jeq close_left - cmp rg3, zero - jeq end - jmp _traverse_left - -open_left: - // check if we've reached the bottom of the stack - pop rg4 - cmp rg4, zero - jeq _traverse_left - - // go to next instruction after open bracket - inc rg0 - jmp loop_start - -close_left: - // push zero to the stack - push zero - jmp _traverse_left diff --git a/resources/dsa/lib/collections/stack.dsa b/resources/dsa/lib/collections/stack.dsa deleted file mode 100644 index e69de29..0000000 diff --git a/resources/dsa/lib/error/handlers.dsa b/resources/dsa/lib/error/handlers.dsa deleted file mode 100644 index 418cef2..0000000 --- a/resources/dsa/lib/error/handlers.dsa +++ /dev/null @@ -1,34 +0,0 @@ -include print "../io/print.dsa" - -dw idt: 0xFFFF0000 - -setup_idt: - push bpr - mov spr, bpr - - // load the IDT into the IDR - ldw idt, idr - - mov bpr, spr - pop bpr - irt - -setup_hard_fault_handler: - push bpr - mov spr, bpr - - lwi handle_hard_fault, rg0 - stw rg0, idr, 4 - - mov bpr, spr - pop bpr - irt - -dw hard_fault_err: "FATAL: Illegal Instruction or Memory Access!" -handle_hard_fault: - call print::reset - lwi hard_fault_err, rg0 - push rg0 - call print::print - pop zero - hlt diff --git a/resources/dsa/lib/io/print.dsa b/resources/dsa/lib/io/print.dsa deleted file mode 100644 index 377d438..0000000 --- a/resources/dsa/lib/io/print.dsa +++ /dev/null @@ -1,244 +0,0 @@ -// lib: -// print.dsa - -// usage: -// -// include print """ -// -// usage for print: -// push (register containing address of string) -// push pcx -// jmp print::print -// -// usage for reset: -// push pcx -// jmp print::reset -// -// usage for clear: -// push pcx -// jmp print::clear -// -// usage for print_byte: -// push (register containing byte) -// push pcx -// jmp print::print_byte -// -// usage for print_word: -// push (register containing word) -// push pcx -// jmp print::print_word -// - -include maths "../maths/core.dsa" - -dw display: 0x20000 -dw current: 0x20000 - -// ------------------------------------------ -// prints the string at addr(arg[0]) to the screen. -print: - push bpr - mov spr, bpr - - ldw bpr, rg0, 8 - ldw current, rg1 - -_print_loop: - ldb rg0, acc - stb acc, rg1 - - addi rg0, 1 - addi rg1, 1 - - cmp acc, zero - jne _print_loop - jmp _end - -// ------------------------------------------ -// prints the value of arg[0] to the screen. -print_word: - // initialise - push bpr - mov spr, bpr - - // load byte into acc - ldw bpr, rg0, 8 - ldw current, rg1 - - addi rg1, 3 - - stb rg0, rg1 - subi rg1, 1 - shr rg0, 8 - stb rg0, rg1 - subi rg1, 1 - shr rg0, 8 - stb rg0, rg1 - subi rg1, 1 - shr rg0, 8 - stb rg0, rg1 - - addi rg1, 4 - jmp _end - -// ------------------------------------------ -// prints the last byte of arg[0] to the screen. -print_byte: - push bpr - mov spr, bpr - - ldw bpr, rg0, 8 - ldw current, rg1 - - stb rg0, rg1 - addi rg1, 1 - jmp _end - -// ------------------------------------------ -// prints the value of arg[0] to the screen in hex. -print_hex_word: - push bpr - mov spr, bpr - - ldw current, rg1 - - ldb bpr, rg0, 8 - push rg0 - call _print_hex_byte - addi spr, 4 - - ldb bpr, rg0, 9 - push rg0 - call _print_hex_byte - addi spr, 4 - - ldb bpr, rg0, 10 - push rg0 - call _print_hex_byte - addi spr, 4 - - ldb bpr, rg0, 11 - push rg0 - call _print_hex_byte - addi spr, 4 - - jmp _end - -// ------------------------------------------ -// prints the last byte of arg[0] to the screen in hex. -print_hex_byte: - push bpr - mov spr, bpr - - ldw bpr, rg0, 8 - ldw current, rg1 - - call _print_hex_byte - jmp _end - -// function body -_print_hex_byte: - // mask to get lower nibble - lli 0xF, rg2 - // save rg0 state - push rg0 - - shr rg0, 4 - and rg0, rg2, rg0 - call _print_hex_nibble - pop rg0 - - and rg0, rg2, rg0 - call _print_hex_nibble - return - -// print a hex digit -_print_hex_nibble: - lli 10, rg3 - cmp rg0, rg3 - jlt _print_hex_nibble_number - addi rg0, 0x37, rg0 - stb rg0, rg1 - addi rg1, 1 - return - -// helper function. -_print_hex_nibble_number: - addi rg0, 0x30, rg0 - stb rg0, rg1 - addi rg1, 1 - return - -// ------------------------------------------ -// print whitespace -print_whitespace: - push bpr - mov spr, bpr - - ldw current, rg1 - lli 0x20, rg0 - stb rg0, rg1 - addi rg1, 1 - jmp _end - -// ------------------------------------------ -// print newline -print_newline: - push bpr - mov spr, bpr - - // load variables into registers - ldw display, rg0 - ldw current, rg1 - - // get the offset from the display base - sub rg1, rg0, rg0 - - lwi 80, rg2 - pusha 3 - push rg0 - push rg2 - call maths::divmod - pop zero // result - pop rg3 // remainder - popa 3 - - sub rg1, rg3, rg2 - addi rg2, 80, rg1 - - // _end saves the display state - jmp _end - -// ------------------------------------------ -// resets the cursor position on the screen to 0x20000. (0,0) -reset: - push bpr - mov spr, bpr - ldw display, rg1 - jmp _end - -// ------------------------------------------ -// clears the screen -clear: - push bpr - mov spr, bpr - // display size = 2000 bytes / 500 words - lli 500 rg0 - ldw display, rg1 - -_clear_loop: - dec rg0 - stw zero, rg1 - addi rg1, 4 - cmp rg0, zero - jgt _clear_loop - jmp _end - -// ------------------------------------------ -// return -_end: - stw rg1, current - - mov bpr, spr - pop bpr - return diff --git a/resources/dsa/lib/maths/core.dsa b/resources/dsa/lib/maths/core.dsa deleted file mode 100644 index 217c5dc..0000000 --- a/resources/dsa/lib/maths/core.dsa +++ /dev/null @@ -1,60 +0,0 @@ -// multiply.dsa -// usage: -// -// include multiply "" -// -// usage for multiply: -// push (arg1) -// push (arg0) -// call multiply::multiply -// pop (arg0) -// pop (arg1) - -multiply: - push bpr - mov spr, bpr - - ldw bpr, rg0, 8 // load op 2 - ldw bpr, rg1, 12 // load op 1 - -_multiply_loop: - add rg2, rg0, rg2 - dec rg1 - - cmp rg1, zero - jgt _multiply_loop - -_multiply_end: - stw rg2, bpr, 8 - - mov bpr, spr - pop bpr - return - -divmod: - push bpr - mov spr, bpr - - ldw bpr, rg1, 8 // load op 2 - ldw bpr, rg0, 12 // load op 1 - - lli 0, rg3 - -_divmod_loop: - cmp rg0, rg1 - jlt _divmod_end - - sub rg0, rg1, rg0 - inc rg3 - - jmp _divmod_loop - -_divmod_end: - // store div in first arg - // store mod in second arg - stw rg3, bpr, 8 - stw rg0, bpr, 12 - - mov bpr, spr - pop bpr - return diff --git a/resources/dsa/lib/maths/fib.dsa b/resources/dsa/lib/maths/fib.dsa deleted file mode 100644 index c6be26f..0000000 --- a/resources/dsa/lib/maths/fib.dsa +++ /dev/null @@ -1,31 +0,0 @@ -include print "../io/print.dsa" - -fib_n: - push bpr - mov spr, bpr - - ldw bpr, rg0, 8 // load arg - mov rg1, rg2 - lwi 1, rg1 - -start: - add rg1, rg2, rg3 - - pusha 4 - push rg1 - call print::print_hex_byte - call print::print_newline - pop zero - popa 4 - - mov rg2, rg1 - mov rg3, rg2 - - dec rg0 - cmp rg0, zero - jgt start - - stw rg1, bpr, 8 - mov bpr, spr - pop bpr - return diff --git a/resources/dsa/main.dsa b/resources/dsa/main.dsa deleted file mode 100644 index 552c80f..0000000 --- a/resources/dsa/main.dsa +++ /dev/null @@ -1,80 +0,0 @@ -include fib: "./lib/maths/fib.dsa" -include maths: "./lib/maths/core.dsa" -include print: "./lib/io/print.dsa" - -dw idt: 0xFFFF0000 -dw stack: 0x10000 -init: - // setup interrupt handlers - ldw idt, idr - lwi handle_hard_fault, rg0 - stw rg0, idr, 4 - // set up a stack. - ldw stack, bpr - mov bpr, spr - -dw string: "hello world" -start: - - lwi 37, rg0 - lwi 12, rg1 - push rg0 - push rg1 - call maths::divmod - pop rg0 // result - pop rg1 // remainder - - push rg1 - push rg0 - call print::print_hex_byte - call print::print_whitespace - pop zero - call print::print_hex_byte - call print::print_newline - - lwi string, rg0 - //lwi 10, rg0 - pusha 4 - push rg0 - call print::print - //call fib::fib_n - pop zero - call print::print_newline - popa 4 - - pusha 4 - push rg0 - call print::print - //call fib::fib_n - pop zero - call print::print_newline - popa 4 - - pusha 4 - push rg0 - call print::print - //call fib::fib_n - pop zero - call print::print_newline - popa 4 - - pusha 4 - push rg0 - call print::print - //call fib::fib_n - pop zero - call print::print_newline - popa 4 - - hlt - -// fault handler in case we fail DSA. -dw hard_fault_err: "FATAL: Illegal Instruction or Memory Access!" -handle_hard_fault: - call print::clear - call print::reset - lwi hard_fault_err, rg0 - push rg0 - call print::print - pop zero - hlt \ No newline at end of file diff --git a/resources/dsa/testprint.dsa b/resources/dsa/testprint.dsa deleted file mode 100644 index 4542823..0000000 --- a/resources/dsa/testprint.dsa +++ /dev/null @@ -1,80 +0,0 @@ -include print "./lib/io/print.dsa" - -dw idt: 0xFFFF0000 -dw stack: 0x10000 -init: - // setup interrupt handlers - ldw idt, idr - lwi handle_hard_fault, rg0 - stw rg0, idr, 4 - // set up a stack. - ldw stack, bpr - mov bpr, spr - - -db string: "I won, the game!" -db hexbyte: 0xab -dw hexword: 0x1234abcd -db replace: "I lost" - -start: - // test print string - lwi string, rg0 - push rg0 - call print::print - pop zero - - // test print hex byte. - ldb hexbyte, rg0 - push rg0 - call print::print_hex_byte - pop zero - - // test print hex word. - ldw hexword, rg0 - push rg0 - call print::print_hex_word - pop zero - - // test print char - lli 0x40, rg0 // print @ - push rg0 - call print::print_byte - pop zero - - // test newline - call print::print_newline - - lwi string rg0 - push rg0 - call print::print - - // test print word - lwi 0x31323334, rg0 // print 1234 - push rg0 - call print::print_word - pop zero - - // test reset cursor pos - call print::reset - - // test print string at reset pos - lwi replace, rg0 - push rg0 - call print::print - pop zero - - hlt - - - -// fault handler in case we fail DSA. -dw hard_fault_err: "FATAL: Illegal Instruction or Memory Access!" -handle_hard_fault: - call print::clear - call print::reset - lwi hard_fault_err, rg0 - push rg0 - call print::print - pop zero - hlt diff --git a/resources/dsb/bf.dsb b/resources/dsb/bf.dsb deleted file mode 100644 index 2b831a14e46872a7943b9adcac710ba835e160b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4 LcmXpjXJ7#U0!09_ diff --git a/resources/dsb/test.dsb b/resources/dsb/test.dsb deleted file mode 100644 index 2b831a14e46872a7943b9adcac710ba835e160b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4 LcmXpjXJ7#U0!09_ diff --git a/resources/emulator/AndroidManifest.xml b/resources/emulator/AndroidManifest.xml deleted file mode 100644 index 21292bf..0000000 --- a/resources/emulator/AndroidManifest.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/resources/emulator/AppIcon.png b/resources/emulator/AppIcon.png deleted file mode 100644 index 4f58b169aecdf23a0dd89d2eb9d03e1dac8bafc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2449 zcmciE`9Bl>1Hke37)8U%T8Z3LVyGDA7$#?=spbsjnrV*J=;N43=|a}Gv^nDwaxIa2 z%~^8hnqnkEu7p-rd>)_QzrTLJKRkbW{R6M$(~i~>;s?Y501~z~xHA9%+P`*+0svY} zeck~8#6oRcBLEPt_!s0*t5hifK!##Ppy0{=6sk|SAD~jHsG!Ti5f^1l{%ZZQMSG_xsqiPM6j^Q?&J;Z+5vI?p!e!eP})-X1&oev%i0DWg@0N?uE!OxzPRRH@0u*H=UsV-3{-b z?`Z8fAx~)J%oxr$CTF$+{pwWPI2hi_@zpcX%_nv>Ye z5aH?l7{mJ0By;j#+}0C(&n*^3_UcmfQ-vt-nJUwB2Q_KM#Jk4YsX`P*-lk}{l)?_O zmS%=~KGj%DNo3Buc;TyS#JBy05((?~3)J#~Q~Y-~g^%~6CG78^5zq$lK!U#0*%Pbn zp|g3GZ`q!lR(o`X_Er<|+RDY25||JY>$;Jq&k5+2eg`HKrYbd;`aM^4GMgXxcXXC} z`g9ML&=yJ^s8w#UeS<;KXnqX1&0oAU;1rAS&JS4|9g=Ne?$0g@db*@KcN|MU&T5nV zG4O#JGPFuHrD1}71qs17@?O}rFn{HAg4kvDwLb?l@Pzk^#ZByV_u{AfBs5NYl?KCN zVN*VWDCYeb!rh1SW%@U1H|H@Ll`)(u^DAfde*1FnJVDDTnrnlXCRvu==Ns6Ie;#ys z)i?d&R5g!kNJTEZBJx6M6mf{##icH?woc=~RttS-6Sj(@JVQ=y&f^iJiTCS<&njAV zl=tVX#4Bb(MVr6uwdXeYz7;;0jVCn!=b^n}b;z2qpS!#N=J^BhU9$34jpC182&~C~ zCwjLxkZd=`KAU@v+BAi@*>Lfo#KObd9ST~X4yi4K8A(3!XIR=_ zqLw6O2@e`|IB4C$``cpnz@9c}fAVUoAnZ1eg+0XHOTx8NQ-s?Lo{bx%Q7lMTF?ghw zTF3`j*SVu0qwG?ow$sW?ob(x*q=j=A&QMw`C0R*bS1dhGhcmjj*|277Tz zP^06nS#zu-jM(dF*Gt!Fv_{V%C2HGc1b^PZa&~*-vy@^!+!-8p`P?aYb9VR?N^GIC%G7fOQMk^MB81p)}-!btS+P0-I-Ha-rYRgXzv-K zRn`@TSQ)ok&C2Yu`PyC)ACoXOla}-b_&i~aqrsvG&+iErtiwGJ_!2c3JM-_dav1e_|+wKWO5 zC;yJM#Hc+#UUR&||5f_Nu!U*27mi(G%axO~YvR76+2VhGd1ncW+qiY3ki?vFF;KDeE1>(Eha8LwFz@eck|t&<4Ut(01qUz4gH=y=0- zua4hxuu&|rhpMM1qr$?NCKT|jJ}w9$YUWUyd>!bfK?p%xa7+syPC9RH+-5}yIS?=i3G=aW}Xu;>TYhq!E5#J}a zeJ2O!Jq$MYstNec_;c-zM5+2%!NT9yRHpKxa;bZ8*4Tuvs_2zXyh+f3{-6n@eEMKI z<`IfG>{U40)yF-2vaJK2wV%K3q7Z%lcgx&kh=ZnW#Fa&427#YG^vdnEZ&E0Rt2v41 zbg7>sM|v{AhBX_es0&RZh}x}N{=YupzdgsAnO0c#2qVR(0001NtsHS>7T(wY0VI@a AegFUf diff --git a/resources/emulator/build_android.ps1 b/resources/emulator/build_android.ps1 deleted file mode 100644 index 0a6df1c..0000000 --- a/resources/emulator/build_android.ps1 +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env pwsh - -$env:ANDROID_HOME = "C:\Users\jacob\AppData\Local\Android\Sdk" -$TOOL_PREFIX = "$env:ANDROID_HOME\build-tools\33.0.0" - -# Only really works on Windows, for aarch64. - -# Create directories -New-Item -ItemType Directory -Force -Path "..\target\apk_build\lib\arm64-v8a" -New-Item -ItemType Directory -Force -Path "..\target\apk_build\res\values" -New-Item -ItemType Directory -Force -Path "..\target\apk_build\res\mipmap-hdpi" -New-Item -ItemType Directory -Force -Path "..\target\apk_build\res\mipmap-mdpi" -New-Item -ItemType Directory -Force -Path "..\target\apk_build\res\mipmap-xhdpi" -New-Item -ItemType Directory -Force -Path "..\target\apk_build\res\mipmap-xxhdpi" - -# Copy the shared library -Copy-Item "..\target\aarch64-linux-android\release\libdsa_rs.so" "..\target\apk_build\lib\arm64-v8a\" - -# Copy the manifest -Copy-Item "..\resources\emulator\AndroidManifest.xml" "..\target\apk_build\AndroidManifest.xml" - -# Copy the icons -Copy-Item "..\resources\emulator\AppIcon.png" "..\target\apk_build\res\mipmap-hdpi\ic_launcher.png" -Copy-Item "..\resources\emulator\AppIcon.png" "..\target\apk_build\res\mipmap-mdpi\ic_launcher.png" -Copy-Item "..\resources\emulator\AppIcon.png" "..\target\apk_build\res\mipmap-xhdpi\ic_launcher.png" -Copy-Item "..\resources\emulator\AppIcon.png" "..\target\apk_build\res\mipmap-xxhdpi\ic_launcher.png" - -# Create strings.xml -@" - - - DSA Emulator - -"@ | Out-File -FilePath "..\target\apk_build\res\values\strings.xml" -Encoding utf8 - -# Change to build directory -Push-Location "..\target\apk_build" - -try { - # Compile resources - & "$TOOL_PREFIX\aapt2.exe" compile --dir res -o compiled_resources.zip - - # Link resources - & "$TOOL_PREFIX\aapt2.exe" link -o unaligned.apk ` - -I "$env:ANDROID_HOME\platforms\android-35\android.jar" ` - --manifest AndroidManifest.xml ` - compiled_resources.zip - - # Add native libraries to APK - & "C:\Program Files\7-Zip\7z.exe" a -tzip unaligned.apk lib\* - - # Align APK - & "$TOOL_PREFIX\zipalign.exe" -v 4 unaligned.apk aligned.apk - - # Generate debug keystore if it doesn't exist - if (-not (Test-Path "debug.keystore")) { - & keytool -genkey -v -keystore debug.keystore -alias androiddebugkey -keyalg RSA -keysize 2048 -validity 10000 -storepass android -keypass android -dname "CN=Android Debug,O=Android,C=US" - } - - # Sign APK - & "$TOOL_PREFIX\apksigner.bat" sign --ks debug.keystore --ks-key-alias androiddebugkey --ks-pass pass:android --key-pass pass:android --out dsa_emulator.apk aligned.apk - - # Copy final APK - Copy-Item "dsa_emulator.apk" "..\dsa_emulator.apk" - - Write-Host "APK created successfully at: ..\target\dsa_emulator.apk" -ForegroundColor Green -} -catch { - Write-Error "Build failed: $_" -} -finally { - # Return to original directory - Pop-Location -} diff --git a/resources/emulator/build_android.sh b/resources/emulator/build_android.sh deleted file mode 100644 index fba7943..0000000 --- a/resources/emulator/build_android.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh - -export ANDROID_HOME="/mnt/c/Users/jacob/AppData/Local/Android/Sdk" -export TOOL_PREFIX="$ANDROID_HOME/build-tools/35.0.1" - -# Only really works on Linux, for aarch64. - -mkdir -p ../target/apk_build/lib/arm64-v8a -mkdir -p ../target/apk_build/res/values -mkdir -p ../target/apk_build/res/mipmap-hdpi -mkdir -p ../target/apk_build/res/mipmap-mdpi -mkdir -p ../target/apk_build/res/mipmap-xhdpi -mkdir -p ../target/apk_build/res/mipmap-xxhdpi - -# Copy the shared library. -cp ../target/aarch64-linux-android/release/libdsa_rs.so ../target/apk_build/lib/arm64-v8a/ - -# Copy the manifest. -cp AndroidManifest.xml ../target/apk_build/AndroidManifest.xml - -cat << EOF > ../target/apk_build/res/values/strings.xml - - - DSA Emulator - -EOF - -pushd ../target/apk_build - -$TOOL_PREFIX/aapt2 compile --dir res -o compiled_resources.zip -$TOOL_PREFIX/aapt2 link -o unaligned.apk \ - -I "$ANDROID_HOME/platforms/android-35/android.jar" \ - --manifest AndroidManifest.xml \ - compiled_resources.zip - -zip -r unaligned.apk lib/ - -$TOOL_PREFIX/zipalign -v 4 unaligned.apk aligned.apk - -keytool -genkey -v -keystore debug.keystore -alias androiddebugkey -keyalg RSA -keysize 2048 -validity 10000 -storepass android -keypass android -dname "CN=Android Debug,O=Android,C=US" - -$TOOL_PREFIX/apksigner sign --ks debug.keystore --ks-key-alias androiddebugkey --ks-pass pass:android --key-pass pass:android --out dsa_emulator.apk aligned.apk - -cp dsa_emulator.apk ../dsa_emulator.apk - -popd diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 5f3e652..0000000 --- a/src/main.rs +++ /dev/null @@ -1,53 +0,0 @@ -use std::{ - sync::{Arc, Mutex}, - thread, -}; - -use dsa_rs::emulator::{ - system::{emulator::run_emulator, memory::MainStore, processor::Processor}, - ui::{ - control_unit::ControlPanel, interface::EmulatorUI, memory_inspector::MemoryInspector, - stack_inspector::StackInspector, - }, -}; - -fn main() -> Result<(), eframe::Error> { - // Initialize Channels - let (cmd_sender, cmd_receiver) = std::sync::mpsc::channel(); - let (state_sender, state_receiver) = std::sync::mpsc::channel(); - - let mainstore = MainStore::new(); - let processor = Processor::new(Box::new(mainstore), vec![]); - - thread::spawn(move || { - run_emulator(&cmd_receiver, &state_sender, processor); - }); - - // Create UI - let mut ui = EmulatorUI::new(cmd_sender.clone(), state_receiver); - - // Create UI modules - let control_unit = ControlPanel::new(cmd_sender.clone()); - ui.add_component(Box::new(control_unit)); - - let mem_inspector = MemoryInspector::new(cmd_sender.clone()); - ui.add_component(Box::new(mem_inspector)); - - let stack_inspector = StackInspector::new(); - ui.add_component(Box::new(stack_inspector)); - - // Run UI - let options = eframe::NativeOptions { - viewport: egui::ViewportBuilder::default().with_inner_size([800.0, 600.0]), - ..Default::default() - }; - - eframe::run_native( - "DSA Simulator (Damn Simple Architecture 🔥)", - options, - Box::new(move |cc| { - cc.egui_ctx.set_visuals(egui::Visuals::default()); - Ok(Box::new(ui)) - }), - ) -}