Fix named types/modes
This commit is contained in:
@@ -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,25 @@ 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").unwrap().parse::<u16>().unwrap() as f64)
|
||||
} else if let Some(slt) = slot_logic_type {
|
||||
Ok(slt.get_str("value").unwrap().parse::<u16>().unwrap() as f64)
|
||||
} else if let Some(bm) = batch_mode {
|
||||
Ok(bm.get_str("value").unwrap().parse::<u8>().unwrap() as f64)
|
||||
} else if let Some(rm) = reagent_mode {
|
||||
Ok(rm.get_str("value").unwrap().parse::<u8>().unwrap() as f64)
|
||||
} else {
|
||||
Err(interpreter::ICError::TypeValueNotKnown)
|
||||
}
|
||||
}
|
||||
Operand::Identifier(id) => {
|
||||
Err(interpreter::ICError::UnknownIdentifier(id.name.to_string()))
|
||||
}
|
||||
@@ -502,8 +502,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 +517,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) {
|
||||
@@ -798,24 +832,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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -895,11 +928,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),
|
||||
}
|
||||
}
|
||||
@@ -1036,7 +1065,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)),
|
||||
],
|
||||
},),),
|
||||
@@ -1159,7 +1196,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 +1277,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,
|
||||
|
||||
@@ -2458,7 +2458,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 +2477,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 +2493,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 +2511,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 +2534,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 +2620,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);
|
||||
|
||||
Reference in New Issue
Block a user