refactor(vm) helpful codegen round 1~
This commit is contained in:
439
Cargo.lock
generated
439
Cargo.lock
generated
@@ -156,9 +156,31 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.7"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.64.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
"peeking_take_while",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 1.0.109",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
@@ -166,6 +188,12 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.15.4"
|
||||
@@ -204,6 +232,15 @@ version = "1.0.90"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
@@ -223,6 +260,17 @@ dependencies = [
|
||||
"windows-targets 0.52.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.4"
|
||||
@@ -263,6 +311,33 @@ version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
|
||||
|
||||
[[package]]
|
||||
name = "color-eyre"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"color-spantrace",
|
||||
"eyre",
|
||||
"indenter",
|
||||
"once_cell",
|
||||
"owo-colors",
|
||||
"tracing-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color-spantrace"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"owo-colors",
|
||||
"tracing-core",
|
||||
"tracing-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.0"
|
||||
@@ -370,6 +445,26 @@ version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "eyre"
|
||||
version = "0.6.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec"
|
||||
dependencies = [
|
||||
"indenter",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
@@ -493,6 +588,12 @@ version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
@@ -529,6 +630,15 @@ version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.8.0"
|
||||
@@ -649,6 +759,12 @@ dependencies = [
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indenter"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
@@ -695,12 +811,40 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.11"
|
||||
@@ -723,7 +867,7 @@ version = "0.94.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c66bfd44a06ae10647fe3f8214762e9369fd4248df1350924b4ef9e770a85ea1"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
@@ -746,12 +890,27 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8dd856d451cc0da70e2ef2ce95a18e39a93b7558bedf10201ad28503f918568"
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
||||
dependencies = [
|
||||
"regex-automata 0.1.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.2"
|
||||
@@ -772,6 +931,26 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
|
||||
dependencies = [
|
||||
"overload",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.1.0"
|
||||
@@ -821,6 +1000,39 @@ version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "onig"
|
||||
version = "6.4.0"
|
||||
source = "git+https://github.com/rust-onig/rust-onig#fa90c0e97e90a056af89f183b23cd417b59ee6a2"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"onig_sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "onig_sys"
|
||||
version = "69.8.1"
|
||||
source = "git+https://github.com/rust-onig/rust-onig#fa90c0e97e90a056af89f183b23cd417b59ee6a2"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"cc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||
|
||||
[[package]]
|
||||
name = "owo-colors"
|
||||
version = "3.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
@@ -850,6 +1062,12 @@ version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
@@ -984,6 +1202,12 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
@@ -1056,7 +1280,7 @@ version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1067,8 +1291,17 @@ checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
"regex-automata 0.4.6",
|
||||
"regex-syntax 0.8.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||
dependencies = [
|
||||
"regex-syntax 0.6.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1079,9 +1312,15 @@ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
"regex-syntax 0.8.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.3"
|
||||
@@ -1094,6 +1333,25 @@ version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.14"
|
||||
@@ -1114,9 +1372,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.197"
|
||||
version = "1.0.200"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||
checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
@@ -1145,9 +1403,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.197"
|
||||
version = "1.0.200"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1166,16 +1424,35 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.115"
|
||||
name = "serde_ignored"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd"
|
||||
checksum = "a8e319a36d1b52126a0d608f24e93b2d81297091818cd70625fcf50a15d84ddf"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.116"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_path_to_error"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.18"
|
||||
@@ -1189,9 +1466,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_with"
|
||||
version = "3.7.0"
|
||||
version = "3.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee80b0e361bbf88fd2f6e242ccd19cfda072cb0faa6ae694ecee08199938569a"
|
||||
checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"chrono",
|
||||
@@ -1207,9 +1484,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_with_macros"
|
||||
version = "3.7.0"
|
||||
version = "3.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6561dc161a9224638a31d876ccdfefbc1df91d3f3a8342eddb35f055d48c7655"
|
||||
checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
@@ -1217,6 +1494,21 @@ dependencies = [
|
||||
"syn 2.0.57",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[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.1"
|
||||
@@ -1314,6 +1606,12 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.58"
|
||||
@@ -1334,6 +1632,16 @@ dependencies = [
|
||||
"syn 2.0.57",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.34"
|
||||
@@ -1517,6 +1825,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-error"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e"
|
||||
dependencies = [
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
||||
dependencies = [
|
||||
"matchers",
|
||||
"nu-ansi-term",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1629,6 +1977,12 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
@@ -1725,6 +2079,40 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
|
||||
dependencies = [
|
||||
"either",
|
||||
"home",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
]
|
||||
|
||||
[[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"
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.52.0"
|
||||
@@ -1871,5 +2259,20 @@ name = "xtask"
|
||||
version = "0.2.3"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"color-eyre",
|
||||
"convert_case",
|
||||
"indexmap 2.2.6",
|
||||
"onig",
|
||||
"phf_codegen",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_ignored",
|
||||
"serde_json",
|
||||
"serde_path_to_error",
|
||||
"serde_with",
|
||||
"textwrap",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
@@ -12,3 +12,7 @@ opt-level = "s"
|
||||
lto = true
|
||||
[profile.dev]
|
||||
opt-level = 1
|
||||
|
||||
|
||||
[patch.crates-io]
|
||||
onig_sys = { git = "https://github.com/rust-onig/rust-onig", revision = "fa90c0e97e90a056af89f183b23cd417b59ee6a2" }
|
||||
|
||||
1
data/database.json
Normal file
1
data/database.json
Normal file
File diff suppressed because one or more lines are too long
12
data/instruction_help_patches.json
Normal file
12
data/instruction_help_patches.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"bapz": "Branch to line c if abs(a) <= max(b * abs(a), float.epsilon * 8)",
|
||||
"bapzal": "Branch to line c if abs(a) <= max(b * abs(a), float.epsilon * 8) and store next line number in ra",
|
||||
"bnaz": "Branch to line c if abs(a) > max (b * abs(a), float.epsilon * 8)",
|
||||
"bnazal": "Branch to line c if abs(a) > max (b * abs(a), float.epsilon * 8) and store next line number in ra",
|
||||
"brapz": "Relative branch to line c if abs(a) <= max(b * abs(a), float.epsilon * 8)",
|
||||
"brnaz": "Relative branch to line c if abs(a) > max(b * abs(a), float.epsilon * 8)",
|
||||
"sapz": "Register = 1 if abs(a) <= max(b * abs(a), float.epsilon * 8), otherwise 0",
|
||||
"snaz": "Register = 1 if abs(a) > max(b * abs(a), float.epsilon), otherwise 0",
|
||||
"log": "Register = base e log(a) or ln(a)",
|
||||
"exp": "Register = exp(a) or e^a"
|
||||
}
|
||||
@@ -14,7 +14,7 @@ const-crc32 = "1.3.0"
|
||||
itertools = "0.12.1"
|
||||
macro_rules_attribute = "0.2.0"
|
||||
paste = "1.0.14"
|
||||
phf = "0.11.2"
|
||||
phf = { version = "0.11.2", features = ["macros"] }
|
||||
rand = "0.8.5"
|
||||
regex = "1.10.3"
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
|
||||
421
ic10emu/build.rs
421
ic10emu/build.rs
@@ -1,421 +0,0 @@
|
||||
use convert_case::{Case, Casing};
|
||||
use std::{
|
||||
collections::BTreeSet,
|
||||
env,
|
||||
fmt::Display,
|
||||
fs::{self, File},
|
||||
io::{BufWriter, Write},
|
||||
path::Path,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
struct EnumVariant<P>
|
||||
where
|
||||
P: Display + FromStr,
|
||||
{
|
||||
pub aliases: Vec<String>,
|
||||
pub value: Option<P>,
|
||||
pub deprecated: bool,
|
||||
}
|
||||
|
||||
struct ReprEnumVariant<P>
|
||||
where
|
||||
P: Display + FromStr,
|
||||
{
|
||||
pub value: P,
|
||||
pub deprecated: bool,
|
||||
pub props: Vec<(String, String)>
|
||||
}
|
||||
|
||||
fn write_repr_enum<'a, T: std::io::Write, I, P>(
|
||||
writer: &mut BufWriter<T>,
|
||||
name: &str,
|
||||
variants: I,
|
||||
use_phf: bool,
|
||||
) where
|
||||
P: Display + FromStr + 'a,
|
||||
I: IntoIterator<Item = &'a (String, ReprEnumVariant<P>)>,
|
||||
{
|
||||
let additional_strum = if use_phf { "#[strum(use_phf)]\n" } else { "" };
|
||||
let repr = std::any::type_name::<P>();
|
||||
write!(
|
||||
writer,
|
||||
"#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, EnumString, AsRefStr, EnumProperty, EnumIter, FromRepr, Serialize, Deserialize)]\n\
|
||||
{additional_strum}\
|
||||
#[repr({repr})]\n\
|
||||
pub enum {name} {{\n"
|
||||
)
|
||||
.unwrap();
|
||||
for (name, variant) in variants {
|
||||
let variant_name = name.replace('.', "").to_case(Case::Pascal);
|
||||
let serialize = vec![name.clone()];
|
||||
let serialize_str = serialize
|
||||
.into_iter()
|
||||
.map(|s| format!("serialize = \"{s}\""))
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ");
|
||||
let mut props = Vec::new();
|
||||
if variant.deprecated {
|
||||
props.push("deprecated = \"true\"".to_owned());
|
||||
}
|
||||
for (prop_name, prop_val) in &variant.props {
|
||||
props.push(format!("{prop_name} = \"{prop_val}\""));
|
||||
}
|
||||
let val = &variant.value;
|
||||
props.push(format!("value = \"{val}\""));
|
||||
let props_str = if !props.is_empty() {
|
||||
format!(", props( {} )", props.join(", "))
|
||||
} else {
|
||||
"".to_owned()
|
||||
};
|
||||
writeln!(
|
||||
writer,
|
||||
" #[strum({serialize_str}{props_str})] {variant_name} = {val}{repr},"
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
writeln!(writer, "}}").unwrap();
|
||||
}
|
||||
|
||||
fn write_enum<'a, T: std::io::Write, I, P>(
|
||||
writer: &mut BufWriter<T>,
|
||||
name: &str,
|
||||
variants: I,
|
||||
use_phf: bool,
|
||||
) where
|
||||
P: Display + FromStr + 'a,
|
||||
I: IntoIterator<Item = &'a (String, EnumVariant<P>)>,
|
||||
{
|
||||
let additional_strum = if use_phf { "#[strum(use_phf)]\n" } else { "" };
|
||||
write!(
|
||||
writer,
|
||||
"#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, EnumString, AsRefStr, EnumProperty, EnumIter, Serialize, Deserialize)]\n\
|
||||
{additional_strum}\
|
||||
pub enum {name} {{\n"
|
||||
)
|
||||
.unwrap();
|
||||
for (name, variant) in variants {
|
||||
let variant_name = name.replace('.', "").to_case(Case::Pascal);
|
||||
let mut serialize = vec![name.clone()];
|
||||
serialize.extend(variant.aliases.iter().cloned());
|
||||
let serialize_str = serialize
|
||||
.into_iter()
|
||||
.map(|s| format!("serialize = \"{s}\""))
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ");
|
||||
let mut props = Vec::new();
|
||||
if variant.deprecated {
|
||||
props.push("deprecated = \"true\"".to_owned());
|
||||
}
|
||||
if let Some(val) = &variant.value {
|
||||
props.push(format!("value = \"{val}\""));
|
||||
}
|
||||
let props_str = if !props.is_empty() {
|
||||
format!(", props( {} )", props.join(", "))
|
||||
} else {
|
||||
"".to_owned()
|
||||
};
|
||||
writeln!(
|
||||
writer,
|
||||
" #[strum({serialize_str}{props_str})] {variant_name},"
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
writeln!(writer, "}}").unwrap();
|
||||
}
|
||||
|
||||
fn write_logictypes() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
|
||||
let dest_path = Path::new(&out_dir).join("logictypes.rs");
|
||||
let output_file = File::create(dest_path).unwrap();
|
||||
let mut writer = BufWriter::new(&output_file);
|
||||
|
||||
let mut logictypes: Vec<(String, ReprEnumVariant<u16>)> = Vec::new();
|
||||
let l_infile = Path::new("data/logictypes.txt");
|
||||
let l_contents = fs::read_to_string(l_infile).unwrap();
|
||||
|
||||
for line in l_contents.lines().filter(|l| !l.trim().is_empty()) {
|
||||
let mut it = line.splitn(3, ' ');
|
||||
let name = it.next().unwrap();
|
||||
let val_str = it.next().unwrap();
|
||||
let value: u16 = val_str.parse().unwrap_or_else(|err| panic!("'{val_str}' not valid u16: {err}"));
|
||||
let docs = it.next();
|
||||
let deprecated = docs
|
||||
.map(|docs| docs.trim().to_uppercase() == "DEPRECATED")
|
||||
.unwrap_or(false);
|
||||
let mut props = Vec::new();
|
||||
if let Some(docs) = docs {
|
||||
props.push(("docs".to_owned(), docs.to_owned()));
|
||||
}
|
||||
logictypes.push((
|
||||
name.to_string(),
|
||||
ReprEnumVariant {
|
||||
value,
|
||||
deprecated,
|
||||
props,
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
let mut slotlogictypes: Vec<(String, ReprEnumVariant<u8>)> = Vec::new();
|
||||
let sl_infile = Path::new("data/slotlogictypes.txt");
|
||||
let sl_contents = fs::read_to_string(sl_infile).unwrap();
|
||||
|
||||
for line in sl_contents.lines().filter(|l| !l.trim().is_empty()) {
|
||||
let mut it = line.splitn(3, ' ');
|
||||
let name = it.next().unwrap();
|
||||
let val_str = it.next().unwrap();
|
||||
let value: u8 = val_str.parse().unwrap_or_else(|err| panic!("'{val_str}' not valid u8: {err}"));
|
||||
let docs = it.next();
|
||||
let deprecated = docs
|
||||
.map(|docs| docs.trim().to_uppercase() == "DEPRECATED")
|
||||
.unwrap_or(false);
|
||||
let mut props = Vec::new();
|
||||
if let Some(docs) = docs {
|
||||
props.push(("docs".to_owned(), docs.to_owned()));
|
||||
}
|
||||
slotlogictypes.push((
|
||||
name.to_string(),
|
||||
ReprEnumVariant {
|
||||
value,
|
||||
deprecated,
|
||||
props,
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
write_repr_enum(&mut writer, "LogicType", &logictypes, true);
|
||||
|
||||
println!("cargo:rerun-if-changed=data/logictypes.txt");
|
||||
|
||||
write_repr_enum(&mut writer, "SlotLogicType", &slotlogictypes, true);
|
||||
|
||||
println!("cargo:rerun-if-changed=data/slotlogictypes.txt");
|
||||
}
|
||||
|
||||
fn write_enums() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
|
||||
let dest_path = Path::new(&out_dir).join("enums.rs");
|
||||
let output_file = File::create(dest_path).unwrap();
|
||||
let mut writer = BufWriter::new(&output_file);
|
||||
|
||||
let mut enums_map: Vec<(String, EnumVariant<u32>)> = Vec::new();
|
||||
let e_infile = Path::new("data/enums.txt");
|
||||
let e_contents = fs::read_to_string(e_infile).unwrap();
|
||||
|
||||
for line in e_contents.lines().filter(|l| !l.trim().is_empty()) {
|
||||
let mut it = line.splitn(3, ' ');
|
||||
let name = it.next().unwrap();
|
||||
let val_str = it.next().unwrap();
|
||||
let val: Option<u32> = val_str.parse().ok();
|
||||
let docs = it.next();
|
||||
let deprecated = docs
|
||||
.map(|docs| docs.trim().to_uppercase() == "DEPRECATED")
|
||||
.unwrap_or(false);
|
||||
|
||||
enums_map.push((
|
||||
name.to_string(),
|
||||
EnumVariant {
|
||||
aliases: Vec::new(),
|
||||
value: val,
|
||||
deprecated,
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
write_enum(&mut writer, "LogicEnums", &enums_map, true);
|
||||
|
||||
println!("cargo:rerun-if-changed=data/enums.txt");
|
||||
}
|
||||
|
||||
fn write_modes() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
|
||||
let dest_path = Path::new(&out_dir).join("modes.rs");
|
||||
let output_file = File::create(dest_path).unwrap();
|
||||
let mut writer = BufWriter::new(&output_file);
|
||||
|
||||
let mut batchmodes: Vec<(String, ReprEnumVariant<u8>)> = Vec::new();
|
||||
let b_infile = Path::new("data/batchmodes.txt");
|
||||
let b_contents = fs::read_to_string(b_infile).unwrap();
|
||||
|
||||
for line in b_contents.lines().filter(|l| !l.trim().is_empty()) {
|
||||
let mut it = line.splitn(3, ' ');
|
||||
let name = it.next().unwrap();
|
||||
let val_str = it.next().unwrap();
|
||||
let value: u8 = val_str.parse().unwrap_or_else(|err| panic!("'{val_str}' not valid u8: {err}"));
|
||||
|
||||
batchmodes.push((
|
||||
name.to_string(),
|
||||
ReprEnumVariant {
|
||||
value,
|
||||
deprecated: false,
|
||||
props: Vec::new(),
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
let mut reagentmodes: Vec<(String, ReprEnumVariant<u8>)> = Vec::new();
|
||||
let r_infile = Path::new("data/reagentmodes.txt");
|
||||
let r_contents = fs::read_to_string(r_infile).unwrap();
|
||||
|
||||
for line in r_contents.lines().filter(|l| !l.trim().is_empty()) {
|
||||
let mut it = line.splitn(3, ' ');
|
||||
let name = it.next().unwrap();
|
||||
let val_str = it.next().unwrap();
|
||||
let value: u8 = val_str.parse().unwrap_or_else(|err| panic!("'{val_str}' not valid u8: {err}"));
|
||||
reagentmodes.push((
|
||||
name.to_string(),
|
||||
ReprEnumVariant {
|
||||
value,
|
||||
deprecated: false,
|
||||
props: Vec::new(),
|
||||
},
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
write_repr_enum(&mut writer, "BatchMode", &batchmodes, false);
|
||||
|
||||
println!("cargo:rerun-if-changed=data/batchmodes.txt");
|
||||
|
||||
write_repr_enum(&mut writer, "ReagentMode", &reagentmodes, false);
|
||||
|
||||
println!("cargo:rerun-if-changed=data/reagentmodes.txt");
|
||||
}
|
||||
|
||||
fn write_constants() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
|
||||
let dest_path = Path::new(&out_dir).join("constants.rs");
|
||||
let output_file = File::create(dest_path).unwrap();
|
||||
let mut writer = BufWriter::new(&output_file);
|
||||
|
||||
let mut constants_lookup_map_builder = ::phf_codegen::Map::new();
|
||||
let infile = Path::new("data/constants.txt");
|
||||
let contents = fs::read_to_string(infile).unwrap();
|
||||
|
||||
for line in contents.lines().filter(|l| !l.trim().is_empty()) {
|
||||
let mut it = line.splitn(3, ' ');
|
||||
let name = it.next().unwrap();
|
||||
let constant = it.next().unwrap();
|
||||
|
||||
constants_lookup_map_builder.entry(name, constant);
|
||||
}
|
||||
|
||||
writeln!(
|
||||
&mut writer,
|
||||
"#[allow(clippy::approx_constant)] pub(crate) const CONSTANTS_LOOKUP: phf::Map<&'static str, f64> = {};",
|
||||
constants_lookup_map_builder.build()
|
||||
)
|
||||
.unwrap();
|
||||
println!("cargo:rerun-if-changed=data/constants.txt");
|
||||
}
|
||||
|
||||
fn write_instructions_enum() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
|
||||
let dest_path = Path::new(&out_dir).join("instructions.rs");
|
||||
let output_file = File::create(dest_path).unwrap();
|
||||
let mut writer = BufWriter::new(&output_file);
|
||||
|
||||
let mut instructions = BTreeSet::new();
|
||||
let infile = Path::new("data/instructions.txt");
|
||||
let contents = fs::read_to_string(infile).unwrap();
|
||||
|
||||
for line in contents.lines() {
|
||||
let mut it = line.split(' ');
|
||||
let instruction = it.next().unwrap();
|
||||
instructions.insert(instruction.to_string());
|
||||
}
|
||||
|
||||
write!(
|
||||
&mut writer,
|
||||
"#[derive(Debug, Display, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]\n\
|
||||
pub enum InstructionOp {{\n\
|
||||
"
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
writeln!(&mut writer, " Nop,").unwrap();
|
||||
|
||||
for typ in &instructions {
|
||||
writeln!(&mut writer, " {},", typ.to_case(Case::Pascal)).unwrap();
|
||||
}
|
||||
writeln!(&mut writer, "}}").unwrap();
|
||||
|
||||
write!(
|
||||
&mut writer,
|
||||
"impl FromStr for InstructionOp {{\n \
|
||||
type Err = ParseError;\n \
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {{\n \
|
||||
let end = s.len();\n \
|
||||
match s {{\n"
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
for typ in &instructions {
|
||||
let name = typ.to_case(Case::Pascal);
|
||||
writeln!(&mut writer, " \"{typ}\" => Ok(Self::{name}),").unwrap();
|
||||
}
|
||||
write!(
|
||||
&mut writer,
|
||||
" _ => Err(crate::grammar::ParseError {{ line: 0, start: 0, end, msg: format!(\"Unknown instruction '{{}}'\", s) }})\n \
|
||||
}}\n \
|
||||
}}\n\
|
||||
}}"
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
println!("cargo:rerun-if-changed=data/instructions.txt");
|
||||
}
|
||||
|
||||
fn write_stationpedia() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
|
||||
let dest_path = Path::new(&out_dir).join("stationpedia_prefabs.rs");
|
||||
let output_file = File::create(dest_path).unwrap();
|
||||
let mut writer = BufWriter::new(&output_file);
|
||||
|
||||
let mut prefabs: Vec<(String, ReprEnumVariant<i32>)> = Vec::new();
|
||||
let l_infile = Path::new("data/stationpedia.txt");
|
||||
let l_contents = fs::read_to_string(l_infile).unwrap();
|
||||
|
||||
for line in l_contents.lines().filter(|l| !l.trim().is_empty()) {
|
||||
let mut it = line.splitn(3, ' ');
|
||||
let val_str = it.next().unwrap();
|
||||
let value: i32 = val_str.parse().unwrap_or_else(|err| panic!("'{val_str}' not valid i32: {err}"));
|
||||
let name = it.next().unwrap();
|
||||
let title = it.next();
|
||||
|
||||
let mut props = Vec::new();
|
||||
if let Some(title) = title {
|
||||
props.push(("title".to_owned(), title.to_owned()));
|
||||
}
|
||||
|
||||
prefabs.push((
|
||||
name.to_string(),
|
||||
ReprEnumVariant {
|
||||
value,
|
||||
deprecated: false,
|
||||
props,
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
write_repr_enum(&mut writer, "StationpediaPrefab", &prefabs, true);
|
||||
|
||||
println!("cargo:rerun-if-changed=data/stationpdeia.txt");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
write_logictypes();
|
||||
write_modes();
|
||||
write_constants();
|
||||
write_enums();
|
||||
|
||||
write_instructions_enum();
|
||||
write_stationpedia();
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -1,4 +0,0 @@
|
||||
Average 0 Average of all read values
|
||||
Maximum 3 Highest of all read values
|
||||
Minimum 2 Lowest of all read values
|
||||
Sum 1 All read values added together
|
||||
@@ -1,7 +0,0 @@
|
||||
nan f64::NAN A constant representing 'not a number'. This constants technically provides a 'quiet' NaN, a signal NaN from some instructions will result in an exception and halt execution
|
||||
pinf f64::INFINITY A constant representing a positive infinite value
|
||||
ninf f64::NEG_INFINITY A constant representing a negative infinite value
|
||||
pi 3.141592653589793f64 \nA constant representing the ratio of the circumference of a circle to its diameter, provided in double percision
|
||||
deg2rad 0.0174532923847437f64 \nDegrees to radians conversion constant
|
||||
rad2deg 57.2957801818848f64 \nRadians to degrees conversion constant
|
||||
epsilon f64::EPSILON A constant representing the smallest value representable in double precision
|
||||
@@ -1,475 +0,0 @@
|
||||
AirCon.Cold 0
|
||||
AirCon.Hot 1
|
||||
AirControl.Draught 4
|
||||
AirControl.None 0
|
||||
AirControl.Offline 1
|
||||
AirControl.Pressure 2
|
||||
Color.Black 7 Black
|
||||
Color.Blue 0 Blue
|
||||
Color.Brown 8 Brown
|
||||
Color.Gray 1 Gray
|
||||
Color.Green 2 Green
|
||||
Color.Khaki 9 Khaki
|
||||
Color.Orange 3 Orange
|
||||
Color.Pink 10 Pink
|
||||
Color.Purple 11 Purple
|
||||
Color.Red 4 Red
|
||||
Color.White 6 White
|
||||
Color.Yellow 5 Yellow
|
||||
DaylightSensorMode.Default 0
|
||||
DaylightSensorMode.Horizontal 1
|
||||
DaylightSensorMode.Vertical 2
|
||||
ElevatorMode.Downward 2
|
||||
ElevatorMode.Stationary 0
|
||||
ElevatorMode.Upward 1
|
||||
EntityState.Alive 0
|
||||
EntityState.Dead 1
|
||||
EntityState.Decay 3
|
||||
EntityState.Unconscious 2
|
||||
Equals 0
|
||||
GasType.CarbonDioxide 4
|
||||
GasType.Hydrogen 16384
|
||||
GasType.LiquidCarbonDioxide 2048
|
||||
GasType.LiquidHydrogen 32768
|
||||
GasType.LiquidNitrogen 128
|
||||
GasType.LiquidNitrousOxide 8192
|
||||
GasType.LiquidOxygen 256
|
||||
GasType.LiquidPollutant 4096
|
||||
GasType.LiquidVolatiles 512
|
||||
GasType.Nitrogen 2
|
||||
GasType.NitrousOxide 64
|
||||
GasType.Oxygen 1
|
||||
GasType.Pollutant 16
|
||||
GasType.PollutedWater 65536
|
||||
GasType.Steam 1024
|
||||
GasType.Undefined 0
|
||||
GasType.Volatiles 8
|
||||
GasType.Water 32
|
||||
Greater 1
|
||||
Less 2
|
||||
LogicSlotType.Charge 10 returns current energy charge the slot occupant is holding
|
||||
LogicSlotType.ChargeRatio 11 returns current energy charge the slot occupant is holding as a ratio between 0 and 1 of its maximum
|
||||
LogicSlotType.Class 12 returns integer representing the class of object
|
||||
LogicSlotType.Damage 4 returns the damage state of the item in the slot
|
||||
LogicSlotType.Efficiency 5 returns the growth efficiency of the plant in the slot
|
||||
LogicSlotType.FilterType 25
|
||||
LogicSlotType.Growth 7 returns the current growth state of the plant in the slot
|
||||
LogicSlotType.Health 6 returns the health of the plant in the slot
|
||||
LogicSlotType.LineNumber 19
|
||||
LogicSlotType.Lock 23
|
||||
LogicSlotType.Mature 16 returns 1 if the plant in this slot is mature, 0 when it isn't
|
||||
LogicSlotType.MaxQuantity 15 returns the max stack size of the item in the slot
|
||||
LogicSlotType.None 0 No description
|
||||
LogicSlotType.OccupantHash 2 returns the has of the current occupant, the unique identifier of the thing
|
||||
LogicSlotType.Occupied 1 returns 0 when slot is not occupied, 1 when it is
|
||||
LogicSlotType.On 22
|
||||
LogicSlotType.Open 21
|
||||
LogicSlotType.PrefabHash 17 returns the hash of the structure in the slot
|
||||
LogicSlotType.Pressure 8 returns pressure of the slot occupants internal atmosphere
|
||||
LogicSlotType.PressureAir 14 returns pressure in the air tank of the jetpack in this slot
|
||||
LogicSlotType.PressureWaste 13 returns pressure in the waste tank of the jetpack in this slot
|
||||
LogicSlotType.Quantity 3 returns the current quantity, such as stack size, of the item in the slot
|
||||
LogicSlotType.ReferenceId 26
|
||||
LogicSlotType.Seeding 18 Whether a plant is seeding (ready to harvest seeds from). Returns 1 if seeding or 0 if not.
|
||||
LogicSlotType.SortingClass 24
|
||||
LogicSlotType.Temperature 9 returns temperature of the slot occupants internal atmosphere
|
||||
LogicSlotType.Volume 20
|
||||
LogicType.Acceleration 216 Change in velocity. Rockets that are deccelerating when landing will show this as negative value.
|
||||
LogicType.Activate 9 1 if device is activated (usually means running), otherwise 0
|
||||
LogicType.AirRelease 75 The current state of the air release system, for example AirRelease = 1 for a Hardsuit sets Air Release to On
|
||||
LogicType.AlignmentError 243
|
||||
LogicType.Apex 238
|
||||
LogicType.AutoLand 226 Engages the automatic landing algorithm. The rocket will automatically throttle and turn on and off its engines to achieve a smooth landing.
|
||||
LogicType.AutoShutOff 218 Turns off all devices in the rocket upon reaching destination
|
||||
LogicType.BestContactFilter 267
|
||||
LogicType.Bpm 103 Bpm
|
||||
LogicType.BurnTimeRemaining 225 Estimated time in seconds until fuel is depleted. Calculated based on current fuel usage.
|
||||
LogicType.CelestialHash 242
|
||||
LogicType.CelestialParentHash 250
|
||||
LogicType.Channel0 165
|
||||
LogicType.Channel1 166
|
||||
LogicType.Channel2 167
|
||||
LogicType.Channel3 168
|
||||
LogicType.Channel4 169
|
||||
LogicType.Channel5 170
|
||||
LogicType.Channel6 171
|
||||
LogicType.Channel7 172
|
||||
LogicType.Charge 11 The current charge the device has
|
||||
LogicType.Chart 256
|
||||
LogicType.ChartedNavPoints 259
|
||||
LogicType.ClearMemory 62 When set to 1, clears the counter memory (e.g. ExportCount). Will set itself back to 0 when actioned
|
||||
LogicType.CollectableGoods 101
|
||||
LogicType.Color 38 \n Whether driven by concerns for clarity, safety or simple aesthetics, {LINK:Stationeers;Stationeers} have access to a small rainbow of colors for their constructions. These are the color setting for devices, represented as an integer.\n\n0: Blue\n1: Grey\n2: Green\n3: Orange\n4: Red\n5: Yellow\n6: White\n7: Black\n8: Brown\n9: Khaki\n10: Pink\n11: Purple\n\n It is an unwavering universal law that anything higher than 11 will be purple. The {LINK:ODA;ODA} is powerless to change this. Similarly, anything lower than 0 will be Blue.\n
|
||||
LogicType.Combustion 98 The assess atmosphere is on fire. Returns 1 if atmosphere is on fire, 0 if not.
|
||||
LogicType.CombustionInput 146 The assess atmosphere is on fire. Returns 1 if device's input network is on fire, 0 if not.
|
||||
LogicType.CombustionInput2 147 The assess atmosphere is on fire. Returns 1 if device's Input2 network is on fire, 0 if not.
|
||||
LogicType.CombustionLimiter 153 Retards the rate of combustion inside the machine (range: 0-100), with 0 being the slowest rate of combustion and 100 being the fastest
|
||||
LogicType.CombustionOutput 148 The assess atmosphere is on fire. Returns 1 if device's Output network is on fire, 0 if not.
|
||||
LogicType.CombustionOutput2 149 The assess atmosphere is on fire. Returns 1 if device's Output2 network is on fire, 0 if not.
|
||||
LogicType.CompletionRatio 61 How complete the current production is for this device, between 0 and 1
|
||||
LogicType.ContactTypeId 198 The type id of the contact.
|
||||
LogicType.CurrentCode 261
|
||||
LogicType.CurrentResearchPodType 93
|
||||
LogicType.Density 262
|
||||
LogicType.DestinationCode 215 Unique identifier code for a destination on the space map.
|
||||
LogicType.Discover 255
|
||||
LogicType.DistanceAu 244
|
||||
LogicType.DistanceKm 249
|
||||
LogicType.DrillCondition 240
|
||||
LogicType.DryMass 220 The Mass in kilograms of the rocket excluding fuel. The more massive the rocket the more fuel will be required to move to a new location in space.
|
||||
LogicType.Eccentricity 247
|
||||
LogicType.ElevatorLevel 40 Level the elevator is currently at
|
||||
LogicType.ElevatorSpeed 39 Current speed of the elevator
|
||||
LogicType.EntityState 239
|
||||
LogicType.EnvironmentEfficiency 104 The Environment Efficiency reported by the machine, as a float between 0 and 1
|
||||
LogicType.Error 4 1 if device is in error state, otherwise 0
|
||||
LogicType.ExhaustVelocity 235
|
||||
LogicType.ExportCount 63 How many items exported since last ClearMemory
|
||||
LogicType.ExportQuantity 31 Total quantity of items exported by the device
|
||||
LogicType.ExportSlotHash 42 DEPRECATED
|
||||
LogicType.ExportSlotOccupant 32 DEPRECATED
|
||||
LogicType.Filtration 74 The current state of the filtration system, for example Filtration = 1 for a Hardsuit sets filtration to On
|
||||
LogicType.FlightControlRule 236
|
||||
LogicType.Flush 174 Set to 1 to activate the flush function on the device
|
||||
LogicType.ForceWrite 85 Forces Logic Writer devices to rewrite value
|
||||
LogicType.ForwardX 227
|
||||
LogicType.ForwardY 228
|
||||
LogicType.ForwardZ 229
|
||||
LogicType.Fuel 99
|
||||
LogicType.Harvest 69 Performs the harvesting action for any plant based machinery
|
||||
LogicType.Horizontal 20 Horizontal setting of the device
|
||||
LogicType.HorizontalRatio 34 Radio of horizontal setting for device
|
||||
LogicType.Idle 37 Returns 1 if the device is currently idle, otherwise 0
|
||||
LogicType.ImportCount 64 How many items imported since last ClearMemory
|
||||
LogicType.ImportQuantity 29 Total quantity of items imported by the device
|
||||
LogicType.ImportSlotHash 43 DEPRECATED
|
||||
LogicType.ImportSlotOccupant 30 DEPRECATED
|
||||
LogicType.Inclination 246
|
||||
LogicType.Index 241
|
||||
LogicType.InterrogationProgress 157 Progress of this sattellite dish's interrogation of its current target, as a ratio from 0-1
|
||||
LogicType.LineNumber 173 The line number of current execution for an integrated circuit running on this device. While this number can be written, use with caution
|
||||
LogicType.Lock 10 1 if device is locked, otherwise 0, can be set in most devices and prevents the user from access the values
|
||||
LogicType.ManualResearchRequiredPod 94
|
||||
LogicType.Mass 219 The total Mass of the rocket in kilograms including fuel and cargo. The more massive the rocket the more fuel will be required to move to a new location in space.
|
||||
LogicType.Maximum 23 Maximum setting of the device
|
||||
LogicType.MineablesInQueue 96
|
||||
LogicType.MineablesInVicinity 95
|
||||
LogicType.MinedQuantity 266
|
||||
LogicType.MinimumWattsToContact 163
|
||||
LogicType.Mode 3 Integer for mode state, different devices will have different mode states available to them
|
||||
LogicType.NavPoints 258
|
||||
LogicType.NextWeatherEventTime 97
|
||||
LogicType.None 0 No description
|
||||
LogicType.On 28 The current state of the device, 0 for off, 1 for on
|
||||
LogicType.Open 2 1 if device is open, otherwise 0
|
||||
LogicType.OperationalTemperatureEfficiency 150 How the input pipe's temperature effects the machines efficiency
|
||||
LogicType.OrbitPeriod 245
|
||||
LogicType.Orientation 230
|
||||
LogicType.Output 70 The output operation for a sort handling device, such as a stacker or sorter, when in logic mode the device will only action one repetition when set zero or above and then back to -1 and await further instructions
|
||||
LogicType.PassedMoles 234
|
||||
LogicType.Plant 68 Performs the planting action for any plant based machinery
|
||||
LogicType.PlantEfficiency1 52 DEPRECATED
|
||||
LogicType.PlantEfficiency2 53 DEPRECATED
|
||||
LogicType.PlantEfficiency3 54 DEPRECATED
|
||||
LogicType.PlantEfficiency4 55 DEPRECATED
|
||||
LogicType.PlantGrowth1 48 DEPRECATED
|
||||
LogicType.PlantGrowth2 49 DEPRECATED
|
||||
LogicType.PlantGrowth3 50 DEPRECATED
|
||||
LogicType.PlantGrowth4 51 DEPRECATED
|
||||
LogicType.PlantHash1 56 DEPRECATED
|
||||
LogicType.PlantHash2 57 DEPRECATED
|
||||
LogicType.PlantHash3 58 DEPRECATED
|
||||
LogicType.PlantHash4 59 DEPRECATED
|
||||
LogicType.PlantHealth1 44 DEPRECATED
|
||||
LogicType.PlantHealth2 45 DEPRECATED
|
||||
LogicType.PlantHealth3 46 DEPRECATED
|
||||
LogicType.PlantHealth4 47 DEPRECATED
|
||||
LogicType.PositionX 76 The current position in X dimension in world coordinates
|
||||
LogicType.PositionY 77 The current position in Y dimension in world coordinates
|
||||
LogicType.PositionZ 78 The current position in Z dimension in world coordinates
|
||||
LogicType.Power 1 Can be read to return if the device is correctly powered or not, set via the power system, return 1 if powered and 0 if not
|
||||
LogicType.PowerActual 26 How much energy the device or network is actually using
|
||||
LogicType.PowerGeneration 65 Returns how much power is being generated
|
||||
LogicType.PowerPotential 25 How much energy the device or network potentially provides
|
||||
LogicType.PowerRequired 36 Power requested from the device and/or network
|
||||
LogicType.PrefabHash 84 The hash of the structure
|
||||
LogicType.Pressure 5 The current pressure reading of the device
|
||||
LogicType.PressureEfficiency 152 How the pressure of the input pipe and waste pipe effect the machines efficiency
|
||||
LogicType.PressureExternal 7 Setting for external pressure safety, in KPa
|
||||
LogicType.PressureInput 106 The current pressure reading of the device's Input Network
|
||||
LogicType.PressureInput2 116 The current pressure reading of the device's Input2 Network
|
||||
LogicType.PressureInternal 8 Setting for internal pressure safety, in KPa
|
||||
LogicType.PressureOutput 126 The current pressure reading of the device's Output Network
|
||||
LogicType.PressureOutput2 136 The current pressure reading of the device's Output2 Network
|
||||
LogicType.PressureSetting 71 The current setting for the internal pressure of the object (e.g. the Hardsuit Air release), in KPa
|
||||
LogicType.Progress 214 Progress of the rocket to the next node on the map expressed as a value between 0-1.
|
||||
LogicType.Quantity 27 Total quantity on the device
|
||||
LogicType.Ratio 24 Context specific value depending on device, 0 to 1 based ratio
|
||||
LogicType.RatioCarbonDioxide 15 The ratio of {GAS:CarbonDioxide} in device atmosphere
|
||||
LogicType.RatioCarbonDioxideInput 109 The ratio of {GAS:CarbonDioxide} in device's input network
|
||||
LogicType.RatioCarbonDioxideInput2 119 The ratio of {GAS:CarbonDioxide} in device's Input2 network
|
||||
LogicType.RatioCarbonDioxideOutput 129 The ratio of {GAS:CarbonDioxide} in device's Output network
|
||||
LogicType.RatioCarbonDioxideOutput2 139 The ratio of {GAS:CarbonDioxide} in device's Output2 network
|
||||
LogicType.RatioHydrogen 252 The ratio of {GAS:Hydrogen} in device's Atmopshere
|
||||
LogicType.RatioLiquidCarbonDioxide 199 The ratio of {GAS:LiquidCarbonDioxide} in device's Atmosphere
|
||||
LogicType.RatioLiquidCarbonDioxideInput 200 The ratio of {GAS:LiquidCarbonDioxide} in device's Input Atmosphere
|
||||
LogicType.RatioLiquidCarbonDioxideInput2 201 The ratio of {GAS:LiquidCarbonDioxide} in device's Input2 Atmosphere
|
||||
LogicType.RatioLiquidCarbonDioxideOutput 202 The ratio of {GAS:LiquidCarbonDioxide} in device's device's Output Atmosphere
|
||||
LogicType.RatioLiquidCarbonDioxideOutput2 203 The ratio of {GAS:LiquidCarbonDioxide} in device's Output2 Atmopshere
|
||||
LogicType.RatioLiquidHydrogen 253 The ratio of {GAS:LiquidHydrogen} in device's Atmopshere
|
||||
LogicType.RatioLiquidNitrogen 177 The ratio of {GAS:LiquidNitrogen} in device atmosphere
|
||||
LogicType.RatioLiquidNitrogenInput 178 The ratio of {GAS:LiquidNitrogen} in device's input network
|
||||
LogicType.RatioLiquidNitrogenInput2 179 The ratio of {GAS:LiquidNitrogen} in device's Input2 network
|
||||
LogicType.RatioLiquidNitrogenOutput 180 The ratio of {GAS:LiquidNitrogen} in device's Output network
|
||||
LogicType.RatioLiquidNitrogenOutput2 181 The ratio of {GAS:LiquidNitrogen} in device's Output2 network
|
||||
LogicType.RatioLiquidNitrousOxide 209 The ratio of {GAS:LiquidNitrousOxide} in device's Atmosphere
|
||||
LogicType.RatioLiquidNitrousOxideInput 210 The ratio of {GAS:LiquidNitrousOxide} in device's Input Atmosphere
|
||||
LogicType.RatioLiquidNitrousOxideInput2 211 The ratio of {GAS:LiquidNitrousOxide} in device's Input2 Atmosphere
|
||||
LogicType.RatioLiquidNitrousOxideOutput 212 The ratio of {GAS:LiquidNitrousOxide} in device's device's Output Atmosphere
|
||||
LogicType.RatioLiquidNitrousOxideOutput2 213 The ratio of {GAS:LiquidNitrousOxide} in device's Output2 Atmopshere
|
||||
LogicType.RatioLiquidOxygen 183 The ratio of {GAS:LiquidOxygen} in device's Atmosphere
|
||||
LogicType.RatioLiquidOxygenInput 184 The ratio of {GAS:LiquidOxygen} in device's Input Atmosphere
|
||||
LogicType.RatioLiquidOxygenInput2 185 The ratio of {GAS:LiquidOxygen} in device's Input2 Atmosphere
|
||||
LogicType.RatioLiquidOxygenOutput 186 The ratio of {GAS:LiquidOxygen} in device's device's Output Atmosphere
|
||||
LogicType.RatioLiquidOxygenOutput2 187 The ratio of {GAS:LiquidOxygen} in device's Output2 Atmopshere
|
||||
LogicType.RatioLiquidPollutant 204 The ratio of {GAS:LiquidPollutant} in device's Atmosphere
|
||||
LogicType.RatioLiquidPollutantInput 205 The ratio of {GAS:LiquidPollutant} in device's Input Atmosphere
|
||||
LogicType.RatioLiquidPollutantInput2 206 The ratio of {GAS:LiquidPollutant} in device's Input2 Atmosphere
|
||||
LogicType.RatioLiquidPollutantOutput 207 The ratio of {GAS:LiquidPollutant} in device's device's Output Atmosphere
|
||||
LogicType.RatioLiquidPollutantOutput2 208 The ratio of {GAS:LiquidPollutant} in device's Output2 Atmopshere
|
||||
LogicType.RatioLiquidVolatiles 188 The ratio of {GAS:LiquidVolatiles} in device's Atmosphere
|
||||
LogicType.RatioLiquidVolatilesInput 189 The ratio of {GAS:LiquidVolatiles} in device's Input Atmosphere
|
||||
LogicType.RatioLiquidVolatilesInput2 190 The ratio of {GAS:LiquidVolatiles} in device's Input2 Atmosphere
|
||||
LogicType.RatioLiquidVolatilesOutput 191 The ratio of {GAS:LiquidVolatiles} in device's device's Output Atmosphere
|
||||
LogicType.RatioLiquidVolatilesOutput2 192 The ratio of {GAS:LiquidVolatiles} in device's Output2 Atmopshere
|
||||
LogicType.RatioNitrogen 16 The ratio of nitrogen in device atmosphere
|
||||
LogicType.RatioNitrogenInput 110 The ratio of nitrogen in device's input network
|
||||
LogicType.RatioNitrogenInput2 120 The ratio of nitrogen in device's Input2 network
|
||||
LogicType.RatioNitrogenOutput 130 The ratio of nitrogen in device's Output network
|
||||
LogicType.RatioNitrogenOutput2 140 The ratio of nitrogen in device's Output2 network
|
||||
LogicType.RatioNitrousOxide 83 The ratio of {GAS:NitrousOxide} in device atmosphere
|
||||
LogicType.RatioNitrousOxideInput 114 The ratio of {GAS:NitrousOxide} in device's input network
|
||||
LogicType.RatioNitrousOxideInput2 124 The ratio of {GAS:NitrousOxide} in device's Input2 network
|
||||
LogicType.RatioNitrousOxideOutput 134 The ratio of {GAS:NitrousOxide} in device's Output network
|
||||
LogicType.RatioNitrousOxideOutput2 144 The ratio of {GAS:NitrousOxide} in device's Output2 network
|
||||
LogicType.RatioOxygen 14 The ratio of oxygen in device atmosphere
|
||||
LogicType.RatioOxygenInput 108 The ratio of oxygen in device's input network
|
||||
LogicType.RatioOxygenInput2 118 The ratio of oxygen in device's Input2 network
|
||||
LogicType.RatioOxygenOutput 128 The ratio of oxygen in device's Output network
|
||||
LogicType.RatioOxygenOutput2 138 The ratio of oxygen in device's Output2 network
|
||||
LogicType.RatioPollutant 17 The ratio of pollutant in device atmosphere
|
||||
LogicType.RatioPollutantInput 111 The ratio of pollutant in device's input network
|
||||
LogicType.RatioPollutantInput2 121 The ratio of pollutant in device's Input2 network
|
||||
LogicType.RatioPollutantOutput 131 The ratio of pollutant in device's Output network
|
||||
LogicType.RatioPollutantOutput2 141 The ratio of pollutant in device's Output2 network
|
||||
LogicType.RatioPollutedWater 254 The ratio of polluted water in device atmosphere
|
||||
LogicType.RatioSteam 193 The ratio of {GAS:Steam} in device's Atmosphere
|
||||
LogicType.RatioSteamInput 194 The ratio of {GAS:Steam} in device's Input Atmosphere
|
||||
LogicType.RatioSteamInput2 195 The ratio of {GAS:Steam} in device's Input2 Atmosphere
|
||||
LogicType.RatioSteamOutput 196 The ratio of {GAS:Steam} in device's device's Output Atmosphere
|
||||
LogicType.RatioSteamOutput2 197 The ratio of {GAS:Steam} in device's Output2 Atmopshere
|
||||
LogicType.RatioVolatiles 18 The ratio of volatiles in device atmosphere
|
||||
LogicType.RatioVolatilesInput 112 The ratio of volatiles in device's input network
|
||||
LogicType.RatioVolatilesInput2 122 The ratio of volatiles in device's Input2 network
|
||||
LogicType.RatioVolatilesOutput 132 The ratio of volatiles in device's Output network
|
||||
LogicType.RatioVolatilesOutput2 142 The ratio of volatiles in device's Output2 network
|
||||
LogicType.RatioWater 19 The ratio of water in device atmosphere
|
||||
LogicType.RatioWaterInput 113 The ratio of water in device's input network
|
||||
LogicType.RatioWaterInput2 123 The ratio of water in device's Input2 network
|
||||
LogicType.RatioWaterOutput 133 The ratio of water in device's Output network
|
||||
LogicType.RatioWaterOutput2 143 The ratio of water in device's Output2 network
|
||||
LogicType.ReEntryAltitude 237
|
||||
LogicType.Reagents 13 Total number of reagents recorded by the device
|
||||
LogicType.RecipeHash 41 Current hash of the recipe the device is set to produce
|
||||
LogicType.ReferenceId 217
|
||||
LogicType.RequestHash 60 When set to the unique identifier, requests an item of the provided type from the device
|
||||
LogicType.RequiredPower 33 Idle operating power quantity, does not necessarily include extra demand power
|
||||
LogicType.ReturnFuelCost 100
|
||||
LogicType.Richness 263
|
||||
LogicType.Rpm 155 The number of revolutions per minute that the device's spinning mechanism is doing
|
||||
LogicType.SemiMajorAxis 248
|
||||
LogicType.Setting 12 A variable setting that can be read or written, depending on the device
|
||||
LogicType.SettingInput 91
|
||||
LogicType.SettingOutput 92
|
||||
LogicType.SignalID 87 Returns the contact ID of the strongest signal from this Satellite
|
||||
LogicType.SignalStrength 86 Returns the degree offset of the strongest contact
|
||||
LogicType.Sites 260
|
||||
LogicType.Size 264
|
||||
LogicType.SizeX 160 Size on the X (right) axis of the object in largeGrids (a largeGrid is 2meters)
|
||||
LogicType.SizeY 161 Size on the Y(Up) axis of the object in largeGrids (a largeGrid is 2meters)
|
||||
LogicType.SizeZ 162 Size on the Z(Forward) axis of the object in largeGrids (a largeGrid is 2meters)
|
||||
LogicType.SolarAngle 22 Solar angle of the device
|
||||
LogicType.SolarIrradiance 176
|
||||
LogicType.SoundAlert 175 Plays a sound alert on the devices speaker
|
||||
LogicType.Stress 156 Machines get stressed when working hard. When Stress reaches 100 the machine will automatically shut down
|
||||
LogicType.Survey 257
|
||||
LogicType.TargetPadIndex 158 The index of the trader landing pad on this devices data network that it will try to call a trader in to land
|
||||
LogicType.TargetX 88 The target position in X dimension in world coordinates
|
||||
LogicType.TargetY 89 The target position in Y dimension in world coordinates
|
||||
LogicType.TargetZ 90 The target position in Z dimension in world coordinates
|
||||
LogicType.Temperature 6 The current temperature reading of the device
|
||||
LogicType.TemperatureDifferentialEfficiency 151 How the difference between the input pipe and waste pipe temperatures effect the machines efficiency
|
||||
LogicType.TemperatureExternal 73 The temperature of the outside of the device, usually the world atmosphere surrounding it
|
||||
LogicType.TemperatureInput 107 The current temperature reading of the device's Input Network
|
||||
LogicType.TemperatureInput2 117 The current temperature reading of the device's Input2 Network
|
||||
LogicType.TemperatureOutput 127 The current temperature reading of the device's Output Network
|
||||
LogicType.TemperatureOutput2 137 The current temperature reading of the device's Output2 Network
|
||||
LogicType.TemperatureSetting 72 The current setting for the internal temperature of the object (e.g. the Hardsuit A/C)
|
||||
LogicType.Throttle 154 Increases the rate at which the machine works (range: 0-100)
|
||||
LogicType.Thrust 221 Total current thrust of all rocket engines on the rocket in Newtons.
|
||||
LogicType.ThrustToWeight 223 Ratio of thrust to weight of rocket. Weight is effected by local body gravity. A rocket with a low thrust to weight will expend more fuel during launch and landing.
|
||||
LogicType.Time 102 Time
|
||||
LogicType.TimeToDestination 224 Estimated time in seconds until rocket arrives at target destination.
|
||||
LogicType.TotalMoles 66 Returns the total moles of the device
|
||||
LogicType.TotalMolesInput 115 Returns the total moles of the device's Input Network
|
||||
LogicType.TotalMolesInput2 125 Returns the total moles of the device's Input2 Network
|
||||
LogicType.TotalMolesOutput 135 Returns the total moles of the device's Output Network
|
||||
LogicType.TotalMolesOutput2 145 Returns the total moles of the device's Output2 Network
|
||||
LogicType.TotalQuantity 265
|
||||
LogicType.TrueAnomaly 251
|
||||
LogicType.VelocityMagnitude 79 The current magnitude of the velocity vector
|
||||
LogicType.VelocityRelativeX 80 The current velocity X relative to the forward vector of this
|
||||
LogicType.VelocityRelativeY 81 The current velocity Y relative to the forward vector of this
|
||||
LogicType.VelocityRelativeZ 82 The current velocity Z relative to the forward vector of this
|
||||
LogicType.VelocityX 231
|
||||
LogicType.VelocityY 232
|
||||
LogicType.VelocityZ 233
|
||||
LogicType.Vertical 21 Vertical setting of the device
|
||||
LogicType.VerticalRatio 35 Radio of vertical setting for device
|
||||
LogicType.Volume 67 Returns the device atmosphere volume
|
||||
LogicType.VolumeOfLiquid 182 The total volume of all liquids in Liters in the atmosphere
|
||||
LogicType.WattsReachingContact 164 The amount of watts actually hitting the contact. This is effected by the power of the dish and how far off-axis the dish is from the contact vector
|
||||
LogicType.Weight 222 Weight of Rocket in Newtons (Including fuel and cargo). Weight is effected by local body gravity.
|
||||
LogicType.WorkingGasEfficiency 105 The Working Gas Efficiency reported by the machine, as a float between 0 and 1
|
||||
NotEquals 3
|
||||
PowerMode.Charged 4
|
||||
PowerMode.Charging 3
|
||||
PowerMode.Discharged 1
|
||||
PowerMode.Discharging 2
|
||||
PowerMode.Idle 0
|
||||
ReEntryProfile.High 3
|
||||
ReEntryProfile.Max 4
|
||||
ReEntryProfile.Medium 2
|
||||
ReEntryProfile.None 0
|
||||
ReEntryProfile.Optimal 1
|
||||
RobotMode.Follow 1
|
||||
RobotMode.MoveToTarget 2
|
||||
RobotMode.None 0
|
||||
RobotMode.PathToTarget 5
|
||||
RobotMode.Roam 3
|
||||
RobotMode.StorageFull 6
|
||||
RobotMode.Unload 4
|
||||
RocketMode.Chart 5
|
||||
RocketMode.Discover 4
|
||||
RocketMode.Invalid 0
|
||||
RocketMode.Mine 2
|
||||
RocketMode.None 1
|
||||
RocketMode.Survey 3
|
||||
SlotClass.AccessCard 22
|
||||
SlotClass.Appliance 18
|
||||
SlotClass.Back 3
|
||||
SlotClass.Battery 14
|
||||
SlotClass.Belt 16
|
||||
SlotClass.Blocked 38
|
||||
SlotClass.Bottle 25
|
||||
SlotClass.Cartridge 21
|
||||
SlotClass.Circuit 24
|
||||
SlotClass.Circuitboard 7
|
||||
SlotClass.CreditCard 28
|
||||
SlotClass.DataDisk 8
|
||||
SlotClass.DirtCanister 29
|
||||
SlotClass.DrillHead 35
|
||||
SlotClass.Egg 15
|
||||
SlotClass.Entity 13
|
||||
SlotClass.Flare 37
|
||||
SlotClass.GasCanister 5
|
||||
SlotClass.GasFilter 4
|
||||
SlotClass.Glasses 27
|
||||
SlotClass.Helmet 1
|
||||
SlotClass.Ingot 19
|
||||
SlotClass.LiquidBottle 32
|
||||
SlotClass.LiquidCanister 31
|
||||
SlotClass.Magazine 23
|
||||
SlotClass.Motherboard 6
|
||||
SlotClass.None 0
|
||||
SlotClass.Ore 10
|
||||
SlotClass.Organ 9
|
||||
SlotClass.Plant 11
|
||||
SlotClass.ProgrammableChip 26
|
||||
SlotClass.ScanningHead 36
|
||||
SlotClass.SensorProcessingUnit 30
|
||||
SlotClass.SoundCartridge 34
|
||||
SlotClass.Suit 2
|
||||
SlotClass.SuitMod 39
|
||||
SlotClass.Tool 17
|
||||
SlotClass.Torpedo 20
|
||||
SlotClass.Uniform 12
|
||||
SlotClass.Wreckage 33
|
||||
SorterInstruction.FilterPrefabHashEquals 1
|
||||
SorterInstruction.FilterPrefabHashNotEquals 2
|
||||
SorterInstruction.FilterQuantityCompare 5
|
||||
SorterInstruction.FilterSlotTypeCompare 4
|
||||
SorterInstruction.FilterSortingClassCompare 3
|
||||
SorterInstruction.LimitNextExecutionByCount 6
|
||||
SorterInstruction.None 0
|
||||
SortingClass.Appliances 6
|
||||
SortingClass.Atmospherics 7
|
||||
SortingClass.Clothing 5
|
||||
SortingClass.Default 0
|
||||
SortingClass.Food 4
|
||||
SortingClass.Ices 10
|
||||
SortingClass.Kits 1
|
||||
SortingClass.Ores 9
|
||||
SortingClass.Resources 3
|
||||
SortingClass.Storage 8
|
||||
SortingClass.Tools 2
|
||||
Sound.AirlockCycling 22
|
||||
Sound.Alarm1 45
|
||||
Sound.Alarm10 12
|
||||
Sound.Alarm11 13
|
||||
Sound.Alarm12 14
|
||||
Sound.Alarm2 1
|
||||
Sound.Alarm3 2
|
||||
Sound.Alarm4 3
|
||||
Sound.Alarm5 4
|
||||
Sound.Alarm6 5
|
||||
Sound.Alarm7 6
|
||||
Sound.Alarm8 10
|
||||
Sound.Alarm9 11
|
||||
Sound.Alert 17
|
||||
Sound.Danger 15
|
||||
Sound.Depressurising 20
|
||||
Sound.FireFireFire 28
|
||||
Sound.Five 33
|
||||
Sound.Floor 34
|
||||
Sound.Four 32
|
||||
Sound.HaltWhoGoesThere 27
|
||||
Sound.HighCarbonDioxide 44
|
||||
Sound.IntruderAlert 19
|
||||
Sound.LiftOff 36
|
||||
Sound.MalfunctionDetected 26
|
||||
Sound.Music1 7
|
||||
Sound.Music2 8
|
||||
Sound.Music3 9
|
||||
Sound.None 0
|
||||
Sound.One 29
|
||||
Sound.PollutantsDetected 43
|
||||
Sound.PowerLow 23
|
||||
Sound.PressureHigh 39
|
||||
Sound.PressureLow 40
|
||||
Sound.Pressurising 21
|
||||
Sound.RocketLaunching 35
|
||||
Sound.StormIncoming 18
|
||||
Sound.SystemFailure 24
|
||||
Sound.TemperatureHigh 41
|
||||
Sound.TemperatureLow 42
|
||||
Sound.Three 31
|
||||
Sound.TraderIncoming 37
|
||||
Sound.TraderLanded 38
|
||||
Sound.Two 30
|
||||
Sound.Warning 16
|
||||
Sound.Welcome 25
|
||||
TransmitterMode.Active 1
|
||||
TransmitterMode.Passive 0
|
||||
Vent.Inward 1
|
||||
Vent.Outward 0
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"english": {
|
||||
"bapz": "Branch to line c if abs(a) <= max(b * abs(a), float.epsilon * 8)",
|
||||
"bapzal": "Branch to line c if abs(a) <= max(b * abs(a), float.epsilon * 8) and store next line number in ra",
|
||||
"bnaz": "Branch to line c if abs(a) > max (b * abs(a), float.epsilon * 8)",
|
||||
"bnazal": "Branch to line c if abs(a) > max (b * abs(a), float.epsilon * 8) and store next line number in ra",
|
||||
"brapz": "Relative branch to line c if abs(a) <= max(b * abs(a), float.epsilon * 8)",
|
||||
"brnaz": "Relative branch to line c if abs(a) > max(b * abs(a), float.epsilon * 8)",
|
||||
"sapz": "Register = 1 if abs(a) <= max(b * abs(a), float.epsilon * 8), otherwise 0",
|
||||
"snaz": "Register = 1 if abs(a) > max(b * abs(a), float.epsilon), otherwise 0",
|
||||
"log": "Register = base e log(a) or ln(a)",
|
||||
"exp": "Register = exp(a) or e^a"
|
||||
}
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
abs REGISTER VALUE
|
||||
acos REGISTER VALUE
|
||||
add REGISTER VALUE VALUE
|
||||
alias NAME REGISTER_DEVICE
|
||||
and REGISTER VALUE VALUE
|
||||
asin REGISTER VALUE
|
||||
atan REGISTER VALUE
|
||||
atan2 REGISTER VALUE VALUE
|
||||
bap VALUE VALUE VALUE VALUE
|
||||
bapal VALUE VALUE VALUE VALUE
|
||||
bapz VALUE VALUE VALUE
|
||||
bapzal VALUE VALUE VALUE
|
||||
bdns DEVICE VALUE
|
||||
bdnsal DEVICE VALUE
|
||||
bdse DEVICE VALUE
|
||||
bdseal DEVICE VALUE
|
||||
beq VALUE VALUE VALUE
|
||||
beqal VALUE VALUE VALUE
|
||||
beqz VALUE VALUE
|
||||
beqzal VALUE VALUE
|
||||
bge VALUE VALUE VALUE
|
||||
bgeal VALUE VALUE VALUE
|
||||
bgez VALUE VALUE
|
||||
bgezal VALUE VALUE
|
||||
bgt VALUE VALUE VALUE
|
||||
bgtal VALUE VALUE VALUE
|
||||
bgtz VALUE VALUE
|
||||
bgtzal VALUE VALUE
|
||||
ble VALUE VALUE VALUE
|
||||
bleal VALUE VALUE VALUE
|
||||
blez VALUE VALUE
|
||||
blezal VALUE VALUE
|
||||
blt VALUE VALUE VALUE
|
||||
bltal VALUE VALUE VALUE
|
||||
bltz VALUE VALUE
|
||||
bltzal VALUE VALUE
|
||||
bna VALUE VALUE VALUE VALUE
|
||||
bnaal VALUE VALUE VALUE VALUE
|
||||
bnan VALUE VALUE
|
||||
bnaz VALUE VALUE VALUE
|
||||
bnazal VALUE VALUE VALUE
|
||||
bne VALUE VALUE VALUE
|
||||
bneal VALUE VALUE VALUE
|
||||
bnez VALUE VALUE
|
||||
bnezal VALUE VALUE
|
||||
brap VALUE VALUE VALUE VALUE
|
||||
brapz VALUE VALUE VALUE
|
||||
brdns DEVICE VALUE
|
||||
brdse DEVICE VALUE
|
||||
breq VALUE VALUE VALUE
|
||||
breqz VALUE VALUE
|
||||
brge VALUE VALUE VALUE
|
||||
brgez VALUE VALUE
|
||||
brgt VALUE VALUE VALUE
|
||||
brgtz VALUE VALUE
|
||||
brle VALUE VALUE VALUE
|
||||
brlez VALUE VALUE
|
||||
brlt VALUE VALUE VALUE
|
||||
brltz VALUE VALUE
|
||||
brna VALUE VALUE VALUE VALUE
|
||||
brnan VALUE VALUE
|
||||
brnaz VALUE VALUE VALUE
|
||||
brne VALUE VALUE VALUE
|
||||
brnez VALUE VALUE
|
||||
ceil REGISTER VALUE
|
||||
cos REGISTER VALUE
|
||||
define NAME NUMBER
|
||||
div REGISTER VALUE VALUE
|
||||
exp REGISTER VALUE
|
||||
floor REGISTER VALUE
|
||||
get REGISTER DEVICE ADDRESS
|
||||
getd REGISTER DEVICE_ID ADDRESS
|
||||
hcf
|
||||
j VALUE
|
||||
jal VALUE
|
||||
jr VALUE
|
||||
l REGISTER DEVICE LOGIC_TYPE
|
||||
lb REGISTER DEVICE_TYPE LOGIC_TYPE BATCH_MODE
|
||||
lbn REGISTER DEVICE_TYPE DEVICE_NAME LOGIC_TYPE BATCH_MODE
|
||||
lbns REGISTER DEVICE_TYPE DEVICE_NAME INDEX SLOT_LOGIC_TYPE BATCH_MODE
|
||||
lbs REGISTER DEVICE_TYPE INDEX SLOT_LOGIC_TYPE BATCH_MODE
|
||||
ld REGISTER DEVICE_ID LOGIC_TYPE
|
||||
log REGISTER VALUE
|
||||
lr REGISTER DEVICE REAGENT_MODE VALUE
|
||||
ls REGISTER DEVICE VALUE SLOT_LOGIC_TYPE
|
||||
max REGISTER VALUE VALUE
|
||||
min REGISTER VALUE VALUE
|
||||
mod REGISTER VALUE VALUE
|
||||
move REGISTER VALUE
|
||||
mul REGISTER VALUE VALUE
|
||||
nor REGISTER VALUE VALUE
|
||||
not REGISTER VALUE
|
||||
or REGISTER VALUE VALUE
|
||||
peek REGISTER
|
||||
poke ADDRESS VALUE
|
||||
pop REGISTER
|
||||
push VALUE
|
||||
put DEVICE ADDRESS VALUE
|
||||
putd DEVICE_ID ADDRESS VALUE
|
||||
rand REGISTER
|
||||
round REGISTER VALUE
|
||||
s DEVICE LOGIC_TYPE VALUE
|
||||
sap REGISTER VALUE VALUE VALUE
|
||||
sapz REGISTER VALUE VALUE
|
||||
sb DEVICE_TYPE LOGIC_TYPE VALUE
|
||||
sbn DEVICE_TYPE DEVICE_NAME LOGIC_TYPE VALUE
|
||||
sbs DEVICE_TYPE INDEX SLOT_LOGIC_TYPE VALUE
|
||||
sd DEVICE_ID LOGIC_TYPE VALUE
|
||||
sdns REGISTER DEVICE
|
||||
sdse REGISTER DEVICE
|
||||
select REGISTER VALUE VALUE VALUE
|
||||
seq REGISTER VALUE VALUE
|
||||
seqz REGISTER VALUE
|
||||
sge REGISTER VALUE VALUE
|
||||
sgez REGISTER VALUE
|
||||
sgt REGISTER VALUE VALUE
|
||||
sgtz REGISTER VALUE
|
||||
sin REGISTER VALUE
|
||||
sla REGISTER VALUE VALUE
|
||||
sle REGISTER VALUE VALUE
|
||||
sleep VALUE
|
||||
slez REGISTER VALUE
|
||||
sll REGISTER VALUE VALUE
|
||||
slt REGISTER VALUE VALUE
|
||||
sltz REGISTER VALUE
|
||||
sna REGISTER VALUE VALUE VALUE
|
||||
snan REGISTER VALUE
|
||||
snanz REGISTER VALUE
|
||||
snaz REGISTER VALUE VALUE
|
||||
sne REGISTER VALUE VALUE
|
||||
snez REGISTER VALUE
|
||||
sqrt REGISTER VALUE
|
||||
sra REGISTER VALUE VALUE
|
||||
srl REGISTER VALUE VALUE
|
||||
ss DEVICE VALUE SLOT_LOGIC_TYPE REGISTER
|
||||
sub REGISTER VALUE VALUE
|
||||
tan REGISTER VALUE
|
||||
trunc REGISTER VALUE
|
||||
xor REGISTER VALUE VALUE
|
||||
yield
|
||||
@@ -1,136 +0,0 @@
|
||||
abs Register = the absolute value of a
|
||||
acos Returns the angle (radians) whos cosine is the specified value
|
||||
add Register = a + b.
|
||||
alias Labels register or device reference with name, device references also affect what shows on the screws on the IC base.
|
||||
and Performs a bitwise logical AND operation on the binary representation of two values. Each bit of the result is determined by evaluating the corresponding bits of the input values. If both bits are 1, the resulting bit is set to 1. Otherwise the resulting bit is set to 0.
|
||||
asin Returns the angle (radians) whos sine is the specified value
|
||||
atan Returns the angle (radians) whos tan is the specified value
|
||||
atan2 Returns the angle (radians) whose tangent is the quotient of two specified values: a (y) and b (x)
|
||||
bap Branch to line d if abs(a - b) <= max(c * max(abs(a), abs(b)), float.epsilon * 8)
|
||||
bapal Branch to line d if abs(a - b) <= max(c * max(abs(a), abs(b)), float.epsilon * 8) and store next line number in ra
|
||||
bapz Branch to line c if abs(a) <= max(b * abs(a), float.epsilon * 8)
|
||||
bapzal Branch to line c if abs(a) <= max(b * abs(a), float.epsilon * 8) and store next line number in ra
|
||||
bdns Branch to line a if device d isn't set
|
||||
bdnsal Jump execution to line a and store next line number if device is not set
|
||||
bdse Branch to line a if device d is set
|
||||
bdseal Jump execution to line a and store next line number if device is set
|
||||
beq Branch to line c if a == b
|
||||
beqal Branch to line c if a == b and store next line number in ra
|
||||
beqz Branch to line b if a == 0
|
||||
beqzal Branch to line b if a == 0 and store next line number in ra
|
||||
bge Branch to line c if a >= b
|
||||
bgeal Branch to line c if a >= b and store next line number in ra
|
||||
bgez Branch to line b if a >= 0
|
||||
bgezal Branch to line b if a >= 0 and store next line number in ra
|
||||
bgt Branch to line c if a > b
|
||||
bgtal Branch to line c if a > b and store next line number in ra
|
||||
bgtz Branch to line b if a > 0
|
||||
bgtzal Branch to line b if a > 0 and store next line number in ra
|
||||
ble Branch to line c if a <= b
|
||||
bleal Branch to line c if a <= b and store next line number in ra
|
||||
blez Branch to line b if a <= 0
|
||||
blezal Branch to line b if a <= 0 and store next line number in ra
|
||||
blt Branch to line c if a < b
|
||||
bltal Branch to line c if a < b and store next line number in ra
|
||||
bltz Branch to line b if a < 0
|
||||
bltzal Branch to line b if a < 0 and store next line number in ra
|
||||
bna Branch to line d if abs(a - b) > max(c * max(abs(a), abs(b)), float.epsilon * 8)
|
||||
bnaal Branch to line d if abs(a - b) <= max(c * max(abs(a), abs(b)), float.epsilon * 8) and store next line number in ra
|
||||
bnan Branch to line b if a is not a number (NaN)
|
||||
bnaz Branch to line c if abs(a) > max (b * abs(a), float.epsilon * 8)
|
||||
bnazal Branch to line c if abs(a) > max (b * abs(a), float.epsilon * 8) and store next line number in ra
|
||||
bne Branch to line c if a != b
|
||||
bneal Branch to line c if a != b and store next line number in ra
|
||||
bnez branch to line b if a != 0
|
||||
bnezal Branch to line b if a != 0 and store next line number in ra
|
||||
brap Relative branch to line d if abs(a - b) <= max(c * max(abs(a), abs(b)), float.epsilon * 8)
|
||||
brapz Relative branch to line c if abs(a) <= max(b * abs(a), float.epsilon * 8)
|
||||
brdns Relative jump to line a if device is not set
|
||||
brdse Relative jump to line a if device is set
|
||||
breq Relative branch to line c if a == b
|
||||
breqz Relative branch to line b if a == 0
|
||||
brge Relative jump to line c if a >= b
|
||||
brgez Relative branch to line b if a >= 0
|
||||
brgt relative jump to line c if a > b
|
||||
brgtz Relative branch to line b if a > 0
|
||||
brle Relative jump to line c if a <= b
|
||||
brlez Relative branch to line b if a <= 0
|
||||
brlt Relative jump to line c if a < b
|
||||
brltz Relative branch to line b if a < 0
|
||||
brna Relative branch to line d if abs(a - b) > max(c * max(abs(a), abs(b)), float.epsilon * 8)
|
||||
brnan Relative branch to line b if a is not a number (NaN)
|
||||
brnaz Relative branch to line c if abs(a) > max(b * abs(a), float.epsilon * 8)
|
||||
brne Relative branch to line c if a != b
|
||||
brnez Relative branch to line b if a != 0
|
||||
ceil Register = smallest integer greater than a
|
||||
cos Returns the cosine of the specified angle (radians)
|
||||
define Creates a label that will be replaced throughout the program with the provided value.
|
||||
div Register = a / b
|
||||
exp Register = exp(a) or e^a
|
||||
floor Register = largest integer less than a
|
||||
hcf Halt and catch fire
|
||||
j Jump execution to line a
|
||||
jal Jump execution to line a and store next line number in ra
|
||||
jr Relative jump to line a
|
||||
l Loads device LogicType to register by housing index value.
|
||||
label DEPRECATED
|
||||
lb Loads LogicType from all output network devices with provided type hash using the provide batch mode. Average (0), Sum (1), Minimum (2), Maximum (3). Can use either the word, or the number.
|
||||
lbn Loads LogicType from all output network devices with provided type and name hashes using the provide batch mode. Average (0), Sum (1), Minimum (2), Maximum (3). Can use either the word, or the number.
|
||||
lbns Loads LogicSlotType from slotIndex from all output network devices with provided type and name hashes using the provide batch mode. Average (0), Sum (1), Minimum (2), Maximum (3). Can use either the word, or the number.
|
||||
lbs Loads LogicSlotType from slotIndex from all output network devices with provided type hash using the provide batch mode. Average (0), Sum (1), Minimum (2), Maximum (3). Can use either the word, or the number.
|
||||
ld Loads device LogicType to register by direct ID reference.
|
||||
log Register = base e log(a) or ln(a)
|
||||
lr Loads reagent of device's ReagentMode where a hash of the reagent type to check for. ReagentMode can be either Contents (0), Required (1), Recipe (2). Can use either the word, or the number.
|
||||
ls Loads slot LogicSlotType on device to register.
|
||||
max Register = max of a or b
|
||||
min Register = min of a or b
|
||||
mod Register = a mod b (note: NOT a % b)
|
||||
move Register = provided num or register value.
|
||||
mul Register = a * b
|
||||
nor Performs a bitwise logical NOR (NOT OR) operation on the binary representation of two values. Each bit of the result is determined by evaluating the corresponding bits of the input values. If both bits are 0, the resulting bit is set to 1. Otherwise, if at least one bit is 1, the resulting bit is set to 0.
|
||||
not Performs a bitwise logical NOT operation flipping each bit of the input value, resulting in a binary complement. If a bit is 1, it becomes 0, and if a bit is 0, it becomes 1.
|
||||
or Performs a bitwise logical OR operation on the binary representation of two values. Each bit of the result is determined by evaluating the corresponding bits of the input values. If either bit is 1, the resulting bit is set to 1. If both bits are 0, the resulting bit is set to 0.
|
||||
peek Register = the value at the top of the stack
|
||||
pop Register = the value at the top of the stack and decrements sp
|
||||
push Pushes the value of a to the stack at sp and increments sp
|
||||
rand Register = a random value x with 0 <= x < 1
|
||||
round Register = a rounded to nearest integer
|
||||
s Stores register value to LogicType on device by housing index value.
|
||||
sap Register = 1 if abs(a - b) <= max(c * max(abs(a), abs(b)), float.epsilon * 8), otherwise 0
|
||||
sapz Register = 1 if abs(a) <= max(b * abs(a), float.epsilon * 8), otherwise 0
|
||||
sb Stores register value to LogicType on all output network devices with provided type hash.
|
||||
sbn Stores register value to LogicType on all output network devices with provided type hash and name.
|
||||
sbs Stores register value to LogicSlotType on all output network devices with provided type hash in the provided slot.
|
||||
sd Stores register value to LogicType on device by direct ID reference.
|
||||
sdns Register = 1 if device is not set, otherwise 0
|
||||
sdse Register = 1 if device is set, otherwise 0.
|
||||
select Register = b if a is non-zero, otherwise c
|
||||
seq Register = 1 if a == b, otherwise 0
|
||||
seqz Register = 1 if a == 0, otherwise 0
|
||||
sge Register = 1 if a >= b, otherwise 0
|
||||
sgez Register = 1 if a >= 0, otherwise 0
|
||||
sgt Register = 1 if a > b, otherwise 0
|
||||
sgtz Register = 1 if a > 0, otherwise 0
|
||||
sin Returns the sine of the specified angle (radians)
|
||||
sla Performs a bitwise arithmetic left shift operation on the binary representation of a value. It shifts the bits to the left and fills the vacated rightmost bits with a copy of the sign bit (the most significant bit).
|
||||
sle Register = 1 if a <= b, otherwise 0
|
||||
sleep Pauses execution on the IC for a seconds
|
||||
slez Register = 1 if a <= 0, otherwise 0
|
||||
sll Performs a bitwise logical left shift operation on the binary representation of a value. It shifts the bits to the left and fills the vacated rightmost bits with zeros.
|
||||
slt Register = 1 if a < b, otherwise 0
|
||||
sltz Register = 1 if a < 0, otherwise 0
|
||||
sna Register = 1 if abs(a - b) > max(c * max(abs(a), abs(b)), float.epsilon * 8), otherwise 0
|
||||
snan Register = 1 if a is NaN, otherwise 0
|
||||
snanz Register = 0 if a is NaN, otherwise 1
|
||||
snaz Register = 1 if abs(a) > max(b * abs(a), float.epsilon), otherwise 0
|
||||
sne Register = 1 if a != b, otherwise 0
|
||||
snez Register = 1 if a != 0, otherwise 0
|
||||
sqrt Register = square root of a
|
||||
sra Performs a bitwise arithmetic right shift operation on the binary representation of a value. It shifts the bits to the right and fills the vacated leftmost bits with a copy of the sign bit (the most significant bit).
|
||||
srl Performs a bitwise logical right shift operation on the binary representation of a value. It shifts the bits to the right and fills the vacated leftmost bits with zeros
|
||||
ss Stores register value to device stored in a slot LogicSlotType on device.
|
||||
sub Register = a - b.
|
||||
tan Returns the tan of the specified angle (radians)
|
||||
trunc Register = a with fractional part removed
|
||||
xor Performs a bitwise logical XOR (exclusive OR) operation on the binary representation of two values. Each bit of the result is determined by evaluating the corresponding bits of the input values. If the bits are different (one bit is 0 and the other is 1), the resulting bit is set to 1. If the bits are the same (both 0 or both 1), the resulting bit is set to 0.
|
||||
yield Pauses execution for 1 tick
|
||||
@@ -1,267 +0,0 @@
|
||||
Acceleration 216 Change in velocity. Rockets that are deccelerating when landing will show this as negative value.
|
||||
Activate 9 1 if device is activated (usually means running), otherwise 0
|
||||
AirRelease 75 The current state of the air release system, for example AirRelease = 1 for a Hardsuit sets Air Release to On
|
||||
AlignmentError 243
|
||||
Apex 238
|
||||
AutoLand 226 Engages the automatic landing algorithm. The rocket will automatically throttle and turn on and off its engines to achieve a smooth landing.
|
||||
AutoShutOff 218 Turns off all devices in the rocket upon reaching destination
|
||||
BestContactFilter 267
|
||||
Bpm 103 Bpm
|
||||
BurnTimeRemaining 225 Estimated time in seconds until fuel is depleted. Calculated based on current fuel usage.
|
||||
CelestialHash 242
|
||||
CelestialParentHash 250
|
||||
Channel0 165 Channel 0 on a cable network which should be considered volatile
|
||||
Channel1 166 Channel 1 on a cable network which should be considered volatile
|
||||
Channel2 167 Channel 2 on a cable network which should be considered volatile
|
||||
Channel3 168 Channel 3 on a cable network which should be considered volatile
|
||||
Channel4 169 Channel 4 on a cable network which should be considered volatile
|
||||
Channel5 170 Channel 5 on a cable network which should be considered volatile
|
||||
Channel6 171 Channel 6 on a cable network which should be considered volatile
|
||||
Channel7 172 Channel 7 on a cable network which should be considered volatile
|
||||
Charge 11 The current charge the device has
|
||||
Chart 256
|
||||
ChartedNavPoints 259
|
||||
ClearMemory 62 When set to 1, clears the counter memory (e.g. ExportCount). Will set itself back to 0 when actioned
|
||||
CollectableGoods 101
|
||||
Color 38 \n Whether driven by concerns for clarity, safety or simple aesthetics, {LINK:Stationeers;Stationeers} have access to a small rainbow of colors for their constructions. These are the color setting for devices, represented as an integer.\n\n0: Blue\n1: Grey\n2: Green\n3: Orange\n4: Red\n5: Yellow\n6: White\n7: Black\n8: Brown\n9: Khaki\n10: Pink\n11: Purple\n\n It is an unwavering universal law that anything higher than 11 will be purple. The {LINK:ODA;ODA} is powerless to change this. Similarly, anything lower than 0 will be Blue.\n
|
||||
Combustion 98 The assess atmosphere is on fire. Returns 1 if atmosphere is on fire, 0 if not.
|
||||
CombustionInput 146 The assess atmosphere is on fire. Returns 1 if device's input network is on fire, 0 if not.
|
||||
CombustionInput2 147 The assess atmosphere is on fire. Returns 1 if device's Input2 network is on fire, 0 if not.
|
||||
CombustionLimiter 153 Retards the rate of combustion inside the machine (range: 0-100), with 0 being the slowest rate of combustion and 100 being the fastest
|
||||
CombustionOutput 148 The assess atmosphere is on fire. Returns 1 if device's Output network is on fire, 0 if not.
|
||||
CombustionOutput2 149 The assess atmosphere is on fire. Returns 1 if device's Output2 network is on fire, 0 if not.
|
||||
CompletionRatio 61 How complete the current production is for this device, between 0 and 1
|
||||
ContactTypeId 198 The type id of the contact.
|
||||
CurrentCode 261
|
||||
CurrentResearchPodType 93
|
||||
Density 262
|
||||
DestinationCode 215 Unique identifier code for a destination on the space map.
|
||||
Discover 255
|
||||
DistanceAu 244
|
||||
DistanceKm 249
|
||||
DrillCondition 240
|
||||
DryMass 220 The Mass in kilograms of the rocket excluding fuel. The more massive the rocket the more fuel will be required to move to a new location in space.
|
||||
Eccentricity 247
|
||||
ElevatorLevel 40 Level the elevator is currently at
|
||||
ElevatorSpeed 39 Current speed of the elevator
|
||||
EntityState 239
|
||||
EnvironmentEfficiency 104 The Environment Efficiency reported by the machine, as a float between 0 and 1
|
||||
Error 4 1 if device is in error state, otherwise 0
|
||||
ExhaustVelocity 235
|
||||
ExportCount 63 How many items exported since last ClearMemory
|
||||
ExportQuantity 31 Total quantity of items exported by the device
|
||||
ExportSlotHash 42 DEPRECATED
|
||||
ExportSlotOccupant 32 DEPRECATED
|
||||
Filtration 74 The current state of the filtration system, for example Filtration = 1 for a Hardsuit sets filtration to On
|
||||
FlightControlRule 236
|
||||
Flush 174 Set to 1 to activate the flush function on the device
|
||||
ForceWrite 85 Forces Logic Writer devices to rewrite value
|
||||
ForwardX 227
|
||||
ForwardY 228
|
||||
ForwardZ 229
|
||||
Fuel 99
|
||||
Harvest 69 Performs the harvesting action for any plant based machinery
|
||||
Horizontal 20 Horizontal setting of the device
|
||||
HorizontalRatio 34 Radio of horizontal setting for device
|
||||
Idle 37 Returns 1 if the device is currently idle, otherwise 0
|
||||
ImportCount 64 How many items imported since last ClearMemory
|
||||
ImportQuantity 29 Total quantity of items imported by the device
|
||||
ImportSlotHash 43 DEPRECATED
|
||||
ImportSlotOccupant 30 DEPRECATED
|
||||
Inclination 246
|
||||
Index 241
|
||||
InterrogationProgress 157 Progress of this sattellite dish's interrogation of its current target, as a ratio from 0-1
|
||||
LineNumber 173 The line number of current execution for an integrated circuit running on this device. While this number can be written, use with caution
|
||||
Lock 10 1 if device is locked, otherwise 0, can be set in most devices and prevents the user from access the values
|
||||
ManualResearchRequiredPod 94
|
||||
Mass 219 The total Mass of the rocket in kilograms including fuel and cargo. The more massive the rocket the more fuel will be required to move to a new location in space.
|
||||
Maximum 23 Maximum setting of the device
|
||||
MineablesInQueue 96
|
||||
MineablesInVicinity 95
|
||||
MinedQuantity 266
|
||||
MinimumWattsToContact 163 Minimum required amount of watts from the dish hitting the target trader contact to start interrogating the contact
|
||||
Mode 3 Integer for mode state, different devices will have different mode states available to them
|
||||
NavPoints 258
|
||||
NextWeatherEventTime 97
|
||||
None 0 No description
|
||||
On 28 The current state of the device, 0 for off, 1 for on
|
||||
Open 2 1 if device is open, otherwise 0
|
||||
OperationalTemperatureEfficiency 150 How the input pipe's temperature effects the machines efficiency
|
||||
OrbitPeriod 245
|
||||
Orientation 230
|
||||
Output 70 The output operation for a sort handling device, such as a stacker or sorter, when in logic mode the device will only action one repetition when set zero or above and then back to -1 and await further instructions
|
||||
PassedMoles 234
|
||||
Plant 68 Performs the planting action for any plant based machinery
|
||||
PlantEfficiency1 52 DEPRECATED
|
||||
PlantEfficiency2 53 DEPRECATED
|
||||
PlantEfficiency3 54 DEPRECATED
|
||||
PlantEfficiency4 55 DEPRECATED
|
||||
PlantGrowth1 48 DEPRECATED
|
||||
PlantGrowth2 49 DEPRECATED
|
||||
PlantGrowth3 50 DEPRECATED
|
||||
PlantGrowth4 51 DEPRECATED
|
||||
PlantHash1 56 DEPRECATED
|
||||
PlantHash2 57 DEPRECATED
|
||||
PlantHash3 58 DEPRECATED
|
||||
PlantHash4 59 DEPRECATED
|
||||
PlantHealth1 44 DEPRECATED
|
||||
PlantHealth2 45 DEPRECATED
|
||||
PlantHealth3 46 DEPRECATED
|
||||
PlantHealth4 47 DEPRECATED
|
||||
PositionX 76 The current position in X dimension in world coordinates
|
||||
PositionY 77 The current position in Y dimension in world coordinates
|
||||
PositionZ 78 The current position in Z dimension in world coordinates
|
||||
Power 1 Can be read to return if the device is correctly powered or not, set via the power system, return 1 if powered and 0 if not
|
||||
PowerActual 26 How much energy the device or network is actually using
|
||||
PowerGeneration 65 Returns how much power is being generated
|
||||
PowerPotential 25 How much energy the device or network potentially provides
|
||||
PowerRequired 36 Power requested from the device and/or network
|
||||
PrefabHash 84 The hash of the structure
|
||||
Pressure 5 The current pressure reading of the device
|
||||
PressureEfficiency 152 How the pressure of the input pipe and waste pipe effect the machines efficiency
|
||||
PressureExternal 7 Setting for external pressure safety, in KPa
|
||||
PressureInput 106 The current pressure reading of the device's Input Network
|
||||
PressureInput2 116 The current pressure reading of the device's Input2 Network
|
||||
PressureInternal 8 Setting for internal pressure safety, in KPa
|
||||
PressureOutput 126 The current pressure reading of the device's Output Network
|
||||
PressureOutput2 136 The current pressure reading of the device's Output2 Network
|
||||
PressureSetting 71 The current setting for the internal pressure of the object (e.g. the Hardsuit Air release), in KPa
|
||||
Progress 214 Progress of the rocket to the next node on the map expressed as a value between 0-1.
|
||||
Quantity 27 Total quantity on the device
|
||||
Ratio 24 Context specific value depending on device, 0 to 1 based ratio
|
||||
RatioCarbonDioxide 15 The ratio of {GAS:CarbonDioxide} in device atmosphere
|
||||
RatioCarbonDioxideInput 109 The ratio of {GAS:CarbonDioxide} in device's input network
|
||||
RatioCarbonDioxideInput2 119 The ratio of {GAS:CarbonDioxide} in device's Input2 network
|
||||
RatioCarbonDioxideOutput 129 The ratio of {GAS:CarbonDioxide} in device's Output network
|
||||
RatioCarbonDioxideOutput2 139 The ratio of {GAS:CarbonDioxide} in device's Output2 network
|
||||
RatioHydrogen 252 The ratio of {GAS:Hydrogen} in device's Atmopshere
|
||||
RatioLiquidCarbonDioxide 199 The ratio of {GAS:LiquidCarbonDioxide} in device's Atmosphere
|
||||
RatioLiquidCarbonDioxideInput 200 The ratio of {GAS:LiquidCarbonDioxide} in device's Input Atmosphere
|
||||
RatioLiquidCarbonDioxideInput2 201 The ratio of {GAS:LiquidCarbonDioxide} in device's Input2 Atmosphere
|
||||
RatioLiquidCarbonDioxideOutput 202 The ratio of {GAS:LiquidCarbonDioxide} in device's device's Output Atmosphere
|
||||
RatioLiquidCarbonDioxideOutput2 203 The ratio of {GAS:LiquidCarbonDioxide} in device's Output2 Atmopshere
|
||||
RatioLiquidHydrogen 253 The ratio of {GAS:LiquidHydrogen} in device's Atmopshere
|
||||
RatioLiquidNitrogen 177 The ratio of {GAS:LiquidNitrogen} in device atmosphere
|
||||
RatioLiquidNitrogenInput 178 The ratio of {GAS:LiquidNitrogen} in device's input network
|
||||
RatioLiquidNitrogenInput2 179 The ratio of {GAS:LiquidNitrogen} in device's Input2 network
|
||||
RatioLiquidNitrogenOutput 180 The ratio of {GAS:LiquidNitrogen} in device's Output network
|
||||
RatioLiquidNitrogenOutput2 181 The ratio of {GAS:LiquidNitrogen} in device's Output2 network
|
||||
RatioLiquidNitrousOxide 209 The ratio of {GAS:LiquidNitrousOxide} in device's Atmosphere
|
||||
RatioLiquidNitrousOxideInput 210 The ratio of {GAS:LiquidNitrousOxide} in device's Input Atmosphere
|
||||
RatioLiquidNitrousOxideInput2 211 The ratio of {GAS:LiquidNitrousOxide} in device's Input2 Atmosphere
|
||||
RatioLiquidNitrousOxideOutput 212 The ratio of {GAS:LiquidNitrousOxide} in device's device's Output Atmosphere
|
||||
RatioLiquidNitrousOxideOutput2 213 The ratio of {GAS:LiquidNitrousOxide} in device's Output2 Atmopshere
|
||||
RatioLiquidOxygen 183 The ratio of {GAS:LiquidOxygen} in device's Atmosphere
|
||||
RatioLiquidOxygenInput 184 The ratio of {GAS:LiquidOxygen} in device's Input Atmosphere
|
||||
RatioLiquidOxygenInput2 185 The ratio of {GAS:LiquidOxygen} in device's Input2 Atmosphere
|
||||
RatioLiquidOxygenOutput 186 The ratio of {GAS:LiquidOxygen} in device's device's Output Atmosphere
|
||||
RatioLiquidOxygenOutput2 187 The ratio of {GAS:LiquidOxygen} in device's Output2 Atmopshere
|
||||
RatioLiquidPollutant 204 The ratio of {GAS:LiquidPollutant} in device's Atmosphere
|
||||
RatioLiquidPollutantInput 205 The ratio of {GAS:LiquidPollutant} in device's Input Atmosphere
|
||||
RatioLiquidPollutantInput2 206 The ratio of {GAS:LiquidPollutant} in device's Input2 Atmosphere
|
||||
RatioLiquidPollutantOutput 207 The ratio of {GAS:LiquidPollutant} in device's device's Output Atmosphere
|
||||
RatioLiquidPollutantOutput2 208 The ratio of {GAS:LiquidPollutant} in device's Output2 Atmopshere
|
||||
RatioLiquidVolatiles 188 The ratio of {GAS:LiquidVolatiles} in device's Atmosphere
|
||||
RatioLiquidVolatilesInput 189 The ratio of {GAS:LiquidVolatiles} in device's Input Atmosphere
|
||||
RatioLiquidVolatilesInput2 190 The ratio of {GAS:LiquidVolatiles} in device's Input2 Atmosphere
|
||||
RatioLiquidVolatilesOutput 191 The ratio of {GAS:LiquidVolatiles} in device's device's Output Atmosphere
|
||||
RatioLiquidVolatilesOutput2 192 The ratio of {GAS:LiquidVolatiles} in device's Output2 Atmopshere
|
||||
RatioNitrogen 16 The ratio of nitrogen in device atmosphere
|
||||
RatioNitrogenInput 110 The ratio of nitrogen in device's input network
|
||||
RatioNitrogenInput2 120 The ratio of nitrogen in device's Input2 network
|
||||
RatioNitrogenOutput 130 The ratio of nitrogen in device's Output network
|
||||
RatioNitrogenOutput2 140 The ratio of nitrogen in device's Output2 network
|
||||
RatioNitrousOxide 83 The ratio of {GAS:NitrousOxide} in device atmosphere
|
||||
RatioNitrousOxideInput 114 The ratio of {GAS:NitrousOxide} in device's input network
|
||||
RatioNitrousOxideInput2 124 The ratio of {GAS:NitrousOxide} in device's Input2 network
|
||||
RatioNitrousOxideOutput 134 The ratio of {GAS:NitrousOxide} in device's Output network
|
||||
RatioNitrousOxideOutput2 144 The ratio of {GAS:NitrousOxide} in device's Output2 network
|
||||
RatioOxygen 14 The ratio of oxygen in device atmosphere
|
||||
RatioOxygenInput 108 The ratio of oxygen in device's input network
|
||||
RatioOxygenInput2 118 The ratio of oxygen in device's Input2 network
|
||||
RatioOxygenOutput 128 The ratio of oxygen in device's Output network
|
||||
RatioOxygenOutput2 138 The ratio of oxygen in device's Output2 network
|
||||
RatioPollutant 17 The ratio of pollutant in device atmosphere
|
||||
RatioPollutantInput 111 The ratio of pollutant in device's input network
|
||||
RatioPollutantInput2 121 The ratio of pollutant in device's Input2 network
|
||||
RatioPollutantOutput 131 The ratio of pollutant in device's Output network
|
||||
RatioPollutantOutput2 141 The ratio of pollutant in device's Output2 network
|
||||
RatioPollutedWater 254 The ratio of polluted water in device atmosphere
|
||||
RatioSteam 193 The ratio of {GAS:Steam} in device's Atmosphere
|
||||
RatioSteamInput 194 The ratio of {GAS:Steam} in device's Input Atmosphere
|
||||
RatioSteamInput2 195 The ratio of {GAS:Steam} in device's Input2 Atmosphere
|
||||
RatioSteamOutput 196 The ratio of {GAS:Steam} in device's device's Output Atmosphere
|
||||
RatioSteamOutput2 197 The ratio of {GAS:Steam} in device's Output2 Atmopshere
|
||||
RatioVolatiles 18 The ratio of volatiles in device atmosphere
|
||||
RatioVolatilesInput 112 The ratio of volatiles in device's input network
|
||||
RatioVolatilesInput2 122 The ratio of volatiles in device's Input2 network
|
||||
RatioVolatilesOutput 132 The ratio of volatiles in device's Output network
|
||||
RatioVolatilesOutput2 142 The ratio of volatiles in device's Output2 network
|
||||
RatioWater 19 The ratio of water in device atmosphere
|
||||
RatioWaterInput 113 The ratio of water in device's input network
|
||||
RatioWaterInput2 123 The ratio of water in device's Input2 network
|
||||
RatioWaterOutput 133 The ratio of water in device's Output network
|
||||
RatioWaterOutput2 143 The ratio of water in device's Output2 network
|
||||
ReEntryAltitude 237
|
||||
Reagents 13 Total number of reagents recorded by the device
|
||||
RecipeHash 41 Current hash of the recipe the device is set to produce
|
||||
ReferenceId 217
|
||||
RequestHash 60 When set to the unique identifier, requests an item of the provided type from the device
|
||||
RequiredPower 33 Idle operating power quantity, does not necessarily include extra demand power
|
||||
ReturnFuelCost 100
|
||||
Richness 263
|
||||
Rpm 155 The number of revolutions per minute that the device's spinning mechanism is doing
|
||||
SemiMajorAxis 248
|
||||
Setting 12 A variable setting that can be read or written, depending on the device
|
||||
SettingInput 91 The input setting for the device
|
||||
SettingOutput 92 The output setting for the device
|
||||
SignalID 87 Returns the contact ID of the strongest signal from this Satellite
|
||||
SignalStrength 86 Returns the degree offset of the strongest contact
|
||||
Sites 260
|
||||
Size 264
|
||||
SizeX 160 Size on the X (right) axis of the object in largeGrids (a largeGrid is 2meters)
|
||||
SizeY 161 Size on the Y(Up) axis of the object in largeGrids (a largeGrid is 2meters)
|
||||
SizeZ 162 Size on the Z(Forward) axis of the object in largeGrids (a largeGrid is 2meters)
|
||||
SolarAngle 22 Solar angle of the device
|
||||
SolarIrradiance 176
|
||||
SoundAlert 175 Plays a sound alert on the devices speaker
|
||||
Stress 156 Machines get stressed when working hard. When Stress reaches 100 the machine will automatically shut down
|
||||
Survey 257
|
||||
TargetPadIndex 158 The index of the trader landing pad on this devices data network that it will try to call a trader in to land
|
||||
TargetX 88 The target position in X dimension in world coordinates
|
||||
TargetY 89 The target position in Y dimension in world coordinates
|
||||
TargetZ 90 The target position in Z dimension in world coordinates
|
||||
Temperature 6 The current temperature reading of the device
|
||||
TemperatureDifferentialEfficiency 151 How the difference between the input pipe and waste pipe temperatures effect the machines efficiency
|
||||
TemperatureExternal 73 The temperature of the outside of the device, usually the world atmosphere surrounding it
|
||||
TemperatureInput 107 The current temperature reading of the device's Input Network
|
||||
TemperatureInput2 117 The current temperature reading of the device's Input2 Network
|
||||
TemperatureOutput 127 The current temperature reading of the device's Output Network
|
||||
TemperatureOutput2 137 The current temperature reading of the device's Output2 Network
|
||||
TemperatureSetting 72 The current setting for the internal temperature of the object (e.g. the Hardsuit A/C)
|
||||
Throttle 154 Increases the rate at which the machine works (range: 0-100)
|
||||
Thrust 221 Total current thrust of all rocket engines on the rocket in Newtons.
|
||||
ThrustToWeight 223 Ratio of thrust to weight of rocket. Weight is effected by local body gravity. A rocket with a low thrust to weight will expend more fuel during launch and landing.
|
||||
Time 102 Time
|
||||
TimeToDestination 224 Estimated time in seconds until rocket arrives at target destination.
|
||||
TotalMoles 66 Returns the total moles of the device
|
||||
TotalMolesInput 115 Returns the total moles of the device's Input Network
|
||||
TotalMolesInput2 125 Returns the total moles of the device's Input2 Network
|
||||
TotalMolesOutput 135 Returns the total moles of the device's Output Network
|
||||
TotalMolesOutput2 145 Returns the total moles of the device's Output2 Network
|
||||
TotalQuantity 265
|
||||
TrueAnomaly 251
|
||||
VelocityMagnitude 79 The current magnitude of the velocity vector
|
||||
VelocityRelativeX 80 The current velocity X relative to the forward vector of this
|
||||
VelocityRelativeY 81 The current velocity Y relative to the forward vector of this
|
||||
VelocityRelativeZ 82 The current velocity Z relative to the forward vector of this
|
||||
VelocityX 231
|
||||
VelocityY 232
|
||||
VelocityZ 233
|
||||
Vertical 21 Vertical setting of the device
|
||||
VerticalRatio 35 Radio of vertical setting for device
|
||||
Volume 67 Returns the device atmosphere volume
|
||||
VolumeOfLiquid 182 The total volume of all liquids in Liters in the atmosphere
|
||||
WattsReachingContact 164 The amount of watts actually hitting the contact. This is effected by the power of the dish and how far off-axis the dish is from the contact vector
|
||||
Weight 222 Weight of Rocket in Newtons (Including fuel and cargo). Weight is effected by local body gravity.
|
||||
WorkingGasEfficiency 105 The Working Gas Efficiency reported by the machine, as a float between 0 and 1
|
||||
@@ -1,4 +0,0 @@
|
||||
Contents 0 The amount of this Reagent present in the machine
|
||||
Recipe 2 The amount of this Reagent required by the Machine's current recipe
|
||||
Required 1 The amount of this Reagent needed to complete the Machine's current recipe after subtracting the amount currently present
|
||||
TotalContents 3
|
||||
@@ -1,27 +0,0 @@
|
||||
Charge 10 returns current energy charge the slot occupant is holding
|
||||
ChargeRatio 11 returns current energy charge the slot occupant is holding as a ratio between 0 and 1 of its maximum
|
||||
Class 12 returns integer representing the class of object
|
||||
Damage 4 returns the damage state of the item in the slot
|
||||
Efficiency 5 returns the growth efficiency of the plant in the slot
|
||||
FilterType 25
|
||||
Growth 7 returns the current growth state of the plant in the slot
|
||||
Health 6 returns the health of the plant in the slot
|
||||
LineNumber 19
|
||||
Lock 23
|
||||
Mature 16 returns 1 if the plant in this slot is mature, 0 when it isn't
|
||||
MaxQuantity 15 returns the max stack size of the item in the slot
|
||||
None 0 No description
|
||||
OccupantHash 2 returns the has of the current occupant, the unique identifier of the thing
|
||||
Occupied 1 returns 0 when slot is not occupied, 1 when it is
|
||||
On 22
|
||||
Open 21
|
||||
PrefabHash 17 returns the hash of the structure in the slot
|
||||
Pressure 8 returns pressure of the slot occupants internal atmosphere
|
||||
PressureAir 14 returns pressure in the air tank of the jetpack in this slot
|
||||
PressureWaste 13 returns pressure in the waste tank of the jetpack in this slot
|
||||
Quantity 3 returns the current quantity, such as stack size, of the item in the slot
|
||||
ReferenceId 26
|
||||
Seeding 18 Whether a plant is seeding (ready to harvest seeds from). Returns 1 if seeding or 0 if not.
|
||||
SortingClass 24
|
||||
Temperature 9 returns temperature of the slot occupants internal atmosphere
|
||||
Volume 20
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,11 @@
|
||||
use crate::{
|
||||
grammar::{LogicType, ReagentMode, SlotLogicType},
|
||||
interpreter::{ICError, ICState},
|
||||
errors::ICError,
|
||||
interpreter::ICState,
|
||||
network::{CableConnectionType, Connection},
|
||||
vm::enums::script_enums::{
|
||||
LogicBatchMethod as BatchMode, LogicReagentMode as ReagentMode,
|
||||
LogicSlotType as SlotLogicType, LogicType,
|
||||
},
|
||||
vm::VM,
|
||||
};
|
||||
use std::{collections::BTreeMap, ops::Deref};
|
||||
|
||||
209
ic10emu/src/errors.rs
Normal file
209
ic10emu/src/errors.rs
Normal file
@@ -0,0 +1,209 @@
|
||||
use crate::vm::instructions::enums::InstructionOp;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt::Display;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug, Serialize, Deserialize)]
|
||||
pub enum VMError {
|
||||
#[error("device with id '{0}' does not exist")]
|
||||
UnknownId(u32),
|
||||
#[error("ic with id '{0}' does not exist")]
|
||||
UnknownIcId(u32),
|
||||
#[error("device with id '{0}' does not have a ic slot")]
|
||||
NoIC(u32),
|
||||
#[error("ic encountered an error: {0}")]
|
||||
ICError(#[from] ICError),
|
||||
#[error("ic encountered an error: {0}")]
|
||||
LineError(#[from] LineError),
|
||||
#[error("invalid network id {0}")]
|
||||
InvalidNetwork(u32),
|
||||
#[error("device {0} not visible to device {1} (not on the same networks)")]
|
||||
DeviceNotVisible(u32, u32),
|
||||
#[error("a device with id {0} already exists")]
|
||||
IdInUse(u32),
|
||||
#[error("device(s) with ids {0:?} already exist")]
|
||||
IdsInUse(Vec<u32>),
|
||||
#[error("atempt to use a set of id's with duplicates: id(s) {0:?} exsist more than once")]
|
||||
DuplicateIds(Vec<u32>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct LineError {
|
||||
pub error: ICError,
|
||||
pub line: u32,
|
||||
}
|
||||
|
||||
impl Display for LineError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Error on line {}: {}", self.line, self.error)
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for LineError {}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||
pub struct ParseError {
|
||||
pub line: usize,
|
||||
pub start: usize,
|
||||
pub end: usize,
|
||||
pub msg: String,
|
||||
}
|
||||
|
||||
impl Display for ParseError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{} at line {} {}:{}",
|
||||
self.msg, self.line, self.start, self.end
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for ParseError {}
|
||||
|
||||
impl ParseError {
|
||||
/// Offset the ParseError in it's line, adding the passed values to it's `start` and `end`
|
||||
#[must_use]
|
||||
pub fn offset(self, offset: usize) -> Self {
|
||||
ParseError {
|
||||
start: self.start + offset,
|
||||
end: self.end + offset,
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
/// Offset the ParseError line, adding the passed value to it's `line`
|
||||
#[must_use]
|
||||
pub fn offset_line(self, offset: usize) -> Self {
|
||||
ParseError {
|
||||
line: self.line + offset,
|
||||
start: self.start,
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
/// Mark the parse error as extending 'length' bytes from `start`
|
||||
#[must_use]
|
||||
pub fn span(self, length: usize) -> Self {
|
||||
ParseError {
|
||||
start: self.start,
|
||||
end: self.start + length,
|
||||
..self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, Clone, Serialize, Deserialize)]
|
||||
pub enum ICError {
|
||||
#[error("error compiling code: {0}")]
|
||||
ParseError(#[from] ParseError),
|
||||
#[error("duplicate label {0}")]
|
||||
DuplicateLabel(String),
|
||||
#[error("instruction pointer out of range: '{0}'")]
|
||||
InstructionPointerOutOfRange(u32),
|
||||
#[error("register pointer out of range: '{0}'")]
|
||||
RegisterIndexOutOfRange(f64),
|
||||
#[error("device pointer out of range: '{0}'")]
|
||||
DeviceIndexOutOfRange(f64),
|
||||
#[error("stack index out of range: '{0}'")]
|
||||
StackIndexOutOfRange(f64),
|
||||
#[error("slot index out of range: '{0}'")]
|
||||
SlotIndexOutOfRange(f64),
|
||||
#[error("pin index {0} out of range 0-6")]
|
||||
PinIndexOutOfRange(usize),
|
||||
#[error("connection index {0} out of range {1}")]
|
||||
ConnectionIndexOutOfRange(usize, usize),
|
||||
#[error("unknown device ID '{0}'")]
|
||||
UnknownDeviceID(f64),
|
||||
#[error("too few operands!: provide: '{provided}', desired: '{desired}'")]
|
||||
TooFewOperands { provided: u32, desired: u32 },
|
||||
#[error("too many operands!: provide: '{provided}', desired: '{desired}'")]
|
||||
TooManyOperands { provided: u32, desired: u32 },
|
||||
#[error("incorrect operand type for instruction `{inst}` operand {index}, not a {desired} ")]
|
||||
IncorrectOperandType {
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
desired: String,
|
||||
},
|
||||
#[error("unknown identifier {0}")]
|
||||
UnknownIdentifier(String),
|
||||
#[error("device Not Set")]
|
||||
DeviceNotSet,
|
||||
#[error("shift Underflow i64(signed long)")]
|
||||
ShiftUnderflowI64,
|
||||
#[error("shift Overflow i64(signed long)")]
|
||||
ShiftOverflowI64,
|
||||
#[error("shift underflow i32(signed int)")]
|
||||
ShiftUnderflowI32,
|
||||
#[error("shift overflow i32(signed int)")]
|
||||
ShiftOverflowI32,
|
||||
#[error("stack underflow")]
|
||||
StackUnderflow,
|
||||
#[error("stack overflow")]
|
||||
StackOverflow,
|
||||
#[error("duplicate define '{0}'")]
|
||||
DuplicateDefine(String),
|
||||
#[error("read only field '{0}'")]
|
||||
ReadOnlyField(String),
|
||||
#[error("write only field '{0}'")]
|
||||
WriteOnlyField(String),
|
||||
#[error("device has no field '{0}'")]
|
||||
DeviceHasNoField(String),
|
||||
#[error("device has not ic")]
|
||||
DeviceHasNoIC,
|
||||
#[error("unknown device '{0}'")]
|
||||
UnknownDeviceId(f64),
|
||||
#[error("unknown logic type '{0}'")]
|
||||
UnknownLogicType(f64),
|
||||
#[error("unknown slot logic type '{0}'")]
|
||||
UnknownSlotLogicType(f64),
|
||||
#[error("unknown batch mode '{0}'")]
|
||||
UnknownBatchMode(f64),
|
||||
#[error("unknown reagent mode '{0}'")]
|
||||
UnknownReagentMode(f64),
|
||||
#[error("type value not known")]
|
||||
TypeValueNotKnown,
|
||||
#[error("empty device list")]
|
||||
EmptyDeviceList,
|
||||
#[error("connection specifier missing")]
|
||||
MissingConnectionSpecifier,
|
||||
#[error("no data network on connection '{0}'")]
|
||||
NotACableConnection(usize),
|
||||
#[error("network not connected on connection '{0}'")]
|
||||
NetworkNotConnected(usize),
|
||||
#[error("bad network Id '{0}'")]
|
||||
BadNetworkId(u32),
|
||||
#[error("channel index out of range '{0}'")]
|
||||
ChannelIndexOutOfRange(usize),
|
||||
#[error("slot has no occupant")]
|
||||
SlotNotOccupied,
|
||||
#[error("generated Enum {0} has no value attached. Report this error.")]
|
||||
NoGeneratedValue(String),
|
||||
#[error("generated Enum {0}'s value does not parse as {1} . Report this error.")]
|
||||
BadGeneratedValueParse(String, String),
|
||||
}
|
||||
|
||||
impl ICError {
|
||||
pub const fn too_few_operands(provided: usize, desired: u32) -> Self {
|
||||
ICError::TooFewOperands {
|
||||
provided: provided as u32,
|
||||
desired,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn too_many_operands(provided: usize, desired: u32) -> Self {
|
||||
ICError::TooManyOperands {
|
||||
provided: provided as u32,
|
||||
desired,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn mismatch_operands(provided: usize, desired: u32) -> Self {
|
||||
if provided < desired as usize {
|
||||
ICError::too_few_operands(provided, desired)
|
||||
} else {
|
||||
ICError::too_many_operands(provided, desired)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,138 +1,62 @@
|
||||
use crate::interpreter::{self, ICError};
|
||||
use crate::interpreter;
|
||||
use crate::tokens::{SplitConsecutiveIndicesExt, SplitConsecutiveWithIndices};
|
||||
use crate::vm::enums::script_enums::{
|
||||
LogicBatchMethod, LogicReagentMode, LogicSlotType, LogicType,
|
||||
};
|
||||
use crate::vm::instructions::{
|
||||
enums::InstructionOp,
|
||||
operands::{Device, DeviceSpec, Identifier, Number, Operand, RegisterSpec},
|
||||
Instruction, CONSTANTS_LOOKUP,
|
||||
};
|
||||
use crate::{
|
||||
errors::{ICError, ParseError},
|
||||
vm::enums::basic_enums::BasicEnum,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use std::error::Error;
|
||||
use std::fmt::Display;
|
||||
use std::str::FromStr;
|
||||
use strum::EnumProperty;
|
||||
use strum::{EnumProperty, IntoEnumIterator};
|
||||
|
||||
pub mod generated {
|
||||
use super::ParseError;
|
||||
use crate::interpreter::ICError;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::str::FromStr;
|
||||
use strum::{
|
||||
AsRefStr, Display, EnumIter, EnumProperty, EnumString, FromRepr, IntoEnumIterator,
|
||||
};
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/instructions.rs"));
|
||||
include!(concat!(env!("OUT_DIR"), "/logictypes.rs"));
|
||||
include!(concat!(env!("OUT_DIR"), "/modes.rs"));
|
||||
include!(concat!(env!("OUT_DIR"), "/constants.rs"));
|
||||
include!(concat!(env!("OUT_DIR"), "/enums.rs"));
|
||||
|
||||
impl TryFrom<f64> for LogicType {
|
||||
type Error = ICError;
|
||||
fn try_from(value: f64) -> Result<Self, <LogicType as TryFrom<f64>>::Error> {
|
||||
if let Some(lt) = LogicType::iter().find(|lt| {
|
||||
lt.get_str("value")
|
||||
.map(|val| val.parse::<u16>().unwrap() as f64 == value)
|
||||
.unwrap_or(false)
|
||||
}) {
|
||||
Ok(lt)
|
||||
} else {
|
||||
Err(crate::interpreter::ICError::UnknownLogicType(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<f64> for SlotLogicType {
|
||||
type Error = ICError;
|
||||
fn try_from(value: f64) -> Result<Self, <SlotLogicType as TryFrom<f64>>::Error> {
|
||||
if let Some(slt) = SlotLogicType::iter().find(|lt| {
|
||||
lt.get_str("value")
|
||||
.map(|val| val.parse::<u8>().unwrap() as f64 == value)
|
||||
.unwrap_or(false)
|
||||
}) {
|
||||
Ok(slt)
|
||||
} else {
|
||||
Err(crate::interpreter::ICError::UnknownSlotLogicType(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<f64> for BatchMode {
|
||||
type Error = ICError;
|
||||
fn try_from(value: f64) -> Result<Self, <BatchMode as TryFrom<f64>>::Error> {
|
||||
if let Some(bm) = BatchMode::iter().find(|lt| {
|
||||
lt.get_str("value")
|
||||
.map(|val| val.parse::<u8>().unwrap() as f64 == value)
|
||||
.unwrap_or(false)
|
||||
}) {
|
||||
Ok(bm)
|
||||
} else {
|
||||
Err(crate::interpreter::ICError::UnknownBatchMode(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<f64> for ReagentMode {
|
||||
type Error = ICError;
|
||||
fn try_from(value: f64) -> Result<Self, <ReagentMode as TryFrom<f64>>::Error> {
|
||||
if let Some(rm) = ReagentMode::iter().find(|lt| {
|
||||
lt.get_str("value")
|
||||
.map(|val| val.parse::<u8>().unwrap() as f64 == value)
|
||||
.unwrap_or(false)
|
||||
}) {
|
||||
Ok(rm)
|
||||
} else {
|
||||
Err(crate::interpreter::ICError::UnknownReagentMode(value))
|
||||
}
|
||||
impl TryFrom<f64> for LogicType {
|
||||
type Error = ICError;
|
||||
fn try_from(value: f64) -> Result<Self, <LogicType as TryFrom<f64>>::Error> {
|
||||
if let Some(lt) = LogicType::iter().find(|lt| *lt as u16 as f64 == value) {
|
||||
Ok(lt)
|
||||
} else {
|
||||
Err(ICError::UnknownLogicType(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub use generated::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||
pub struct ParseError {
|
||||
pub line: usize,
|
||||
pub start: usize,
|
||||
pub end: usize,
|
||||
pub msg: String,
|
||||
}
|
||||
|
||||
impl Display for ParseError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{} at line {} {}:{}",
|
||||
self.msg, self.line, self.start, self.end
|
||||
)
|
||||
impl TryFrom<f64> for LogicSlotType {
|
||||
type Error = ICError;
|
||||
fn try_from(value: f64) -> Result<Self, <LogicSlotType as TryFrom<f64>>::Error> {
|
||||
if let Some(slt) = LogicSlotType::iter().find(|lt| *lt as u8 as f64 == value) {
|
||||
Ok(slt)
|
||||
} else {
|
||||
Err(ICError::UnknownSlotLogicType(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for ParseError {}
|
||||
|
||||
impl ParseError {
|
||||
/// Offset the ParseError in it's line, adding the passed values to it's `start` and `end`
|
||||
#[must_use]
|
||||
pub fn offset(self, offset: usize) -> Self {
|
||||
ParseError {
|
||||
start: self.start + offset,
|
||||
end: self.end + offset,
|
||||
..self
|
||||
impl TryFrom<f64> for LogicBatchMethod {
|
||||
type Error = ICError;
|
||||
fn try_from(value: f64) -> Result<Self, <LogicBatchMethod as TryFrom<f64>>::Error> {
|
||||
if let Some(bm) = LogicBatchMethod::iter().find(|lt| *lt as u8 as f64 == value) {
|
||||
Ok(bm)
|
||||
} else {
|
||||
Err(ICError::UnknownBatchMode(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Offset the ParseError line, adding the passed value to it's `line`
|
||||
#[must_use]
|
||||
pub fn offset_line(self, offset: usize) -> Self {
|
||||
ParseError {
|
||||
line: self.line + offset,
|
||||
start: self.start,
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
/// Mark the parse error as extending 'length' bytes from `start`
|
||||
#[must_use]
|
||||
pub fn span(self, length: usize) -> Self {
|
||||
ParseError {
|
||||
start: self.start,
|
||||
end: self.start + length,
|
||||
..self
|
||||
impl TryFrom<f64> for LogicReagentMode {
|
||||
type Error = ICError;
|
||||
fn try_from(value: f64) -> Result<Self, <LogicReagentMode as TryFrom<f64>>::Error> {
|
||||
if let Some(rm) = LogicReagentMode::iter().find(|lt| *lt as u8 as f64 == value) {
|
||||
Ok(rm)
|
||||
} else {
|
||||
Err(ICError::UnknownReagentMode(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -246,12 +170,6 @@ impl FromStr for Comment {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Instruction {
|
||||
pub instruction: InstructionOp,
|
||||
pub operands: Vec<Operand>,
|
||||
}
|
||||
|
||||
impl FromStr for Instruction {
|
||||
type Err = ParseError;
|
||||
/// parse a non-empty string for an instruction and it's operands
|
||||
@@ -259,9 +177,16 @@ impl FromStr for Instruction {
|
||||
let mut tokens_iter = s.split_consecutive_with_indices(&[' ', '\t'][..]);
|
||||
let instruction: InstructionOp = {
|
||||
if let Some((index, token)) = tokens_iter.next() {
|
||||
token
|
||||
.parse::<InstructionOp>()
|
||||
.map_err(|e| e.offset(index).span(token.len()))
|
||||
token.parse::<InstructionOp>().map_err(|_e| {
|
||||
ParseError {
|
||||
line: 0,
|
||||
start: 0,
|
||||
end: 0,
|
||||
msg: format!("unknown instruction '{token}'"),
|
||||
}
|
||||
.offset(index)
|
||||
.span(token.len())
|
||||
})
|
||||
} else {
|
||||
Err(ParseError {
|
||||
line: 0,
|
||||
@@ -320,290 +245,6 @@ fn get_operand_tokens<'a>(
|
||||
operand_tokens
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
pub enum Device {
|
||||
Db,
|
||||
Numbered(u32),
|
||||
Indirect { indirection: u32, target: u32 },
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct RegisterSpec {
|
||||
pub indirection: u32,
|
||||
pub target: u32,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DeviceSpec {
|
||||
pub device: Device,
|
||||
pub connection: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum Operand {
|
||||
RegisterSpec(RegisterSpec),
|
||||
DeviceSpec(DeviceSpec),
|
||||
Number(Number),
|
||||
Type {
|
||||
logic_type: Option<LogicType>,
|
||||
slot_logic_type: Option<SlotLogicType>,
|
||||
batch_mode: Option<BatchMode>,
|
||||
reagent_mode: Option<ReagentMode>,
|
||||
identifier: Identifier,
|
||||
},
|
||||
Identifier(Identifier),
|
||||
}
|
||||
|
||||
impl Operand {
|
||||
pub fn as_value(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<f64, interpreter::ICError> {
|
||||
match self.translate_alias(ic) {
|
||||
Operand::RegisterSpec(RegisterSpec {
|
||||
indirection,
|
||||
target,
|
||||
}) => ic.get_register(indirection, target),
|
||||
Operand::Number(num) => Ok(num.value()),
|
||||
Operand::Type {
|
||||
logic_type,
|
||||
slot_logic_type,
|
||||
batch_mode,
|
||||
reagent_mode,
|
||||
identifier: _,
|
||||
} => {
|
||||
if let Some(lt) = logic_type {
|
||||
Ok(lt
|
||||
.get_str("value")
|
||||
.ok_or_else(|| ICError::NoGeneratedValue(lt.to_string()))?
|
||||
.parse::<u16>()
|
||||
.map_err(|_| {
|
||||
ICError::BadGeneratedValueParse(lt.to_string(), "u16".to_owned())
|
||||
})? as f64)
|
||||
} else if let Some(slt) = slot_logic_type {
|
||||
Ok(slt
|
||||
.get_str("value")
|
||||
.ok_or_else(|| ICError::NoGeneratedValue(slt.to_string()))?
|
||||
.parse::<u8>()
|
||||
.map_err(|_| {
|
||||
ICError::BadGeneratedValueParse(slt.to_string(), "u8".to_owned())
|
||||
})? as f64)
|
||||
} else if let Some(bm) = batch_mode {
|
||||
Ok(bm
|
||||
.get_str("value")
|
||||
.ok_or_else(|| ICError::NoGeneratedValue(bm.to_string()))?
|
||||
.parse::<u8>()
|
||||
.map_err(|_| {
|
||||
ICError::BadGeneratedValueParse(bm.to_string(), "u8".to_owned())
|
||||
})? as f64)
|
||||
} else if let Some(rm) = reagent_mode {
|
||||
Ok(rm
|
||||
.get_str("value")
|
||||
.ok_or_else(|| ICError::NoGeneratedValue(rm.to_string()))?
|
||||
.parse::<u8>()
|
||||
.map_err(|_| {
|
||||
ICError::BadGeneratedValueParse(rm.to_string(), "u8".to_owned())
|
||||
})? as f64)
|
||||
} else {
|
||||
Err(interpreter::ICError::TypeValueNotKnown)
|
||||
}
|
||||
}
|
||||
Operand::Identifier(id) => {
|
||||
Err(interpreter::ICError::UnknownIdentifier(id.name.to_string()))
|
||||
}
|
||||
Operand::DeviceSpec { .. } => Err(interpreter::ICError::IncorrectOperandType {
|
||||
inst,
|
||||
index,
|
||||
desired: "Value".to_owned(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_value_i64(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
signed: bool,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<i64, interpreter::ICError> {
|
||||
match self {
|
||||
Self::Number(num) => Ok(num.value_i64(signed)),
|
||||
_ => {
|
||||
let val = self.as_value(ic, inst, index)?;
|
||||
if val < -9.223_372_036_854_776E18 {
|
||||
Err(interpreter::ICError::ShiftUnderflowI64)
|
||||
} else if val <= 9.223_372_036_854_776E18 {
|
||||
Ok(interpreter::f64_to_i64(val, signed))
|
||||
} else {
|
||||
Err(interpreter::ICError::ShiftOverflowI64)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn as_value_i32(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
signed: bool,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<i32, interpreter::ICError> {
|
||||
match self {
|
||||
Self::Number(num) => Ok(num.value_i64(signed) as i32),
|
||||
_ => {
|
||||
let val = self.as_value(ic, inst, index)?;
|
||||
if val < -2147483648.0 {
|
||||
Err(interpreter::ICError::ShiftUnderflowI32)
|
||||
} else if val <= 2147483647.0 {
|
||||
Ok(val as i32)
|
||||
} else {
|
||||
Err(interpreter::ICError::ShiftOverflowI32)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_register(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<RegisterSpec, interpreter::ICError> {
|
||||
match self.translate_alias(ic) {
|
||||
Operand::RegisterSpec(reg) => Ok(reg),
|
||||
Operand::Identifier(id) => {
|
||||
Err(interpreter::ICError::UnknownIdentifier(id.name.to_string()))
|
||||
}
|
||||
_ => Err(interpreter::ICError::IncorrectOperandType {
|
||||
inst,
|
||||
index,
|
||||
desired: "Register".to_owned(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_device(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<(Option<u32>, Option<usize>), interpreter::ICError> {
|
||||
match self.translate_alias(ic) {
|
||||
Operand::DeviceSpec(DeviceSpec { device, connection }) => match device {
|
||||
Device::Db => Ok((Some(ic.device), connection)),
|
||||
Device::Numbered(p) => {
|
||||
let dp = ic
|
||||
.pins
|
||||
.borrow()
|
||||
.get(p as usize)
|
||||
.ok_or(interpreter::ICError::DeviceIndexOutOfRange(p as f64))
|
||||
.copied()?;
|
||||
Ok((dp, connection))
|
||||
}
|
||||
Device::Indirect {
|
||||
indirection,
|
||||
target,
|
||||
} => {
|
||||
let val = ic.get_register(indirection, target)?;
|
||||
let dp = ic
|
||||
.pins
|
||||
.borrow()
|
||||
.get(val as usize)
|
||||
.ok_or(interpreter::ICError::DeviceIndexOutOfRange(val))
|
||||
.copied()?;
|
||||
Ok((dp, connection))
|
||||
}
|
||||
},
|
||||
Operand::Identifier(id) => {
|
||||
Err(interpreter::ICError::UnknownIdentifier(id.name.to_string()))
|
||||
}
|
||||
_ => Err(interpreter::ICError::IncorrectOperandType {
|
||||
inst,
|
||||
index,
|
||||
desired: "Value".to_owned(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_logic_type(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<LogicType, ICError> {
|
||||
match &self {
|
||||
Operand::Type {
|
||||
logic_type: Some(lt),
|
||||
..
|
||||
} => Ok(*lt),
|
||||
_ => LogicType::try_from(self.as_value(ic, inst, index)?),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_slot_logic_type(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<SlotLogicType, ICError> {
|
||||
match &self {
|
||||
Operand::Type {
|
||||
slot_logic_type: Some(slt),
|
||||
..
|
||||
} => Ok(*slt),
|
||||
_ => SlotLogicType::try_from(self.as_value(ic, inst, index)?),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_batch_mode(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<BatchMode, ICError> {
|
||||
match &self {
|
||||
Operand::Type {
|
||||
batch_mode: Some(bm),
|
||||
..
|
||||
} => Ok(*bm),
|
||||
_ => BatchMode::try_from(self.as_value(ic, inst, index)?),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_reagent_mode(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<ReagentMode, ICError> {
|
||||
match &self {
|
||||
Operand::Type {
|
||||
reagent_mode: Some(rm),
|
||||
..
|
||||
} => Ok(*rm),
|
||||
_ => ReagentMode::try_from(self.as_value(ic, inst, index)?),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn translate_alias(&self, ic: &interpreter::IC) -> Self {
|
||||
match &self {
|
||||
Operand::Identifier(id) | Operand::Type { identifier: id, .. } => {
|
||||
if let Some(alias) = ic.aliases.borrow().get(&id.name) {
|
||||
alias.clone()
|
||||
} else if let Some(define) = ic.defines.borrow().get(&id.name) {
|
||||
Operand::Number(Number::Float(*define))
|
||||
} else if let Some(label) = ic.program.borrow().labels.get(&id.name) {
|
||||
Operand::Number(Number::Float(*label as f64))
|
||||
} else {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
_ => self.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Operand {
|
||||
type Err = ParseError;
|
||||
/// Parse a str containing an single instruction operand
|
||||
@@ -874,15 +515,13 @@ impl FromStr for Operand {
|
||||
}
|
||||
} else if let Some(val) = CONSTANTS_LOOKUP.get(s) {
|
||||
Ok(Operand::Number(Number::Constant(*val)))
|
||||
} else if let Ok(val) = LogicEnums::from_str(s) {
|
||||
Ok(Operand::Number(Number::Enum(
|
||||
val.get_str("value").unwrap().parse().unwrap(),
|
||||
)))
|
||||
} else if let Ok(val) = BasicEnum::from_str(s) {
|
||||
Ok(Operand::Number(Number::Enum(val.get_value() as f64)))
|
||||
} else {
|
||||
let lt = LogicType::from_str(s).ok();
|
||||
let slt = SlotLogicType::from_str(s).ok();
|
||||
let bm = BatchMode::from_str(s).ok();
|
||||
let rm = ReagentMode::from_str(s).ok();
|
||||
let slt = LogicSlotType::from_str(s).ok();
|
||||
let bm = LogicBatchMethod::from_str(s).ok();
|
||||
let rm = LogicReagentMode::from_str(s).ok();
|
||||
let identifier = Identifier::from_str(s)?;
|
||||
if lt.is_some() || slt.is_some() || bm.is_some() || rm.is_some() {
|
||||
Ok(Operand::Type {
|
||||
@@ -1007,11 +646,6 @@ impl FromStr for Label {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Identifier {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl FromStr for Identifier {
|
||||
type Err = ParseError;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
@@ -1057,16 +691,6 @@ impl Display for Identifier {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum Number {
|
||||
Float(f64),
|
||||
Binary(i64),
|
||||
Hexadecimal(i64),
|
||||
Constant(f64),
|
||||
String(String),
|
||||
Enum(f64),
|
||||
}
|
||||
|
||||
impl Number {
|
||||
pub fn value(&self) -> f64 {
|
||||
match self {
|
||||
@@ -1249,7 +873,7 @@ mod tests {
|
||||
}),
|
||||
Operand::Type {
|
||||
logic_type: Some(LogicType::On),
|
||||
slot_logic_type: Some(SlotLogicType::On),
|
||||
slot_logic_type: Some(LogicSlotType::On),
|
||||
batch_mode: None,
|
||||
reagent_mode: None,
|
||||
identifier: Identifier {
|
||||
@@ -1458,9 +1082,9 @@ mod tests {
|
||||
test_roundtrip("1.2345");
|
||||
test_roundtrip("-1.2345");
|
||||
test_roundtrip(LogicType::Pressure.as_ref());
|
||||
test_roundtrip(SlotLogicType::Occupied.as_ref());
|
||||
test_roundtrip(BatchMode::Average.as_ref());
|
||||
test_roundtrip(ReagentMode::Recipe.as_ref());
|
||||
test_roundtrip(LogicSlotType::Occupied.as_ref());
|
||||
test_roundtrip(LogicBatchMethod::Average.as_ref());
|
||||
test_roundtrip(LogicReagentMode::Recipe.as_ref());
|
||||
test_roundtrip("pi");
|
||||
test_roundtrip("pinf");
|
||||
test_roundtrip("ninf");
|
||||
@@ -1478,30 +1102,35 @@ mod tests {
|
||||
let value = lt.get_str("value");
|
||||
assert!(value.is_some());
|
||||
assert!(value.unwrap().parse::<u16>().is_ok());
|
||||
assert_eq!(lt as u16, value.unwrap());
|
||||
}
|
||||
for slt in SlotLogicType::iter() {
|
||||
for slt in LogicSlotType::iter() {
|
||||
println!("testing SlotLogicType.{slt}");
|
||||
let value = slt.get_str("value");
|
||||
assert!(value.is_some());
|
||||
assert!(value.unwrap().parse::<u8>().is_ok());
|
||||
assert_eq!(slt as u8, value.unwrap());
|
||||
}
|
||||
for bm in BatchMode::iter() {
|
||||
for bm in LogicReagentMode::iter() {
|
||||
println!("testing BatchMode.{bm}");
|
||||
let value = bm.get_str("value");
|
||||
assert!(value.is_some());
|
||||
assert!(value.unwrap().parse::<u8>().is_ok());
|
||||
assert_eq!(bm as u8, value.unwrap());
|
||||
}
|
||||
for rm in ReagentMode::iter() {
|
||||
for rm in LogicReagentMode::iter() {
|
||||
println!("testing ReagentMode.{rm}");
|
||||
let value = rm.get_str("value");
|
||||
assert!(value.is_some());
|
||||
assert!(value.unwrap().parse::<u8>().is_ok());
|
||||
assert_eq!(rm as u8, value.unwrap());
|
||||
}
|
||||
for le in LogicEnums::iter() {
|
||||
println!("testing Enum.{le}");
|
||||
for le in BasicEnum::iter() {
|
||||
println!("testing BasicEnum {le}");
|
||||
let value = le.get_str("value");
|
||||
assert!(value.is_some());
|
||||
assert!(value.unwrap().parse::<u32>().is_ok());
|
||||
assert_eq!(le.get_value(), value.unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,142 +18,21 @@ use time::format_description;
|
||||
|
||||
use crate::{
|
||||
device::SlotType,
|
||||
grammar::{self, LogicType, ParseError, SlotLogicType},
|
||||
vm::VM,
|
||||
errors::{ICError, LineError, ParseError},
|
||||
grammar,
|
||||
vm::{
|
||||
enums::script_enums::{LogicSlotType as SlotLogicType, LogicType},
|
||||
instructions::{
|
||||
enums::InstructionOp,
|
||||
operands::{DeviceSpec, Operand, RegisterSpec},
|
||||
Instruction,
|
||||
},
|
||||
VM,
|
||||
},
|
||||
};
|
||||
|
||||
use serde_with::serde_as;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct LineError {
|
||||
error: ICError,
|
||||
line: u32,
|
||||
}
|
||||
|
||||
impl Display for LineError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Error on line {}: {}", self.line, self.error)
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for LineError {}
|
||||
|
||||
#[derive(Debug, Error, Clone, Serialize, Deserialize)]
|
||||
pub enum ICError {
|
||||
#[error("error compiling code: {0}")]
|
||||
ParseError(#[from] ParseError),
|
||||
#[error("duplicate label {0}")]
|
||||
DuplicateLabel(String),
|
||||
#[error("instruction pointer out of range: '{0}'")]
|
||||
InstructionPointerOutOfRange(u32),
|
||||
#[error("register pointer out of range: '{0}'")]
|
||||
RegisterIndexOutOfRange(f64),
|
||||
#[error("device pointer out of range: '{0}'")]
|
||||
DeviceIndexOutOfRange(f64),
|
||||
#[error("stack index out of range: '{0}'")]
|
||||
StackIndexOutOfRange(f64),
|
||||
#[error("slot index out of range: '{0}'")]
|
||||
SlotIndexOutOfRange(f64),
|
||||
#[error("pin index {0} out of range 0-6")]
|
||||
PinIndexOutOfRange(usize),
|
||||
#[error("connection index {0} out of range {1}")]
|
||||
ConnectionIndexOutOfRange(usize, usize),
|
||||
#[error("unknown device ID '{0}'")]
|
||||
UnknownDeviceID(f64),
|
||||
#[error("too few operands!: provide: '{provided}', desired: '{desired}'")]
|
||||
TooFewOperands { provided: u32, desired: u32 },
|
||||
#[error("too many operands!: provide: '{provided}', desired: '{desired}'")]
|
||||
TooManyOperands { provided: u32, desired: u32 },
|
||||
#[error("incorrect operand type for instruction `{inst}` operand {index}, not a {desired} ")]
|
||||
IncorrectOperandType {
|
||||
inst: grammar::InstructionOp,
|
||||
index: u32,
|
||||
desired: String,
|
||||
},
|
||||
#[error("unknown identifier {0}")]
|
||||
UnknownIdentifier(String),
|
||||
#[error("device Not Set")]
|
||||
DeviceNotSet,
|
||||
#[error("shift Underflow i64(signed long)")]
|
||||
ShiftUnderflowI64,
|
||||
#[error("shift Overflow i64(signed long)")]
|
||||
ShiftOverflowI64,
|
||||
#[error("shift underflow i32(signed int)")]
|
||||
ShiftUnderflowI32,
|
||||
#[error("shift overflow i32(signed int)")]
|
||||
ShiftOverflowI32,
|
||||
#[error("stack underflow")]
|
||||
StackUnderflow,
|
||||
#[error("stack overflow")]
|
||||
StackOverflow,
|
||||
#[error("duplicate define '{0}'")]
|
||||
DuplicateDefine(String),
|
||||
#[error("read only field '{0}'")]
|
||||
ReadOnlyField(String),
|
||||
#[error("write only field '{0}'")]
|
||||
WriteOnlyField(String),
|
||||
#[error("device has no field '{0}'")]
|
||||
DeviceHasNoField(String),
|
||||
#[error("device has not ic")]
|
||||
DeviceHasNoIC,
|
||||
#[error("unknown device '{0}'")]
|
||||
UnknownDeviceId(f64),
|
||||
#[error("unknown logic type '{0}'")]
|
||||
UnknownLogicType(f64),
|
||||
#[error("unknown slot logic type '{0}'")]
|
||||
UnknownSlotLogicType(f64),
|
||||
#[error("unknown batch mode '{0}'")]
|
||||
UnknownBatchMode(f64),
|
||||
#[error("unknown reagent mode '{0}'")]
|
||||
UnknownReagentMode(f64),
|
||||
#[error("type value not known")]
|
||||
TypeValueNotKnown,
|
||||
#[error("empty device list")]
|
||||
EmptyDeviceList,
|
||||
#[error("connection specifier missing")]
|
||||
MissingConnectionSpecifier,
|
||||
#[error("no data network on connection '{0}'")]
|
||||
NotACableConnection(usize),
|
||||
#[error("network not connected on connection '{0}'")]
|
||||
NetworkNotConnected(usize),
|
||||
#[error("bad network Id '{0}'")]
|
||||
BadNetworkId(u32),
|
||||
#[error("channel index out of range '{0}'")]
|
||||
ChannelIndexOutOfRange(usize),
|
||||
#[error("slot has no occupant")]
|
||||
SlotNotOccupied,
|
||||
#[error("generated Enum {0} has no value attached. Report this error.")]
|
||||
NoGeneratedValue(String),
|
||||
#[error("generated Enum {0}'s value does not parse as {1} . Report this error.")]
|
||||
BadGeneratedValueParse(String, String),
|
||||
}
|
||||
|
||||
impl ICError {
|
||||
pub const fn too_few_operands(provided: usize, desired: u32) -> Self {
|
||||
ICError::TooFewOperands {
|
||||
provided: provided as u32,
|
||||
desired,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn too_many_operands(provided: usize, desired: u32) -> Self {
|
||||
ICError::TooManyOperands {
|
||||
provided: provided as u32,
|
||||
desired,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn mismatch_operands(provided: usize, desired: u32) -> Self {
|
||||
if provided < desired as usize {
|
||||
ICError::too_few_operands(provided, desired)
|
||||
} else {
|
||||
ICError::too_many_operands(provided, desired)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum ICState {
|
||||
Start,
|
||||
@@ -195,7 +74,7 @@ pub struct IC {
|
||||
/// Instruction Count since last yield
|
||||
pub ic: Cell<u16>,
|
||||
pub stack: RefCell<[f64; 512]>,
|
||||
pub aliases: RefCell<BTreeMap<String, grammar::Operand>>,
|
||||
pub aliases: RefCell<BTreeMap<String, Operand>>,
|
||||
pub defines: RefCell<BTreeMap<String, f64>>,
|
||||
pub pins: RefCell<[Option<u32>; 6]>,
|
||||
pub code: RefCell<String>,
|
||||
@@ -215,7 +94,7 @@ pub struct FrozenIC {
|
||||
pub ic: u16,
|
||||
#[serde_as(as = "[_; 512]")]
|
||||
pub stack: [f64; 512],
|
||||
pub aliases: BTreeMap<String, grammar::Operand>,
|
||||
pub aliases: BTreeMap<String, Operand>,
|
||||
pub defines: BTreeMap<String, f64>,
|
||||
pub pins: [Option<u32>; 6],
|
||||
pub state: ICState,
|
||||
@@ -264,7 +143,7 @@ impl From<FrozenIC> for IC {
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Program {
|
||||
pub instructions: Vec<grammar::Instruction>,
|
||||
pub instructions: Vec<Instruction>,
|
||||
pub errors: Vec<ICError>,
|
||||
pub labels: BTreeMap<String, u32>,
|
||||
}
|
||||
@@ -293,8 +172,8 @@ impl Program {
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(line_number, line)| match line.code {
|
||||
None => Ok(grammar::Instruction {
|
||||
instruction: grammar::InstructionOp::Nop,
|
||||
None => Ok(Instruction {
|
||||
instruction: InstructionOp::Nop,
|
||||
operands: vec![],
|
||||
}),
|
||||
Some(code) => match code {
|
||||
@@ -304,8 +183,8 @@ impl Program {
|
||||
} else {
|
||||
labels_set.insert(label.id.name.clone());
|
||||
labels.insert(label.id.name, line_number as u32);
|
||||
Ok(grammar::Instruction {
|
||||
instruction: grammar::InstructionOp::Nop,
|
||||
Ok(Instruction {
|
||||
instruction: InstructionOp::Nop,
|
||||
operands: vec![],
|
||||
})
|
||||
}
|
||||
@@ -331,8 +210,8 @@ impl Program {
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(line_number, line)| match line.code {
|
||||
None => grammar::Instruction {
|
||||
instruction: grammar::InstructionOp::Nop,
|
||||
None => Instruction {
|
||||
instruction: InstructionOp::Nop,
|
||||
operands: vec![],
|
||||
},
|
||||
Some(code) => match code {
|
||||
@@ -343,16 +222,16 @@ impl Program {
|
||||
labels_set.insert(label.id.name.clone());
|
||||
labels.insert(label.id.name, line_number as u32);
|
||||
}
|
||||
grammar::Instruction {
|
||||
instruction: grammar::InstructionOp::Nop,
|
||||
Instruction {
|
||||
instruction: InstructionOp::Nop,
|
||||
operands: vec![],
|
||||
}
|
||||
}
|
||||
grammar::Code::Instruction(instruction) => instruction,
|
||||
grammar::Code::Invalid(err) => {
|
||||
errors.push(err.into());
|
||||
grammar::Instruction {
|
||||
instruction: grammar::InstructionOp::Nop,
|
||||
Instruction {
|
||||
instruction: InstructionOp::Nop,
|
||||
operands: vec![],
|
||||
}
|
||||
}
|
||||
@@ -366,7 +245,7 @@ impl Program {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_line(&self, line: u32) -> Result<&grammar::Instruction, ICError> {
|
||||
pub fn get_line(&self, line: u32) -> Result<&Instruction, ICError> {
|
||||
self.instructions
|
||||
.get(line as usize)
|
||||
.ok_or(ICError::InstructionPointerOutOfRange(line))
|
||||
@@ -560,14 +439,13 @@ impl IC {
|
||||
}
|
||||
|
||||
fn internal_step(&self, vm: &VM, advance_ip_on_err: bool) -> Result<(), ICError> {
|
||||
use grammar::*;
|
||||
use ICError::*;
|
||||
|
||||
let mut next_ip = self.ip() + 1;
|
||||
// XXX: This closure should be replaced with a try block
|
||||
// https://github.com/rust-lang/rust/issues/31436
|
||||
let mut process_op = |this: &Self| -> Result<(), ICError> {
|
||||
use grammar::InstructionOp::*;
|
||||
use InstructionOp::*;
|
||||
|
||||
// force the program borrow to drop
|
||||
let line = {
|
||||
@@ -578,7 +456,9 @@ impl IC {
|
||||
let inst = line.instruction;
|
||||
match inst {
|
||||
Nop => Ok(()),
|
||||
Hcf => Ok(()), // TODO
|
||||
Hcf => Ok(()), // TODO
|
||||
Clr => Ok(()), // TODO
|
||||
Label => Ok(()), // NOP
|
||||
Sleep => match &operands[..] {
|
||||
[a] => {
|
||||
let a = a.as_value(this, inst, 1)?;
|
||||
@@ -2577,31 +2457,31 @@ impl IC {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
const CHANNEL_LOGIC_TYPES: [grammar::LogicType; 8] = [
|
||||
grammar::LogicType::Channel0,
|
||||
grammar::LogicType::Channel1,
|
||||
grammar::LogicType::Channel2,
|
||||
grammar::LogicType::Channel3,
|
||||
grammar::LogicType::Channel4,
|
||||
grammar::LogicType::Channel5,
|
||||
grammar::LogicType::Channel6,
|
||||
grammar::LogicType::Channel7,
|
||||
const CHANNEL_LOGIC_TYPES: [LogicType; 8] = [
|
||||
LogicType::Channel0,
|
||||
LogicType::Channel1,
|
||||
LogicType::Channel2,
|
||||
LogicType::Channel3,
|
||||
LogicType::Channel4,
|
||||
LogicType::Channel5,
|
||||
LogicType::Channel6,
|
||||
LogicType::Channel7,
|
||||
];
|
||||
|
||||
trait LogicTypeExt {
|
||||
fn as_channel(&self) -> Option<usize>;
|
||||
}
|
||||
impl LogicTypeExt for grammar::LogicType {
|
||||
impl LogicTypeExt for LogicType {
|
||||
fn as_channel(&self) -> Option<usize> {
|
||||
match self {
|
||||
grammar::LogicType::Channel0 => Some(0),
|
||||
grammar::LogicType::Channel1 => Some(1),
|
||||
grammar::LogicType::Channel2 => Some(2),
|
||||
grammar::LogicType::Channel3 => Some(3),
|
||||
grammar::LogicType::Channel4 => Some(4),
|
||||
grammar::LogicType::Channel5 => Some(5),
|
||||
grammar::LogicType::Channel6 => Some(6),
|
||||
grammar::LogicType::Channel7 => Some(7),
|
||||
LogicType::Channel0 => Some(0),
|
||||
LogicType::Channel1 => Some(1),
|
||||
LogicType::Channel2 => Some(2),
|
||||
LogicType::Channel3 => Some(3),
|
||||
LogicType::Channel4 => Some(4),
|
||||
LogicType::Channel5 => Some(5),
|
||||
LogicType::Channel6 => Some(6),
|
||||
LogicType::Channel7 => Some(7),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
pub mod device;
|
||||
pub mod errors;
|
||||
pub mod grammar;
|
||||
pub mod interpreter;
|
||||
pub mod network;
|
||||
mod rand_mscorlib;
|
||||
pub mod tokens;
|
||||
pub mod device;
|
||||
pub mod vm;
|
||||
pub mod network;
|
||||
|
||||
|
||||
@@ -131,7 +131,6 @@ pub enum NetworkError {
|
||||
}
|
||||
|
||||
impl Network {
|
||||
|
||||
pub fn new(id: u32) -> Self {
|
||||
Network {
|
||||
id,
|
||||
|
||||
3717
ic10emu/src/vm/enums/basic_enums.rs
Normal file
3717
ic10emu/src/vm/enums/basic_enums.rs
Normal file
File diff suppressed because it is too large
Load Diff
3
ic10emu/src/vm/enums/mod.rs
Normal file
3
ic10emu/src/vm/enums/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub mod basic_enums;
|
||||
pub mod prefabs;
|
||||
pub mod script_enums;
|
||||
10103
ic10emu/src/vm/enums/prefabs.rs
Normal file
10103
ic10emu/src/vm/enums/prefabs.rs
Normal file
File diff suppressed because it is too large
Load Diff
2275
ic10emu/src/vm/enums/script_enums.rs
Normal file
2275
ic10emu/src/vm/enums/script_enums.rs
Normal file
File diff suppressed because it is too large
Load Diff
1076
ic10emu/src/vm/instructions/enums.rs
Normal file
1076
ic10emu/src/vm/instructions/enums.rs
Normal file
File diff suppressed because it is too large
Load Diff
26
ic10emu/src/vm/instructions/mod.rs
Normal file
26
ic10emu/src/vm/instructions/mod.rs
Normal file
@@ -0,0 +1,26 @@
|
||||
pub mod enums;
|
||||
pub mod operands;
|
||||
pub mod traits;
|
||||
|
||||
use enums::InstructionOp;
|
||||
use operands::Operand;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use phf::phf_map;
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Instruction {
|
||||
pub instruction: InstructionOp,
|
||||
pub operands: Vec<Operand>,
|
||||
}
|
||||
|
||||
#[allow(clippy::approx_constant)]
|
||||
pub static CONSTANTS_LOOKUP: phf::Map<&'static str, f64> = phf_map! {
|
||||
"nan" => f64::NAN,
|
||||
"ninf" => f64::NEG_INFINITY,
|
||||
"deg2rad" => 0.0174532923847437f64,
|
||||
"rad2deg" => 57.2957801818848f64,
|
||||
"epsilon" => f64::EPSILON,
|
||||
"pinf" => f64::INFINITY,
|
||||
"pi" => 3.141592653589793f64,
|
||||
};
|
||||
302
ic10emu/src/vm/instructions/operands.rs
Normal file
302
ic10emu/src/vm/instructions/operands.rs
Normal file
@@ -0,0 +1,302 @@
|
||||
use crate::errors::ICError;
|
||||
use crate::interpreter;
|
||||
use crate::vm::enums::script_enums::{
|
||||
LogicBatchMethod as BatchMode, LogicReagentMode as ReagentMode, LogicSlotType as SlotLogicType,
|
||||
LogicType,
|
||||
};
|
||||
use crate::vm::instructions::enums::InstructionOp;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum::EnumProperty;
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
pub enum Device {
|
||||
Db,
|
||||
Numbered(u32),
|
||||
Indirect { indirection: u32, target: u32 },
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct RegisterSpec {
|
||||
pub indirection: u32,
|
||||
pub target: u32,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DeviceSpec {
|
||||
pub device: Device,
|
||||
pub connection: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Identifier {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum Number {
|
||||
Float(f64),
|
||||
Binary(i64),
|
||||
Hexadecimal(i64),
|
||||
Constant(f64),
|
||||
String(String),
|
||||
Enum(f64),
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum Operand {
|
||||
RegisterSpec(RegisterSpec),
|
||||
DeviceSpec(DeviceSpec),
|
||||
Number(Number),
|
||||
Type {
|
||||
logic_type: Option<LogicType>,
|
||||
slot_logic_type: Option<SlotLogicType>,
|
||||
batch_mode: Option<BatchMode>,
|
||||
reagent_mode: Option<ReagentMode>,
|
||||
identifier: Identifier,
|
||||
},
|
||||
Identifier(Identifier),
|
||||
}
|
||||
|
||||
impl Operand {
|
||||
pub fn as_value(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<f64, ICError> {
|
||||
match self.translate_alias(ic) {
|
||||
Operand::RegisterSpec(RegisterSpec {
|
||||
indirection,
|
||||
target,
|
||||
}) => ic.get_register(indirection, target),
|
||||
Operand::Number(num) => Ok(num.value()),
|
||||
Operand::Type {
|
||||
logic_type,
|
||||
slot_logic_type,
|
||||
batch_mode,
|
||||
reagent_mode,
|
||||
identifier: _,
|
||||
} => {
|
||||
if let Some(lt) = logic_type {
|
||||
Ok(lt
|
||||
.get_str("value")
|
||||
.ok_or_else(|| ICError::NoGeneratedValue(lt.to_string()))?
|
||||
.parse::<u16>()
|
||||
.map_err(|_| {
|
||||
ICError::BadGeneratedValueParse(lt.to_string(), "u16".to_owned())
|
||||
})? as f64)
|
||||
} else if let Some(slt) = slot_logic_type {
|
||||
Ok(slt
|
||||
.get_str("value")
|
||||
.ok_or_else(|| ICError::NoGeneratedValue(slt.to_string()))?
|
||||
.parse::<u8>()
|
||||
.map_err(|_| {
|
||||
ICError::BadGeneratedValueParse(slt.to_string(), "u8".to_owned())
|
||||
})? as f64)
|
||||
} else if let Some(bm) = batch_mode {
|
||||
Ok(bm
|
||||
.get_str("value")
|
||||
.ok_or_else(|| ICError::NoGeneratedValue(bm.to_string()))?
|
||||
.parse::<u8>()
|
||||
.map_err(|_| {
|
||||
ICError::BadGeneratedValueParse(bm.to_string(), "u8".to_owned())
|
||||
})? as f64)
|
||||
} else if let Some(rm) = reagent_mode {
|
||||
Ok(rm
|
||||
.get_str("value")
|
||||
.ok_or_else(|| ICError::NoGeneratedValue(rm.to_string()))?
|
||||
.parse::<u8>()
|
||||
.map_err(|_| {
|
||||
ICError::BadGeneratedValueParse(rm.to_string(), "u8".to_owned())
|
||||
})? as f64)
|
||||
} else {
|
||||
Err(ICError::TypeValueNotKnown)
|
||||
}
|
||||
}
|
||||
Operand::Identifier(id) => Err(ICError::UnknownIdentifier(id.name.to_string())),
|
||||
Operand::DeviceSpec { .. } => Err(ICError::IncorrectOperandType {
|
||||
inst,
|
||||
index,
|
||||
desired: "Value".to_owned(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_value_i64(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
signed: bool,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<i64, ICError> {
|
||||
match self {
|
||||
Self::Number(num) => Ok(num.value_i64(signed)),
|
||||
_ => {
|
||||
let val = self.as_value(ic, inst, index)?;
|
||||
if val < -9.223_372_036_854_776E18 {
|
||||
Err(ICError::ShiftUnderflowI64)
|
||||
} else if val <= 9.223_372_036_854_776E18 {
|
||||
Ok(interpreter::f64_to_i64(val, signed))
|
||||
} else {
|
||||
Err(ICError::ShiftOverflowI64)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn as_value_i32(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
signed: bool,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<i32, ICError> {
|
||||
match self {
|
||||
Self::Number(num) => Ok(num.value_i64(signed) as i32),
|
||||
_ => {
|
||||
let val = self.as_value(ic, inst, index)?;
|
||||
if val < -2147483648.0 {
|
||||
Err(ICError::ShiftUnderflowI32)
|
||||
} else if val <= 2147483647.0 {
|
||||
Ok(val as i32)
|
||||
} else {
|
||||
Err(ICError::ShiftOverflowI32)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_register(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<RegisterSpec, ICError> {
|
||||
match self.translate_alias(ic) {
|
||||
Operand::RegisterSpec(reg) => Ok(reg),
|
||||
Operand::Identifier(id) => Err(ICError::UnknownIdentifier(id.name.to_string())),
|
||||
_ => Err(ICError::IncorrectOperandType {
|
||||
inst,
|
||||
index,
|
||||
desired: "Register".to_owned(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_device(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<(Option<u32>, Option<usize>), ICError> {
|
||||
match self.translate_alias(ic) {
|
||||
Operand::DeviceSpec(DeviceSpec { device, connection }) => match device {
|
||||
Device::Db => Ok((Some(ic.device), connection)),
|
||||
Device::Numbered(p) => {
|
||||
let dp = ic
|
||||
.pins
|
||||
.borrow()
|
||||
.get(p as usize)
|
||||
.ok_or(ICError::DeviceIndexOutOfRange(p as f64))
|
||||
.copied()?;
|
||||
Ok((dp, connection))
|
||||
}
|
||||
Device::Indirect {
|
||||
indirection,
|
||||
target,
|
||||
} => {
|
||||
let val = ic.get_register(indirection, target)?;
|
||||
let dp = ic
|
||||
.pins
|
||||
.borrow()
|
||||
.get(val as usize)
|
||||
.ok_or(ICError::DeviceIndexOutOfRange(val))
|
||||
.copied()?;
|
||||
Ok((dp, connection))
|
||||
}
|
||||
},
|
||||
Operand::Identifier(id) => Err(ICError::UnknownIdentifier(id.name.to_string())),
|
||||
_ => Err(ICError::IncorrectOperandType {
|
||||
inst,
|
||||
index,
|
||||
desired: "Value".to_owned(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_logic_type(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<LogicType, ICError> {
|
||||
match &self {
|
||||
Operand::Type {
|
||||
logic_type: Some(lt),
|
||||
..
|
||||
} => Ok(*lt),
|
||||
_ => LogicType::try_from(self.as_value(ic, inst, index)?),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_slot_logic_type(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<SlotLogicType, ICError> {
|
||||
match &self {
|
||||
Operand::Type {
|
||||
slot_logic_type: Some(slt),
|
||||
..
|
||||
} => Ok(*slt),
|
||||
_ => SlotLogicType::try_from(self.as_value(ic, inst, index)?),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_batch_mode(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<BatchMode, ICError> {
|
||||
match &self {
|
||||
Operand::Type {
|
||||
batch_mode: Some(bm),
|
||||
..
|
||||
} => Ok(*bm),
|
||||
_ => BatchMode::try_from(self.as_value(ic, inst, index)?),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_reagent_mode(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<ReagentMode, ICError> {
|
||||
match &self {
|
||||
Operand::Type {
|
||||
reagent_mode: Some(rm),
|
||||
..
|
||||
} => Ok(*rm),
|
||||
_ => ReagentMode::try_from(self.as_value(ic, inst, index)?),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn translate_alias(&self, ic: &interpreter::IC) -> Self {
|
||||
match &self {
|
||||
Operand::Identifier(id) | Operand::Type { identifier: id, .. } => {
|
||||
if let Some(alias) = ic.aliases.borrow().get(&id.name) {
|
||||
alias.clone()
|
||||
} else if let Some(define) = ic.defines.borrow().get(&id.name) {
|
||||
Operand::Number(Number::Float(*define))
|
||||
} else if let Some(label) = ic.program.borrow().labels.get(&id.name) {
|
||||
Operand::Number(Number::Float(*label as f64))
|
||||
} else {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
_ => self.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
1675
ic10emu/src/vm/instructions/traits.rs
Normal file
1675
ic10emu/src/vm/instructions/traits.rs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,15 @@
|
||||
|
||||
|
||||
mod object;
|
||||
pub mod enums;
|
||||
pub mod instructions;
|
||||
pub mod object;
|
||||
|
||||
use crate::{
|
||||
device::{Device, DeviceTemplate, SlotOccupant, SlotOccupantTemplate},
|
||||
grammar::{BatchMode, LogicType, SlotLogicType},
|
||||
interpreter::{self, FrozenIC, ICError, LineError},
|
||||
errors::{ICError, VMError},
|
||||
interpreter::{self, FrozenIC},
|
||||
network::{CableConnectionType, Connection, FrozenNetwork, Network},
|
||||
vm::enums::script_enums::{
|
||||
LogicBatchMethod as BatchMode, LogicSlotType as SlotLogicType, LogicType,
|
||||
},
|
||||
};
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
@@ -16,31 +19,6 @@ use std::{
|
||||
|
||||
use itertools::Itertools;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug, Serialize, Deserialize)]
|
||||
pub enum VMError {
|
||||
#[error("device with id '{0}' does not exist")]
|
||||
UnknownId(u32),
|
||||
#[error("ic with id '{0}' does not exist")]
|
||||
UnknownIcId(u32),
|
||||
#[error("device with id '{0}' does not have a ic slot")]
|
||||
NoIC(u32),
|
||||
#[error("ic encountered an error: {0}")]
|
||||
ICError(#[from] ICError),
|
||||
#[error("ic encountered an error: {0}")]
|
||||
LineError(#[from] LineError),
|
||||
#[error("invalid network id {0}")]
|
||||
InvalidNetwork(u32),
|
||||
#[error("device {0} not visible to device {1} (not on the same networks)")]
|
||||
DeviceNotVisible(u32, u32),
|
||||
#[error("a device with id {0} already exists")]
|
||||
IdInUse(u32),
|
||||
#[error("device(s) with ids {0:?} already exist")]
|
||||
IdsInUse(Vec<u32>),
|
||||
#[error("atempt to use a set of id's with duplicates: id(s) {0:?} exsist more than once")]
|
||||
DuplicateIds(Vec<u32>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VM {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::grammar::{LogicType, SlotLogicType};
|
||||
use crate::vm::enums::script_enums::{LogicSlotType as SlotLogicType, LogicType};
|
||||
|
||||
#[derive(Error, Debug, Serialize, Deserialize)]
|
||||
pub enum LogicError {
|
||||
@@ -14,7 +14,7 @@ pub enum LogicError {
|
||||
#[error("can't write slot {1} SlotLogicType {0}")]
|
||||
CantSlotWrite(SlotLogicType, usize),
|
||||
#[error("slot id {0} is out of range 0..{1}")]
|
||||
SlotIndexOutOfRange(usize, usize)
|
||||
SlotIndexOutOfRange(usize, usize),
|
||||
}
|
||||
|
||||
#[derive(Error, Debug, Serialize, Deserialize)]
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use macro_rules_attribute::derive;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
mod macros;
|
||||
mod traits;
|
||||
mod stationpedia;
|
||||
mod errors;
|
||||
pub mod errors;
|
||||
pub mod macros;
|
||||
pub mod stationpedia;
|
||||
pub mod traits;
|
||||
|
||||
use traits::*;
|
||||
|
||||
use crate::{device::SlotType, grammar::SlotLogicType};
|
||||
use crate::{device::SlotType, vm::enums::script_enums::LogicSlotType as SlotLogicType};
|
||||
|
||||
pub type ObjectID = u32;
|
||||
pub type BoxedObject = Box<dyn Object<ID = ObjectID>>;
|
||||
@@ -46,7 +46,6 @@ pub struct LogicField {
|
||||
pub value: f64,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||
pub struct Slot {
|
||||
pub typ: SlotType,
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum::{AsRefStr, Display, EnumIter, EnumProperty, EnumString, FromRepr};
|
||||
|
||||
use crate::vm::enums::prefabs::StationpediaPrefab;
|
||||
use crate::vm::object::BoxedObject;
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/stationpedia_prefabs.rs"));
|
||||
|
||||
#[allow(unused)]
|
||||
pub enum PrefabTemplate {
|
||||
Hash(i32),
|
||||
@@ -27,4 +23,4 @@ pub fn object_from_prefab_template(template: &PrefabTemplate) -> Option<BoxedObj
|
||||
}
|
||||
}
|
||||
|
||||
mod generic;
|
||||
pub mod generic;
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
use crate::{
|
||||
grammar::{LogicType, SlotLogicType},
|
||||
vm::{
|
||||
object::{
|
||||
errors::{LogicError, MemoryError},
|
||||
macros::ObjectInterface,
|
||||
traits::*,
|
||||
FieldType, LogicField, Name, ObjectID, Slot,
|
||||
},
|
||||
VM,
|
||||
use crate::vm::{
|
||||
enums::script_enums::{LogicSlotType as SlotLogicType, LogicType},
|
||||
object::{
|
||||
errors::{LogicError, MemoryError},
|
||||
macros::ObjectInterface,
|
||||
traits::*,
|
||||
FieldType, LogicField, Name, ObjectID, Slot,
|
||||
},
|
||||
VM,
|
||||
};
|
||||
use macro_rules_attribute::derive;
|
||||
use std::{collections::BTreeMap, usize};
|
||||
@@ -47,25 +45,9 @@ macro_rules! GWLogicable {
|
||||
}
|
||||
};
|
||||
}
|
||||
pub trait GWMemory {
|
||||
fn memory_size(&self) -> usize;
|
||||
}
|
||||
macro_rules! GWMemory {
|
||||
(
|
||||
$( #[$attr:meta] )*
|
||||
$viz:vis struct $struct:ident {
|
||||
$($body:tt)*
|
||||
}
|
||||
) => {
|
||||
impl GWMemory for $struct {
|
||||
fn memory_size(&self) -> usize {
|
||||
self.memory.len()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub trait GWMemoryReadable: GWMemory {
|
||||
pub trait GWMemoryReadable {
|
||||
fn memory_size(&self) -> usize;
|
||||
fn memory(&self) -> &Vec<f64>;
|
||||
}
|
||||
macro_rules! GWMemoryReadable {
|
||||
@@ -76,13 +58,16 @@ macro_rules! GWMemoryReadable {
|
||||
}
|
||||
) => {
|
||||
impl GWMemoryReadable for $struct {
|
||||
fn memory_size(&self) -> usize {
|
||||
self.memory.len()
|
||||
}
|
||||
fn memory(&self) -> &Vec<f64> {
|
||||
&self.memory
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
pub trait GWMemoryWritable: GWMemory + GWMemoryReadable {
|
||||
pub trait GWMemoryWritable: GWMemoryReadable {
|
||||
fn memory_mut(&mut self) -> &mut Vec<f64>;
|
||||
}
|
||||
macro_rules! GWMemoryWritable {
|
||||
@@ -202,12 +187,10 @@ impl<T: GWLogicable + Object> Logicable for T {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: GWMemory + Object> Memory for T {
|
||||
impl<T: GWMemoryReadable + Object> MemoryReadable for T {
|
||||
fn memory_size(&self) -> usize {
|
||||
self.memory_size()
|
||||
}
|
||||
}
|
||||
impl<T: GWMemoryReadable + Memory + Object> MemoryReadable for T {
|
||||
fn get_memory(&self, index: i32) -> Result<f64, MemoryError> {
|
||||
if index < 0 {
|
||||
Err(MemoryError::StackUnderflow(index, self.memory().len()))
|
||||
@@ -218,7 +201,7 @@ impl<T: GWMemoryReadable + Memory + Object> MemoryReadable for T {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T: GWMemoryWritable + Memory + Object> MemoryWritable for T {
|
||||
impl<T: GWMemoryWritable + MemoryReadable + Object> MemoryWritable for T {
|
||||
fn set_memory(&mut self, index: i32, val: f64) -> Result<(), MemoryError> {
|
||||
if index < 0 {
|
||||
Err(MemoryError::StackUnderflow(index, self.memory().len()))
|
||||
@@ -270,8 +253,8 @@ pub struct GenericLogicableDevice {
|
||||
slots: Vec<Slot>,
|
||||
}
|
||||
|
||||
#[derive(ObjectInterface!, GWLogicable!, GWMemory!, GWMemoryReadable!)]
|
||||
#[custom(implements(Object { Logicable, Memory, MemoryReadable }))]
|
||||
#[derive(ObjectInterface!, GWLogicable!, GWMemoryReadable!)]
|
||||
#[custom(implements(Object { Logicable, MemoryReadable }))]
|
||||
pub struct GenericLogicableMemoryReadable {
|
||||
#[custom(object_id)]
|
||||
id: ObjectID,
|
||||
@@ -283,8 +266,8 @@ pub struct GenericLogicableMemoryReadable {
|
||||
memory: Vec<f64>,
|
||||
}
|
||||
|
||||
#[derive(ObjectInterface!, GWLogicable!, GWMemory!, GWMemoryReadable!, GWMemoryWritable!)]
|
||||
#[custom(implements(Object { Logicable, Memory, MemoryReadable, MemoryWritable }))]
|
||||
#[derive(ObjectInterface!, GWLogicable!, GWMemoryReadable!, GWMemoryWritable!)]
|
||||
#[custom(implements(Object { Logicable, MemoryReadable, MemoryWritable }))]
|
||||
pub struct GenericLogicableMemoryReadWritable {
|
||||
#[custom(object_id)]
|
||||
id: ObjectID,
|
||||
@@ -296,8 +279,8 @@ pub struct GenericLogicableMemoryReadWritable {
|
||||
memory: Vec<f64>,
|
||||
}
|
||||
|
||||
#[derive(ObjectInterface!, GWLogicable!, GWDevice!, GWMemory!, GWMemoryReadable!, GWMemoryWritable!)]
|
||||
#[custom(implements(Object { Logicable, Device, Memory, MemoryReadable }))]
|
||||
#[derive(ObjectInterface!, GWLogicable!, GWDevice!, GWMemoryReadable!, GWMemoryWritable!)]
|
||||
#[custom(implements(Object { Logicable, Device, MemoryReadable }))]
|
||||
pub struct GenericLogicableDeviceMemoryReadable {
|
||||
#[custom(object_id)]
|
||||
id: ObjectID,
|
||||
@@ -309,8 +292,8 @@ pub struct GenericLogicableDeviceMemoryReadable {
|
||||
memory: Vec<f64>,
|
||||
}
|
||||
|
||||
#[derive(ObjectInterface!, GWLogicable!, GWDevice!, GWMemory!, GWMemoryReadable!, GWMemoryWritable!)]
|
||||
#[custom(implements(Object { Logicable, Device, Memory, MemoryReadable, MemoryWritable }))]
|
||||
#[derive(ObjectInterface!, GWLogicable!, GWDevice!, GWMemoryReadable!, GWMemoryWritable!)]
|
||||
#[custom(implements(Object { Logicable, Device, MemoryReadable, MemoryWritable }))]
|
||||
pub struct GenericLogicableDeviceMemoryReadWriteablable {
|
||||
#[custom(object_id)]
|
||||
id: ObjectID,
|
||||
|
||||
@@ -1,39 +1,55 @@
|
||||
use std::fmt::Debug;
|
||||
use crate::{
|
||||
errors::ICError,
|
||||
vm::{
|
||||
enums::script_enums::{LogicSlotType, LogicType},
|
||||
instructions::Instruction,
|
||||
object::{
|
||||
errors::{LogicError, MemoryError},
|
||||
macros::tag_object_traits,
|
||||
ObjectID, Slot,
|
||||
},
|
||||
VM,
|
||||
},
|
||||
};
|
||||
|
||||
use crate::{grammar, vm::{object::{errors::{LogicError, MemoryError}, macros::tag_object_traits, ObjectID, Slot}, VM}};
|
||||
use std::fmt::Debug;
|
||||
|
||||
tag_object_traits! {
|
||||
#![object_trait(Object: Debug)]
|
||||
|
||||
pub trait Memory {
|
||||
pub trait MemoryReadable {
|
||||
fn memory_size(&self) -> usize;
|
||||
fn get_memory(&self, index: i32) -> Result<f64, MemoryError>;
|
||||
}
|
||||
|
||||
pub trait MemoryWritable: Memory {
|
||||
pub trait MemoryWritable: MemoryReadable {
|
||||
fn set_memory(&mut self, index: i32, val: f64) -> Result<(), MemoryError>;
|
||||
fn clear_memory(&mut self) -> Result<(), MemoryError>;
|
||||
}
|
||||
|
||||
pub trait MemoryReadable: Memory {
|
||||
fn get_memory(&self, index: i32) -> Result<f64, MemoryError>;
|
||||
}
|
||||
|
||||
pub trait Logicable {
|
||||
fn prefab_hash(&self) -> i32;
|
||||
/// returns 0 if not set
|
||||
fn name_hash(&self) -> i32;
|
||||
fn is_logic_readable(&self) -> bool;
|
||||
fn is_logic_writeable(&self) -> bool;
|
||||
fn can_logic_read(&self, lt: grammar::LogicType) -> bool;
|
||||
fn can_logic_write(&self, lt: grammar::LogicType) -> bool;
|
||||
fn set_logic(&mut self, lt: grammar::LogicType, value: f64, force: bool) -> Result<(), LogicError>;
|
||||
fn get_logic(&self, lt: grammar::LogicType) -> Result<f64, LogicError>;
|
||||
fn can_logic_read(&self, lt: LogicType) -> bool;
|
||||
fn can_logic_write(&self, lt: LogicType) -> bool;
|
||||
fn set_logic(&mut self, lt: LogicType, value: f64, force: bool) -> Result<(), LogicError>;
|
||||
fn get_logic(&self, lt: LogicType) -> Result<f64, LogicError>;
|
||||
|
||||
fn slots_count(&self) -> usize;
|
||||
fn get_slot(&self, index: usize) -> Option<&Slot>;
|
||||
fn get_slot_mut(&mut self, index: usize) -> Option<&mut Slot>;
|
||||
fn can_slot_logic_read(&self, slt: grammar::SlotLogicType, index: usize) -> bool;
|
||||
fn get_slot_logic(&self, slt: grammar::SlotLogicType, index: usize, vm: &VM) -> Result<f64, LogicError>;
|
||||
fn can_slot_logic_read(&self, slt: LogicSlotType, index: usize) -> bool;
|
||||
fn get_slot_logic(&self, slt: LogicSlotType, index: usize, vm: &VM) -> Result<f64, LogicError>;
|
||||
}
|
||||
|
||||
pub trait SourceCode {
|
||||
fn set_source_code(&mut self, code: &str) -> Result<(), ICError>;
|
||||
fn set_source_code_with_invalid(&mut self, code: &str);
|
||||
fn get_source_code(&self) -> String;
|
||||
fn get_line(&self, line: usize) -> Result<&Instruction, ICError>;
|
||||
}
|
||||
|
||||
pub trait CircuitHolder: Logicable {
|
||||
@@ -49,17 +65,17 @@ tag_object_traits! {
|
||||
fn get_batch_mut(&self) -> Vec<LogicableRefMut<Self>>;
|
||||
}
|
||||
|
||||
pub trait SourceCode {
|
||||
pub trait Programmable: crate::vm::instructions::traits::ICInstructable {
|
||||
fn get_source_code(&self) -> String;
|
||||
fn set_source_code(&self, code: String);
|
||||
|
||||
fn step(&mut self) -> Result<(), crate::errors::ICError>;
|
||||
}
|
||||
|
||||
pub trait Instructable: Memory {
|
||||
pub trait Instructable: MemoryWritable {
|
||||
// fn get_instructions(&self) -> Vec<LogicInstruction>
|
||||
}
|
||||
|
||||
pub trait LogicStack: Memory {
|
||||
pub trait LogicStack: MemoryWritable {
|
||||
// fn logic_stack(&self) -> LogicStack;
|
||||
}
|
||||
|
||||
@@ -67,10 +83,17 @@ tag_object_traits! {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
impl<T: Debug> Debug for dyn Object<ID = T> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Object: (ID = {:?}, Type = {})", self.id(), self.type_name())
|
||||
write!(
|
||||
f,
|
||||
"Object: (ID = {:?}, Type = {})",
|
||||
self.id(),
|
||||
self.type_name()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@ fn main() {
|
||||
ts_types.push_str(<_tstype);
|
||||
|
||||
let slt_tsunion: String = Itertools::intersperse(
|
||||
ic10emu::grammar::generated::SlotLogicType::iter().map(|slt| format!("\"{}\"", slt.as_ref())),
|
||||
ic10emu::grammar::generated::SlotLogicType::iter()
|
||||
.map(|slt| format!("\"{}\"", slt.as_ref())),
|
||||
"\n | ".to_owned(),
|
||||
)
|
||||
.collect();
|
||||
|
||||
@@ -10,10 +10,8 @@ pub fn set_panic_hook() {
|
||||
console_error_panic_hook::set_once();
|
||||
web_sys::console::log_1(&format!("Panic hook set...").into());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
extern crate web_sys;
|
||||
|
||||
// A macro to provide `println!(..)`-style syntax for `console.log` logging.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use futures::stream::TryStreamExt;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
use tokio::sync::RwLock;
|
||||
use futures::stream::TryStreamExt;
|
||||
use tower_lsp::{LspService, Server};
|
||||
use wasm_bindgen::{prelude::*, JsCast};
|
||||
use wasm_bindgen_futures::stream::JsStream;
|
||||
@@ -60,7 +60,7 @@ pub async fn serve(config: ServerConfig) -> Result<(), JsValue> {
|
||||
let output = wasm_streams::WritableStream::from_raw(output);
|
||||
let output = output.try_into_async_write().map_err(|err| err.0)?;
|
||||
|
||||
let (service, messages) = LspService::new(|client| ic10lsp_lib::server::Backend{
|
||||
let (service, messages) = LspService::new(|client| ic10lsp_lib::server::Backend {
|
||||
client,
|
||||
files: Arc::new(RwLock::new(HashMap::new())),
|
||||
config: Arc::new(RwLock::new(ic10lsp_lib::server::Configuration::default())),
|
||||
|
||||
@@ -5,4 +5,22 @@ edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.5.4", features = ["derive", "env"] }
|
||||
color-eyre = "0.6.3"
|
||||
convert_case = "0.6.0"
|
||||
indexmap = { version = "2.2.6", features = ["serde"] }
|
||||
# onig = "6.4.0"
|
||||
phf_codegen = "0.11.2"
|
||||
regex = "1.10.4"
|
||||
serde = "1.0.200"
|
||||
serde_derive = "1.0.200"
|
||||
serde_ignored = "0.1.10"
|
||||
serde_json = "1.0.116"
|
||||
serde_path_to_error = "0.1.16"
|
||||
serde_with = "3.8.1"
|
||||
textwrap = { version = "0.16.1", default-features = false }
|
||||
thiserror = "1.0.58"
|
||||
tracing = "0.1.40"
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||
|
||||
onig = { git = "https://github.com/rust-onig/rust-onig", revision = "fa90c0e97e90a056af89f183b23cd417b59ee6a2" }
|
||||
|
||||
|
||||
28
xtask/src/enums.rs
Normal file
28
xtask/src/enums.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(rename = "Enums")]
|
||||
pub struct Enums {
|
||||
#[serde(rename = "scriptEnums")]
|
||||
pub script_enums: BTreeMap<String, EnumListing>,
|
||||
#[serde(rename = "basicEnums")]
|
||||
pub basic_enums: BTreeMap<String, EnumListing>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(rename = "EnumListing")]
|
||||
pub struct EnumListing {
|
||||
#[serde(rename = "enumName")]
|
||||
pub enum_name: String,
|
||||
pub values: BTreeMap<String, EnumEntry>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(rename = "EnumEntry")]
|
||||
pub struct EnumEntry {
|
||||
pub value: i64,
|
||||
pub deprecated: bool,
|
||||
pub description: String,
|
||||
}
|
||||
101
xtask/src/generate.rs
Normal file
101
xtask/src/generate.rs
Normal file
@@ -0,0 +1,101 @@
|
||||
use color_eyre::eyre;
|
||||
|
||||
use std::{collections::BTreeMap, process::Command};
|
||||
|
||||
use crate::{enums::Enums, stationpedia::Stationpedia};
|
||||
|
||||
mod database;
|
||||
mod enums;
|
||||
mod instructions;
|
||||
mod utils;
|
||||
|
||||
pub fn generate(
|
||||
stationpedia_path: &std::path::Path,
|
||||
workspace: &std::path::Path,
|
||||
) -> color_eyre::Result<()> {
|
||||
let mut pedia: Stationpedia = parse_json(&mut serde_json::Deserializer::from_reader(
|
||||
std::io::BufReader::new(std::fs::File::open(
|
||||
stationpedia_path.join("Stationpedia.json"),
|
||||
)?),
|
||||
))?;
|
||||
|
||||
let instruction_help_patches: BTreeMap<String, String> = parse_json(
|
||||
&mut serde_json::Deserializer::from_reader(std::io::BufReader::new(std::fs::File::open(
|
||||
workspace.join("data").join("instruction_help_patches.json"),
|
||||
)?)),
|
||||
)?;
|
||||
|
||||
for (inst, patch) in instruction_help_patches {
|
||||
if let Some(cmd) = pedia.script_commands.get_mut(&inst) {
|
||||
cmd.desc = patch;
|
||||
} else {
|
||||
eprintln!("Warning: can find instruction '{inst}' to patch help!");
|
||||
}
|
||||
}
|
||||
|
||||
let enums: Enums = parse_json(&mut serde_json::Deserializer::from_reader(
|
||||
std::io::BufReader::new(std::fs::File::open(stationpedia_path.join("Enums.json"))?),
|
||||
))?;
|
||||
|
||||
database::generate_database(&pedia, &enums, workspace)?;
|
||||
let enums_files = enums::generate_enums(&pedia, &enums, workspace)?;
|
||||
let inst_files = instructions::generate_instructions(&pedia, workspace)?;
|
||||
|
||||
let generated_files = [enums_files.as_slice(), inst_files.as_slice()].concat();
|
||||
|
||||
eprintln!("Formatting generated files...");
|
||||
for file in &generated_files {
|
||||
prepend_genereated_comment(file)?;
|
||||
}
|
||||
let mut cmd = Command::new("cargo");
|
||||
cmd.current_dir(workspace);
|
||||
cmd.arg("fmt").arg("--");
|
||||
cmd.args(&generated_files);
|
||||
cmd.status()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn parse_json<'a, T: serde::Deserialize<'a>>(
|
||||
jd: impl serde::Deserializer<'a>,
|
||||
) -> Result<T, color_eyre::Report> {
|
||||
let mut track = serde_path_to_error::Track::new();
|
||||
let path = serde_path_to_error::Deserializer::new(jd, &mut track);
|
||||
let mut fun = |path: serde_ignored::Path| {
|
||||
tracing::warn!(key=%path,"Found ignored key");
|
||||
};
|
||||
serde_ignored::deserialize(path, &mut fun).map_err(|e| {
|
||||
eyre::eyre!(
|
||||
"path: {track} | error = {e}",
|
||||
track = track.path().to_string(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn prepend_genereated_comment(file_path: &std::path::Path) -> color_eyre::Result<()> {
|
||||
use std::io::Write;
|
||||
let tmp_path = file_path.with_extension("rs.tmp");
|
||||
{
|
||||
let mut tmp = std::fs::File::create(&tmp_path)?;
|
||||
let mut src = std::fs::File::open(file_path)?;
|
||||
write!(
|
||||
&mut tmp,
|
||||
"// ================================================= \n\
|
||||
// !! <-----> DO NOT MODIFY <-----> !! \n\
|
||||
// \n\
|
||||
// This module was automatically generated by an
|
||||
// xtask \n\
|
||||
// \n\
|
||||
// run `cargo xtask generate` from the workspace \n\
|
||||
// to regenerate \n\
|
||||
// \n\
|
||||
// ================================================= \n\
|
||||
\n\
|
||||
\n\
|
||||
"
|
||||
)?;
|
||||
std::io::copy(&mut src, &mut tmp)?;
|
||||
}
|
||||
std::fs::remove_file(file_path)?;
|
||||
std::fs::rename(&tmp_path, file_path)?;
|
||||
Ok(())
|
||||
}
|
||||
674
xtask/src/generate/database.rs
Normal file
674
xtask/src/generate/database.rs
Normal file
@@ -0,0 +1,674 @@
|
||||
use std::{collections::BTreeMap, io::Write};
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
enums,
|
||||
stationpedia::{self, Page, Stationpedia},
|
||||
};
|
||||
|
||||
pub fn generate_database(
|
||||
stationpedia: &stationpedia::Stationpedia,
|
||||
enums: &enums::Enums,
|
||||
workspace: &std::path::Path,
|
||||
) -> color_eyre::Result<()> {
|
||||
let templates = generate_templates(stationpedia)?;
|
||||
|
||||
println!("Writing prefab database ...");
|
||||
|
||||
let prefabs: BTreeMap<String, ObjectTemplate> = templates
|
||||
.into_iter()
|
||||
.map(|obj| (obj.prefab().prefab_name.clone(), obj))
|
||||
.collect();
|
||||
let prefabs_by_hash: BTreeMap<i32, String> = prefabs
|
||||
.iter()
|
||||
.map(|(key, val)| (val.prefab().prefab_hash, key.clone()))
|
||||
.collect();
|
||||
|
||||
let structures = prefabs
|
||||
.iter()
|
||||
.filter_map(|(_, val)| {
|
||||
use ObjectTemplate::*;
|
||||
match val {
|
||||
Structure(_)
|
||||
| StructureSlots(_)
|
||||
| StructureLogic(_)
|
||||
| StructureLogicDevice(_)
|
||||
| StructureLogicDeviceMemory(_) => Some(val.prefab().prefab_name.clone()),
|
||||
Item(_) | ItemSlots(_) | ItemLogic(_) | ItemLogicMemory(_) => None,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let items = prefabs
|
||||
.iter()
|
||||
.filter_map(|(_, val)| {
|
||||
use ObjectTemplate::*;
|
||||
match val {
|
||||
Structure(_)
|
||||
| StructureSlots(_)
|
||||
| StructureLogic(_)
|
||||
| StructureLogicDevice(_)
|
||||
| StructureLogicDeviceMemory(_) => None,
|
||||
Item(_) | ItemSlots(_) | ItemLogic(_) | ItemLogicMemory(_) => {
|
||||
Some(val.prefab().prefab_name.clone())
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let logicable_items = prefabs
|
||||
.iter()
|
||||
.filter_map(|(_, val)| {
|
||||
use ObjectTemplate::*;
|
||||
match val {
|
||||
Structure(_)
|
||||
| StructureSlots(_)
|
||||
| StructureLogic(_)
|
||||
| StructureLogicDevice(_)
|
||||
| StructureLogicDeviceMemory(_)
|
||||
| Item(_)
|
||||
| ItemSlots(_) => None,
|
||||
ItemLogic(_) | ItemLogicMemory(_) => Some(val.prefab().prefab_name.clone()),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let devices = prefabs
|
||||
.iter()
|
||||
.filter_map(|(_, val)| {
|
||||
use ObjectTemplate::*;
|
||||
match val {
|
||||
Structure(_) | StructureSlots(_) | StructureLogic(_) | Item(_) | ItemSlots(_)
|
||||
| ItemLogic(_) | ItemLogicMemory(_) => None,
|
||||
StructureLogicDevice(_) | StructureLogicDeviceMemory(_) => {
|
||||
Some(val.prefab().prefab_name.clone())
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let db: ObjectDatabase = ObjectDatabase {
|
||||
prefabs,
|
||||
reagents: stationpedia.reagents.clone(),
|
||||
enums: enums.clone(),
|
||||
prefabs_by_hash,
|
||||
structures,
|
||||
devices,
|
||||
items,
|
||||
logicable_items,
|
||||
};
|
||||
|
||||
let data_path = workspace.join("data");
|
||||
if !data_path.exists() {
|
||||
std::fs::create_dir(&data_path)?;
|
||||
}
|
||||
let database_path = data_path.join("database.json");
|
||||
let mut database_file = std::io::BufWriter::new(std::fs::File::create(database_path)?);
|
||||
serde_json::to_writer(&mut database_file, &db)?;
|
||||
database_file.flush()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn generate_templates(pedia: &Stationpedia) -> color_eyre::Result<Vec<ObjectTemplate>> {
|
||||
println!("Generating templates ...");
|
||||
let mut templates: Vec<ObjectTemplate> = Vec::new();
|
||||
for page in pedia.pages.iter() {
|
||||
let prefab = PrefabInfo {
|
||||
prefab_name: page.prefab_name.clone(),
|
||||
prefab_hash: page.prefab_hash,
|
||||
desc: page.description.clone(),
|
||||
name: page.title.clone(),
|
||||
};
|
||||
// every page should either by a item or a structure
|
||||
// in theory every device is logicable
|
||||
// in theory everything with memory is logicable
|
||||
match page {
|
||||
Page {
|
||||
item: Some(item),
|
||||
structure: None,
|
||||
logic_info: None,
|
||||
slot_inserts,
|
||||
memory: None,
|
||||
device: None,
|
||||
transmission_receiver: None,
|
||||
wireless_logic: None,
|
||||
circuit_holder: None,
|
||||
..
|
||||
} if slot_inserts.is_empty() => {
|
||||
templates.push(ObjectTemplate::Item(ItemTemplate {
|
||||
prefab,
|
||||
item: item.into(),
|
||||
}));
|
||||
}
|
||||
Page {
|
||||
item: Some(item),
|
||||
structure: None,
|
||||
logic_info: None,
|
||||
slot_inserts,
|
||||
memory: None,
|
||||
device: None,
|
||||
transmission_receiver: None,
|
||||
wireless_logic: None,
|
||||
circuit_holder: None,
|
||||
..
|
||||
} => {
|
||||
templates.push(ObjectTemplate::ItemSlots(ItemSlotsTemplate {
|
||||
prefab,
|
||||
item: item.into(),
|
||||
slots: slot_inserts_to_info(slot_inserts),
|
||||
}));
|
||||
}
|
||||
Page {
|
||||
item: Some(item),
|
||||
structure: None,
|
||||
logic_info: Some(logic),
|
||||
slot_inserts,
|
||||
memory: None,
|
||||
device: None,
|
||||
transmission_receiver,
|
||||
wireless_logic,
|
||||
circuit_holder,
|
||||
..
|
||||
} => {
|
||||
let mut logic: LogicInfo = logic.into();
|
||||
if !page.mode_insert.is_empty() {
|
||||
logic.modes = Some(mode_inserts_to_info(&page.mode_insert));
|
||||
}
|
||||
logic.transmission_receiver = transmission_receiver.unwrap_or(false);
|
||||
logic.wireless_logic = wireless_logic.unwrap_or(false);
|
||||
logic.circuit_holder = circuit_holder.unwrap_or(false);
|
||||
|
||||
templates.push(ObjectTemplate::ItemLogic(ItemLogicTemplate {
|
||||
prefab,
|
||||
item: item.into(),
|
||||
logic,
|
||||
slots: slot_inserts_to_info(slot_inserts),
|
||||
}));
|
||||
}
|
||||
Page {
|
||||
item: Some(item),
|
||||
structure: None,
|
||||
logic_info: Some(logic),
|
||||
slot_inserts,
|
||||
memory: Some(memory),
|
||||
device: None,
|
||||
transmission_receiver,
|
||||
wireless_logic,
|
||||
circuit_holder,
|
||||
..
|
||||
} => {
|
||||
let mut logic: LogicInfo = logic.into();
|
||||
if !page.mode_insert.is_empty() {
|
||||
logic.modes = Some(mode_inserts_to_info(&page.mode_insert));
|
||||
}
|
||||
logic.transmission_receiver = transmission_receiver.unwrap_or(false);
|
||||
logic.wireless_logic = wireless_logic.unwrap_or(false);
|
||||
logic.circuit_holder = circuit_holder.unwrap_or(false);
|
||||
|
||||
templates.push(ObjectTemplate::ItemLogicMemory(ItemLogicMemoryTemplate {
|
||||
prefab,
|
||||
item: item.into(),
|
||||
logic,
|
||||
slots: slot_inserts_to_info(slot_inserts),
|
||||
memory: memory.into(),
|
||||
}));
|
||||
}
|
||||
Page {
|
||||
item: None,
|
||||
structure: Some(structure),
|
||||
slot_inserts,
|
||||
logic_info: None,
|
||||
memory: None,
|
||||
device: None,
|
||||
transmission_receiver: None,
|
||||
wireless_logic: None,
|
||||
circuit_holder: None,
|
||||
..
|
||||
} if slot_inserts.is_empty() => {
|
||||
templates.push(ObjectTemplate::Structure(StructureTemplate {
|
||||
prefab,
|
||||
structure: structure.into(),
|
||||
}));
|
||||
// println!("Structure")
|
||||
}
|
||||
Page {
|
||||
item: None,
|
||||
structure: Some(structure),
|
||||
slot_inserts,
|
||||
logic_info: None,
|
||||
memory: None,
|
||||
device: None,
|
||||
transmission_receiver: None,
|
||||
wireless_logic: None,
|
||||
circuit_holder: None,
|
||||
..
|
||||
} => {
|
||||
templates.push(ObjectTemplate::StructureSlots(StructureSlotsTemplate {
|
||||
prefab,
|
||||
structure: structure.into(),
|
||||
slots: slot_inserts_to_info(slot_inserts),
|
||||
}));
|
||||
// println!("Structure")
|
||||
}
|
||||
Page {
|
||||
item: None,
|
||||
structure: Some(structure),
|
||||
logic_info: Some(logic),
|
||||
slot_inserts,
|
||||
memory: None,
|
||||
device: None,
|
||||
transmission_receiver,
|
||||
wireless_logic,
|
||||
circuit_holder,
|
||||
..
|
||||
} => {
|
||||
let mut logic: LogicInfo = logic.into();
|
||||
if !page.mode_insert.is_empty() {
|
||||
logic.modes = Some(mode_inserts_to_info(&page.mode_insert));
|
||||
}
|
||||
logic.transmission_receiver = transmission_receiver.unwrap_or(false);
|
||||
logic.wireless_logic = wireless_logic.unwrap_or(false);
|
||||
logic.circuit_holder = circuit_holder.unwrap_or(false);
|
||||
|
||||
templates.push(ObjectTemplate::StructureLogic(StructureLogicTemplate {
|
||||
prefab,
|
||||
structure: structure.into(),
|
||||
logic,
|
||||
slots: slot_inserts_to_info(slot_inserts),
|
||||
}));
|
||||
// println!("Structure")
|
||||
}
|
||||
Page {
|
||||
item: None,
|
||||
structure: Some(structure),
|
||||
logic_info: Some(logic),
|
||||
slot_inserts,
|
||||
memory: None,
|
||||
device: Some(device),
|
||||
transmission_receiver,
|
||||
wireless_logic,
|
||||
circuit_holder,
|
||||
..
|
||||
} => {
|
||||
let mut logic: LogicInfo = logic.into();
|
||||
if !page.mode_insert.is_empty() {
|
||||
logic.modes = Some(mode_inserts_to_info(&page.mode_insert));
|
||||
}
|
||||
logic.transmission_receiver = transmission_receiver.unwrap_or(false);
|
||||
logic.wireless_logic = wireless_logic.unwrap_or(false);
|
||||
logic.circuit_holder = circuit_holder.unwrap_or(false);
|
||||
|
||||
templates.push(ObjectTemplate::StructureLogicDevice(
|
||||
StructureLogicDeviceTemplate {
|
||||
prefab,
|
||||
structure: structure.into(),
|
||||
logic,
|
||||
slots: slot_inserts_to_info(slot_inserts),
|
||||
device: device.into(),
|
||||
},
|
||||
));
|
||||
// println!("Structure")
|
||||
}
|
||||
Page {
|
||||
item: None,
|
||||
structure: Some(structure),
|
||||
logic_info: Some(logic),
|
||||
slot_inserts,
|
||||
memory: Some(memory),
|
||||
device: Some(device),
|
||||
transmission_receiver,
|
||||
wireless_logic,
|
||||
circuit_holder,
|
||||
..
|
||||
} => {
|
||||
let mut logic: LogicInfo = logic.into();
|
||||
if !page.mode_insert.is_empty() {
|
||||
logic.modes = Some(mode_inserts_to_info(&page.mode_insert));
|
||||
}
|
||||
logic.transmission_receiver = transmission_receiver.unwrap_or(false);
|
||||
logic.wireless_logic = wireless_logic.unwrap_or(false);
|
||||
logic.circuit_holder = circuit_holder.unwrap_or(false);
|
||||
templates.push(ObjectTemplate::StructureLogicDeviceMemory(
|
||||
StructureLogicDeviceMemoryTemplate {
|
||||
prefab,
|
||||
structure: structure.into(),
|
||||
logic,
|
||||
slots: slot_inserts_to_info(slot_inserts),
|
||||
device: device.into(),
|
||||
memory: memory.into(),
|
||||
},
|
||||
));
|
||||
// println!("Structure")
|
||||
}
|
||||
_ => panic!(
|
||||
"Non conforming: {:?} \n\titem: {:?}\n\tstructure: {:?}\n\tlogic_info: {:?}\n\tslot_inserts: {:?}\n\tslot_logic: {:?}\n\tmemory: {:?}\n\tdevice: {:?}",
|
||||
page.key,
|
||||
page.item,
|
||||
page.structure,
|
||||
page.logic_info,
|
||||
page.slot_inserts,
|
||||
page.logic_slot_insert,
|
||||
page.memory,
|
||||
page.device,
|
||||
),
|
||||
}
|
||||
}
|
||||
Ok(templates)
|
||||
}
|
||||
|
||||
fn slot_inserts_to_info(slots: &[stationpedia::SlotInsert]) -> Vec<SlotInfo> {
|
||||
let mut tmp: Vec<_> = slots.into();
|
||||
tmp.sort_by(|a, b| a.slot_index.cmp(&b.slot_index));
|
||||
tmp.iter()
|
||||
.map(|slot| SlotInfo {
|
||||
name: slot.slot_name.clone(),
|
||||
typ: slot.slot_type.clone(),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn mode_inserts_to_info(modes: &[stationpedia::ModeInsert]) -> BTreeMap<u32, String> {
|
||||
modes
|
||||
.iter()
|
||||
.map(|mode| (mode.logic_access_types, mode.logic_name.clone()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ObjectDatabase {
|
||||
pub prefabs: BTreeMap<String, ObjectTemplate>,
|
||||
pub reagents: BTreeMap<String, stationpedia::Reagent>,
|
||||
pub enums: enums::Enums,
|
||||
pub prefabs_by_hash: BTreeMap<i32, String>,
|
||||
pub structures: Vec<String>,
|
||||
pub devices: Vec<String>,
|
||||
pub items: Vec<String>,
|
||||
pub logicable_items: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ObjectTemplate {
|
||||
Structure(StructureTemplate),
|
||||
StructureSlots(StructureSlotsTemplate),
|
||||
StructureLogic(StructureLogicTemplate),
|
||||
StructureLogicDevice(StructureLogicDeviceTemplate),
|
||||
StructureLogicDeviceMemory(StructureLogicDeviceMemoryTemplate),
|
||||
Item(ItemTemplate),
|
||||
ItemSlots(ItemSlotsTemplate),
|
||||
ItemLogic(ItemLogicTemplate),
|
||||
ItemLogicMemory(ItemLogicMemoryTemplate),
|
||||
}
|
||||
|
||||
impl ObjectTemplate {
|
||||
fn prefab(&self) -> &PrefabInfo {
|
||||
use ObjectTemplate::*;
|
||||
match self {
|
||||
Structure(s) => &s.prefab,
|
||||
StructureSlots(s) => &s.prefab,
|
||||
StructureLogic(s) => &s.prefab,
|
||||
StructureLogicDevice(s) => &s.prefab,
|
||||
StructureLogicDeviceMemory(s) => &s.prefab,
|
||||
Item(i) => &i.prefab,
|
||||
ItemSlots(i) => &i.prefab,
|
||||
ItemLogic(i) => &i.prefab,
|
||||
ItemLogicMemory(i) => &i.prefab,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PrefabInfo {
|
||||
pub prefab_name: String,
|
||||
pub prefab_hash: i32,
|
||||
pub desc: String,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SlotInfo {
|
||||
pub name: String,
|
||||
pub typ: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct LogicInfo {
|
||||
pub logic_slot_types: BTreeMap<u32, stationpedia::LogicSlotTypes>,
|
||||
pub logic_types: stationpedia::LogicTypes,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub modes: Option<BTreeMap<u32, String>>,
|
||||
pub transmission_receiver: bool,
|
||||
pub wireless_logic: bool,
|
||||
pub circuit_holder: bool,
|
||||
}
|
||||
|
||||
impl From<&stationpedia::LogicInfo> for LogicInfo {
|
||||
fn from(value: &stationpedia::LogicInfo) -> Self {
|
||||
LogicInfo {
|
||||
logic_slot_types: value.logic_slot_types.clone(),
|
||||
logic_types: value.logic_types.clone(),
|
||||
modes: None,
|
||||
transmission_receiver: false,
|
||||
wireless_logic: false,
|
||||
circuit_holder: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ItemInfo {
|
||||
pub consumable: bool,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub filter_type: Option<String>,
|
||||
pub ingredient: bool,
|
||||
pub max_quantity: f64,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub reagents: Option<BTreeMap<String, f64>>,
|
||||
pub slot_class: String,
|
||||
pub sorting_class: String,
|
||||
}
|
||||
|
||||
impl From<&stationpedia::Item> for ItemInfo {
|
||||
fn from(item: &stationpedia::Item) -> Self {
|
||||
ItemInfo {
|
||||
consumable: item.consumable.unwrap_or(false),
|
||||
filter_type: item.filter_type.clone(),
|
||||
ingredient: item.ingredient.unwrap_or(false),
|
||||
max_quantity: item.max_quantity.unwrap_or(1.0),
|
||||
reagents: item
|
||||
.reagents
|
||||
.as_ref()
|
||||
.map(|map| map.iter().map(|(key, val)| (key.clone(), *val)).collect()),
|
||||
slot_class: item.slot_class.clone(),
|
||||
sorting_class: item.sorting_class.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DeviceInfo {
|
||||
pub connection_list: Vec<(String, String)>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub device_pins_length: Option<i64>,
|
||||
pub has_activate_state: bool,
|
||||
pub has_atmosphere: bool,
|
||||
pub has_color_state: bool,
|
||||
pub has_lock_state: bool,
|
||||
pub has_mode_state: bool,
|
||||
pub has_on_off_state: bool,
|
||||
pub has_open_state: bool,
|
||||
pub has_reagents: bool,
|
||||
}
|
||||
|
||||
impl From<&stationpedia::Device> for DeviceInfo {
|
||||
fn from(value: &stationpedia::Device) -> Self {
|
||||
DeviceInfo {
|
||||
connection_list: value.connection_list.clone(),
|
||||
device_pins_length: value.devices_length,
|
||||
has_activate_state: value.has_activate_state,
|
||||
has_atmosphere: value.has_atmosphere,
|
||||
has_color_state: value.has_color_state,
|
||||
has_lock_state: value.has_lock_state,
|
||||
has_mode_state: value.has_mode_state,
|
||||
has_on_off_state: value.has_on_off_state,
|
||||
has_open_state: value.has_open_state,
|
||||
has_reagents: value.has_reagents,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct StructureInfo {
|
||||
pub small_grid: bool,
|
||||
}
|
||||
|
||||
impl From<&stationpedia::Structure> for StructureInfo {
|
||||
fn from(value: &stationpedia::Structure) -> Self {
|
||||
StructureInfo {
|
||||
small_grid: value.small_grid,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Instruction {
|
||||
pub description: String,
|
||||
pub typ: String,
|
||||
pub value: i64,
|
||||
}
|
||||
|
||||
impl From<&stationpedia::Instruction> for Instruction {
|
||||
fn from(value: &stationpedia::Instruction) -> Self {
|
||||
Instruction {
|
||||
description: value.description.clone(),
|
||||
typ: value.type_.clone(),
|
||||
value: value.value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct MemoryInfo {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub instructions: Option<BTreeMap<String, Instruction>>,
|
||||
pub memory_access: String,
|
||||
pub memory_size: i64,
|
||||
}
|
||||
|
||||
impl From<&stationpedia::Memory> for MemoryInfo {
|
||||
fn from(value: &stationpedia::Memory) -> Self {
|
||||
MemoryInfo {
|
||||
instructions: value.instructions.as_ref().map(|insts| {
|
||||
insts
|
||||
.iter()
|
||||
.map(|(key, value)| (key.clone(), value.into()))
|
||||
.collect()
|
||||
}),
|
||||
memory_access: value.memory_access.clone(),
|
||||
memory_size: value.memory_size,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct StructureTemplate {
|
||||
pub prefab: PrefabInfo,
|
||||
pub structure: StructureInfo,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct StructureSlotsTemplate {
|
||||
pub prefab: PrefabInfo,
|
||||
pub structure: StructureInfo,
|
||||
pub slots: Vec<SlotInfo>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct StructureLogicTemplate {
|
||||
pub prefab: PrefabInfo,
|
||||
pub structure: StructureInfo,
|
||||
pub logic: LogicInfo,
|
||||
pub slots: Vec<SlotInfo>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct StructureLogicDeviceTemplate {
|
||||
pub prefab: PrefabInfo,
|
||||
pub structure: StructureInfo,
|
||||
pub logic: LogicInfo,
|
||||
pub slots: Vec<SlotInfo>,
|
||||
pub device: DeviceInfo,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct StructureLogicDeviceMemoryTemplate {
|
||||
pub prefab: PrefabInfo,
|
||||
pub structure: StructureInfo,
|
||||
pub logic: LogicInfo,
|
||||
pub slots: Vec<SlotInfo>,
|
||||
pub device: DeviceInfo,
|
||||
pub memory: MemoryInfo,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ItemTemplate {
|
||||
pub prefab: PrefabInfo,
|
||||
pub item: ItemInfo,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ItemSlotsTemplate {
|
||||
pub prefab: PrefabInfo,
|
||||
pub item: ItemInfo,
|
||||
pub slots: Vec<SlotInfo>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ItemLogicTemplate {
|
||||
pub prefab: PrefabInfo,
|
||||
pub item: ItemInfo,
|
||||
pub logic: LogicInfo,
|
||||
pub slots: Vec<SlotInfo>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ItemLogicMemoryTemplate {
|
||||
pub prefab: PrefabInfo,
|
||||
pub item: ItemInfo,
|
||||
pub logic: LogicInfo,
|
||||
pub slots: Vec<SlotInfo>,
|
||||
pub memory: MemoryInfo,
|
||||
}
|
||||
397
xtask/src/generate/enums.rs
Normal file
397
xtask/src/generate/enums.rs
Normal file
@@ -0,0 +1,397 @@
|
||||
use convert_case::{Case, Casing};
|
||||
use std::collections::BTreeMap;
|
||||
use std::{
|
||||
fmt::Display,
|
||||
io::{BufWriter, Write},
|
||||
path::PathBuf,
|
||||
str::FromStr,
|
||||
};
|
||||
pub fn generate_enums(
|
||||
stationpedia: &crate::stationpedia::Stationpedia,
|
||||
enums: &crate::enums::Enums,
|
||||
workspace: &std::path::Path,
|
||||
) -> color_eyre::Result<Vec<PathBuf>> {
|
||||
println!("Writing Enum Listings ...");
|
||||
let enums_path = workspace
|
||||
.join("ic10emu")
|
||||
.join("src")
|
||||
.join("vm")
|
||||
.join("enums");
|
||||
if !enums_path.exists() {
|
||||
std::fs::create_dir(&enums_path)?;
|
||||
}
|
||||
|
||||
let mut writer =
|
||||
std::io::BufWriter::new(std::fs::File::create(enums_path.join("script_enums.rs"))?);
|
||||
write_repr_enum_use_header(&mut writer)?;
|
||||
for enm in enums.script_enums.values() {
|
||||
write_enum_listing(&mut writer, enm)?;
|
||||
}
|
||||
|
||||
let mut writer =
|
||||
std::io::BufWriter::new(std::fs::File::create(enums_path.join("basic_enums.rs"))?);
|
||||
write_repr_enum_use_header(&mut writer)?;
|
||||
for enm in enums.basic_enums.values() {
|
||||
write_enum_listing(&mut writer, enm)?;
|
||||
}
|
||||
write_enum_aggragate_mod(&mut writer, &enums.basic_enums)?;
|
||||
|
||||
let mut writer = std::io::BufWriter::new(std::fs::File::create(enums_path.join("prefabs.rs"))?);
|
||||
write_repr_enum_use_header(&mut writer)?;
|
||||
let prefabs = stationpedia
|
||||
.pages
|
||||
.iter()
|
||||
.map(|page| {
|
||||
let variant = ReprEnumVariant {
|
||||
value: page.prefab_hash,
|
||||
deprecated: false,
|
||||
props: vec![
|
||||
("name".to_owned(), page.title.clone()),
|
||||
("desc".to_owned(), page.description.clone()),
|
||||
],
|
||||
};
|
||||
(page.prefab_name.clone(), variant)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
write_repr_enum(&mut writer, "StationpediaPrefab", &prefabs, true)?;
|
||||
|
||||
Ok(vec![
|
||||
enums_path.join("script_enums.rs"),
|
||||
enums_path.join("basic_enums.rs"),
|
||||
enums_path.join("prefabs.rs"),
|
||||
])
|
||||
}
|
||||
|
||||
fn write_enum_aggragate_mod<T: std::io::Write>(
|
||||
writer: &mut BufWriter<T>,
|
||||
enums: &BTreeMap<String, crate::enums::EnumListing>,
|
||||
) -> color_eyre::Result<()> {
|
||||
let variant_lines = enums
|
||||
.iter()
|
||||
.map(|(name, listing)| {
|
||||
let name = if name.is_empty() || name == "_unnamed" {
|
||||
"Unnamed"
|
||||
} else {
|
||||
name
|
||||
};
|
||||
format!(
|
||||
" {}({}),",
|
||||
name.to_case(Case::Pascal),
|
||||
listing.enum_name.to_case(Case::Pascal)
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
let value_arms = enums
|
||||
.keys()
|
||||
.map(|name| {
|
||||
let variant_name = (if name.is_empty() || name == "_unnamed" {
|
||||
"Unnamed"
|
||||
} else {
|
||||
name
|
||||
})
|
||||
.to_case(Case::Pascal);
|
||||
format!(" Self::{variant_name}(enm) => *enm as u32,",)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
let get_str_arms = enums
|
||||
.keys()
|
||||
.map(|name| {
|
||||
let variant_name = (if name.is_empty() || name == "_unnamed" {
|
||||
"Unnamed"
|
||||
} else {
|
||||
name
|
||||
})
|
||||
.to_case(Case::Pascal);
|
||||
format!(" Self::{variant_name}(enm) => enm.get_str(prop),",)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
let iter_chain = enums
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, (name, listing))| {
|
||||
let variant_name = (if name.is_empty() || name == "_unnamed" {
|
||||
"Unnamed"
|
||||
} else {
|
||||
name
|
||||
})
|
||||
.to_case(Case::Pascal);
|
||||
let enum_name = listing.enum_name.to_case(Case::Pascal);
|
||||
if index == 0 {
|
||||
format!("{enum_name}::iter().map(|enm| Self::{variant_name}(enm))")
|
||||
} else {
|
||||
format!(".chain({enum_name}::iter().map(|enm| Self::{variant_name}(enm)))")
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
write!(
|
||||
writer,
|
||||
"pub enum BasicEnum {{\n\
|
||||
{variant_lines}
|
||||
}}\n\
|
||||
impl BasicEnum {{\n \
|
||||
pub fn get_value(&self) -> u32 {{\n \
|
||||
match self {{\n \
|
||||
{value_arms}\n \
|
||||
}}\n \
|
||||
}}\n\
|
||||
pub fn get_str(&self, prop: &str) -> Option<&'static str> {{\n \
|
||||
match self {{\n \
|
||||
{get_str_arms}\n \
|
||||
}}\n \
|
||||
}}\n\
|
||||
pub fn iter() -> impl std::iter::Iterator<Item = Self> {{\n \
|
||||
use strum::IntoEnumIterator;\n \
|
||||
{iter_chain}\n \
|
||||
}}
|
||||
}}\n\
|
||||
"
|
||||
)?;
|
||||
let arms = enums
|
||||
.iter()
|
||||
.flat_map(|(name, listing)| {
|
||||
let variant_name = (if name.is_empty() || name == "_unnamed" {
|
||||
"Unnamed"
|
||||
} else {
|
||||
name
|
||||
})
|
||||
.to_case(Case::Pascal);
|
||||
let name = if name == "_unnamed" {
|
||||
"".to_string()
|
||||
} else {
|
||||
name.clone()
|
||||
};
|
||||
let enum_name = listing.enum_name.to_case(Case::Pascal);
|
||||
listing.values.keys().map(move |variant| {
|
||||
let sep = if name.is_empty() { "" } else { "." };
|
||||
let pat = format!("{name}{sep}{variant}").to_lowercase();
|
||||
let variant = variant.to_case(Case::Pascal);
|
||||
format!("\"{pat}\" => Ok(Self::{variant_name}({enum_name}::{variant})),")
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n ");
|
||||
write!(
|
||||
writer,
|
||||
"\
|
||||
impl std::str::FromStr for BasicEnum {{\n \
|
||||
type Err = crate::errors::ParseError;\n \
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {{\n \
|
||||
let end = s.len();\n \
|
||||
match s {{\n \
|
||||
{arms}\n \
|
||||
_ => Err(crate::errors::ParseError{{ line: 0, start: 0, end, msg: format!(\"Unknown enum '{{}}'\", s) }})\n \
|
||||
}}\n \
|
||||
}}\n\
|
||||
}}\
|
||||
"
|
||||
)?;
|
||||
let display_arms = enums
|
||||
.keys()
|
||||
.map(|name| {
|
||||
let variant_name = (if name.is_empty() || name == "_unnamed" {
|
||||
"Unnamed"
|
||||
} else {
|
||||
name
|
||||
})
|
||||
.to_case(Case::Pascal);
|
||||
let name = if name == "_unnamed" {
|
||||
"".to_string()
|
||||
} else {
|
||||
name.clone()
|
||||
};
|
||||
let sep = if name.is_empty() || name == "_unnamed" {
|
||||
""
|
||||
} else {
|
||||
"."
|
||||
};
|
||||
let pat = format!("{name}{sep}{{}}");
|
||||
format!(" Self::{variant_name}(enm) => write!(f, \"{pat}\", enm),",)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n ");
|
||||
write!(
|
||||
writer,
|
||||
"\
|
||||
impl std::fmt::Display for BasicEnum {{\n \
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {{\n \
|
||||
match self {{\n \
|
||||
{display_arms}\n \
|
||||
}}\n \
|
||||
}}\n\
|
||||
}}\
|
||||
"
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn write_enum_listing<T: std::io::Write>(
|
||||
writer: &mut BufWriter<T>,
|
||||
enm: &crate::enums::EnumListing,
|
||||
) -> color_eyre::Result<()> {
|
||||
let max = enm
|
||||
.values
|
||||
.values()
|
||||
.map(|var| var.value)
|
||||
.max()
|
||||
.expect("enum should have max value");
|
||||
let min = enm
|
||||
.values
|
||||
.values()
|
||||
.map(|var| var.value)
|
||||
.min()
|
||||
.expect("enum should have min value");
|
||||
|
||||
if max < u8::MAX as i64 && min >= u8::MIN as i64 {
|
||||
let variants: Vec<_> = enm
|
||||
.values
|
||||
.iter()
|
||||
.map(|(n, var)| {
|
||||
let variant = ReprEnumVariant {
|
||||
value: var.value as u8,
|
||||
deprecated: var.deprecated,
|
||||
props: vec![("docs".to_owned(), var.description.to_owned())],
|
||||
};
|
||||
(n.clone(), variant)
|
||||
})
|
||||
.collect();
|
||||
write_repr_enum(
|
||||
writer,
|
||||
&enm.enum_name.to_case(Case::Pascal),
|
||||
&variants,
|
||||
true,
|
||||
)?;
|
||||
} else if max < u16::MAX as i64 && min >= u16::MIN as i64 {
|
||||
let variants: Vec<_> = enm
|
||||
.values
|
||||
.iter()
|
||||
.map(|(n, var)| {
|
||||
let variant = ReprEnumVariant {
|
||||
value: var.value as u16,
|
||||
deprecated: var.deprecated,
|
||||
props: vec![("docs".to_owned(), var.description.to_owned())],
|
||||
};
|
||||
(n.clone(), variant)
|
||||
})
|
||||
.collect();
|
||||
write_repr_enum(writer, &enm.enum_name, &variants, true)?;
|
||||
} else if max < u32::MAX as i64 && min >= u32::MIN as i64 {
|
||||
let variants: Vec<_> = enm
|
||||
.values
|
||||
.iter()
|
||||
.map(|(n, var)| {
|
||||
let variant = ReprEnumVariant {
|
||||
value: var.value as u32,
|
||||
deprecated: var.deprecated,
|
||||
props: vec![("docs".to_owned(), var.description.to_owned())],
|
||||
};
|
||||
(n.clone(), variant)
|
||||
})
|
||||
.collect();
|
||||
write_repr_enum(writer, &enm.enum_name, &variants, true)?;
|
||||
} else if max < i32::MAX as i64 && min >= i32::MIN as i64 {
|
||||
let variants: Vec<_> = enm
|
||||
.values
|
||||
.iter()
|
||||
.map(|(n, var)| {
|
||||
let variant = ReprEnumVariant {
|
||||
value: var.value as i32,
|
||||
deprecated: var.deprecated,
|
||||
props: vec![("docs".to_owned(), var.description.to_owned())],
|
||||
};
|
||||
(n.clone(), variant)
|
||||
})
|
||||
.collect();
|
||||
write_repr_enum(writer, &enm.enum_name, &variants, true)?;
|
||||
} else {
|
||||
let variants: Vec<_> = enm
|
||||
.values
|
||||
.iter()
|
||||
.map(|(n, var)| {
|
||||
let variant = ReprEnumVariant {
|
||||
value: var.value as i32,
|
||||
deprecated: var.deprecated,
|
||||
props: vec![("docs".to_owned(), var.description.to_owned())],
|
||||
};
|
||||
(n.clone(), variant)
|
||||
})
|
||||
.collect();
|
||||
write_repr_enum(writer, &enm.enum_name, &variants, true)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct ReprEnumVariant<P>
|
||||
where
|
||||
P: Display + FromStr,
|
||||
{
|
||||
pub value: P,
|
||||
pub deprecated: bool,
|
||||
pub props: Vec<(String, String)>,
|
||||
}
|
||||
|
||||
fn write_repr_enum_use_header<T: std::io::Write>(
|
||||
writer: &mut BufWriter<T>,
|
||||
) -> color_eyre::Result<()> {
|
||||
write!(
|
||||
writer,
|
||||
"use serde::{{Deserialize, Serialize}};\n\
|
||||
use strum::{{\n \
|
||||
AsRefStr, Display, EnumIter, EnumProperty, EnumString, FromRepr,\n\
|
||||
}};\n"
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_repr_enum<'a, T: std::io::Write, I, P>(
|
||||
writer: &mut BufWriter<T>,
|
||||
name: &str,
|
||||
variants: I,
|
||||
use_phf: bool,
|
||||
) -> color_eyre::Result<()>
|
||||
where
|
||||
P: Display + FromStr + 'a,
|
||||
I: IntoIterator<Item = &'a (String, ReprEnumVariant<P>)>,
|
||||
{
|
||||
let additional_strum = if use_phf { "#[strum(use_phf)]\n" } else { "" };
|
||||
let repr = std::any::type_name::<P>();
|
||||
write!(
|
||||
writer,
|
||||
"#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, EnumString, AsRefStr, EnumProperty, EnumIter, FromRepr, Serialize, Deserialize)]\n\
|
||||
{additional_strum}\
|
||||
#[repr({repr})]\n\
|
||||
pub enum {name} {{\n"
|
||||
)?;
|
||||
for (name, variant) in variants {
|
||||
let variant_name = name.replace('.', "").to_case(Case::Pascal);
|
||||
let serialize = vec![name.clone()];
|
||||
let serialize_str = serialize
|
||||
.into_iter()
|
||||
.map(|s| format!("serialize = \"{s}\""))
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ");
|
||||
let mut props = Vec::new();
|
||||
if variant.deprecated {
|
||||
props.push("deprecated = \"true\"".to_owned());
|
||||
}
|
||||
for (prop_name, prop_val) in &variant.props {
|
||||
props.push(format!("{prop_name} = r#\"{prop_val}\"#"));
|
||||
}
|
||||
let val = &variant.value;
|
||||
props.push(format!("value = \"{val}\""));
|
||||
let props_str = if !props.is_empty() {
|
||||
format!(", props( {} )", props.join(", "))
|
||||
} else {
|
||||
"".to_owned()
|
||||
};
|
||||
writeln!(
|
||||
writer,
|
||||
" #[strum({serialize_str}{props_str})] {variant_name} = {val}{repr},"
|
||||
)?;
|
||||
}
|
||||
writeln!(writer, "}}")?;
|
||||
Ok(())
|
||||
}
|
||||
216
xtask/src/generate/instructions.rs
Normal file
216
xtask/src/generate/instructions.rs
Normal file
@@ -0,0 +1,216 @@
|
||||
use convert_case::{Case, Casing};
|
||||
use std::{collections::BTreeMap, path::PathBuf};
|
||||
|
||||
use crate::{generate::utils, stationpedia};
|
||||
|
||||
pub fn generate_instructions(
|
||||
stationpedia: &stationpedia::Stationpedia,
|
||||
workspace: &std::path::Path,
|
||||
) -> color_eyre::Result<Vec<PathBuf>> {
|
||||
let instructions_path = workspace
|
||||
.join("ic10emu")
|
||||
.join("src")
|
||||
.join("vm")
|
||||
.join("instructions");
|
||||
if !instructions_path.exists() {
|
||||
std::fs::create_dir(&instructions_path)?;
|
||||
}
|
||||
let mut writer =
|
||||
std::io::BufWriter::new(std::fs::File::create(instructions_path.join("enums.rs"))?);
|
||||
write_instructions_enum(&mut writer, &stationpedia.script_commands)?;
|
||||
|
||||
let mut writer =
|
||||
std::io::BufWriter::new(std::fs::File::create(instructions_path.join("traits.rs"))?);
|
||||
|
||||
write_instruction_interface_trait(&mut writer)?;
|
||||
for (typ, info) in &stationpedia.script_commands {
|
||||
write_instruction_trait(&mut writer, (typ, info))?;
|
||||
}
|
||||
write_instruction_super_trait(&mut writer, &stationpedia.script_commands)?;
|
||||
|
||||
Ok(vec![
|
||||
instructions_path.join("enums.rs"),
|
||||
instructions_path.join("traits.rs"),
|
||||
])
|
||||
}
|
||||
|
||||
fn write_instructions_enum<T: std::io::Write>(
|
||||
writer: &mut T,
|
||||
instructions: &BTreeMap<String, stationpedia::Command>,
|
||||
) -> color_eyre::Result<()> {
|
||||
println!("Writing instruction Listings ...");
|
||||
|
||||
let mut instructions = instructions.clone();
|
||||
for (_, ref mut info) in instructions.iter_mut() {
|
||||
info.example = utils::strip_color(&info.example);
|
||||
}
|
||||
|
||||
write!(
|
||||
writer,
|
||||
"use serde::{{Deserialize, Serialize}};\n\
|
||||
use strum::{{\n \
|
||||
Display, EnumIter, EnumProperty, EnumString, FromRepr,\n\
|
||||
}};\n
|
||||
use crate::vm::object::traits::Programmable;\n\
|
||||
use crate::vm::instructions::traits::*;\n\
|
||||
"
|
||||
)?;
|
||||
|
||||
write!(
|
||||
writer,
|
||||
"#[derive(Debug, Display, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Serialize, Deserialize)]\n\
|
||||
#[derive(EnumIter, EnumString, EnumProperty, FromRepr)]\n\
|
||||
#[strum(use_phf, serialize_all = \"lowercase\")]\n\
|
||||
#[serde(rename_all = \"lowercase\")]\n\
|
||||
pub enum InstructionOp {{\n\
|
||||
"
|
||||
)?;
|
||||
writeln!(writer, " Nop,")?;
|
||||
for (name, info) in &instructions {
|
||||
let props_str = format!(
|
||||
"props( example = \"{}\", desc = \"{}\", operands = \"{}\" )",
|
||||
&info.example,
|
||||
&info.desc,
|
||||
count_operands(&info.example)
|
||||
);
|
||||
writeln!(
|
||||
writer,
|
||||
" #[strum({props_str})] {},",
|
||||
name.to_case(Case::Pascal)
|
||||
)?;
|
||||
}
|
||||
writeln!(writer, "}}")?;
|
||||
|
||||
write!(
|
||||
writer,
|
||||
"impl InstructionOp {{\n \
|
||||
pub fn num_operands(&self) -> usize {{\n \
|
||||
self.get_str(\"operands\").expect(\"instruction without operand property\").parse::<usize>().expect(\"invalid instruction operand property\")\n \
|
||||
}}\n\
|
||||
\n \
|
||||
pub fn execute<T>(\n \
|
||||
&self,\n \
|
||||
ic: &mut T,\n \
|
||||
vm: &crate::vm::VM,\n \
|
||||
operands: &[crate::vm::instructions::operands::Operand],\n \
|
||||
) -> Result<(), crate::errors::ICError>\n \
|
||||
where\n \
|
||||
T: Programmable,\n\
|
||||
{{\n \
|
||||
let num_operands = self.num_operands();\n \
|
||||
if operands.len() != num_operands {{\n \
|
||||
return Err(crate::errors::ICError::mismatch_operands(operands.len(), num_operands as u32));\n \
|
||||
}}\n \
|
||||
match self {{\n \
|
||||
Self::Nop => Ok(()),\n \
|
||||
"
|
||||
)?;
|
||||
|
||||
for (name, info) in instructions {
|
||||
let num_operands = count_operands(&info.example);
|
||||
let operands = (0..num_operands)
|
||||
.map(|i| format!("&operands[{}]", i))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
let trait_name = name.to_case(Case::Pascal);
|
||||
writeln!(
|
||||
writer,
|
||||
" Self::{trait_name} => ic.execute_{name}(vm, {operands}),",
|
||||
)?;
|
||||
}
|
||||
|
||||
write!(
|
||||
writer,
|
||||
" }}\
|
||||
}}\n\
|
||||
}}
|
||||
"
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_instruction_trait<T: std::io::Write>(
|
||||
writer: &mut T,
|
||||
instruction: (&str, &stationpedia::Command),
|
||||
) -> color_eyre::Result<()> {
|
||||
let (name, info) = instruction;
|
||||
let trait_name = format!("{}Instruction", name.to_case(Case::Pascal));
|
||||
let operands = operand_names(&info.example)
|
||||
.iter()
|
||||
.map(|name| {
|
||||
format!(
|
||||
"{}: &crate::vm::instructions::operands::Operand",
|
||||
name.to_case(Case::Snake)
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
let example = utils::strip_color(&info.example);
|
||||
write!(
|
||||
writer,
|
||||
"pub trait {trait_name}: IntegratedCircuit {{\n \
|
||||
/// {example} \n \
|
||||
fn execute_{name}(&mut self, vm: &crate::vm::VM, {operands}) -> Result<(), crate::errors::ICError>;\n\
|
||||
}}"
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn count_operands(example: &str) -> usize {
|
||||
example.split(' ').count() - 1
|
||||
}
|
||||
|
||||
fn operand_names(example: &str) -> Vec<String> {
|
||||
utils::strip_color(example)
|
||||
.split(' ')
|
||||
.skip(1)
|
||||
.map(|name| name.split(['?', '(']).next().unwrap().to_string())
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn write_instruction_interface_trait<T: std::io::Write>(writer: &mut T) -> color_eyre::Result<()> {
|
||||
write!(
|
||||
writer,
|
||||
"\
|
||||
use std::collections::BTreeMap;\n\
|
||||
use crate::vm::object::traits::{{Logicable, MemoryWritable, SourceCode}};\n\
|
||||
use crate::errors::ICError; \n\
|
||||
pub trait IntegratedCircuit: Logicable + MemoryWritable + SourceCode {{\n \
|
||||
fn get_instruciton_pointer(&self) -> usize;\n \
|
||||
fn set_next_instruction(&mut self, next_instruction: usize);\n \
|
||||
fn reset(&mut self);\n \
|
||||
fn get_real_target(&self, indirection: u32, target: u32) -> Result<f64, ICError>;\n \
|
||||
fn get_register(&self, indirection: u32, target: u32) -> Result<f64, ICError>;\n \
|
||||
fn set_register(&mut self, indirection: u32, target: u32, val: f64) -> Result<f64, ICError>;\n \
|
||||
fn set_return_address(&mut self, addr: f64);\n \
|
||||
fn push_stack(&mut self, val: f64) -> Result<f64, ICError>;\n \
|
||||
fn pop_stack(&mut self) -> Result<f64, ICError>;\n \
|
||||
fn peek_stack(&self) -> Result<f64, ICError>;\n \
|
||||
fn get_aliases(&self) -> &BTreeMap<String, crate::vm::instructions::operands::Operand>;\n \
|
||||
fn get_defines(&self) -> &BTreeMap<String, f64>;\n \
|
||||
fn get_lables(&self) -> &BTreeMap<String, u32>;\n\
|
||||
}}\n\
|
||||
"
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_instruction_super_trait<T: std::io::Write>(
|
||||
writer: &mut T,
|
||||
instructions: &BTreeMap<String, stationpedia::Command>,
|
||||
) -> color_eyre::Result<()> {
|
||||
let traits = instructions
|
||||
.keys()
|
||||
.map(|name| format!("{}Instruction", name.to_case(Case::Pascal)))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" + ");
|
||||
write!(
|
||||
writer,
|
||||
"\
|
||||
pub trait ICInstructable: {traits} {{}}\n\
|
||||
impl <T> ICInstructable for T where T: {traits} {{}}
|
||||
"
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
60
xtask/src/generate/utils.rs
Normal file
60
xtask/src/generate/utils.rs
Normal file
@@ -0,0 +1,60 @@
|
||||
use onig::{Captures, Regex, RegexOptions, Syntax};
|
||||
|
||||
pub fn strip_color(s: &str) -> String {
|
||||
let color_regex = Regex::with_options(
|
||||
r#"<color=(#?\w+)>((:?(?!<color=(?:#?\w+)>).)+?)</color>"#,
|
||||
RegexOptions::REGEX_OPTION_MULTILINE | RegexOptions::REGEX_OPTION_CAPTURE_GROUP,
|
||||
Syntax::default(),
|
||||
)
|
||||
.unwrap();
|
||||
let mut new = s.to_owned();
|
||||
loop {
|
||||
new = color_regex.replace_all(&new, |caps: &Captures| caps.at(2).unwrap_or("").to_string());
|
||||
if !color_regex.is_match(&new) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
new
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn color_to_heml(s: &str) -> String {
|
||||
let color_regex = Regex::with_options(
|
||||
r#"<color=(#?\w+)>((:?(?!<color=(?:#?\w+)>).)+?)</color>"#,
|
||||
RegexOptions::REGEX_OPTION_MULTILINE | RegexOptions::REGEX_OPTION_CAPTURE_GROUP,
|
||||
Syntax::default(),
|
||||
)
|
||||
.unwrap();
|
||||
let mut new = s.to_owned();
|
||||
loop {
|
||||
new = color_regex.replace_all(&new, |caps: &Captures| {
|
||||
format!(
|
||||
r#"<div style="color: {};">{}</div>"#,
|
||||
caps.at(1).unwrap_or(""),
|
||||
caps.at(2).unwrap_or("")
|
||||
)
|
||||
});
|
||||
if !color_regex.is_match(&new) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
new
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn strip_link(s: &str) -> String {
|
||||
let link_regex = Regex::with_options(
|
||||
r#"<link=(\w+)>(.+?)</link>"#,
|
||||
RegexOptions::REGEX_OPTION_MULTILINE | RegexOptions::REGEX_OPTION_CAPTURE_GROUP,
|
||||
Syntax::default(),
|
||||
)
|
||||
.unwrap();
|
||||
let mut new = s.to_owned();
|
||||
loop {
|
||||
new = link_regex.replace_all(&new, |caps: &Captures| caps.at(2).unwrap_or("").to_string());
|
||||
if !link_regex.is_match(&new) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
new
|
||||
}
|
||||
@@ -2,6 +2,10 @@ use std::process::{Command, ExitStatus};
|
||||
|
||||
use clap::{Parser, Subcommand};
|
||||
|
||||
mod enums;
|
||||
mod generate;
|
||||
mod stationpedia;
|
||||
|
||||
/// Helper program to start ic10emu and website.
|
||||
///
|
||||
/// Can be invoked as `cargo xtask <command>`
|
||||
@@ -44,11 +48,19 @@ enum Task {
|
||||
Deploy {},
|
||||
/// bump the cargo.toml and package,json versions
|
||||
Version {
|
||||
#[arg(last = true, default_value = "patch", value_parser = clap::builder::PossibleValuesParser::new(VALID_VERSION_TYPE))]
|
||||
#[arg(default_value = "patch", value_parser = clap::builder::PossibleValuesParser::new(VALID_VERSION_TYPE))]
|
||||
version: String,
|
||||
},
|
||||
/// update changelog
|
||||
Changelog {},
|
||||
Generate {
|
||||
#[arg()]
|
||||
/// Path to Stationeers installation. Used to locate "Stationpedia.json" and "Enums.json"
|
||||
/// generated by https://github.com/Ryex/StationeersStationpediaExtractor
|
||||
/// Otherwise looks for both files in `<workspace>` or `<workspace>/data`.
|
||||
/// Can also point directly at a folder containing the two files.
|
||||
path: Option<std::ffi::OsString>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(thiserror::Error)]
|
||||
@@ -57,6 +69,8 @@ enum Error {
|
||||
BuildFailed(String, String, std::process::ExitStatus),
|
||||
#[error("failed to run command `{0}`")]
|
||||
Command(String, #[source] std::io::Error),
|
||||
#[error("can not find `Stationpedia.json` and/or `Enums.json` at `{0}`")]
|
||||
BadStationeresPath(std::path::PathBuf),
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Error {
|
||||
@@ -75,7 +89,8 @@ impl std::fmt::Debug for Error {
|
||||
}
|
||||
|
||||
const VERSION: Option<&str> = option_env!("CARGO_PKG_VERSION");
|
||||
fn main() -> Result<(), Error> {
|
||||
fn main() -> color_eyre::Result<()> {
|
||||
color_eyre::install()?;
|
||||
let args = Args::parse();
|
||||
let workspace = {
|
||||
let out = Command::new("cargo")
|
||||
@@ -132,21 +147,78 @@ fn main() -> Result<(), Error> {
|
||||
cmd.args(["version", &version]).status().map_err(|e| {
|
||||
Error::Command(format!("{}", cmd.get_program().to_string_lossy()), e)
|
||||
})?;
|
||||
},
|
||||
Task::Changelog { } => {
|
||||
}
|
||||
Task::Changelog {} => {
|
||||
let mut cmd = Command::new("git-changelog");
|
||||
cmd.current_dir(&workspace);
|
||||
cmd.args([
|
||||
"-io", "CHANGELOG.md",
|
||||
"-t", "path:CHANGELOG.md.jinja",
|
||||
"-c", "conventional",
|
||||
"--bump", VERSION.unwrap_or("auto"),
|
||||
"-io",
|
||||
"CHANGELOG.md",
|
||||
"-t",
|
||||
"path:CHANGELOG.md.jinja",
|
||||
"-c",
|
||||
"conventional",
|
||||
"--bump",
|
||||
VERSION.unwrap_or("auto"),
|
||||
"--parse-refs",
|
||||
"--trailers"
|
||||
]).status().map_err(|e| {
|
||||
Error::Command(format!("{}", cmd.get_program().to_string_lossy()), e)
|
||||
})?;
|
||||
},
|
||||
"--trailers",
|
||||
])
|
||||
.status()
|
||||
.map_err(|e| Error::Command(format!("{}", cmd.get_program().to_string_lossy()), e))?;
|
||||
}
|
||||
Task::Generate { path } => {
|
||||
let path = match path {
|
||||
Some(path) => {
|
||||
let mut path = std::path::PathBuf::from(path);
|
||||
if path.exists()
|
||||
&& path
|
||||
.parent()
|
||||
.and_then(|p| p.file_name())
|
||||
.is_some_and(|p| p == "Stationeers")
|
||||
&& path.file_name().is_some_and(|name| {
|
||||
(std::env::consts::OS == "windows" && name == "rocketstation.exe")
|
||||
|| (name == "rocketstation")
|
||||
|| (name == "rocketstation_Data")
|
||||
})
|
||||
{
|
||||
path = path.parent().unwrap().to_path_buf();
|
||||
}
|
||||
if path.is_dir()
|
||||
&& path.file_name().is_some_and(|name| name == "Stationeers")
|
||||
&& path.join("Stationpedia").join("Stationpedia.json").exists()
|
||||
{
|
||||
path = path.join("Stationpedia");
|
||||
}
|
||||
if path.is_file()
|
||||
&& path
|
||||
.file_name()
|
||||
.is_some_and(|name| name == "Stationpedia.json")
|
||||
{
|
||||
path = path.parent().unwrap().to_path_buf();
|
||||
}
|
||||
path
|
||||
}
|
||||
None => {
|
||||
let mut path = workspace.clone();
|
||||
if path.join("data").join("Stationpedia.json").exists()
|
||||
&& path.join("data").join("Enums.json").exists()
|
||||
{
|
||||
path = path.join("data")
|
||||
}
|
||||
|
||||
path
|
||||
}
|
||||
};
|
||||
|
||||
if path.is_dir()
|
||||
&& path.join("Stationpedia.json").exists()
|
||||
&& path.join("Enums.json").exists()
|
||||
{
|
||||
generate::generate(&path, &workspace)?;
|
||||
} else {
|
||||
return Err(Error::BadStationeresPath(path).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
346
xtask/src/stationpedia.rs
Normal file
346
xtask/src/stationpedia.rs
Normal file
@@ -0,0 +1,346 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use serde_with::{serde_as, DisplayFromStr};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename = "Stationpedia", deny_unknown_fields)]
|
||||
pub struct Stationpedia {
|
||||
pub pages: Vec<Page>,
|
||||
pub reagents: BTreeMap<String, Reagent>,
|
||||
#[serde(rename = "scriptCommands")]
|
||||
pub script_commands: BTreeMap<String, Command>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl Stationpedia {
|
||||
pub fn lookup_prefab_name(&self, prefab_name: &'_ str) -> Option<&Page> {
|
||||
self.pages.iter().find(|p| p.prefab_name == prefab_name)
|
||||
}
|
||||
|
||||
pub fn lookup_key(&self, key: &str) -> Option<&Page> {
|
||||
self.pages.iter().find(|p| p.key == key)
|
||||
}
|
||||
|
||||
pub fn lookup_hash(&self, hash: i32) -> Option<&Page> {
|
||||
self.pages.iter().find(|p| p.prefab_hash == hash)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Reagent {
|
||||
#[serde(rename = "Hash")]
|
||||
pub hash: i64,
|
||||
#[serde(rename = "Unit")]
|
||||
pub unit: String,
|
||||
#[serde(rename = "Sources")]
|
||||
pub sources: Option<BTreeMap<String, f64>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Command {
|
||||
pub desc: String,
|
||||
pub example: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Page {
|
||||
#[serde(rename = "ConnectionInsert")]
|
||||
pub connection_insert: Vec<ConnectionInsert>,
|
||||
#[serde(rename = "ConstructedByKits")]
|
||||
pub constructs: Vec<Constructs>,
|
||||
#[serde(rename = "Description")]
|
||||
pub description: String,
|
||||
#[serde(rename = "Device")]
|
||||
pub device: Option<Device>,
|
||||
/// the item , if none then deprecated
|
||||
#[serde(rename = "Item")]
|
||||
pub item: Option<Item>,
|
||||
#[serde(rename = "Structure")]
|
||||
pub structure: Option<Structure>,
|
||||
#[serde(rename = "Key")]
|
||||
pub key: String,
|
||||
#[serde(rename = "LogicInfo")]
|
||||
pub logic_info: Option<LogicInfo>,
|
||||
#[serde(rename = "LogicInsert")]
|
||||
pub logic_insert: Vec<LogicInsert>,
|
||||
#[serde(rename = "LogicSlotInsert")]
|
||||
pub logic_slot_insert: Vec<LogicSlotInsert>,
|
||||
#[serde(rename = "Memory")]
|
||||
pub memory: Option<Memory>,
|
||||
#[serde(rename = "ModeInsert")]
|
||||
pub mode_insert: Vec<ModeInsert>,
|
||||
#[serde(rename = "PrefabHash")]
|
||||
pub prefab_hash: i32,
|
||||
#[serde(rename = "PrefabName")]
|
||||
pub prefab_name: String,
|
||||
#[serde(rename = "SlotInserts")]
|
||||
pub slot_inserts: Vec<SlotInsert>,
|
||||
#[serde(rename = "Title")]
|
||||
pub title: String,
|
||||
#[serde(rename = "TransmissionReceiver")]
|
||||
pub transmission_receiver: Option<bool>,
|
||||
#[serde(rename = "WirelessLogic")]
|
||||
pub wireless_logic: Option<bool>,
|
||||
#[serde(rename = "CircuitHolder")]
|
||||
pub circuit_holder: Option<bool>,
|
||||
#[serde(rename = "BasePowerDraw")]
|
||||
pub base_power_draw: Option<String>,
|
||||
#[serde(rename = "MaxPressure")]
|
||||
pub max_pressure: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Constructs {
|
||||
#[serde(rename = "NameOfThing")]
|
||||
pub name_of_thing: String,
|
||||
#[serde(rename = "PageLink")]
|
||||
pub page_link: String,
|
||||
#[serde(rename = "PrefabHash")]
|
||||
pub prefab_hash: i32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Structure {
|
||||
#[serde(rename = "SmallGrid")]
|
||||
pub small_grid: bool,
|
||||
#[serde(rename = "BuildStates")]
|
||||
pub build_states: BuildStates,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
pub struct BuildStates(pub Vec<BuildState>);
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct BuildState {
|
||||
#[serde(rename = "Tool")]
|
||||
pub tool: Option<Vec<Tool>>,
|
||||
#[serde(rename = "ToolExit")]
|
||||
pub tool_exit: Option<Vec<Tool>>,
|
||||
#[serde(rename = "CanManufacture", default)]
|
||||
pub can_manufacture: bool,
|
||||
#[serde(rename = "MachineTier")]
|
||||
pub machine_tier: Option<MachineTier>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
pub enum MachineTier {
|
||||
Undefined,
|
||||
TierOne,
|
||||
TierTwo,
|
||||
TierThree,
|
||||
Max,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Tool {
|
||||
#[serde(rename = "IsTool", default)]
|
||||
pub is_tool: bool,
|
||||
#[serde(rename = "PrefabName")]
|
||||
pub prefab_name: String,
|
||||
#[serde(rename = "Quantity")]
|
||||
pub quantity: Option<i64>,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct SlotInsert {
|
||||
#[serde(rename = "SlotIndex")]
|
||||
#[serde_as(as = "DisplayFromStr")]
|
||||
pub slot_index: u32,
|
||||
#[serde(rename = "SlotName")]
|
||||
pub slot_name: String,
|
||||
#[serde(rename = "SlotType")]
|
||||
pub slot_type: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct LogicInsert {
|
||||
#[serde(rename = "LogicAccessTypes")]
|
||||
pub logic_access_types: String,
|
||||
#[serde(rename = "LogicName")]
|
||||
pub logic_name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct LogicSlotInsert {
|
||||
#[serde(rename = "LogicAccessTypes")]
|
||||
pub logic_access_types: String,
|
||||
#[serde(rename = "LogicName")]
|
||||
pub logic_name: String,
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct ModeInsert {
|
||||
#[serde(rename = "LogicAccessTypes")]
|
||||
#[serde_as(as = "DisplayFromStr")]
|
||||
pub logic_access_types: u32,
|
||||
#[serde(rename = "LogicName")]
|
||||
pub logic_name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct ConnectionInsert {
|
||||
#[serde(rename = "LogicAccessTypes")]
|
||||
pub logic_access_types: String,
|
||||
#[serde(rename = "LogicName")]
|
||||
pub logic_name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct LogicInfo {
|
||||
#[serde(rename = "LogicSlotTypes")]
|
||||
pub logic_slot_types: BTreeMap<u32, LogicSlotTypes>,
|
||||
#[serde(rename = "LogicTypes")]
|
||||
pub logic_types: LogicTypes,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
pub struct LogicSlotTypes {
|
||||
#[serde(flatten)]
|
||||
pub slot_types: BTreeMap<String, String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
pub struct LogicTypes {
|
||||
#[serde(flatten)]
|
||||
pub types: BTreeMap<String, String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Memory {
|
||||
#[serde(rename = "Instructions")]
|
||||
pub instructions: Option<BTreeMap<String, Instruction>>,
|
||||
#[serde(rename = "MemoryAccess")]
|
||||
pub memory_access: String,
|
||||
#[serde(rename = "MemorySize")]
|
||||
pub memory_size: i64,
|
||||
#[serde(rename = "MemorySizeReadable")]
|
||||
pub memory_size_readable: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Instruction {
|
||||
#[serde(rename = "Description")]
|
||||
pub description: String,
|
||||
#[serde(rename = "Type")]
|
||||
pub type_: String,
|
||||
#[serde(rename = "Value")]
|
||||
pub value: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Item {
|
||||
#[serde(rename = "Consumable")]
|
||||
pub consumable: Option<bool>,
|
||||
#[serde(rename = "FilterType")]
|
||||
pub filter_type: Option<String>,
|
||||
#[serde(rename = "Ingredient")]
|
||||
pub ingredient: Option<bool>,
|
||||
#[serde(rename = "MaxQuantity")]
|
||||
pub max_quantity: Option<f64>,
|
||||
#[serde(rename = "Reagents")]
|
||||
pub reagents: Option<indexmap::IndexMap<String, f64>>,
|
||||
#[serde(rename = "SlotClass")]
|
||||
pub slot_class: String,
|
||||
#[serde(rename = "SortingClass")]
|
||||
pub sorting_class: String,
|
||||
#[serde(rename = "Recipes", default)]
|
||||
pub recipes: Vec<Recipe>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Recipe {
|
||||
#[serde(rename = "CreatorPrefabName")]
|
||||
pub creator_prefab_name: String,
|
||||
#[serde(rename = "TierName")]
|
||||
pub tier_name: String,
|
||||
#[serde(rename = "Time")]
|
||||
pub time: f64,
|
||||
#[serde(rename = "Energy")]
|
||||
pub energy: f64,
|
||||
#[serde(rename = "Temperature")]
|
||||
pub temperature: RecipeTemperature,
|
||||
#[serde(rename = "Pressure")]
|
||||
pub pressure: RecipePressure,
|
||||
#[serde(rename = "RequiredMix")]
|
||||
pub required_mix: RecipeGasMix,
|
||||
#[serde(rename = "CountTypes")]
|
||||
pub count_types: i64,
|
||||
#[serde(flatten)]
|
||||
pub reagents: indexmap::IndexMap<String, f64>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct RecipeTemperature {
|
||||
#[serde(rename = "Start")]
|
||||
pub start: f64,
|
||||
#[serde(rename = "Stop")]
|
||||
pub stop: f64,
|
||||
#[serde(rename = "IsValid")]
|
||||
pub is_valid: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct RecipePressure {
|
||||
#[serde(rename = "Start")]
|
||||
pub start: f64,
|
||||
#[serde(rename = "Stop")]
|
||||
pub stop: f64,
|
||||
#[serde(rename = "IsValid")]
|
||||
pub is_valid: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
pub struct RecipeGasMix {
|
||||
#[serde(rename = "Rule")]
|
||||
pub rule: i64,
|
||||
#[serde(rename = "IsAny")]
|
||||
pub is_any: bool,
|
||||
#[serde(rename = "IsAnyToRemove")]
|
||||
pub is_any_to_remove: bool,
|
||||
#[serde(flatten)]
|
||||
pub reagents: BTreeMap<String, f64>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
pub struct Device {
|
||||
#[serde(rename = "ConnectionList")]
|
||||
pub connection_list: Vec<(String, String)>,
|
||||
#[serde(rename = "DevicesLength")]
|
||||
pub devices_length: Option<i64>,
|
||||
#[serde(rename = "HasActivateState")]
|
||||
pub has_activate_state: bool,
|
||||
#[serde(rename = "HasAtmosphere")]
|
||||
pub has_atmosphere: bool,
|
||||
#[serde(rename = "HasColorState")]
|
||||
pub has_color_state: bool,
|
||||
#[serde(rename = "HasLockState")]
|
||||
pub has_lock_state: bool,
|
||||
#[serde(rename = "HasModeState")]
|
||||
pub has_mode_state: bool,
|
||||
#[serde(rename = "HasOnOffState")]
|
||||
pub has_on_off_state: bool,
|
||||
#[serde(rename = "HasOpenState")]
|
||||
pub has_open_state: bool,
|
||||
#[serde(rename = "HasReagents")]
|
||||
pub has_reagents: bool,
|
||||
}
|
||||
Reference in New Issue
Block a user