Logic and SlotLogic types are sometimes the same name
- idealy this would be parsed to the corect varient based on the instrution but runtime switching works too. Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use crate::interpreter;
|
||||
use crate::interpreter::{self, ICError};
|
||||
use crate::tokens::{SplitConsecutiveIndicesExt, SplitConsecutiveWithIndices};
|
||||
use itertools::Itertools;
|
||||
use std::error::Error;
|
||||
@@ -349,6 +349,7 @@ pub enum Operand {
|
||||
Number(Number),
|
||||
LogicType(LogicType),
|
||||
SlotLogicType(SlotLogicType),
|
||||
LogicOrSlotLogicType(LogicType, SlotLogicType),
|
||||
BatchMode(BatchMode),
|
||||
ReagentMode(ReagentMode),
|
||||
Identifier(Identifier),
|
||||
@@ -369,11 +370,16 @@ impl Operand {
|
||||
Operand::Number(num) => Ok(num.value()),
|
||||
Operand::LogicType(lt) => lt
|
||||
.get_str("value")
|
||||
.map(|val| val.parse::<u8>().unwrap() as f64)
|
||||
.map(|val| val.parse::<u16>().unwrap() as f64)
|
||||
.ok_or(interpreter::ICError::TypeValueNotKnown),
|
||||
Operand::SlotLogicType(slt) => slt
|
||||
.get_str("value")
|
||||
.map(|val| val.parse::<u8>().unwrap() as f64)
|
||||
.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")
|
||||
@@ -487,6 +493,32 @@ impl Operand {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_logic_type(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<LogicType, ICError> {
|
||||
match &self {
|
||||
Operand::LogicType(lt) => Ok(*lt),
|
||||
Operand::LogicOrSlotLogicType(lt, _slt) => Ok(*lt),
|
||||
_ => LogicType::try_from(self.as_value(ic, inst, index)?),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_slot_logic_type(
|
||||
&self,
|
||||
ic: &interpreter::IC,
|
||||
inst: InstructionOp,
|
||||
index: u32,
|
||||
) -> Result<SlotLogicType, ICError> {
|
||||
match &self {
|
||||
Operand::SlotLogicType(slt) => Ok(*slt),
|
||||
Operand::LogicOrSlotLogicType(_lt, slt) => Ok(*slt),
|
||||
_ => SlotLogicType::try_from(self.as_value(ic, inst, index)?),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn translate_alias(&self, ic: &interpreter::IC) -> Self {
|
||||
match &self {
|
||||
Operand::Identifier(id) => {
|
||||
@@ -765,9 +797,17 @@ impl FromStr for Operand {
|
||||
val.get_str("value").unwrap().parse().unwrap(),
|
||||
)))
|
||||
} else if let Ok(lt) = LogicType::from_str(s) {
|
||||
Ok(Operand::LogicType(lt))
|
||||
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) {
|
||||
Ok(Operand::SlotLogicType(slt))
|
||||
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) {
|
||||
@@ -855,6 +895,7 @@ impl Display for Operand {
|
||||
},
|
||||
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::Identifier(ident) => Display::fmt(&ident, f),
|
||||
@@ -1029,6 +1070,7 @@ mod tests {
|
||||
define a_hash HASH(\"This is a String\")\n\
|
||||
alias a_var r0\n\
|
||||
alias a_device d0\n\
|
||||
s d0 On 1\n\
|
||||
s d0 12 0 \n\
|
||||
move r2 LogicType.Temperature\n\
|
||||
move r3 pinf\n\
|
||||
@@ -1107,6 +1149,20 @@ mod tests {
|
||||
},),),
|
||||
comment: None,
|
||||
},
|
||||
Line {
|
||||
code: Some(Code::Instruction(Instruction {
|
||||
instruction: InstructionOp::S,
|
||||
operands: vec![
|
||||
Operand::DeviceSpec(DeviceSpec {
|
||||
device: Device::Numbered(0),
|
||||
connection: None
|
||||
}),
|
||||
Operand::LogicOrSlotLogicType(LogicType::On, SlotLogicType::On),
|
||||
Operand::Number(Number::Float(1.0))
|
||||
]
|
||||
})),
|
||||
comment: None,
|
||||
},
|
||||
Line {
|
||||
code: Some(Code::Instruction(Instruction {
|
||||
instruction: InstructionOp::S,
|
||||
@@ -1295,10 +1351,10 @@ mod tests {
|
||||
test_roundtrip("42");
|
||||
test_roundtrip("1.2345");
|
||||
test_roundtrip("-1.2345");
|
||||
test_roundtrip(&LogicType::Pressure.to_string());
|
||||
test_roundtrip(&SlotLogicType::Occupied.to_string());
|
||||
test_roundtrip(&BatchMode::Average.to_string());
|
||||
test_roundtrip(&ReagentMode::Recipe.to_string());
|
||||
test_roundtrip(LogicType::Pressure.as_ref());
|
||||
test_roundtrip(SlotLogicType::Occupied.as_ref());
|
||||
test_roundtrip(BatchMode::Average.as_ref());
|
||||
test_roundtrip(ReagentMode::Recipe.as_ref());
|
||||
test_roundtrip("pi");
|
||||
test_roundtrip("pinf");
|
||||
test_roundtrip("ninf");
|
||||
|
||||
@@ -2135,7 +2135,7 @@ impl IC {
|
||||
let (Some(device_id), connection) = dev.as_device(this, inst, 1)? else {
|
||||
return Err(DeviceNotSet);
|
||||
};
|
||||
let lt = LogicType::try_from(lt.as_value(this, inst, 2)?)?;
|
||||
let lt = lt.as_logic_type(this, inst, 2)?;
|
||||
if CHANNEL_LOGIC_TYPES.contains(<) {
|
||||
let channel = lt.as_channel().unwrap();
|
||||
let Some(connection) = connection else {
|
||||
@@ -2171,7 +2171,7 @@ impl IC {
|
||||
let device = vm.get_device_same_network(this.device, device_id as u16);
|
||||
match device {
|
||||
Some(device) => {
|
||||
let lt = LogicType::try_from(lt.as_value(this, inst, 2)?)?;
|
||||
let lt = lt.as_logic_type(this, inst, 2)?;
|
||||
let val = val.as_value(this, inst, 3)?;
|
||||
device.borrow_mut().set_field(lt, val)?;
|
||||
vm.set_modified(device_id as u16);
|
||||
@@ -2183,7 +2183,7 @@ impl IC {
|
||||
oprs => Err(ICError::mismatch_operands(oprs.len(), 3)),
|
||||
},
|
||||
Ss => match &operands[..] {
|
||||
[dev, index, lt, val] => {
|
||||
[dev, index, slt, val] => {
|
||||
let (Some(device_id), _connection) = dev.as_device(this, inst, 1)? else {
|
||||
return Err(DeviceNotSet);
|
||||
};
|
||||
@@ -2191,9 +2191,9 @@ impl IC {
|
||||
match device {
|
||||
Some(device) => {
|
||||
let index = index.as_value(this, inst, 2)?;
|
||||
let lt = SlotLogicType::try_from(lt.as_value(this, inst, 3)?)?;
|
||||
let slt = slt.as_slot_logic_type(this, inst, 3)?;
|
||||
let val = val.as_value(this, inst, 4)?;
|
||||
device.borrow_mut().set_slot_field(index, lt, val)?;
|
||||
device.borrow_mut().set_slot_field(index, slt, val)?;
|
||||
vm.set_modified(device_id);
|
||||
Ok(())
|
||||
}
|
||||
@@ -2205,7 +2205,7 @@ impl IC {
|
||||
Sb => match &operands[..] {
|
||||
[prefab, lt, val] => {
|
||||
let prefab = prefab.as_value(this, inst, 1)?;
|
||||
let lt = LogicType::try_from(lt.as_value(this, inst, 2)?)?;
|
||||
let lt = lt.as_logic_type(this, inst, 2)?;
|
||||
let val = val.as_value(this, inst, 3)?;
|
||||
vm.set_batch_device_field(this.device, prefab, lt, val)?;
|
||||
Ok(())
|
||||
@@ -2213,12 +2213,12 @@ impl IC {
|
||||
oprs => Err(ICError::mismatch_operands(oprs.len(), 3)),
|
||||
},
|
||||
Sbs => match &operands[..] {
|
||||
[prefab, index, lt, val] => {
|
||||
[prefab, index, slt, val] => {
|
||||
let prefab = prefab.as_value(this, inst, 1)?;
|
||||
let index = index.as_value(this, inst, 2)?;
|
||||
let lt = SlotLogicType::try_from(lt.as_value(this, inst, 3)?)?;
|
||||
let slt = slt.as_slot_logic_type(this, inst, 3)?;
|
||||
let val = val.as_value(this, inst, 4)?;
|
||||
vm.set_batch_device_slot_field(this.device, prefab, index, lt, val)?;
|
||||
vm.set_batch_device_slot_field(this.device, prefab, index, slt, val)?;
|
||||
Ok(())
|
||||
}
|
||||
oprs => Err(ICError::mismatch_operands(oprs.len(), 4)),
|
||||
@@ -2227,7 +2227,7 @@ impl IC {
|
||||
[prefab, name, lt, val] => {
|
||||
let prefab = prefab.as_value(this, inst, 1)?;
|
||||
let name = name.as_value(this, inst, 2)?;
|
||||
let lt = LogicType::try_from(lt.as_value(this, inst, 3)?)?;
|
||||
let lt = lt.as_logic_type(this, inst, 3)?;
|
||||
let val = val.as_value(this, inst, 4)?;
|
||||
vm.set_batch_name_device_field(this.device, prefab, name, lt, val)?;
|
||||
Ok(())
|
||||
@@ -2244,7 +2244,7 @@ impl IC {
|
||||
let (Some(device_id), connection) = dev.as_device(this, inst, 2)? else {
|
||||
return Err(DeviceNotSet);
|
||||
};
|
||||
let lt = LogicType::try_from(lt.as_value(this, inst, 3)?)?;
|
||||
let lt = lt.as_logic_type(this, inst, 3)?;
|
||||
if CHANNEL_LOGIC_TYPES.contains(<) {
|
||||
let channel = lt.as_channel().unwrap();
|
||||
let Some(connection) = connection else {
|
||||
@@ -2283,7 +2283,7 @@ impl IC {
|
||||
let device = vm.get_device_same_network(this.device, device_id as u16);
|
||||
match device {
|
||||
Some(device) => {
|
||||
let lt = LogicType::try_from(lt.as_value(this, inst, 3)?)?;
|
||||
let lt = lt.as_logic_type(this, inst, 3)?;
|
||||
let val = device.borrow().get_field(lt)?;
|
||||
this.set_register(indirection, target, val)?;
|
||||
Ok(())
|
||||
@@ -2294,7 +2294,7 @@ impl IC {
|
||||
oprs => Err(ICError::mismatch_operands(oprs.len(), 3)),
|
||||
},
|
||||
Ls => match &operands[..] {
|
||||
[reg, dev, index, lt] => {
|
||||
[reg, dev, index, slt] => {
|
||||
let RegisterSpec {
|
||||
indirection,
|
||||
target,
|
||||
@@ -2306,8 +2306,8 @@ impl IC {
|
||||
match device {
|
||||
Some(device) => {
|
||||
let index = index.as_value(this, inst, 3)?;
|
||||
let lt = SlotLogicType::try_from(lt.as_value(this, inst, 4)?)?;
|
||||
let val = device.borrow().get_slot_field(index, lt)?;
|
||||
let slt = slt.as_slot_logic_type(this, inst, 4)?;
|
||||
let val = device.borrow().get_slot_field(index, slt)?;
|
||||
this.set_register(indirection, target, val)?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -2346,7 +2346,7 @@ impl IC {
|
||||
target,
|
||||
} = reg.as_register(this, inst, 1)?;
|
||||
let prefab = prefab.as_value(this, inst, 2)?;
|
||||
let lt = LogicType::try_from(lt.as_value(this, inst, 3)?)?;
|
||||
let lt = lt.as_logic_type(this, inst, 3)?;
|
||||
let bm = BatchMode::try_from(bm.as_value(this, inst, 4)?)?;
|
||||
let val = vm.get_batch_device_field(this.device, prefab, lt, bm)?;
|
||||
this.set_register(indirection, target, val)?;
|
||||
@@ -2362,7 +2362,7 @@ impl IC {
|
||||
} = reg.as_register(this, inst, 1)?;
|
||||
let prefab = prefab.as_value(this, inst, 2)?;
|
||||
let name = name.as_value(this, inst, 3)?;
|
||||
let lt = LogicType::try_from(lt.as_value(this, inst, 4)?)?;
|
||||
let lt = lt.as_logic_type(this, inst, 4)?;
|
||||
let bm = BatchMode::try_from(bm.as_value(this, inst, 5)?)?;
|
||||
let val =
|
||||
vm.get_batch_name_device_field(this.device, prefab, name, lt, bm)?;
|
||||
@@ -2380,7 +2380,7 @@ impl IC {
|
||||
let prefab = prefab.as_value(this, inst, 2)?;
|
||||
let name = name.as_value(this, inst, 3)?;
|
||||
let index = index.as_value(this, inst, 4)?;
|
||||
let slt = SlotLogicType::try_from(slt.as_value(this, inst, 5)?)?;
|
||||
let slt = slt.as_slot_logic_type(this, inst, 5)?;
|
||||
let bm = BatchMode::try_from(bm.as_value(this, inst, 6)?)?;
|
||||
let val = vm.get_batch_name_device_slot_field(
|
||||
this.device,
|
||||
@@ -2403,7 +2403,7 @@ impl IC {
|
||||
} = reg.as_register(this, inst, 1)?;
|
||||
let prefab = prefab.as_value(this, inst, 2)?;
|
||||
let index = index.as_value(this, inst, 3)?;
|
||||
let slt = SlotLogicType::try_from(slt.as_value(this, inst, 4)?)?;
|
||||
let slt = slt.as_slot_logic_type(this, inst, 4)?;
|
||||
let bm = BatchMode::try_from(bm.as_value(this, inst, 5)?)?;
|
||||
let val =
|
||||
vm.get_batch_device_slot_field(this.device, prefab, index, slt, bm)?;
|
||||
|
||||
@@ -538,8 +538,8 @@ impl VM {
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(index, conn)| match conn {
|
||||
&Connection::CableNetwork(_) => Some(index),
|
||||
&Connection::Other => None,
|
||||
Connection::CableNetwork(_) => Some(index),
|
||||
Connection::Other => None,
|
||||
});
|
||||
self.devices.insert(id, Rc::new(RefCell::new(device)));
|
||||
if let Some(first_data_network) = first_data_network {
|
||||
@@ -583,8 +583,8 @@ impl VM {
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(index, conn)| match conn {
|
||||
&Connection::CableNetwork(_) => Some(index),
|
||||
&Connection::Other => None,
|
||||
Connection::CableNetwork(_) => Some(index),
|
||||
Connection::Other => None,
|
||||
});
|
||||
self.devices.insert(id, Rc::new(RefCell::new(device)));
|
||||
self.ics.insert(ic_id, Rc::new(RefCell::new(ic)));
|
||||
|
||||
Reference in New Issue
Block a user