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:
Rachel Powers
2024-04-11 17:07:28 -07:00
parent 03b55822a4
commit 6b790cea16
3 changed files with 88 additions and 32 deletions

View File

@@ -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");

View File

@@ -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(&lt) {
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(&lt) {
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)?;

View File

@@ -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)));