finished implimenting instrucitons
This commit is contained in:
90
ic10emu/Cargo.lock
generated
90
ic10emu/Cargo.lock
generated
@@ -71,10 +71,11 @@ dependencies = [
|
||||
"convert_case",
|
||||
"getrandom",
|
||||
"itertools",
|
||||
"phf",
|
||||
"phf 0.11.2",
|
||||
"phf_codegen",
|
||||
"rand",
|
||||
"regex",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
"thiserror",
|
||||
"web-time",
|
||||
@@ -122,13 +123,24 @@ version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259"
|
||||
dependencies = [
|
||||
"phf_macros",
|
||||
"phf_shared 0.10.0",
|
||||
"proc-macro-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"phf_shared 0.11.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -137,8 +149,18 @@ version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
"phf_generator 0.11.2",
|
||||
"phf_shared 0.11.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
|
||||
dependencies = [
|
||||
"phf_shared 0.10.0",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -147,10 +169,33 @@ version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"phf_shared 0.11.2",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_macros"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0"
|
||||
dependencies = [
|
||||
"phf_generator 0.10.0",
|
||||
"phf_shared 0.10.0",
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.11.2"
|
||||
@@ -166,6 +211,12 @@ version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.20+deprecated"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.79"
|
||||
@@ -255,6 +306,16 @@ version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29"
|
||||
dependencies = [
|
||||
"phf 0.10.1",
|
||||
"strum_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.26.2"
|
||||
@@ -265,7 +326,18 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -296,7 +368,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -338,7 +410,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.53",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -360,7 +432,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.53",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -17,6 +17,7 @@ itertools = "0.12.1"
|
||||
phf = "0.11.2"
|
||||
rand = "0.8.5"
|
||||
regex = "1.10.3"
|
||||
strum = { version = "0.26.2", features = ["derive", "phf", "strum_macros"] }
|
||||
strum_macros = "0.26.2"
|
||||
thiserror = "1.0.58"
|
||||
|
||||
|
||||
252
ic10emu/build.rs
252
ic10emu/build.rs
@@ -1,20 +1,90 @@
|
||||
use convert_case::{Case, Casing};
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
collections::{HashMap, HashSet},
|
||||
env,
|
||||
fmt::Display,
|
||||
fs::{self, File},
|
||||
io::{BufWriter, Write},
|
||||
path::Path,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
fn write_logictypes(logictypes_grammar: &mut HashSet<String>) {
|
||||
trait PrimitiveRepr {}
|
||||
impl PrimitiveRepr for u8 {}
|
||||
impl PrimitiveRepr for u16 {}
|
||||
impl PrimitiveRepr for u32 {}
|
||||
impl PrimitiveRepr for u64 {}
|
||||
impl PrimitiveRepr for u128 {}
|
||||
impl PrimitiveRepr for usize {}
|
||||
impl PrimitiveRepr for i8 {}
|
||||
impl PrimitiveRepr for i16 {}
|
||||
impl PrimitiveRepr for i32 {}
|
||||
impl PrimitiveRepr for i64 {}
|
||||
impl PrimitiveRepr for i128 {}
|
||||
impl PrimitiveRepr for isize {}
|
||||
|
||||
struct EnumVariant<P>
|
||||
where
|
||||
P: Display + FromStr,
|
||||
{
|
||||
pub aliases: Vec<String>,
|
||||
pub value: Option<P>,
|
||||
pub depricated: bool,
|
||||
}
|
||||
|
||||
fn write_repr_enum<T: std::io::Write, I, P>(
|
||||
writer: &mut BufWriter<T>,
|
||||
name: &str,
|
||||
variants: &I,
|
||||
use_phf: bool,
|
||||
) where
|
||||
P: Display + FromStr,
|
||||
for<'a> &'a I: IntoIterator<Item = (&'a String, &'a EnumVariant<P>)>,
|
||||
{
|
||||
let additional_strum = if use_phf { "#[strum(use_phf)]\n" } else { "" };
|
||||
write!(
|
||||
writer,
|
||||
"#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, Hash, EnumString, AsRefStr, EnumProperty, EnumIter)]\n\
|
||||
{additional_strum}\
|
||||
pub enum {name} {{\n"
|
||||
)
|
||||
.unwrap();
|
||||
for (name, variant) in variants.into_iter() {
|
||||
let variant_name = name.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 depricated_str = if variant.depricated {
|
||||
", depricated = \"true\"".to_string()
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
let props_str = if let Some(val) = &variant.value {
|
||||
format!(", props( value = \"{val}\"{depricated_str})")
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
write!(
|
||||
writer,
|
||||
" #[strum({serialize_str}{props_str})] {variant_name},\n"
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
write!(writer, "}}\n").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 logictype_lookup_map_builder = ::phf_codegen::Map::new();
|
||||
let mut logictypes: HashMap<String, EnumVariant<u8>> = HashMap::new();
|
||||
let l_infile = Path::new("data/logictypes.txt");
|
||||
let l_contents = fs::read_to_string(l_infile).unwrap();
|
||||
|
||||
@@ -23,14 +93,41 @@ fn write_logictypes(logictypes_grammar: &mut HashSet<String>) {
|
||||
let name = it.next().unwrap();
|
||||
let val_str = it.next().unwrap();
|
||||
let val: Option<u8> = val_str.parse().ok();
|
||||
let docs = it.next();
|
||||
let depricated = docs
|
||||
.map(|docs| docs.trim().to_uppercase() == "DEPRECATED")
|
||||
.unwrap_or(false);
|
||||
|
||||
logictypes_grammar.insert(name.to_string());
|
||||
if let Some(v) = val {
|
||||
logictype_lookup_map_builder.entry(name, &format!("{}u8", v));
|
||||
if let Some(val) = val {
|
||||
if let Some((_other_name, variant)) = logictypes
|
||||
.iter_mut()
|
||||
.find(|(_, variant)| variant.value == Some(val))
|
||||
{
|
||||
variant.aliases.push(name.to_string());
|
||||
variant.depricated = depricated;
|
||||
} else {
|
||||
logictypes.insert(
|
||||
name.to_string(),
|
||||
EnumVariant {
|
||||
aliases: Vec::new(),
|
||||
value: Some(val),
|
||||
depricated,
|
||||
},
|
||||
);
|
||||
}
|
||||
} else {
|
||||
logictypes.insert(
|
||||
name.to_string(),
|
||||
EnumVariant {
|
||||
aliases: Vec::new(),
|
||||
value: val,
|
||||
depricated,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let mut slotlogictype_lookup_map_builder = ::phf_codegen::Map::new();
|
||||
let mut slotlogictypes: HashMap<String, EnumVariant<u8>> = HashMap::new();
|
||||
let sl_infile = Path::new("data/slotlogictypes.txt");
|
||||
let sl_contents = fs::read_to_string(sl_infile).unwrap();
|
||||
|
||||
@@ -39,32 +136,50 @@ fn write_logictypes(logictypes_grammar: &mut HashSet<String>) {
|
||||
let name = it.next().unwrap();
|
||||
let val_str = it.next().unwrap();
|
||||
let val: Option<u8> = val_str.parse().ok();
|
||||
let docs = it.next();
|
||||
let depricated = docs
|
||||
.map(|docs| docs.trim().to_uppercase() == "DEPRECATED")
|
||||
.unwrap_or(false);
|
||||
|
||||
logictypes_grammar.insert(name.to_string());
|
||||
if let Some(v) = val {
|
||||
slotlogictype_lookup_map_builder.entry(name, &format!("{}u8", v));
|
||||
if let Some(val) = val {
|
||||
if let Some((_other_name, variant)) = slotlogictypes
|
||||
.iter_mut()
|
||||
.find(|(_, variant)| variant.value == Some(val))
|
||||
{
|
||||
variant.aliases.push(name.to_string());
|
||||
variant.depricated = depricated;
|
||||
} else {
|
||||
slotlogictypes.insert(
|
||||
name.to_string(),
|
||||
EnumVariant {
|
||||
aliases: Vec::new(),
|
||||
value: Some(val),
|
||||
depricated,
|
||||
},
|
||||
);
|
||||
}
|
||||
} else {
|
||||
slotlogictypes.insert(
|
||||
name.to_string(),
|
||||
EnumVariant {
|
||||
aliases: Vec::new(),
|
||||
value: val,
|
||||
depricated,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
write!(
|
||||
&mut writer,
|
||||
"pub(crate) const LOGIC_TYPE_LOOKUP: phf::Map<&'static str, u8> = {};\n",
|
||||
logictype_lookup_map_builder.build()
|
||||
)
|
||||
.unwrap();
|
||||
write_repr_enum(&mut writer, "LogicType", &logictypes, true);
|
||||
|
||||
println!("cargo:rerun-if-changed=data/logictypes.txt");
|
||||
|
||||
write!(
|
||||
&mut writer,
|
||||
"pub(crate) const SLOT_TYPE_LOOKUP: phf::Map<&'static str, u8> = {};\n",
|
||||
slotlogictype_lookup_map_builder.build()
|
||||
)
|
||||
.unwrap();
|
||||
write_repr_enum(&mut writer, "SlotLogicType", &slotlogictypes, true);
|
||||
|
||||
println!("cargo:rerun-if-changed=data/slotlogictypes.txt");
|
||||
}
|
||||
|
||||
fn write_enums(enums_grammar: &mut HashSet<String>) {
|
||||
fn write_enums() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
|
||||
let dest_path = Path::new(&out_dir).join("enums.rs");
|
||||
@@ -83,7 +198,6 @@ fn write_enums(enums_grammar: &mut HashSet<String>) {
|
||||
let val: Option<u8> = val_str.parse().ok();
|
||||
|
||||
if !check_set.contains(name) {
|
||||
enums_grammar.insert(name.to_string());
|
||||
check_set.insert(name);
|
||||
}
|
||||
|
||||
@@ -102,14 +216,14 @@ fn write_enums(enums_grammar: &mut HashSet<String>) {
|
||||
println!("cargo:rerun-if-changed=data/enums.txt");
|
||||
}
|
||||
|
||||
fn write_modes(logictypes_grammar: &mut HashSet<String>) {
|
||||
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 batchmode_lookup_map_builder = ::phf_codegen::Map::new();
|
||||
let mut batchmodes: HashMap<String, EnumVariant<u8>> = HashMap::new();
|
||||
let b_infile = Path::new("data/batchmodes.txt");
|
||||
let b_contents = fs::read_to_string(b_infile).unwrap();
|
||||
|
||||
@@ -119,13 +233,35 @@ fn write_modes(logictypes_grammar: &mut HashSet<String>) {
|
||||
let val_str = it.next().unwrap();
|
||||
let val: Option<u8> = val_str.parse().ok();
|
||||
|
||||
logictypes_grammar.insert(name.to_string());
|
||||
if let Some(v) = val {
|
||||
batchmode_lookup_map_builder.entry(name, &format!("{}u8", v));
|
||||
if let Some(val) = val {
|
||||
if let Some((_other_name, variant)) = batchmodes
|
||||
.iter_mut()
|
||||
.find(|(_, variant)| variant.value == Some(val))
|
||||
{
|
||||
variant.aliases.push(name.to_string());
|
||||
} else {
|
||||
batchmodes.insert(
|
||||
name.to_string(),
|
||||
EnumVariant {
|
||||
aliases: Vec::new(),
|
||||
value: Some(val),
|
||||
depricated: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
} else {
|
||||
batchmodes.insert(
|
||||
name.to_string(),
|
||||
EnumVariant {
|
||||
aliases: Vec::new(),
|
||||
value: val,
|
||||
depricated: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let mut reagentmode_lookup_map_builder = ::phf_codegen::Map::new();
|
||||
let mut reagentmodes: HashMap<String, EnumVariant<u8>> = HashMap::new();
|
||||
let r_infile = Path::new("data/reagentmodes.txt");
|
||||
let r_contents = fs::read_to_string(r_infile).unwrap();
|
||||
|
||||
@@ -135,32 +271,44 @@ fn write_modes(logictypes_grammar: &mut HashSet<String>) {
|
||||
let val_str = it.next().unwrap();
|
||||
let val: Option<u8> = val_str.parse().ok();
|
||||
|
||||
logictypes_grammar.insert(name.to_string());
|
||||
if let Some(v) = val {
|
||||
reagentmode_lookup_map_builder.entry(name, &format!("{}u8", v));
|
||||
if let Some(val) = val {
|
||||
if let Some((_other_name, variant)) = reagentmodes
|
||||
.iter_mut()
|
||||
.find(|(_, variant)| variant.value == Some(val))
|
||||
{
|
||||
variant.aliases.push(name.to_string());
|
||||
} else {
|
||||
reagentmodes.insert(
|
||||
name.to_string(),
|
||||
EnumVariant {
|
||||
aliases: Vec::new(),
|
||||
value: Some(val),
|
||||
depricated: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
} else {
|
||||
reagentmodes.insert(
|
||||
name.to_string(),
|
||||
EnumVariant {
|
||||
aliases: Vec::new(),
|
||||
value: val,
|
||||
depricated: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
write!(
|
||||
&mut writer,
|
||||
"pub(crate) const BATCH_MODE_LOOKUP: phf::Map<&'static str, u8> = {};\n",
|
||||
batchmode_lookup_map_builder.build()
|
||||
)
|
||||
.unwrap();
|
||||
write_repr_enum(&mut writer, "BatchMode", &batchmodes, false);
|
||||
|
||||
println!("cargo:rerun-if-changed=data/batchmodes.txt");
|
||||
|
||||
write!(
|
||||
&mut writer,
|
||||
"pub(crate) const REAGENT_MODE_LOOKUP: phf::Map<&'static str, u8> = {};\n",
|
||||
reagentmode_lookup_map_builder.build()
|
||||
)
|
||||
.unwrap();
|
||||
write_repr_enum(&mut writer, "ReagentMode", &reagentmodes, false);
|
||||
|
||||
println!("cargo:rerun-if-changed=data/reagentmodes.txt");
|
||||
}
|
||||
|
||||
fn write_constants(constants_grammar: &mut HashSet<String>) {
|
||||
fn write_constants() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
|
||||
let dest_path = Path::new(&out_dir).join("constants.rs");
|
||||
@@ -176,7 +324,6 @@ fn write_constants(constants_grammar: &mut HashSet<String>) {
|
||||
let name = it.next().unwrap();
|
||||
let constant = it.next().unwrap();
|
||||
|
||||
constants_grammar.insert(name.to_string());
|
||||
constants_lookup_map_builder.entry(name, constant);
|
||||
}
|
||||
|
||||
@@ -248,14 +395,11 @@ fn write_instructions_enum() {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut logictype_grammar = HashSet::new();
|
||||
let mut enums_grammar = HashSet::new();
|
||||
let mut constants_grammar = HashSet::new();
|
||||
// write_instructions();
|
||||
write_logictypes(&mut logictype_grammar);
|
||||
write_modes(&mut logictype_grammar);
|
||||
write_constants(&mut constants_grammar);
|
||||
write_enums(&mut enums_grammar);
|
||||
write_logictypes();
|
||||
write_modes();
|
||||
write_constants();
|
||||
write_enums();
|
||||
|
||||
write_instructions_enum();
|
||||
}
|
||||
|
||||
@@ -75,7 +75,6 @@ j VALUE
|
||||
jal VALUE
|
||||
jr VALUE
|
||||
l REGISTER DEVICE LOGIC_TYPE
|
||||
label NAME REGISTER_DEVICE
|
||||
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
|
||||
|
||||
@@ -11,14 +11,14 @@ Bypass None Bypasses some internal behavoiur of the atmospherics device.
|
||||
CelestialHash 242
|
||||
CelestialParentHash 250
|
||||
Channel None Channel on a cable network which should be considered volatile
|
||||
Channel0 165
|
||||
Channel1 166
|
||||
Channel2 167
|
||||
Channel3 168
|
||||
Channel4 169
|
||||
Channel5 170
|
||||
Channel6 171
|
||||
Channel7 172
|
||||
Channel0 165 Channel on a cable network which should be considered volatile
|
||||
Channel1 166 Channel on a cable network which should be considered volatile
|
||||
Channel2 167 Channel on a cable network which should be considered volatile
|
||||
Channel3 168 Channel on a cable network which should be considered volatile
|
||||
Channel4 169 Channel on a cable network which should be considered volatile
|
||||
Channel5 170 Channel on a cable network which should be considered volatile
|
||||
Channel6 171 Channel on a cable network which should be considered volatile
|
||||
Channel7 172 Channel on a cable network which should be considered volatile
|
||||
Charge 11 The current charge the device has
|
||||
ClearMemory 62 When set to 1, clears the counter memory (e.g. ExportCount). Will set itself back to 0 when actioned
|
||||
CollectableGoods 101
|
||||
@@ -45,9 +45,9 @@ EnvironmentEfficiency 104 The Environment Efficiency reported by the machine, as
|
||||
Error 4 1 if device is in error state, otherwise 0
|
||||
ExhaustVelocity 235
|
||||
ExportCount 63 How many items exported since last ClearMemory
|
||||
ExportQuantity None Total quantity of items exported by the device
|
||||
ExportSlotHash None DEPRECATED
|
||||
ExportSlotOccupant None DEPRECATED
|
||||
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
|
||||
@@ -61,9 +61,9 @@ 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 None Total quantity of items imported by the device
|
||||
ImportSlotHash None DEPRECATED
|
||||
ImportSlotOccupant None DEPRECATED
|
||||
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
|
||||
@@ -72,10 +72,10 @@ Lock 10 1 if device is locked, otherwise 0, can be set in most devices and preve
|
||||
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
|
||||
MinWattsToContact None Minimum required amount of watts from the dish hitting the target trader contact to start interrogating the contact
|
||||
MinWattsToContact 163 Minimum required amount of watts from the dish hitting the target trader contact to start interrogating the contact
|
||||
MineablesInQueue 96
|
||||
MineablesInVicinity 95
|
||||
MinimumWattsToContact 163
|
||||
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
|
||||
NextWeatherEventTime 97
|
||||
None None No description
|
||||
@@ -105,7 +105,7 @@ PlantHealth2 None DEPRECATED
|
||||
PlantHealth3 None DEPRECATED
|
||||
PlantHealth4 None DEPRECATED
|
||||
PositionX 76 The current position in X dimension in world coordinates
|
||||
PositionY None The current position in Y 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
|
||||
@@ -206,9 +206,9 @@ Rpm 155 The number of revolutions per minute that the device's spinning mechanis
|
||||
SemiMajorAxis 248
|
||||
Setting 12 A variable setting that can be read or written, depending on the device
|
||||
SettingInput 91
|
||||
SettingInputHash None The input setting for the device
|
||||
SettingInputHash 91 The input setting for the device
|
||||
SettingOutput 92
|
||||
SettingOutputHash None The output setting for the device
|
||||
SettingOutputHash 91 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
|
||||
SizeX 160 Size on the X (right) axis of the object in largeGrids (a largeGrid is 2meters)
|
||||
|
||||
@@ -4,6 +4,87 @@ use itertools::Itertools;
|
||||
use std::error::Error;
|
||||
use std::fmt::Display;
|
||||
use std::str::FromStr;
|
||||
use strum::EnumProperty;
|
||||
|
||||
pub mod generated {
|
||||
use super::ParseError;
|
||||
use crate::interpreter::ICError;
|
||||
use std::str::FromStr;
|
||||
use strum::AsRefStr;
|
||||
use strum::Display;
|
||||
use strum::EnumIter;
|
||||
use strum::EnumProperty;
|
||||
use strum::EnumString;
|
||||
use strum::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::<u8>().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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub use generated::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ParseError {
|
||||
@@ -57,12 +138,6 @@ impl ParseError {
|
||||
}
|
||||
}
|
||||
|
||||
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"));
|
||||
|
||||
pub fn parse(code: &str) -> Result<Vec<Line>, ParseError> {
|
||||
code.lines()
|
||||
.enumerate()
|
||||
@@ -203,10 +278,13 @@ pub enum Operand {
|
||||
},
|
||||
DeviceSpec {
|
||||
device: Device,
|
||||
channel: Option<u32>,
|
||||
connection: Option<u32>,
|
||||
},
|
||||
Number(Number),
|
||||
LogicType(LogicType),
|
||||
SlotLogicType(SlotLogicType),
|
||||
BatchMode(BatchMode),
|
||||
ReagentMode(ReagentMode),
|
||||
Identifier(Identifier),
|
||||
}
|
||||
|
||||
@@ -218,16 +296,34 @@ impl Operand {
|
||||
target,
|
||||
} => ic.get_register(*indirection, *target),
|
||||
&Operand::Number(num) => Ok(num.value()),
|
||||
&Operand::LogicType(lt) => Ok(lt.value),
|
||||
&Operand::LogicType(lt) => lt
|
||||
.get_str("value")
|
||||
.map(|val| val.parse::<u8>().unwrap() as f64)
|
||||
.ok_or(interpreter::ICError::TypeValueNotKnown),
|
||||
&Operand::SlotLogicType(slt) => slt
|
||||
.get_str("value")
|
||||
.map(|val| val.parse::<u8>().unwrap() as f64)
|
||||
.ok_or(interpreter::ICError::TypeValueNotKnown),
|
||||
&Operand::BatchMode(bm) => bm
|
||||
.get_str("value")
|
||||
.map(|val| val.parse::<u8>().unwrap() as f64)
|
||||
.ok_or(interpreter::ICError::TypeValueNotKnown),
|
||||
&Operand::ReagentMode(rm) => rm
|
||||
.get_str("value")
|
||||
.map(|val| val.parse::<u8>().unwrap() as f64)
|
||||
.ok_or(interpreter::ICError::TypeValueNotKnown),
|
||||
&Operand::Identifier(ident) => ic.get_ident_value(&ident.name),
|
||||
&Operand::DeviceSpec { .. } => Err(interpreter::ICError::DeviceNotValue),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn get_value_i64(&self, ic: &interpreter::IC, signed: bool) -> Result<i64, interpreter::ICError> {
|
||||
pub fn get_value_i64(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
signed: bool,
|
||||
) -> Result<i64, interpreter::ICError> {
|
||||
let val = self.get_value(ic)?;
|
||||
if val < -9.223372036854776E+18 {
|
||||
if val < -9.223372036854776E+18 {
|
||||
Err(interpreter::ICError::ShiftUnderflowI64)
|
||||
} else if val <= 9.223372036854776E+18 {
|
||||
Ok(interpreter::f64_to_i64(val, signed))
|
||||
@@ -252,15 +348,15 @@ impl Operand {
|
||||
ic: &interpreter::IC,
|
||||
) -> Result<(Option<u16>, Option<u32>), interpreter::ICError> {
|
||||
match &self {
|
||||
&Operand::DeviceSpec { device, channel } => match device {
|
||||
Device::Db => Ok((Some(ic.id), *channel)),
|
||||
&Operand::DeviceSpec { device, connection } => match device {
|
||||
Device::Db => Ok((Some(ic.id), *connection)),
|
||||
Device::Numbered(p) => {
|
||||
let dp = ic
|
||||
.pins
|
||||
.get(*p as usize)
|
||||
.ok_or(interpreter::ICError::DeviceIndexOutOfRange(*p as f64))
|
||||
.copied()?;
|
||||
Ok((dp, *channel))
|
||||
Ok((dp, *connection))
|
||||
}
|
||||
Device::Indirect {
|
||||
indirection,
|
||||
@@ -272,7 +368,7 @@ impl Operand {
|
||||
.get(val as usize)
|
||||
.ok_or(interpreter::ICError::DeviceIndexOutOfRange(val))
|
||||
.copied()?;
|
||||
Ok((dp, *channel))
|
||||
Ok((dp, *connection))
|
||||
}
|
||||
},
|
||||
&Operand::Identifier(id) => ic.get_ident_device_id(&id.name),
|
||||
@@ -322,20 +418,20 @@ impl FromStr for Operand {
|
||||
['d', rest @ ..] => match rest {
|
||||
['b'] => Ok(Operand::DeviceSpec {
|
||||
device: Device::Db,
|
||||
channel: None,
|
||||
connection: None,
|
||||
}),
|
||||
['b', ':', chan @ ..] => {
|
||||
if chan.into_iter().all(|c| c.is_digit(10)) {
|
||||
Ok(Operand::DeviceSpec {
|
||||
device: Device::Db,
|
||||
channel: Some(String::from_iter(chan).parse().unwrap()),
|
||||
connection: Some(String::from_iter(chan).parse().unwrap()),
|
||||
})
|
||||
} else {
|
||||
Err(ParseError {
|
||||
line: 0,
|
||||
start: 3,
|
||||
end: 3,
|
||||
msg: format!("Invalid device channel specifier"),
|
||||
msg: format!("Invalid device connection specifier"),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -346,25 +442,25 @@ impl FromStr for Operand {
|
||||
.take_while_ref(|c| c.is_digit(10))
|
||||
.collect::<String>();
|
||||
let target = target_str.parse::<u32>().ok();
|
||||
let channel = {
|
||||
let connection = {
|
||||
if rest_iter.peek() == Some(&&':') {
|
||||
// take off ':'
|
||||
rest_iter.next();
|
||||
let channel_str = rest_iter
|
||||
let connection_str = rest_iter
|
||||
.take_while_ref(|c| c.is_digit(10))
|
||||
.collect::<String>();
|
||||
let channel = channel_str.parse::<u32>().unwrap();
|
||||
let connection = connection_str.parse::<u32>().unwrap();
|
||||
let trailing = rest_iter.clone().collect::<Vec<_>>();
|
||||
if trailing.len() == 0 {
|
||||
Ok(Some(channel))
|
||||
Ok(Some(connection))
|
||||
} else {
|
||||
let start =
|
||||
2 + indirection + target_str.len() + 1 + channel_str.len();
|
||||
2 + indirection + target_str.len() + 1 + connection_str.len();
|
||||
Err(ParseError {
|
||||
line: 0,
|
||||
start,
|
||||
end: start,
|
||||
msg: format!("Invalid device channel specifier"),
|
||||
msg: format!("Invalid device connection specifier"),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
@@ -379,7 +475,7 @@ impl FromStr for Operand {
|
||||
indirection: indirection as u32,
|
||||
target,
|
||||
},
|
||||
channel,
|
||||
connection: connection,
|
||||
})
|
||||
} else {
|
||||
Err(ParseError {
|
||||
@@ -399,24 +495,24 @@ impl FromStr for Operand {
|
||||
.take_while_ref(|c| c.is_digit(10))
|
||||
.collect::<String>();
|
||||
let target = target_str.parse::<u32>().ok();
|
||||
let channel = {
|
||||
let connection = {
|
||||
if rest_iter.peek() == Some(&&':') {
|
||||
// take off ':'
|
||||
rest_iter.next();
|
||||
let channel_str = rest_iter
|
||||
let connection_str = rest_iter
|
||||
.take_while_ref(|c| c.is_digit(10))
|
||||
.collect::<String>();
|
||||
let channel = channel_str.parse::<u32>().unwrap();
|
||||
let connection = connection_str.parse::<u32>().unwrap();
|
||||
let trailing = rest_iter.clone().collect::<Vec<_>>();
|
||||
if trailing.len() == 0 {
|
||||
Ok(Some(channel))
|
||||
Ok(Some(connection))
|
||||
} else {
|
||||
let start = 1 + target_str.len() + 1 + channel_str.len();
|
||||
let start = 1 + target_str.len() + 1 + connection_str.len();
|
||||
Err(ParseError {
|
||||
line: 0,
|
||||
start,
|
||||
end: start,
|
||||
msg: format!("Invalid device channel specifier"),
|
||||
msg: format!("Invalid device connection specifier"),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
@@ -428,7 +524,7 @@ impl FromStr for Operand {
|
||||
if trailing.len() == 0 {
|
||||
Ok(Operand::DeviceSpec {
|
||||
device: Device::Numbered(target),
|
||||
channel,
|
||||
connection: connection,
|
||||
})
|
||||
} else {
|
||||
Err(ParseError {
|
||||
@@ -537,26 +633,14 @@ impl FromStr for Operand {
|
||||
Ok(Operand::Number(Number::Constant(*val)))
|
||||
} else if let Some(val) = ENUM_LOOKUP.get(s) {
|
||||
Ok(Operand::Number(Number::Enum(*val as f64)))
|
||||
} else if let Some(val) = LOGIC_TYPE_LOOKUP.get(s) {
|
||||
Ok(Operand::LogicType(LogicType {
|
||||
name: s.to_string(),
|
||||
value: *val as f64,
|
||||
}))
|
||||
} else if let Some(val) = SLOT_TYPE_LOOKUP.get(s) {
|
||||
Ok(Operand::LogicType(LogicType {
|
||||
name: s.to_string(),
|
||||
value: *val as f64,
|
||||
}))
|
||||
} else if let Some(val) = BATCH_MODE_LOOKUP.get(s) {
|
||||
Ok(Operand::LogicType(LogicType {
|
||||
name: s.to_string(),
|
||||
value: *val as f64,
|
||||
}))
|
||||
} else if let Some(val) = REAGENT_MODE_LOOKUP.get(s) {
|
||||
Ok(Operand::LogicType(LogicType {
|
||||
name: s.to_string(),
|
||||
value: *val as f64,
|
||||
}))
|
||||
} else if let Ok(lt) = LogicType::from_str(s) {
|
||||
Ok(Operand::LogicType(lt))
|
||||
} else if let Ok(slt) = SlotLogicType::from_str(s) {
|
||||
Ok(Operand::SlotLogicType(slt))
|
||||
} else if let Ok(bm) = BatchMode::from_str(s) {
|
||||
Ok(Operand::BatchMode(bm))
|
||||
} else if let Ok(rm) = ReagentMode::from_str(s) {
|
||||
Ok(Operand::ReagentMode(rm))
|
||||
} else {
|
||||
Ok(Operand::Identifier(s.parse::<Identifier>()?))
|
||||
}
|
||||
@@ -565,11 +649,11 @@ impl FromStr for Operand {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct LogicType {
|
||||
pub name: String,
|
||||
pub value: f64,
|
||||
}
|
||||
// #[derive(PartialEq, Debug)]
|
||||
// pub struct LogicType {
|
||||
// pub name: String,
|
||||
// pub value: f64,
|
||||
// }
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
pub struct Label {
|
||||
@@ -673,6 +757,7 @@ impl Number {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::generated::*;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
@@ -687,12 +772,9 @@ mod tests {
|
||||
operands: vec![
|
||||
Operand::DeviceSpec {
|
||||
device: Device::Numbered(0),
|
||||
channel: None,
|
||||
connection: None,
|
||||
},
|
||||
Operand::LogicType(LogicType {
|
||||
name: "Setting".to_string(),
|
||||
value: 12.0,
|
||||
},),
|
||||
Operand::LogicType(LogicType::Setting),
|
||||
Operand::Number(Number::Float(0.0)),
|
||||
],
|
||||
},),),
|
||||
@@ -800,7 +882,7 @@ mod tests {
|
||||
},),
|
||||
Operand::DeviceSpec {
|
||||
device: Device::Numbered(0),
|
||||
channel: None,
|
||||
connection: None,
|
||||
},
|
||||
],
|
||||
},),),
|
||||
@@ -812,7 +894,7 @@ mod tests {
|
||||
operands: vec![
|
||||
Operand::DeviceSpec {
|
||||
device: Device::Numbered(0),
|
||||
channel: None,
|
||||
connection: None,
|
||||
},
|
||||
Operand::Number(Number::Float(12.0)),
|
||||
Operand::Number(Number::Float(0.0)),
|
||||
@@ -871,12 +953,9 @@ mod tests {
|
||||
indirection: 0,
|
||||
target: 15,
|
||||
},
|
||||
channel: None,
|
||||
connection: None,
|
||||
},
|
||||
Operand::LogicType(LogicType {
|
||||
name: "RatioWater".to_string(),
|
||||
value: 19.0,
|
||||
},),
|
||||
Operand::LogicType(LogicType::RatioWater),
|
||||
],
|
||||
},),),
|
||||
comment: None,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,14 @@
|
||||
use core::f64;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
|
||||
mod tokens;
|
||||
mod grammar;
|
||||
mod interpreter;
|
||||
mod rand_mscorlib;
|
||||
mod tokens;
|
||||
|
||||
use grammar::{BatchMode, LogicType, ReagentMode, SlotLogicType};
|
||||
use interpreter::ICError;
|
||||
use itertools::Itertools;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
@@ -16,29 +18,47 @@ pub enum VMError {
|
||||
#[error("Device with id '{0}' does not have a IC Slot")]
|
||||
NoIC(u16),
|
||||
#[error("IC encoutered an error: {0}")]
|
||||
ICError(#[from] interpreter::ICError)
|
||||
ICError(#[from] ICError),
|
||||
#[error("Invalid network ID {0}")]
|
||||
InvalidNetwork(u16),
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum FieldType {
|
||||
Read,
|
||||
Write,
|
||||
ReadWrite
|
||||
ReadWrite,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LogicField {
|
||||
pub field_type: FieldType,
|
||||
pub value: f64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Slot {
|
||||
pub fields: HashMap<grammar::SlotLogicType, LogicField>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy)]
|
||||
pub enum Connection {
|
||||
CableNetwork(Option<u16>),
|
||||
#[default]
|
||||
Other,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Device {
|
||||
pub id: u16,
|
||||
pub fields: HashMap<u32, LogicField>,
|
||||
pub ic: Option<interpreter::IC>
|
||||
pub name: Option<String>,
|
||||
pub name_hash: Option<f64>,
|
||||
pub fields: HashMap<grammar::LogicType, LogicField>,
|
||||
pub slots: Vec<Slot>,
|
||||
pub reagents: HashMap<ReagentMode, HashMap<i32, f64>>,
|
||||
pub ic: Option<interpreter::IC>,
|
||||
pub connections: [Connection; 8],
|
||||
pub prefab_hash: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -70,8 +90,10 @@ impl IdSequenceGenerator {
|
||||
pub struct VM {
|
||||
pub ics: HashSet<u16>,
|
||||
pub devices: HashMap<u16, Device>,
|
||||
pub networks: Vec<Network>,
|
||||
pub networks: HashMap<u16, Network>,
|
||||
pub default_network: u16,
|
||||
id_gen: IdSequenceGenerator,
|
||||
network_id_gen: IdSequenceGenerator,
|
||||
random: crate::rand_mscorlib::Random,
|
||||
}
|
||||
|
||||
@@ -84,9 +106,57 @@ impl Default for Network {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum NetworkError {
|
||||
#[error("")]
|
||||
ChannelIndexOutOfRange,
|
||||
}
|
||||
|
||||
impl Network {
|
||||
pub fn contains(&self, ids: &[u16]) -> bool {
|
||||
ids.iter().all(|id| self.devices.contains(id))
|
||||
}
|
||||
|
||||
pub fn add(&mut self, id: u16) -> bool {
|
||||
self.devices.insert(id)
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, id: u16) -> bool {
|
||||
self.devices.remove(&id)
|
||||
}
|
||||
|
||||
pub fn set_channel(&mut self, chan: usize, val: f64) -> Result<f64, NetworkError> {
|
||||
if chan > 7 {
|
||||
Err(NetworkError::ChannelIndexOutOfRange)
|
||||
} else {
|
||||
let last = self.channels[chan];
|
||||
self.channels[chan] = val;
|
||||
Ok(last)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_channel(&self, chan: usize) -> Result<f64, NetworkError> {
|
||||
if chan > 7 {
|
||||
Err(NetworkError::ChannelIndexOutOfRange)
|
||||
} else {
|
||||
Ok(self.channels[chan])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Device {
|
||||
pub fn new(id: u16) -> Self {
|
||||
Device { id, fields: HashMap::new(), ic: None }
|
||||
Device {
|
||||
id,
|
||||
name: None,
|
||||
name_hash: None,
|
||||
fields: HashMap::new(),
|
||||
slots: Vec::new(),
|
||||
reagents: HashMap::new(),
|
||||
ic: None,
|
||||
connections: [Connection::default(); 8],
|
||||
prefab_hash: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_ic(id: u16) -> Self {
|
||||
@@ -94,32 +164,207 @@ impl Device {
|
||||
device.ic = Some(interpreter::IC::new(id));
|
||||
device
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_network_id(&self, connection: usize) -> Result<u16, ICError> {
|
||||
if connection >= 8 {
|
||||
Err(ICError::ConnecitonIndexOutOFRange(connection as u32))
|
||||
} else {
|
||||
if let Connection::CableNetwork(network_id) = self.connections[connection] {
|
||||
if let Some(network_id) = network_id {
|
||||
Ok(network_id)
|
||||
} else {
|
||||
Err(ICError::NetworkNotConnected(connection as u32))
|
||||
}
|
||||
} else {
|
||||
Err(ICError::NotDataConnection(connection as u32))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_field(&self, typ: grammar::LogicType) -> Result<f64, ICError> {
|
||||
if let Some(field) = self.fields.get(&typ) {
|
||||
if field.field_type == FieldType::Read || field.field_type == FieldType::ReadWrite {
|
||||
Ok(field.value)
|
||||
} else {
|
||||
Err(ICError::WriteOnlyField(typ.to_string()))
|
||||
}
|
||||
} else {
|
||||
Err(ICError::DeviceHasNoField(typ.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_field(&mut self, typ: grammar::LogicType, val: f64) -> Result<(), ICError> {
|
||||
if let Some(field) = self.fields.get_mut(&typ) {
|
||||
if field.field_type == FieldType::Write || field.field_type == FieldType::ReadWrite {
|
||||
field.value = val;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ICError::ReadOnlyField(typ.to_string()))
|
||||
}
|
||||
} else {
|
||||
Err(ICError::DeviceHasNoField(typ.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_slot_field(&self, index: f64, typ: grammar::SlotLogicType) -> Result<f64, ICError> {
|
||||
if let Some(field) = self
|
||||
.slots
|
||||
.get(index as usize)
|
||||
.ok_or(ICError::SlotIndexOutOfRange(index))?
|
||||
.fields
|
||||
.get(&typ)
|
||||
{
|
||||
if field.field_type == FieldType::Read || field.field_type == FieldType::ReadWrite {
|
||||
Ok(field.value)
|
||||
} else {
|
||||
Err(ICError::WriteOnlyField(typ.to_string()))
|
||||
}
|
||||
} else {
|
||||
Err(ICError::DeviceHasNoField(typ.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_slot_field(
|
||||
&mut self,
|
||||
index: f64,
|
||||
typ: grammar::SlotLogicType,
|
||||
val: f64,
|
||||
) -> Result<(), ICError> {
|
||||
if let Some(field) = self
|
||||
.slots
|
||||
.get_mut(index as usize)
|
||||
.ok_or(ICError::SlotIndexOutOfRange(index))?
|
||||
.fields
|
||||
.get_mut(&typ)
|
||||
{
|
||||
if field.field_type == FieldType::Write || field.field_type == FieldType::ReadWrite {
|
||||
field.value = val;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ICError::ReadOnlyField(typ.to_string()))
|
||||
}
|
||||
} else {
|
||||
Err(ICError::DeviceHasNoField(typ.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_reagent(&self, rm: &ReagentMode, reagent: f64) -> f64 {
|
||||
if let Some(mode) = self.reagents.get(rm) {
|
||||
if let Some(val) = mode.get(&(reagent as i32)) {
|
||||
return *val;
|
||||
}
|
||||
}
|
||||
0.0
|
||||
}
|
||||
}
|
||||
|
||||
impl VM {
|
||||
pub fn new() -> Self {
|
||||
let id_gen = IdSequenceGenerator::default();
|
||||
let mut network_id_gen = IdSequenceGenerator::default();
|
||||
let default_network = Network::default();
|
||||
let mut networks = HashMap::new();
|
||||
let default_network_key = network_id_gen.next();
|
||||
networks.insert(default_network_key, default_network);
|
||||
|
||||
let mut vm = VM {
|
||||
ics: HashSet::new(),
|
||||
devices: HashMap::new(),
|
||||
networks: vec![default_network],
|
||||
networks,
|
||||
default_network: default_network_key,
|
||||
id_gen,
|
||||
network_id_gen,
|
||||
random: crate::rand_mscorlib::Random::new(),
|
||||
};
|
||||
vm.add_ic();
|
||||
let _ = vm.add_ic(None);
|
||||
vm
|
||||
}
|
||||
|
||||
pub fn add_ic(&mut self) {
|
||||
let device = Device::with_ic(self.id_gen.next());
|
||||
self.ics.insert(device.id);
|
||||
self.devices.insert(device.id, device);
|
||||
fn new_device(&mut self) -> Device {
|
||||
Device::new(self.id_gen.next())
|
||||
}
|
||||
|
||||
fn new_ic(&mut self) -> Device {
|
||||
Device::with_ic(self.id_gen.next())
|
||||
}
|
||||
|
||||
pub fn add_device(&mut self, network: Option<u16>) -> Result<u16, VMError> {
|
||||
if let Some(n) = &network {
|
||||
if !self.networks.contains_key(n) {
|
||||
return Err(VMError::InvalidNetwork(*n));
|
||||
}
|
||||
}
|
||||
let mut device = self.new_device();
|
||||
if let Some(first_network) = device
|
||||
.connections
|
||||
.iter_mut()
|
||||
.filter_map(|c| {
|
||||
if let Connection::CableNetwork(c) = c {
|
||||
Some(c)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.next()
|
||||
{
|
||||
first_network.replace(if let Some(network) = network {
|
||||
network
|
||||
} else {
|
||||
self.default_network
|
||||
});
|
||||
}
|
||||
let id = device.id;
|
||||
self.devices.insert(id, device);
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
pub fn add_ic(&mut self, network: Option<u16>) -> Result<u16, VMError> {
|
||||
if let Some(n) = &network {
|
||||
if !self.networks.contains_key(n) {
|
||||
return Err(VMError::InvalidNetwork(*n));
|
||||
}
|
||||
}
|
||||
let mut device = self.new_ic();
|
||||
if let Some(first_network) = device
|
||||
.connections
|
||||
.iter_mut()
|
||||
.filter_map(|c| {
|
||||
if let Connection::CableNetwork(c) = c {
|
||||
Some(c)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.next()
|
||||
{
|
||||
first_network.replace(if let Some(network) = network {
|
||||
network
|
||||
} else {
|
||||
self.default_network
|
||||
});
|
||||
}
|
||||
let id = device.id;
|
||||
self.devices.insert(id, device);
|
||||
self.ics.insert(id);
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
pub fn add_network(&mut self) -> u16 {
|
||||
let next_id = self.network_id_gen.next();
|
||||
self.networks.insert(next_id, Network::default());
|
||||
next_id
|
||||
}
|
||||
|
||||
pub fn get_default_network(&mut self) -> &mut Network {
|
||||
self.networks.get_mut(&self.default_network).unwrap()
|
||||
}
|
||||
|
||||
pub fn get_network(&mut self, id: u16) -> Option<&mut Network> {
|
||||
self.networks.get_mut(&id)
|
||||
}
|
||||
|
||||
pub fn remove_ic(&mut self, id: u16) {
|
||||
if self.ics.remove(&id) {
|
||||
if self.ics.remove(&id) {
|
||||
self.devices.remove(&id);
|
||||
}
|
||||
}
|
||||
@@ -133,4 +378,294 @@ impl VM {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub fn get_device(&mut self, id: u16) -> Option<&mut Device> {
|
||||
self.devices.get_mut(&id)
|
||||
}
|
||||
|
||||
pub fn get_device_same_network(&mut self, source: u16, other: u16) -> Option<&mut Device> {
|
||||
if self.devices_on_same_network(&[source, other]) {
|
||||
self.get_device(other)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_network_channel(&self, id: usize, channel: usize) -> Result<f64, ICError> {
|
||||
let network = self
|
||||
.networks
|
||||
.get(&(id as u16))
|
||||
.ok_or(ICError::BadNetworkId(id as u32))?;
|
||||
Ok(network.channels[channel])
|
||||
}
|
||||
|
||||
pub fn set_network_channel(&mut self, id: usize, channel: usize, val: f64) -> Result<(), ICError> {
|
||||
let network = self
|
||||
.networks
|
||||
.get_mut(&(id as u16))
|
||||
.ok_or(ICError::BadNetworkId(id as u32))?;
|
||||
network.channels[channel] = val;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn devices_on_same_network(&self, ids: &[u16]) -> bool {
|
||||
for (_id, net) in self.networks.iter() {
|
||||
if net.contains(ids) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn set_batch_device_field(
|
||||
&mut self,
|
||||
source: u16,
|
||||
prefab: f64,
|
||||
typ: LogicType,
|
||||
val: f64,
|
||||
) -> Result<(), ICError> {
|
||||
let networks = &self.networks;
|
||||
self.devices
|
||||
.iter_mut()
|
||||
.map(|(id, device)| {
|
||||
if device.fields.get(&LogicType::PrefabHash).map(|f| f.value) == Some(prefab)
|
||||
&& networks
|
||||
.iter()
|
||||
.any(|(_net_id, net)| net.contains(&[source, *id]))
|
||||
{
|
||||
device.set_field(typ, val)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
.try_collect()
|
||||
}
|
||||
|
||||
pub fn set_batch_device_slot_field(
|
||||
&mut self,
|
||||
source: u16,
|
||||
prefab: f64,
|
||||
index: f64,
|
||||
typ: SlotLogicType,
|
||||
val: f64,
|
||||
) -> Result<(), ICError> {
|
||||
let networks = &self.networks;
|
||||
self.devices
|
||||
.iter_mut()
|
||||
.map(|(id, device)| {
|
||||
if device.fields.get(&LogicType::PrefabHash).map(|f| f.value) == Some(prefab)
|
||||
&& networks
|
||||
.iter()
|
||||
.any(|(_net_id, net)| net.contains(&[source, *id]))
|
||||
{
|
||||
device.set_slot_field(index, typ, val)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
.try_collect()
|
||||
}
|
||||
|
||||
pub fn set_batch_name_device_field(
|
||||
&mut self,
|
||||
source: u16,
|
||||
prefab: f64,
|
||||
name: f64,
|
||||
typ: LogicType,
|
||||
val: f64,
|
||||
) -> Result<(), ICError> {
|
||||
let networks = &self.networks;
|
||||
self.devices
|
||||
.iter_mut()
|
||||
.map(|(id, device)| {
|
||||
if device.fields.get(&LogicType::PrefabHash).map(|f| f.value) == Some(prefab)
|
||||
&& Some(name) == device.name_hash
|
||||
&& networks
|
||||
.iter()
|
||||
.any(|(_net_id, net)| net.contains(&[source, *id]))
|
||||
{
|
||||
device.set_field(typ, val)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
.try_collect()
|
||||
}
|
||||
|
||||
pub fn get_batch_device_field(
|
||||
&mut self,
|
||||
source: u16,
|
||||
prefab: f64,
|
||||
typ: LogicType,
|
||||
mode: BatchMode,
|
||||
) -> Result<f64, ICError> {
|
||||
let networks = &self.networks;
|
||||
let samples = self
|
||||
.devices
|
||||
.iter_mut()
|
||||
.map(|(id, device)| {
|
||||
if device.fields.get(&LogicType::PrefabHash).map(|f| f.value) == Some(prefab)
|
||||
&& networks
|
||||
.iter()
|
||||
.any(|(_net_id, net)| net.contains(&[source, *id]))
|
||||
{
|
||||
device.get_field(typ).map(|val| Some(val))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
})
|
||||
.collect::<Result<Vec<_>, ICError>>()?
|
||||
.into_iter()
|
||||
.filter_map(|val| {
|
||||
val.map(|val| if val.is_nan() { None } else { Some(val) })
|
||||
.flatten()
|
||||
})
|
||||
.collect_vec();
|
||||
match mode {
|
||||
BatchMode::Sum => Ok(samples.iter().sum()),
|
||||
BatchMode::Average => Ok(samples.iter().copied().sum::<f64>() / samples.len() as f64),
|
||||
BatchMode::Minimum => Ok(*samples
|
||||
.iter()
|
||||
.min_by(|a, b| a.partial_cmp(b).unwrap())
|
||||
.unwrap_or(&0.0)),
|
||||
BatchMode::Maximum => Ok(*samples
|
||||
.iter()
|
||||
.max_by(|a, b| a.partial_cmp(b).unwrap())
|
||||
.unwrap_or(&0.0)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_batch_name_device_field(
|
||||
&mut self,
|
||||
source: u16,
|
||||
prefab: f64,
|
||||
name: f64,
|
||||
typ: LogicType,
|
||||
mode: BatchMode,
|
||||
) -> Result<f64, ICError> {
|
||||
let networks = &self.networks;
|
||||
let samples = self
|
||||
.devices
|
||||
.iter_mut()
|
||||
.map(|(id, device)| {
|
||||
if device.fields.get(&LogicType::PrefabHash).map(|f| f.value) == Some(prefab)
|
||||
&& Some(name) == device.name_hash
|
||||
&& networks
|
||||
.iter()
|
||||
.any(|(_net_id, net)| net.contains(&[source, *id]))
|
||||
{
|
||||
device.get_field(typ).map(|val| Some(val))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
})
|
||||
.collect::<Result<Vec<_>, ICError>>()?
|
||||
.into_iter()
|
||||
.filter_map(|val| {
|
||||
val.map(|val| if val.is_nan() { None } else { Some(val) })
|
||||
.flatten()
|
||||
})
|
||||
.collect_vec();
|
||||
match mode {
|
||||
BatchMode::Sum => Ok(samples.iter().sum()),
|
||||
BatchMode::Average => Ok(samples.iter().copied().sum::<f64>() / samples.len() as f64),
|
||||
BatchMode::Minimum => Ok(*samples
|
||||
.iter()
|
||||
.min_by(|a, b| a.partial_cmp(b).unwrap())
|
||||
.unwrap_or(&0.0)),
|
||||
BatchMode::Maximum => Ok(*samples
|
||||
.iter()
|
||||
.max_by(|a, b| a.partial_cmp(b).unwrap())
|
||||
.unwrap_or(&0.0)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_batch_name_device_slot_field(
|
||||
&mut self,
|
||||
source: u16,
|
||||
prefab: f64,
|
||||
name: f64,
|
||||
index: f64,
|
||||
typ: SlotLogicType,
|
||||
mode: BatchMode,
|
||||
) -> Result<f64, ICError> {
|
||||
let networks = &self.networks;
|
||||
let samples = self
|
||||
.devices
|
||||
.iter_mut()
|
||||
.map(|(id, device)| {
|
||||
if device.fields.get(&LogicType::PrefabHash).map(|f| f.value) == Some(prefab)
|
||||
&& Some(name) == device.name_hash
|
||||
&& networks
|
||||
.iter()
|
||||
.any(|(_net_id, net)| net.contains(&[source, *id]))
|
||||
{
|
||||
device.get_slot_field(index, typ).map(|val| Some(val))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
})
|
||||
.collect::<Result<Vec<_>, ICError>>()?
|
||||
.into_iter()
|
||||
.filter_map(|val| {
|
||||
val.map(|val| if val.is_nan() { None } else { Some(val) })
|
||||
.flatten()
|
||||
})
|
||||
.collect_vec();
|
||||
match mode {
|
||||
BatchMode::Sum => Ok(samples.iter().sum()),
|
||||
BatchMode::Average => Ok(samples.iter().copied().sum::<f64>() / samples.len() as f64),
|
||||
BatchMode::Minimum => Ok(*samples
|
||||
.iter()
|
||||
.min_by(|a, b| a.partial_cmp(b).unwrap())
|
||||
.unwrap_or(&0.0)),
|
||||
BatchMode::Maximum => Ok(*samples
|
||||
.iter()
|
||||
.max_by(|a, b| a.partial_cmp(b).unwrap())
|
||||
.unwrap_or(&0.0)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_batch_device_slot_field(
|
||||
&mut self,
|
||||
source: u16,
|
||||
prefab: f64,
|
||||
index: f64,
|
||||
typ: SlotLogicType,
|
||||
mode: BatchMode,
|
||||
) -> Result<f64, ICError> {
|
||||
let networks = &self.networks;
|
||||
let samples = self
|
||||
.devices
|
||||
.iter_mut()
|
||||
.map(|(id, device)| {
|
||||
if device.fields.get(&LogicType::PrefabHash).map(|f| f.value) == Some(prefab)
|
||||
&& networks
|
||||
.iter()
|
||||
.any(|(_net_id, net)| net.contains(&[source, *id]))
|
||||
{
|
||||
device.get_slot_field(index, typ).map(|val| Some(val))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
})
|
||||
.collect::<Result<Vec<_>, ICError>>()?
|
||||
.into_iter()
|
||||
.filter_map(|val| {
|
||||
val.map(|val| if val.is_nan() { None } else { Some(val) })
|
||||
.flatten()
|
||||
})
|
||||
.collect_vec();
|
||||
match mode {
|
||||
BatchMode::Sum => Ok(samples.iter().sum()),
|
||||
BatchMode::Average => Ok(samples.iter().copied().sum::<f64>() / samples.len() as f64),
|
||||
BatchMode::Minimum => Ok(*samples
|
||||
.iter()
|
||||
.min_by(|a, b| a.partial_cmp(b).unwrap())
|
||||
.unwrap_or(&0.0)),
|
||||
BatchMode::Maximum => Ok(*samples
|
||||
.iter()
|
||||
.max_by(|a, b| a.partial_cmp(b).unwrap())
|
||||
.unwrap_or(&0.0)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
92
ic10emu_wasm/Cargo.lock
generated
92
ic10emu_wasm/Cargo.lock
generated
@@ -80,7 +80,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -139,10 +139,11 @@ dependencies = [
|
||||
"convert_case",
|
||||
"getrandom",
|
||||
"itertools",
|
||||
"phf",
|
||||
"phf 0.11.2",
|
||||
"phf_codegen",
|
||||
"rand",
|
||||
"regex",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
"thiserror",
|
||||
"web-time",
|
||||
@@ -203,13 +204,24 @@ version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259"
|
||||
dependencies = [
|
||||
"phf_macros",
|
||||
"phf_shared 0.10.0",
|
||||
"proc-macro-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"phf_shared 0.11.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -218,8 +230,18 @@ version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
"phf_generator 0.11.2",
|
||||
"phf_shared 0.11.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
|
||||
dependencies = [
|
||||
"phf_shared 0.10.0",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -228,10 +250,33 @@ version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"phf_shared 0.11.2",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_macros"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0"
|
||||
dependencies = [
|
||||
"phf_generator 0.10.0",
|
||||
"phf_shared 0.10.0",
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.11.2"
|
||||
@@ -259,6 +304,12 @@ version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.20+deprecated"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.79"
|
||||
@@ -357,6 +408,16 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29"
|
||||
dependencies = [
|
||||
"phf 0.10.1",
|
||||
"strum_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.26.2"
|
||||
@@ -367,7 +428,18 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -398,7 +470,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -440,7 +512,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.53",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -475,7 +547,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.53",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user