Compare commits
10 Commits
a049f839f2
...
758b9c9cb7
Author | SHA1 | Date | |
---|---|---|---|
758b9c9cb7 | |||
91023adad3 | |||
7b15ea828c | |||
f3f6de5b0b | |||
867e75eeb7 | |||
|
bedf8d54c4 | ||
|
b5d88f735a | ||
|
4647b9fe63 | ||
|
6e2691f50b | ||
|
36a8432411 |
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,4 +1,4 @@
|
|||
**/.vscode/
|
||||
|
||||
**/debug/
|
||||
**/target/
|
||||
result
|
||||
|
|
460
Cargo.lock
generated
460
Cargo.lock
generated
|
@ -2,66 +2,15 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.7.3"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"block-padding",
|
||||
"byte-tools",
|
||||
"byteorder",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-padding"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
|
||||
dependencies = [
|
||||
"byte-tools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
@ -69,126 +18,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.19"
|
||||
name = "cpufeatures"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
|
||||
checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"time",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[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 = "digest"
|
||||
version = "0.8.1"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enum-iterator"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4eeac5c5edb79e4e39fe8439ef35207780a11f69c52cbe424ce3dfad4cb78de6"
|
||||
dependencies = [
|
||||
"enum-iterator-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enum-iterator-derive"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fake-simd"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fox32asm"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
"pest",
|
||||
"pest_derive",
|
||||
"vergen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.4"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getset"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e45727250e75cc04ff2846a66397da8ef2b3db8e40e0cef4df67950a07621eb9"
|
||||
dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.13.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f29229cc1b24c0e6062f6e742aa3e256492a5323365e5ed3413599f8a5eff7d6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
"libgit2-sys",
|
||||
"log",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -199,100 +73,38 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.115"
|
||||
version = "0.2.153"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a8d982fa7a96a000f6ec4cfe966de9703eccde29750df2bb8949da91b0e818d"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
version = "0.12.26+1.3.0"
|
||||
name = "memchr"
|
||||
version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19e1c899248e606fbfe68dcb31d8b0176ebab833b103824af31bddf4b7457494"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"libz-sys",
|
||||
"pkg-config",
|
||||
]
|
||||
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.1.3"
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "maplit"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
|
||||
|
||||
[[package]]
|
||||
name = "matches"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.1.3"
|
||||
version = "2.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
||||
checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"thiserror",
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_derive"
|
||||
version = "2.1.0"
|
||||
version = "2.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
|
||||
checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_generator",
|
||||
|
@ -300,9 +112,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pest_generator"
|
||||
version = "2.1.3"
|
||||
version = "2.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
|
||||
checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
|
@ -313,235 +125,95 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pest_meta"
|
||||
version = "2.1.3"
|
||||
version = "2.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
|
||||
checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d"
|
||||
dependencies = [
|
||||
"maplit",
|
||||
"once_cell",
|
||||
"pest",
|
||||
"sha-1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.32"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
|
||||
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.10"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.6"
|
||||
name = "sha2"
|
||||
version = "0.10.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
|
||||
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
"fake-simd",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.81"
|
||||
version = "2.0.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
|
||||
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.30"
|
||||
version = "1.0.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
|
||||
checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.30"
|
||||
version = "1.0.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
|
||||
checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.14.0"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.3"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
||||
checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.7"
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "vergen"
|
||||
version = "6.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3893329bee75c101278e0234b646fa72221547d63f97fb66ac112a0569acd110"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
"chrono",
|
||||
"enum-iterator",
|
||||
"getset",
|
||||
"git2",
|
||||
"rustversion",
|
||||
"thiserror",
|
||||
]
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||
|
||||
[[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-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
|
|
@ -2,13 +2,8 @@
|
|||
name = "fox32asm"
|
||||
version = "0.3.0"
|
||||
edition = "2021"
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
lazy_static = "1.4.0"
|
||||
pest = "2.1.3"
|
||||
pest_derive = "2.1.0"
|
||||
|
||||
[build-dependencies]
|
||||
anyhow = "1.0"
|
||||
vergen = { version = "6", default-features = false, features = ["build", "git"] }
|
||||
|
|
8
build.rs
8
build.rs
|
@ -1,8 +0,0 @@
|
|||
use anyhow::Result;
|
||||
use vergen::{Config, ShaKind, vergen};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let mut config = Config::default();
|
||||
*config.git_mut().sha_kind_mut() = ShaKind::Short;
|
||||
vergen(config)
|
||||
}
|
59
flake.lock
Normal file
59
flake.lock
Normal file
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1694529238,
|
||||
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1697009197,
|
||||
"narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
30
flake.nix
Normal file
30
flake.nix
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
description = "fox32asm";
|
||||
|
||||
inputs = {
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils }:
|
||||
flake-utils.lib.eachDefaultSystem (sys:
|
||||
let pkgs = import nixpkgs { system = sys; };
|
||||
|
||||
in rec {
|
||||
packages.fox32asm = pkgs.rustPlatform.buildRustPackage rec {
|
||||
pname = "fox32asm";
|
||||
version = "0.3.0";
|
||||
|
||||
src = ./. ;
|
||||
cargoLock = { lockFile = ./Cargo.lock; };
|
||||
|
||||
NIX_SEMVER = version;
|
||||
NIX_GIT_SHA_SHORT = if self ? rev then builtins.substring 0 7 self.rev else "dirty";
|
||||
};
|
||||
packages.default = packages.fox32asm;
|
||||
|
||||
devShells.default = pkgs.mkShell {
|
||||
packages = [ pkgs.cargo ];
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
|
@ -2,7 +2,7 @@ WHITESPACE = _{ " " | "\t" | "\n" | "\r" | "\x0B" | "\x0C" | "\xA0" | SPACE_SEPA
|
|||
COMMENT = _{ ";" ~ (!"\n" ~ ANY)* }
|
||||
|
||||
assembly = {
|
||||
SOI ~ (origin | include_bin_optional | include_bin | data | constant | label | instruction)* ~ EOI
|
||||
SOI ~ (origin | include_bin_optional | include_bin | data | constant | label | instruction | opt)* ~ EOI
|
||||
}
|
||||
|
||||
origin = {
|
||||
|
@ -12,6 +12,13 @@ origin = {
|
|||
origin_padding = { "org.pad" ~ operand_value }
|
||||
origin_no_padding = { "org" ~ operand_value }
|
||||
|
||||
opton = { "opton" }
|
||||
optoff = { "optoff" }
|
||||
opt = {
|
||||
opton |
|
||||
optoff
|
||||
}
|
||||
|
||||
include_bin = { "#include_bin" ~ immediate_str }
|
||||
include_bin_optional = { "#include_bin_optional" ~ immediate_str }
|
||||
|
||||
|
@ -48,7 +55,9 @@ operand = {
|
|||
operand_value
|
||||
}
|
||||
operand_value_ptr = {
|
||||
operand_value
|
||||
register ~ "+" ~ operand_value |
|
||||
operand_value
|
||||
|
||||
}
|
||||
operand_value = {
|
||||
register |
|
||||
|
@ -65,6 +74,13 @@ size = @{
|
|||
".32"
|
||||
}
|
||||
|
||||
incdec_amount = @{
|
||||
"1" |
|
||||
"2" |
|
||||
"4" |
|
||||
"8"
|
||||
}
|
||||
|
||||
condition = @{
|
||||
"ifz" |
|
||||
"ifnz" |
|
||||
|
@ -83,6 +99,7 @@ instruction = {
|
|||
instruction_conditional = {
|
||||
instruction_zero ~ size? |
|
||||
instruction_one ~ size? ~ operand |
|
||||
instruction_incdec ~ size? ~ operand ~ ("," ~ incdec_amount)? |
|
||||
instruction_two ~ size? ~ operand ~ "," ~ operand
|
||||
}
|
||||
|
||||
|
@ -99,8 +116,6 @@ instruction_zero = @{
|
|||
}
|
||||
|
||||
instruction_one = @{
|
||||
"inc" |
|
||||
"dec" |
|
||||
"not" |
|
||||
"jmp" |
|
||||
"call" |
|
||||
|
@ -115,6 +130,11 @@ instruction_one = @{
|
|||
"flp"
|
||||
}
|
||||
|
||||
instruction_incdec = @{
|
||||
"inc" |
|
||||
"dec"
|
||||
}
|
||||
|
||||
instruction_two = @{
|
||||
"add" |
|
||||
"sub" |
|
||||
|
|
444
src/main.rs
444
src/main.rs
|
@ -168,8 +168,6 @@ enum InstructionZero {
|
|||
#[derive(PartialEq, Debug, Clone, Copy)]
|
||||
enum InstructionOne {
|
||||
// one operand
|
||||
Inc,
|
||||
Dec,
|
||||
Not,
|
||||
Jmp,
|
||||
Call,
|
||||
|
@ -184,6 +182,13 @@ enum InstructionOne {
|
|||
Flp,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Copy)]
|
||||
enum InstructionIncDec {
|
||||
// one or two operands
|
||||
Inc,
|
||||
Dec,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Copy)]
|
||||
enum InstructionTwo {
|
||||
// two operands
|
||||
|
@ -241,26 +246,42 @@ enum LabelKind {
|
|||
Global,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
struct OperationZero {
|
||||
size: Size,
|
||||
condition: Condition,
|
||||
instruction: InstructionZero,
|
||||
}
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
struct OperationOne {
|
||||
size: Size,
|
||||
condition: Condition,
|
||||
instruction: InstructionOne,
|
||||
operand: Box<AstNode>,
|
||||
}
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
struct OperationIncDec {
|
||||
size: Size,
|
||||
condition: Condition,
|
||||
instruction: InstructionIncDec,
|
||||
lhs: Box<AstNode>,
|
||||
rhs: Box<AstNode>,
|
||||
}
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
struct OperationTwo {
|
||||
size: Size,
|
||||
condition: Condition,
|
||||
instruction: InstructionTwo,
|
||||
lhs: Box<AstNode>,
|
||||
rhs: Box<AstNode>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
enum AstNode {
|
||||
OperationZero {
|
||||
size: Size,
|
||||
condition: Condition,
|
||||
instruction: InstructionZero,
|
||||
},
|
||||
OperationOne {
|
||||
size: Size,
|
||||
condition: Condition,
|
||||
instruction: InstructionOne,
|
||||
operand: Box<AstNode>,
|
||||
},
|
||||
OperationTwo {
|
||||
size: Size,
|
||||
condition: Condition,
|
||||
instruction: InstructionTwo,
|
||||
lhs: Box<AstNode>,
|
||||
rhs: Box<AstNode>,
|
||||
},
|
||||
OperationZero(OperationZero) ,
|
||||
OperationOne (OperationOne),
|
||||
OperationIncDec(OperationIncDec) ,
|
||||
OperationTwo (OperationTwo),
|
||||
|
||||
Immediate8(u8),
|
||||
Immediate16(u16),
|
||||
|
@ -268,6 +289,7 @@ enum AstNode {
|
|||
Register(u8),
|
||||
ImmediatePointer(u32),
|
||||
RegisterPointer(u8),
|
||||
RegisterPointerOffset(u8, u8),
|
||||
|
||||
Constant {
|
||||
name: String,
|
||||
|
@ -302,6 +324,7 @@ enum AstNode {
|
|||
|
||||
Origin(u32),
|
||||
OriginPadded(u32),
|
||||
Optimize(bool)
|
||||
}
|
||||
|
||||
fn format_address_table(m: &HashMap<String, (u32, bool)>) -> String {
|
||||
|
@ -314,7 +337,10 @@ fn format_address_table(m: &HashMap<String, (u32, bool)>) -> String {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
let version_string = format!("fox32asm {} ({})", env!("VERGEN_BUILD_SEMVER"), env!("VERGEN_GIT_SHA_SHORT"));
|
||||
let version_string = match (option_env!("NIX_SEMVER"), option_env!("NIX_GIT_SHA_SHORT")) {
|
||||
(Some(semver), Some(sha)) => format!("fox32asm {semver} ({sha})"),
|
||||
_ => format!("fox32asm (dev)"),
|
||||
};
|
||||
println!("{}", version_string);
|
||||
|
||||
let args: Vec<String> = env::args().collect();
|
||||
|
@ -352,7 +378,7 @@ fn main() {
|
|||
}
|
||||
|
||||
println!("Parsing file...");
|
||||
let ast = match parse(&input_file) {
|
||||
let mut ast = match parse(&input_file) {
|
||||
Ok(x) => x,
|
||||
Err(x) => {
|
||||
println!("{:#?}", x);
|
||||
|
@ -364,7 +390,9 @@ fn main() {
|
|||
let mut current_address: u32 = 0;
|
||||
|
||||
println!("Assembling...");
|
||||
for node in ast {
|
||||
let mut optimize = false;
|
||||
for mut node in ast {
|
||||
node = optimize_node(node, &mut optimize);
|
||||
if let AstNode::LabelDefine {name, ..} = node {
|
||||
let mut address_table = LABEL_ADDRESSES.lock().unwrap();
|
||||
if let Some(_) = address_table.get(&name) {
|
||||
|
@ -392,6 +420,8 @@ fn main() {
|
|||
} else if let AstNode::IncludedBinary(binary_vec) = node {
|
||||
current_address += binary_vec.len() as u32;
|
||||
instructions.push(binary_vec.into());
|
||||
} else if let AstNode::Optimize(_) = node {
|
||||
|
||||
} else {
|
||||
let instruction = assemble_node(node);
|
||||
instruction.set_address(current_address);
|
||||
|
@ -551,7 +581,6 @@ fn parse(source: &str) -> Result<Vec<AstNode>, Error<Rule>> {
|
|||
|
||||
fn build_ast_from_expression(pair: pest::iterators::Pair<Rule>) -> AstNode {
|
||||
//println!("{:#?}\n\n", pair); // debug
|
||||
|
||||
let pair_rule = pair.as_rule();
|
||||
let mut inner_pair = pair.into_inner();
|
||||
*CURRENT_CONDITION.lock().unwrap() = Condition::Always;
|
||||
|
@ -574,6 +603,7 @@ fn build_ast_from_expression(pair: pest::iterators::Pair<Rule>) -> AstNode {
|
|||
Rule::constant => parse_constant(inner_pair),
|
||||
Rule::label => parse_label(inner_pair.next().unwrap(), inner_pair.next()),
|
||||
Rule::data => parse_data(inner_pair.next().unwrap()),
|
||||
Rule::opt => parse_opt(inner_pair.next().unwrap()),
|
||||
Rule::origin => parse_origin(inner_pair.next().unwrap()),
|
||||
Rule::include_bin => include_binary_file(inner_pair.next().unwrap(), false),
|
||||
Rule::include_bin_optional => include_binary_file(inner_pair.next().unwrap(), true),
|
||||
|
@ -674,7 +704,13 @@ fn parse_data(pair: pest::iterators::Pair<Rule>) -> AstNode {
|
|||
_ => panic!("Unsupported data: {}", pair.as_str()),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_opt(rule: pest::iterators::Pair<Rule>) -> AstNode {
|
||||
match rule.as_str() {
|
||||
"opton"=>AstNode::Optimize(true),
|
||||
"optoff"=>AstNode::Optimize(false),
|
||||
_ => panic!("Unknown optimize flag {}", rule.as_str())
|
||||
}
|
||||
}
|
||||
fn parse_origin(pair: pest::iterators::Pair<Rule>) -> AstNode {
|
||||
//println!("{:#?}", pair);
|
||||
match pair.as_rule() {
|
||||
|
@ -713,6 +749,16 @@ fn parse_size(pair: &pest::iterators::Pair<Rule>) -> Size {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_incdec_amount(pair: pest::iterators::Pair<Rule>) -> AstNode {
|
||||
match pair.as_str() {
|
||||
"1" => AstNode::Immediate8(0),
|
||||
"2" => AstNode::Immediate8(1),
|
||||
"4" => AstNode::Immediate8(2),
|
||||
"8" => AstNode::Immediate8(3),
|
||||
_ => panic!("Unsupported increment/decrement: {}", pair.as_str()),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_condition(pair: &pest::iterators::Pair<Rule>) -> Condition {
|
||||
match pair.as_str() {
|
||||
"ifz" => Condition::Zero,
|
||||
|
@ -754,6 +800,21 @@ fn parse_instruction(pair: pest::iterators::Pair<Rule>) -> AstNode {
|
|||
let operand_ast = build_ast_from_expression(operand);
|
||||
parse_instruction_one(instruction_conditional_pair, operand_ast, size, condition)
|
||||
}
|
||||
Rule::instruction_incdec => {
|
||||
if inner_pair.peek().unwrap().as_rule() == Rule::size {
|
||||
size = parse_size(&inner_pair.next().unwrap());
|
||||
}
|
||||
*CURRENT_SIZE.lock().unwrap() = size;
|
||||
let lhs = inner_pair.next().unwrap();
|
||||
let lhs_ast = build_ast_from_expression(lhs);
|
||||
let rhs_ast = if inner_pair.peek().is_some() {
|
||||
let rhs = inner_pair.next().unwrap();
|
||||
parse_incdec_amount(rhs)
|
||||
} else {
|
||||
AstNode::Immediate8(0)
|
||||
};
|
||||
parse_instruction_incdec(instruction_conditional_pair, lhs_ast, rhs_ast, size, condition)
|
||||
}
|
||||
Rule::instruction_two => {
|
||||
if inner_pair.peek().unwrap().as_rule() == Rule::size {
|
||||
size = parse_size(&inner_pair.next().unwrap());
|
||||
|
@ -788,45 +849,67 @@ fn immediate_to_astnode(immediate: u32, size: Size, is_pointer: bool) -> AstNode
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_immediate(pair: pest::iterators::Pair<Rule>) -> u32 {
|
||||
match pair.as_rule() {
|
||||
Rule::immediate_bin => {
|
||||
let body_bin_str = pair.into_inner().next().unwrap().as_str();
|
||||
u32::from_str_radix(&remove_underscores(body_bin_str), 2).unwrap()
|
||||
}
|
||||
Rule::immediate_hex => {
|
||||
let body_hex_str = pair.into_inner().next().unwrap().as_str();
|
||||
u32::from_str_radix(&remove_underscores(body_hex_str), 16).unwrap()
|
||||
}
|
||||
Rule::immediate_dec => {
|
||||
let dec_str = pair.as_span().as_str();
|
||||
remove_underscores(dec_str).parse::<u32>().unwrap()
|
||||
}
|
||||
Rule::immediate_char => {
|
||||
let body_char_str = pair.into_inner().next().unwrap().as_str();
|
||||
body_char_str.chars().nth(0).unwrap() as u8 as u32
|
||||
}
|
||||
_=> {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_register(pair: pest::iterators::Pair<Rule>) -> u8 {
|
||||
let register_num_pair = pair.into_inner().next().unwrap();
|
||||
let register_num = if register_num_pair.as_str() == "sp" { 32 }
|
||||
else if register_num_pair.as_str() == "esp" { 33 }
|
||||
else if register_num_pair.as_str() == "fp" { 34 }
|
||||
else { register_num_pair.as_str().parse::<u8>().unwrap() };
|
||||
if register_num > 34 { panic!("register number out of range"); }
|
||||
register_num
|
||||
}
|
||||
|
||||
fn parse_operand(mut pair: pest::iterators::Pair<Rule>, is_pointer: bool) -> AstNode {
|
||||
//println!("parse_operand: {:#?}", pair); // debug
|
||||
// dbg!(&pair);
|
||||
let size = *CURRENT_SIZE.lock().unwrap();
|
||||
let pointer_offset =
|
||||
if is_pointer {
|
||||
// skip past the operand_value_ptr pair and look at its operand_value rule
|
||||
pair = pair.into_inner().next().unwrap();
|
||||
}
|
||||
let mut pairs = pair.into_inner();
|
||||
pair = pairs.next().unwrap();
|
||||
pairs.next()
|
||||
// pair = pair.into_inner().next().unwrap();
|
||||
}else {
|
||||
None
|
||||
};
|
||||
match pair.as_rule() {
|
||||
Rule::operand_value => {
|
||||
let mut inner_pair = pair.into_inner();
|
||||
let operand_value_pair = inner_pair.next().unwrap();
|
||||
match operand_value_pair.as_rule() {
|
||||
Rule::immediate_bin => {
|
||||
let body_bin_str = operand_value_pair.into_inner().next().unwrap().as_str();
|
||||
let immediate = u32::from_str_radix(&remove_underscores(body_bin_str), 2).unwrap();
|
||||
immediate_to_astnode(immediate, size, is_pointer)
|
||||
}
|
||||
Rule::immediate_bin|
|
||||
Rule::immediate_char|
|
||||
Rule::immediate_dec|
|
||||
Rule::immediate_hex => {
|
||||
let body_hex_str = operand_value_pair.into_inner().next().unwrap().as_str();
|
||||
let immediate = u32::from_str_radix(&remove_underscores(body_hex_str), 16).unwrap();
|
||||
immediate_to_astnode(immediate, size, is_pointer)
|
||||
}
|
||||
Rule::immediate_dec => {
|
||||
let dec_str = operand_value_pair.as_span().as_str();
|
||||
let immediate = remove_underscores(dec_str).parse::<u32>().unwrap();
|
||||
immediate_to_astnode(immediate, size, is_pointer)
|
||||
}
|
||||
Rule::immediate_char => {
|
||||
let body_char_str = operand_value_pair.into_inner().next().unwrap().as_str();
|
||||
let immediate = body_char_str.chars().nth(0).unwrap() as u8 as u32;
|
||||
immediate_to_astnode(immediate, size, is_pointer)
|
||||
immediate_to_astnode(parse_immediate(operand_value_pair), size, is_pointer)
|
||||
}
|
||||
Rule::register => {
|
||||
let register_num_pair = operand_value_pair.into_inner().next().unwrap();
|
||||
let register_num = if register_num_pair.as_str() == "sp" { 32 }
|
||||
else if register_num_pair.as_str() == "esp" { 33 }
|
||||
else if register_num_pair.as_str() == "fp" { 34 }
|
||||
else { register_num_pair.as_str().parse::<u8>().unwrap() };
|
||||
if register_num > 34 { panic!("register number out of range"); }
|
||||
let register_num = parse_register(operand_value_pair);
|
||||
if is_pointer {
|
||||
AstNode::RegisterPointer(register_num)
|
||||
} else {
|
||||
|
@ -850,12 +933,25 @@ fn parse_operand(mut pair: pest::iterators::Pair<Rule>, is_pointer: bool) -> Ast
|
|||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
Rule::register => {
|
||||
let register_num = parse_register(pair);
|
||||
let offset = if let Some(offset_pair) = pointer_offset {
|
||||
parse_immediate(offset_pair.into_inner().next().unwrap())
|
||||
} else {
|
||||
0
|
||||
};
|
||||
if offset == 0 {
|
||||
AstNode::RegisterPointer(register_num)
|
||||
} else {
|
||||
AstNode::RegisterPointerOffset(register_num, offset as u8)
|
||||
}
|
||||
}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_instruction_zero(pair: pest::iterators::Pair<Rule>, size: Size, condition: Condition) -> AstNode {
|
||||
AstNode::OperationZero {
|
||||
AstNode::OperationZero ( OperationZero {
|
||||
size: size,
|
||||
condition: condition,
|
||||
instruction: match pair.as_str() {
|
||||
|
@ -869,17 +965,15 @@ fn parse_instruction_zero(pair: pest::iterators::Pair<Rule>, size: Size, conditi
|
|||
"mse" => InstructionZero::Mse,
|
||||
"mcl" => InstructionZero::Mcl,
|
||||
_ => panic!("Unsupported conditional instruction (zero): {}", pair.as_str()),
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_instruction_one(pair: pest::iterators::Pair<Rule>, mut operand: AstNode, size: Size, condition: Condition) -> AstNode {
|
||||
AstNode::OperationOne {
|
||||
AstNode::OperationOne ( OperationOne {
|
||||
size: size,
|
||||
condition: condition,
|
||||
instruction: match pair.as_str() {
|
||||
"inc" => InstructionOne::Inc,
|
||||
"dec" => InstructionOne::Dec,
|
||||
"not" => InstructionOne::Not,
|
||||
"jmp" => InstructionOne::Jmp,
|
||||
"call" => InstructionOne::Call,
|
||||
|
@ -921,12 +1015,40 @@ fn parse_instruction_one(pair: pest::iterators::Pair<Rule>, mut operand: AstNode
|
|||
"flp" => InstructionOne::Flp,
|
||||
_ => panic!("Unsupported conditional instruction (one): {}", pair.as_str()),
|
||||
},
|
||||
operand: Box::new(operand),
|
||||
}
|
||||
operand: Box::new(operand)
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_instruction_incdec(pair: pest::iterators::Pair<Rule>, lhs: AstNode, rhs: AstNode, size: Size, condition: Condition) -> AstNode {
|
||||
AstNode::OperationIncDec ( OperationIncDec {
|
||||
size: size,
|
||||
condition: condition,
|
||||
instruction: match pair.as_str() {
|
||||
"inc" => InstructionIncDec::Inc,
|
||||
"dec" => InstructionIncDec::Dec,
|
||||
_ => panic!("Unsupported conditional instruction (two): {}", pair.as_str()),
|
||||
},
|
||||
lhs: Box::new(lhs),
|
||||
rhs: Box::new(rhs),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
fn parse_instruction_two(pair: pest::iterators::Pair<Rule>, mut lhs: AstNode, mut rhs: AstNode, size: Size, condition: Condition) -> AstNode {
|
||||
AstNode::OperationTwo {
|
||||
match pair.as_str() {
|
||||
"sla" |
|
||||
"sra" |
|
||||
"srl" |
|
||||
"rol" |
|
||||
"ror" |
|
||||
"bse" |
|
||||
"bcl" |
|
||||
"bts" => if let Some(value) = node_value(&rhs) {
|
||||
rhs = AstNode::Immediate8(value as u8);
|
||||
}
|
||||
_=>()
|
||||
}
|
||||
AstNode::OperationTwo ( OperationTwo {
|
||||
size: size,
|
||||
condition: condition,
|
||||
instruction: match pair.as_str() {
|
||||
|
@ -975,7 +1097,7 @@ fn parse_instruction_two(pair: pest::iterators::Pair<Rule>, mut lhs: AstNode, mu
|
|||
},
|
||||
lhs: Box::new(lhs),
|
||||
rhs: Box::new(rhs),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn assemble_node(node: AstNode) -> AssembledInstruction {
|
||||
|
@ -1010,12 +1132,14 @@ fn assemble_node(node: AstNode) -> AssembledInstruction {
|
|||
|
||||
let mut instruction_data: Vec<u8> = Vec::new();
|
||||
|
||||
instruction_data.push(condition_source_destination_to_byte(&node));
|
||||
let condition_source_destination = condition_source_destination_to_byte(&node);
|
||||
instruction_data.push(condition_source_destination);
|
||||
instruction_data.push(instruction_to_byte(&node));
|
||||
|
||||
let mut instruction: AssembledInstruction = instruction_data.into();
|
||||
|
||||
node_to_immediate_values(&node, &mut instruction);
|
||||
//0x80 bit determines if we need to write the pointer offsets or not
|
||||
node_to_immediate_values(&node, &mut instruction, condition_source_destination & 0x80 != 0);
|
||||
|
||||
instruction
|
||||
}
|
||||
|
@ -1040,7 +1164,7 @@ fn size_to_byte(size: Size) -> u8 {
|
|||
|
||||
fn instruction_to_byte(node: &AstNode) -> u8 {
|
||||
match *node {
|
||||
AstNode::OperationZero {size, instruction, ..} => {
|
||||
AstNode::OperationZero (OperationZero{size, instruction, ..}) => {
|
||||
match instruction {
|
||||
InstructionZero::Nop => 0x00 | size_to_byte(size),
|
||||
InstructionZero::Halt => 0x10 | size_to_byte(size),
|
||||
|
@ -1053,10 +1177,8 @@ fn instruction_to_byte(node: &AstNode) -> u8 {
|
|||
InstructionZero::Mcl => 0x1D | size_to_byte(size),
|
||||
}
|
||||
}
|
||||
AstNode::OperationOne {size, instruction, ..} => {
|
||||
AstNode::OperationOne (OperationOne{size, instruction, ..}) => {
|
||||
match instruction {
|
||||
InstructionOne::Inc => 0x11 | size_to_byte(size),
|
||||
InstructionOne::Dec => 0x31 | size_to_byte(size),
|
||||
InstructionOne::Not => 0x33 | size_to_byte(size),
|
||||
InstructionOne::Jmp => 0x08 | size_to_byte(size),
|
||||
InstructionOne::Call => 0x18 | size_to_byte(size),
|
||||
|
@ -1071,7 +1193,13 @@ fn instruction_to_byte(node: &AstNode) -> u8 {
|
|||
InstructionOne::Flp => 0x3D | size_to_byte(size),
|
||||
}
|
||||
}
|
||||
AstNode::OperationTwo {size, instruction, ..} => {
|
||||
AstNode::OperationIncDec (OperationIncDec{size, instruction, ..}) => {
|
||||
match instruction {
|
||||
InstructionIncDec::Inc => 0x11 | size_to_byte(size),
|
||||
InstructionIncDec::Dec => 0x31 | size_to_byte(size),
|
||||
}
|
||||
}
|
||||
AstNode::OperationTwo (OperationTwo{size, instruction, ..}) => {
|
||||
match instruction {
|
||||
InstructionTwo::Add => 0x01 | size_to_byte(size),
|
||||
InstructionTwo::Sub => 0x21 | size_to_byte(size),
|
||||
|
@ -1118,20 +1246,32 @@ fn condition_to_bits(condition: &Condition) -> u8 {
|
|||
|
||||
fn condition_source_destination_to_byte(node: &AstNode) -> u8 {
|
||||
let source: u8 = match node {
|
||||
AstNode::OperationZero {..} => 0x00,
|
||||
AstNode::OperationOne {operand, ..} => {
|
||||
AstNode::OperationZero (_) => 0x00,
|
||||
AstNode::OperationOne (OperationOne{operand, ..}) => {
|
||||
match operand.as_ref() {
|
||||
AstNode::Register(_) => 0x00,
|
||||
AstNode::RegisterPointer(_) => 0x01,
|
||||
AstNode::RegisterPointerOffset(_, _) => 0x81,
|
||||
AstNode::Immediate8(_) | AstNode::Immediate16(_) | AstNode::Immediate32(_) | AstNode::LabelOperand {..} => 0x02,
|
||||
AstNode::ImmediatePointer(_) | AstNode::LabelOperandPointer {..} => 0x03,
|
||||
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
|
||||
}
|
||||
}
|
||||
AstNode::OperationTwo {rhs, ..} => {
|
||||
AstNode::OperationIncDec (OperationIncDec{lhs, ..}) => {
|
||||
match lhs.as_ref() {
|
||||
AstNode::Register(_) => 0x00,
|
||||
AstNode::RegisterPointer(_) => 0x01,
|
||||
AstNode::RegisterPointerOffset(_, _) => 0x81,
|
||||
AstNode::Immediate8(_) | AstNode::Immediate16(_) | AstNode::Immediate32(_) | AstNode::LabelOperand {..} => 0x02,
|
||||
AstNode::ImmediatePointer(_) | AstNode::LabelOperandPointer {..} => 0x03,
|
||||
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
|
||||
}
|
||||
}
|
||||
AstNode::OperationTwo (OperationTwo{rhs, ..}) => {
|
||||
match rhs.as_ref() {
|
||||
AstNode::Register(_) => 0x00,
|
||||
AstNode::RegisterPointer(_) => 0x01,
|
||||
AstNode::RegisterPointerOffset(_, _) => 0x81,
|
||||
AstNode::Immediate8(_) | AstNode::Immediate16(_) | AstNode::Immediate32(_) | AstNode::LabelOperand {..} => 0x02,
|
||||
AstNode::ImmediatePointer(_) | AstNode::LabelOperandPointer {..} => 0x03,
|
||||
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
|
||||
|
@ -1140,12 +1280,19 @@ fn condition_source_destination_to_byte(node: &AstNode) -> u8 {
|
|||
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
|
||||
};
|
||||
let destination: u8 = match node {
|
||||
AstNode::OperationZero {..} => 0x00,
|
||||
AstNode::OperationOne {..} => 0x00,
|
||||
AstNode::OperationTwo {lhs, ..} => {
|
||||
AstNode::OperationZero(_) => 0x00,
|
||||
AstNode::OperationOne (_)=> 0x00,
|
||||
AstNode::OperationIncDec (OperationIncDec{ rhs, ..}) => {
|
||||
match rhs.as_ref() {
|
||||
AstNode::Immediate8(n) => *n << 2,
|
||||
_ => panic!(""),
|
||||
}
|
||||
}
|
||||
AstNode::OperationTwo (OperationTwo{lhs, ..}) => {
|
||||
match lhs.as_ref() {
|
||||
AstNode::Register(_) => 0x00,
|
||||
AstNode::RegisterPointer(_) => 0x04,
|
||||
AstNode::RegisterPointerOffset(_, _) => 0x84,
|
||||
AstNode::Immediate8(_) | AstNode::Immediate16(_) | AstNode::Immediate32(_) | AstNode::LabelOperand {..} => 0x08,
|
||||
AstNode::ImmediatePointer(_) | AstNode::LabelOperandPointer {..} => 0x0C,
|
||||
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
|
||||
|
@ -1154,9 +1301,10 @@ fn condition_source_destination_to_byte(node: &AstNode) -> u8 {
|
|||
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
|
||||
};
|
||||
let condition: u8 = match node {
|
||||
AstNode::OperationZero {condition, ..} => condition_to_bits(condition),
|
||||
AstNode::OperationOne {condition, ..} => condition_to_bits(condition),
|
||||
AstNode::OperationTwo {condition, ..} => condition_to_bits(condition),
|
||||
AstNode::OperationZero (OperationZero{condition, ..}) => condition_to_bits(condition),
|
||||
AstNode::OperationOne (OperationOne{condition, ..}) => condition_to_bits(condition),
|
||||
AstNode::OperationIncDec (OperationIncDec{condition, ..}) => condition_to_bits(condition),
|
||||
AstNode::OperationTwo (OperationTwo{condition, ..}) => condition_to_bits(condition),
|
||||
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
|
||||
};
|
||||
condition | source | destination
|
||||
|
@ -1187,11 +1335,23 @@ fn generate_backpatch_immediate(name: &String, size: Size, instruction: &Assembl
|
|||
targets.push(BackpatchTarget::new(instruction, index, size, is_relative));
|
||||
}
|
||||
|
||||
fn operand_to_immediate_value(instruction: &AssembledInstruction, node: &AstNode){
|
||||
|
||||
fn operand_to_immediate_value(instruction: &AssembledInstruction, node: &AstNode, pointer_offset: bool){
|
||||
let mut vec = instruction.borrow_mut();
|
||||
match *node {
|
||||
AstNode::Register (register) => vec.push(register),
|
||||
AstNode::RegisterPointer(register) => vec.push(register),
|
||||
AstNode::RegisterPointer(register) => {
|
||||
vec.push(register);
|
||||
if pointer_offset {
|
||||
vec.push(0);
|
||||
}
|
||||
}
|
||||
AstNode::RegisterPointerOffset(register, offset) => {
|
||||
vec.push(register);
|
||||
if pointer_offset {
|
||||
vec.push(offset);
|
||||
}
|
||||
}
|
||||
|
||||
AstNode::Immediate8 (immediate) => vec.push(immediate),
|
||||
AstNode::Immediate16 (immediate) => vec.extend_from_slice(&immediate.to_le_bytes()),
|
||||
|
@ -1209,18 +1369,22 @@ fn operand_to_immediate_value(instruction: &AssembledInstruction, node: &AstNode
|
|||
|
||||
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn node_to_immediate_values(node: &AstNode, instruction: &AssembledInstruction) {
|
||||
fn node_to_immediate_values(node: &AstNode, instruction: &AssembledInstruction, pointer_offset: bool) {
|
||||
{
|
||||
match node {
|
||||
AstNode::OperationZero {..} => {}
|
||||
|
||||
AstNode::OperationOne {operand, ..} =>
|
||||
operand_to_immediate_value(instruction, operand.as_ref()),
|
||||
AstNode::OperationOne (OperationOne{operand, ..}) =>
|
||||
operand_to_immediate_value(instruction, operand.as_ref(), pointer_offset),
|
||||
|
||||
AstNode::OperationTwo {rhs, ..} =>
|
||||
operand_to_immediate_value(instruction, rhs.as_ref()),
|
||||
AstNode::OperationIncDec (OperationIncDec{lhs, ..}) =>
|
||||
operand_to_immediate_value(instruction, lhs.as_ref(), pointer_offset),
|
||||
|
||||
AstNode::OperationTwo (OperationTwo{rhs, ..}) =>
|
||||
operand_to_immediate_value(instruction, rhs.as_ref(), pointer_offset),
|
||||
|
||||
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
|
||||
}
|
||||
|
@ -1229,10 +1393,118 @@ fn node_to_immediate_values(node: &AstNode, instruction: &AssembledInstruction)
|
|||
match node {
|
||||
AstNode::OperationZero {..} => {}
|
||||
AstNode::OperationOne {..} => {}
|
||||
AstNode::OperationIncDec {..} => {}
|
||||
|
||||
AstNode::OperationTwo {lhs, ..} =>
|
||||
operand_to_immediate_value(instruction, lhs.as_ref()),
|
||||
AstNode::OperationTwo (OperationTwo{lhs, ..}) =>
|
||||
operand_to_immediate_value(instruction, lhs.as_ref(), pointer_offset),
|
||||
|
||||
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
fn node_value(node: &AstNode) -> Option<u32> {
|
||||
match *node {
|
||||
AstNode::Immediate16(n) => Some(n as u32),
|
||||
AstNode::Immediate32(n) => Some(n as u32),
|
||||
AstNode::Immediate8(n) => Some(n as u32),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
fn optimize_node(node: AstNode, enabled: &mut bool) -> AstNode {
|
||||
if let AstNode::Optimize(value) = node {
|
||||
*enabled = value;
|
||||
}
|
||||
if *enabled {
|
||||
match node {
|
||||
AstNode::OperationTwo(mut n) => {
|
||||
let v = node_value(&n.rhs);
|
||||
if let Some(v) = v {
|
||||
match n.instruction {
|
||||
InstructionTwo::Add => {
|
||||
match v {
|
||||
1 => return AstNode::OperationIncDec(OperationIncDec { size: n.size, condition: n.condition, instruction: InstructionIncDec::Inc, lhs: n.lhs, rhs: Box::new(AstNode::Immediate8(0)) }),
|
||||
2 => return AstNode::OperationIncDec(OperationIncDec { size: n.size, condition: n.condition, instruction: InstructionIncDec::Inc, lhs: n.lhs, rhs: Box::new(AstNode::Immediate8(1)) }),
|
||||
4 => return AstNode::OperationIncDec(OperationIncDec { size: n.size, condition: n.condition, instruction: InstructionIncDec::Inc, lhs: n.lhs, rhs: Box::new(AstNode::Immediate8(2)) }),
|
||||
8 => return AstNode::OperationIncDec(OperationIncDec { size: n.size, condition: n.condition, instruction: InstructionIncDec::Inc, lhs: n.lhs, rhs: Box::new(AstNode::Immediate8(3)) }),
|
||||
_ => ()
|
||||
}
|
||||
|
||||
},
|
||||
InstructionTwo::Sub => {
|
||||
match v {
|
||||
1 => return AstNode::OperationIncDec(OperationIncDec { size: n.size, condition: n.condition, instruction: InstructionIncDec::Dec, lhs: n.lhs, rhs: Box::new(AstNode::Immediate8(0)) }),
|
||||
2 => return AstNode::OperationIncDec(OperationIncDec { size: n.size, condition: n.condition, instruction: InstructionIncDec::Dec, lhs: n.lhs, rhs: Box::new(AstNode::Immediate8(1)) }),
|
||||
4 => return AstNode::OperationIncDec(OperationIncDec { size: n.size, condition: n.condition, instruction: InstructionIncDec::Dec, lhs: n.lhs, rhs: Box::new(AstNode::Immediate8(2)) }),
|
||||
8 => return AstNode::OperationIncDec(OperationIncDec { size: n.size, condition: n.condition, instruction: InstructionIncDec::Dec, lhs: n.lhs, rhs: Box::new(AstNode::Immediate8(3)) }),
|
||||
_ => ()
|
||||
}
|
||||
|
||||
},
|
||||
InstructionTwo::Mov => {
|
||||
if let Size::Word = n.size {
|
||||
if let AstNode::Register(_) = *n.lhs {
|
||||
if v <= 0xff {
|
||||
n.size = Size::Byte;
|
||||
n.instruction = InstructionTwo::Movz;
|
||||
n.rhs = Box::new(AstNode::Immediate8(v as u8));
|
||||
}
|
||||
|
||||
else if v <= 0xffff {
|
||||
n.size = Size::Half;
|
||||
n.instruction = InstructionTwo::Movz;
|
||||
n.rhs = Box::new(AstNode::Immediate16(v as u16));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
InstructionTwo::Mul => {
|
||||
if let Size::Word = n.size {
|
||||
if v.is_power_of_two() {
|
||||
n.instruction = InstructionTwo::Sla;
|
||||
n.rhs = Box::new(AstNode::Immediate8(v.trailing_zeros() as u8));
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
InstructionTwo::Idiv => {
|
||||
if let Size::Word = n.size {
|
||||
if v.is_power_of_two() {
|
||||
n.instruction = InstructionTwo::Sra;
|
||||
n.rhs = Box::new(AstNode::Immediate8(v.trailing_zeros() as u8));
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
InstructionTwo::Div => {
|
||||
if let Size::Word = n.size {
|
||||
if v.is_power_of_two() {
|
||||
n.instruction = InstructionTwo::Srl;
|
||||
n.rhs = Box::new(AstNode::Immediate8(v.trailing_zeros() as u8));
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
// InstructionTwo::Sla
|
||||
// | InstructionTwo::Srl | InstructionTwo::Sra
|
||||
// | InstructionTwo::Bcl | InstructionTwo::Bse
|
||||
// | InstructionTwo::Bts
|
||||
// | InstructionTwo::Ror | InstructionTwo::Rol
|
||||
// => {
|
||||
// n.rhs = Box::new(AstNode::Immediate8(v as u8));
|
||||
|
||||
// }
|
||||
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
AstNode::OperationTwo(n)
|
||||
}
|
||||
_=> node
|
||||
}
|
||||
} else {
|
||||
node
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user