@@ -44,13 +44,15 @@ fn write_repr_enum<'a, T: std::io::Write, I, P>(
|
||||
.map(|s| format!("serialize = \"{s}\""))
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ");
|
||||
let deprecated_str = if variant.deprecated {
|
||||
", deprecated = \"true\"".to_owned()
|
||||
} else {
|
||||
"".to_owned()
|
||||
};
|
||||
let props_str = if let Some(val) = &variant.value {
|
||||
format!(", props( value = \"{val}\"{deprecated_str})")
|
||||
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()
|
||||
};
|
||||
@@ -70,7 +72,7 @@ fn write_logictypes() {
|
||||
let output_file = File::create(dest_path).unwrap();
|
||||
let mut writer = BufWriter::new(&output_file);
|
||||
|
||||
let mut logictypes: Vec<(String, EnumVariant<u8>)> = Vec::new();
|
||||
let mut logictypes: Vec<(String, EnumVariant<u16>)> = Vec::new();
|
||||
let l_infile = Path::new("data/logictypes.txt");
|
||||
let l_contents = fs::read_to_string(l_infile).unwrap();
|
||||
|
||||
@@ -78,7 +80,7 @@ fn write_logictypes() {
|
||||
let mut it = line.splitn(3, ' ');
|
||||
let name = it.next().unwrap();
|
||||
let val_str = it.next().unwrap();
|
||||
let val: Option<u8> = val_str.parse().ok();
|
||||
let val: Option<u16> = val_str.parse().ok();
|
||||
let docs = it.next();
|
||||
let deprecated = docs
|
||||
.map(|docs| docs.trim().to_uppercase() == "DEPRECATED")
|
||||
|
||||
@@ -7,18 +7,16 @@ AutoLand 226 Engages the automatic landing algorithm. The rocket will automatica
|
||||
AutoShutOff 218 Turns off all devices in the rocket upon reaching destination
|
||||
Bpm 103 Bpm
|
||||
BurnTimeRemaining 225 Estimated time in seconds until fuel is depleted. Calculated based on current fuel usage.
|
||||
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 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
|
||||
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
|
||||
@@ -92,7 +90,6 @@ OperationalTemperatureEfficiency 150 How the input pipe's temperature effects th
|
||||
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
|
||||
OverShootTarget None How far is the landing rocket going to overshoot its landing target at its current thrust. Expressed as a negative value in meters. ensure this is at zero by the time a rocket lands or risk total loss of rocket.
|
||||
PassedMoles 234
|
||||
Plant 68 Performs the planting action for any plant based machinery
|
||||
PlantEfficiency1 52 DEPRECATED
|
||||
@@ -228,7 +225,6 @@ SizeX 160 Size on the X (right) axis of the object in largeGrids (a largeGrid is
|
||||
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
|
||||
SolarConstant None Solar constant of the world
|
||||
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
|
||||
@@ -257,7 +253,6 @@ 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
|
||||
Unknown None No description available
|
||||
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
|
||||
|
||||
@@ -8,7 +8,7 @@ import xml.etree.ElementTree as ET
|
||||
from collections import defaultdict
|
||||
from itertools import chain
|
||||
from pathlib import Path
|
||||
|
||||
from typing import Any # type:ignore[reportAny]
|
||||
|
||||
def intOrNone(val: str):
|
||||
try:
|
||||
@@ -219,23 +219,28 @@ def extract_data(install_path: Path, data_path: Path, language: str):
|
||||
logic_types_path = Path("data") / "logictypes.txt"
|
||||
with logic_types_path.open(mode="w") as f:
|
||||
for t, (v, help) in sorted(logictypes.items()):
|
||||
_ = f.write(f"{t} {v} {help.replace("\r", "").replace("\n", "\\n")}\n")
|
||||
if v is not None:
|
||||
_ = f.write(f"{t} {v} {help.replace("\r", "").replace("\n", "\\n")}\n")
|
||||
slot_logic_types_path = Path("data") / "slotlogictypes.txt"
|
||||
with slot_logic_types_path.open(mode="w") as f:
|
||||
for t, (v, help) in sorted(slotlogictypes.items()):
|
||||
_ = f.write(f"{t} {v} {help.replace("\r", "").replace("\n", "\\n")}\n")
|
||||
if v is not None:
|
||||
_ = f.write(f"{t} {v} {help.replace("\r", "").replace("\n", "\\n")}\n")
|
||||
batch_modes_path = Path("data") / "batchmodes.txt"
|
||||
with batch_modes_path.open(mode="w") as f:
|
||||
for t, (v, help) in sorted(batchmodes.items()):
|
||||
_ = f.write(f"{t} {v} {help.replace("\r", "").replace("\n", "\\n")}\n")
|
||||
if v is not None:
|
||||
_ = f.write(f"{t} {v} {help.replace("\r", "").replace("\n", "\\n")}\n")
|
||||
reagent_modes_path = Path("data") / "reagentmodes.txt"
|
||||
with reagent_modes_path.open(mode="w") as f:
|
||||
for t, (v, help) in sorted(reagentmodes.items()):
|
||||
_ = f.write(f"{t} {v} {help.replace("\r", "").replace("\n", "\\n")}\n")
|
||||
if v is not None:
|
||||
_ = f.write(f"{t} {v} {help.replace("\r", "").replace("\n", "\\n")}\n")
|
||||
enums_path = Path("data") / "enums.txt"
|
||||
with enums_path.open(mode="w") as f:
|
||||
for name, (val, help) in sorted(enums.items()):
|
||||
_ = f.write(f"{name} {val} {help.replace("\r", "").replace("\n", "\\n")}\n")
|
||||
if val is not None:
|
||||
_ = f.write(f"{name} {val} {help.replace("\r", "").replace("\n", "\\n")}\n")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -347,11 +347,13 @@ pub enum Operand {
|
||||
RegisterSpec(RegisterSpec),
|
||||
DeviceSpec(DeviceSpec),
|
||||
Number(Number),
|
||||
LogicType(LogicType),
|
||||
SlotLogicType(SlotLogicType),
|
||||
LogicOrSlotLogicType(LogicType, SlotLogicType),
|
||||
BatchMode(BatchMode),
|
||||
ReagentMode(ReagentMode),
|
||||
Type {
|
||||
logic_type: Option<LogicType>,
|
||||
slot_logic_type: Option<SlotLogicType>,
|
||||
batch_mode: Option<BatchMode>,
|
||||
reagent_mode: Option<ReagentMode>,
|
||||
identifier: Identifier,
|
||||
},
|
||||
Identifier(Identifier),
|
||||
}
|
||||
|
||||
@@ -368,27 +370,49 @@ impl Operand {
|
||||
target,
|
||||
}) => ic.get_register(indirection, target),
|
||||
Operand::Number(num) => Ok(num.value()),
|
||||
Operand::LogicType(lt) => lt
|
||||
.get_str("value")
|
||||
.map(|val| val.parse::<u16>().unwrap() as f64)
|
||||
.ok_or(interpreter::ICError::TypeValueNotKnown),
|
||||
Operand::SlotLogicType(slt) => slt
|
||||
.get_str("value")
|
||||
.map(|val| val.parse::<u16>().unwrap() as f64)
|
||||
.ok_or(interpreter::ICError::TypeValueNotKnown),
|
||||
// default to using LogicType when converting to value
|
||||
Operand::LogicOrSlotLogicType(lt, _) => lt
|
||||
.get_str("value")
|
||||
.map(|val| val.parse::<u16>().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::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()))
|
||||
}
|
||||
@@ -400,6 +424,49 @@ impl Operand {
|
||||
}
|
||||
}
|
||||
|
||||
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()),
|
||||
_ => {
|
||||
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,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<i32, interpreter::ICError> {
|
||||
match self {
|
||||
Self::Number(num) => Ok(num.value_i64() 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,
|
||||
@@ -462,39 +529,6 @@ impl Operand {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_value_i64(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
signed: bool,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<i64, interpreter::ICError> {
|
||||
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,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<i32, interpreter::ICError> {
|
||||
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_logic_type(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
@@ -502,8 +536,10 @@ impl Operand {
|
||||
index: u32,
|
||||
) -> Result<LogicType, ICError> {
|
||||
match &self {
|
||||
Operand::LogicType(lt) => Ok(*lt),
|
||||
Operand::LogicOrSlotLogicType(lt, _slt) => Ok(*lt),
|
||||
Operand::Type {
|
||||
logic_type: Some(lt),
|
||||
..
|
||||
} => Ok(*lt),
|
||||
_ => LogicType::try_from(self.as_value(ic, inst, index)?),
|
||||
}
|
||||
}
|
||||
@@ -515,15 +551,47 @@ impl Operand {
|
||||
index: u32,
|
||||
) -> Result<SlotLogicType, ICError> {
|
||||
match &self {
|
||||
Operand::SlotLogicType(slt) => Ok(*slt),
|
||||
Operand::LogicOrSlotLogicType(_lt, slt) => Ok(*slt),
|
||||
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::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) {
|
||||
@@ -723,7 +791,7 @@ impl FromStr for Operand {
|
||||
let num_str = rest_iter
|
||||
.take_while_ref(|c| c.is_ascii_hexdigit())
|
||||
.collect::<String>();
|
||||
let num = i64::from_str_radix(&num_str, 16).unwrap() as f64;
|
||||
let num = i64::from_str_radix(&num_str, 16).unwrap();
|
||||
if rest_iter.next().is_none() {
|
||||
Ok(Operand::Number(Number::Hexadecimal(num)))
|
||||
} else {
|
||||
@@ -740,7 +808,7 @@ impl FromStr for Operand {
|
||||
let num_str = rest_iter
|
||||
.take_while_ref(|c| c.is_digit(2))
|
||||
.collect::<String>();
|
||||
let num = i64::from_str_radix(&num_str, 2).unwrap() as f64;
|
||||
let num = i64::from_str_radix(&num_str, 2).unwrap();
|
||||
if rest_iter.next().is_none() {
|
||||
Ok(Operand::Number(Number::Binary(num)))
|
||||
} else {
|
||||
@@ -798,24 +866,23 @@ impl FromStr for Operand {
|
||||
Ok(Operand::Number(Number::Enum(
|
||||
val.get_str("value").unwrap().parse().unwrap(),
|
||||
)))
|
||||
} else if let Ok(lt) = LogicType::from_str(s) {
|
||||
if let Ok(slt) = SlotLogicType::from_str(s) {
|
||||
Ok(Operand::LogicOrSlotLogicType(lt, slt))
|
||||
} else {
|
||||
Ok(Operand::LogicType(lt))
|
||||
}
|
||||
} else if let Ok(slt) = SlotLogicType::from_str(s) {
|
||||
if let Ok(lt) = LogicType::from_str(s) {
|
||||
Ok(Operand::LogicOrSlotLogicType(lt, slt))
|
||||
} else {
|
||||
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>()?))
|
||||
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 identifier = Identifier::from_str(s)?;
|
||||
if lt.is_some() || slt.is_some() || bm.is_some() || rm.is_some() {
|
||||
Ok(Operand::Type {
|
||||
logic_type: lt,
|
||||
slot_logic_type: slt,
|
||||
batch_mode: bm,
|
||||
reagent_mode: rm,
|
||||
identifier,
|
||||
})
|
||||
} else {
|
||||
Ok(Operand::Identifier(identifier))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -865,12 +932,10 @@ impl Display for Operand {
|
||||
Operand::Number(number) => match number {
|
||||
Number::Float(_) => Display::fmt(&number.value(), f),
|
||||
Number::Hexadecimal(n) => {
|
||||
// FIXME: precision loss here, maybe we should track the source i64?
|
||||
write!(f, "${:x}", *n as i64)
|
||||
write!(f, "${:x}", *n)
|
||||
}
|
||||
Number::Binary(n) => {
|
||||
// FIXME: precision loss here, maybe we should track the source i64?
|
||||
write!(f, "%{:b}", *n as i64)
|
||||
write!(f, "%{:b}", *n)
|
||||
}
|
||||
Number::Constant(c) => {
|
||||
dbg!(c);
|
||||
@@ -895,11 +960,7 @@ impl Display for Operand {
|
||||
Display::fmt(&number.value(), f)
|
||||
}
|
||||
},
|
||||
Operand::LogicType(logic) => Display::fmt(logic, f),
|
||||
Operand::SlotLogicType(slot_logic) => Display::fmt(slot_logic, f),
|
||||
Operand::LogicOrSlotLogicType(logic, _) => Display::fmt(logic, f),
|
||||
Operand::BatchMode(batch_mode) => Display::fmt(batch_mode, f),
|
||||
Operand::ReagentMode(reagent_mode) => Display::fmt(reagent_mode, f),
|
||||
Operand::Type { identifier, .. } => Display::fmt(&identifier, f),
|
||||
Operand::Identifier(ident) => Display::fmt(&ident, f),
|
||||
}
|
||||
}
|
||||
@@ -987,8 +1048,8 @@ impl Display for Identifier {
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum Number {
|
||||
Float(f64),
|
||||
Binary(f64),
|
||||
Hexadecimal(f64),
|
||||
Binary(i64),
|
||||
Hexadecimal(i64),
|
||||
Constant(f64),
|
||||
String(String),
|
||||
Enum(f64),
|
||||
@@ -997,14 +1058,19 @@ pub enum Number {
|
||||
impl Number {
|
||||
pub fn value(&self) -> f64 {
|
||||
match self {
|
||||
Number::Enum(val)
|
||||
| Number::Float(val)
|
||||
| Number::Binary(val)
|
||||
| Number::Constant(val)
|
||||
| Number::Hexadecimal(val) => *val,
|
||||
Number::Enum(val) | Number::Float(val) | Number::Constant(val) => *val,
|
||||
|
||||
Number::Binary(val) | Number::Hexadecimal(val) => *val as f64,
|
||||
Number::String(s) => const_crc32::crc32(s.as_bytes()) as i32 as f64,
|
||||
}
|
||||
}
|
||||
pub fn value_i64(&self) -> i64 {
|
||||
match self {
|
||||
Number::Enum(val) | Number::Float(val) | Number::Constant(val) => *val as i64,
|
||||
Number::Binary(val) | Number::Hexadecimal(val) => *val,
|
||||
Number::String(s) => const_crc32::crc32(s.as_bytes()) as i32 as i64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -1036,7 +1102,15 @@ mod tests {
|
||||
device: Device::Numbered(0),
|
||||
connection: None,
|
||||
}),
|
||||
Operand::LogicType(LogicType::Setting),
|
||||
Operand::Type {
|
||||
logic_type: Some(LogicType::Setting),
|
||||
slot_logic_type: None,
|
||||
batch_mode: None,
|
||||
reagent_mode: None,
|
||||
identifier: Identifier {
|
||||
name: "Setting".to_owned(),
|
||||
},
|
||||
},
|
||||
Operand::Number(Number::Float(0.0)),
|
||||
],
|
||||
},),),
|
||||
@@ -1057,7 +1131,7 @@ mod tests {
|
||||
indirection: 0,
|
||||
target: 0,
|
||||
}),
|
||||
Operand::Number(Number::Hexadecimal(4095.0)),
|
||||
Operand::Number(Number::Hexadecimal(4095)),
|
||||
],
|
||||
},),),
|
||||
comment: None,
|
||||
@@ -1159,7 +1233,15 @@ mod tests {
|
||||
device: Device::Numbered(0),
|
||||
connection: None
|
||||
}),
|
||||
Operand::LogicOrSlotLogicType(LogicType::On, SlotLogicType::On),
|
||||
Operand::Type {
|
||||
logic_type: Some(LogicType::On),
|
||||
slot_logic_type: Some(SlotLogicType::On),
|
||||
batch_mode: None,
|
||||
reagent_mode: None,
|
||||
identifier: Identifier {
|
||||
name: "On".to_owned(),
|
||||
},
|
||||
},
|
||||
Operand::Number(Number::Float(1.0))
|
||||
]
|
||||
})),
|
||||
@@ -1232,7 +1314,15 @@ mod tests {
|
||||
},
|
||||
connection: None,
|
||||
}),
|
||||
Operand::LogicType(LogicType::RatioWater),
|
||||
Operand::Type {
|
||||
logic_type: Some(LogicType::RatioWater),
|
||||
slot_logic_type: None,
|
||||
batch_mode: None,
|
||||
reagent_mode: None,
|
||||
identifier: Identifier {
|
||||
name: "RatioWater".to_owned(),
|
||||
},
|
||||
},
|
||||
],
|
||||
},),),
|
||||
comment: None,
|
||||
@@ -1271,7 +1361,7 @@ mod tests {
|
||||
indirection: 0,
|
||||
target: 1,
|
||||
}),
|
||||
Operand::Number(Number::Hexadecimal(255.0)),
|
||||
Operand::Number(Number::Hexadecimal(255)),
|
||||
],
|
||||
},),),
|
||||
comment: None,
|
||||
@@ -1284,7 +1374,7 @@ mod tests {
|
||||
indirection: 0,
|
||||
target: 1,
|
||||
}),
|
||||
Operand::Number(Number::Binary(8.0)),
|
||||
Operand::Number(Number::Binary(8)),
|
||||
],
|
||||
},),),
|
||||
comment: None,
|
||||
@@ -1365,4 +1455,34 @@ mod tests {
|
||||
test_roundtrip("$abcd");
|
||||
test_roundtrip("%1001");
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn all_generated_enums_have_value() {
|
||||
use strum::IntoEnumIterator;
|
||||
for lt in LogicType::iter() {
|
||||
println!("testing LogicType.{lt}");
|
||||
let value = lt.get_str("value");
|
||||
assert!(value.is_some());
|
||||
assert!(value.unwrap().parse::<u16>().is_ok());
|
||||
}
|
||||
for slt in SlotLogicType::iter() {
|
||||
println!("testing SlotLogicType.{slt}");
|
||||
let value = slt.get_str("value");
|
||||
assert!(value.is_some());
|
||||
assert!(value.unwrap().parse::<u8>().is_ok());
|
||||
}
|
||||
for bm in BatchMode::iter() {
|
||||
println!("testing BatchMode.{bm}");
|
||||
let value = bm.get_str("value");
|
||||
assert!(value.is_some());
|
||||
assert!(value.unwrap().parse::<u8>().is_ok());
|
||||
}
|
||||
for rm in ReagentMode::iter() {
|
||||
println!("testing ReagentMode.{rm}");
|
||||
let value = rm.get_str("value");
|
||||
assert!(value.is_some());
|
||||
assert!(value.unwrap().parse::<u8>().is_ok());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +119,10 @@ pub enum ICError {
|
||||
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 {
|
||||
@@ -2458,7 +2462,7 @@ impl IC {
|
||||
let device = vm.get_device_same_network(this.device, device_id);
|
||||
match device {
|
||||
Some(device) => {
|
||||
let rm = ReagentMode::try_from(rm.as_value(this, inst, 3)?)?;
|
||||
let rm = rm.as_reagent_mode(this, inst, 3)?;
|
||||
let name = name.as_value(this, inst, 4)?;
|
||||
let val = device.borrow().get_reagent(&rm, name);
|
||||
this.set_register(indirection, target, val)?;
|
||||
@@ -2477,7 +2481,7 @@ impl IC {
|
||||
} = reg.as_register(this, inst, 1)?;
|
||||
let prefab = prefab.as_value(this, inst, 2)?;
|
||||
let lt = lt.as_logic_type(this, inst, 3)?;
|
||||
let bm = BatchMode::try_from(bm.as_value(this, inst, 4)?)?;
|
||||
let bm = bm.as_batch_mode(this, inst, 4)?;
|
||||
let val = vm.get_batch_device_field(this.device, prefab, lt, bm)?;
|
||||
this.set_register(indirection, target, val)?;
|
||||
Ok(())
|
||||
@@ -2493,7 +2497,7 @@ impl IC {
|
||||
let prefab = prefab.as_value(this, inst, 2)?;
|
||||
let name = name.as_value(this, inst, 3)?;
|
||||
let lt = lt.as_logic_type(this, inst, 4)?;
|
||||
let bm = BatchMode::try_from(bm.as_value(this, inst, 5)?)?;
|
||||
let bm = bm.as_batch_mode(this, inst, 5)?;
|
||||
let val =
|
||||
vm.get_batch_name_device_field(this.device, prefab, name, lt, bm)?;
|
||||
this.set_register(indirection, target, val)?;
|
||||
@@ -2511,7 +2515,7 @@ impl IC {
|
||||
let name = name.as_value(this, inst, 3)?;
|
||||
let index = index.as_value(this, inst, 4)?;
|
||||
let slt = slt.as_slot_logic_type(this, inst, 5)?;
|
||||
let bm = BatchMode::try_from(bm.as_value(this, inst, 6)?)?;
|
||||
let bm = bm.as_batch_mode(this, inst, 6)?;
|
||||
let val = vm.get_batch_name_device_slot_field(
|
||||
this.device,
|
||||
prefab,
|
||||
@@ -2534,7 +2538,7 @@ impl IC {
|
||||
let prefab = prefab.as_value(this, inst, 2)?;
|
||||
let index = index.as_value(this, inst, 3)?;
|
||||
let slt = slt.as_slot_logic_type(this, inst, 4)?;
|
||||
let bm = BatchMode::try_from(bm.as_value(this, inst, 5)?)?;
|
||||
let bm = bm.as_batch_mode(this, inst, 5)?;
|
||||
let val =
|
||||
vm.get_batch_device_slot_field(this.device, prefab, index, slt, bm)?;
|
||||
this.set_register(indirection, target, val)?;
|
||||
@@ -2620,15 +2624,15 @@ mod tests {
|
||||
vm.set_code(
|
||||
ic,
|
||||
r#"lb r0 HASH("ItemActiveVent") On Sum
|
||||
#lb r1 HASH("ItemActiveVent") On Maximum
|
||||
lb r1 HASH("ItemActiveVent") On Maximum
|
||||
lb r2 HASH("ItemActiveVent") On Minimum"#,
|
||||
)?;
|
||||
vm.step_ic(ic, false)?;
|
||||
let r0 = ic_chip.get_register(0, 0).unwrap();
|
||||
assert_eq!(r0, 0.0);
|
||||
vm.step_ic(ic, false)?;
|
||||
// let r1 = ic_chip.get_register(0, 1).unwrap();
|
||||
// assert_eq!(r1, f64::NEG_INFINITY);
|
||||
let r1 = ic_chip.get_register(0, 1).unwrap();
|
||||
assert_eq!(r1, f64::NEG_INFINITY);
|
||||
vm.step_ic(ic, false)?;
|
||||
let r2 = ic_chip.get_register(0, 2).unwrap();
|
||||
assert_eq!(r2, f64::INFINITY);
|
||||
|
||||
@@ -377,7 +377,7 @@ impl VM {
|
||||
ic.borrow().ic.replace(0);
|
||||
self.set_modified(id);
|
||||
for _i in 0..128 {
|
||||
if let Err(err) = ic.borrow_mut().step(self, ignore_errors) {
|
||||
if let Err(err) = ic.borrow().step(self, ignore_errors) {
|
||||
if !ignore_errors {
|
||||
return Err(err.into());
|
||||
}
|
||||
|
||||
@@ -59,8 +59,8 @@ export type OperandReagentMode = { readonly ReagentMode: string };
|
||||
export type Identifier = { readonly Identifier: { name: string } };
|
||||
|
||||
export type NumberFloat = { readonly Float: number };
|
||||
export type NumberBinary = { readonly Binary: number };
|
||||
export type NumberHexadecimal = { readonly Hexadecimal: number };
|
||||
export type NumberBinary = { readonly Binary: BigInt };
|
||||
export type NumberHexadecimal = { readonly Hexadecimal: BigInt };
|
||||
export type NumberConstant = { readonly Constant: number };
|
||||
export type NumberString = { readonly String: string };
|
||||
export type NumberEnum = { readonly Enum: number };
|
||||
|
||||
Reference in New Issue
Block a user