Skip to content

Commit

Permalink
refactor(vm): add proper reagent interface, trace VM, fix slot serial…
Browse files Browse the repository at this point in the history
…ization

Signed-off-by: Rachel Powers <[email protected]>
  • Loading branch information
Ryex committed Sep 17, 2024
1 parent c810806 commit 08c42a2
Show file tree
Hide file tree
Showing 27 changed files with 8,112 additions and 5,236 deletions.
6 changes: 6 additions & 0 deletions ic10emu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ strum_macros = "0.26.2"
thiserror = "1.0.61"
time = { version = "0.3.36", features = [
"formatting",
"parsing",
"serde",
"local-offset",
] }
tsify = { version = "0.4.5", optional = true, features = ["js"] }
wasm-bindgen = { version = "0.2.92", optional = true }
tracing = "0.1.40"

[target.'cfg(target_arch = "wasm32")'.dependencies]
getrandom = { version = "0.2", features = ["js"] }
Expand All @@ -54,3 +56,7 @@ tsify = ["dep:tsify", "dep:wasm-bindgen", "stationeers_data/tsify"]
prefab_database = [
"stationeers_data/prefab_database",
] # compile with the prefab database enabled

reagent_database = [
"stationeers_data/reagent_database",
] # compile with the prefab database enabled
42 changes: 28 additions & 14 deletions ic10emu/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub enum VMError {
IdInUse(u32),
#[error("device(s) with ids {0:?} already exist")]
IdsInUse(Vec<u32>),
#[error("atempt to use a set of id's with duplicates: id(s) {0:?} exsist more than once")]
#[error("attempt to use a set of id's with duplicates: id(s) {0:?} exist more than once")]
DuplicateIds(Vec<u32>),
#[error("object {0} is not a device")]
NotADevice(ObjectID),
Expand Down Expand Up @@ -64,7 +64,7 @@ pub enum VMError {
#[error("object {0} is not logicable")]
NotLogicable(ObjectID),
#[error("network object {0} is not a network")]
NonNetworkNetwork(ObjectID)
NonNetworkNetwork(ObjectID),
}

#[derive(Error, Debug, Serialize, Deserialize)]
Expand All @@ -81,15 +81,15 @@ pub enum TemplateError {
#[error("incorrect template for concrete impl {0} from prefab {1}: {2:?}")]
IncorrectTemplate(String, Prefab, ObjectTemplate),
#[error("frozen memory size error: {0} is not {1}")]
MemorySize(usize, usize)

MemorySize(usize, usize),
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct LineError {
pub error: ICError,
pub line: u32,
pub msg: String,
}

impl Display for LineError {
Expand Down Expand Up @@ -154,6 +154,7 @@ impl ParseError {
}

#[derive(Debug, Error, Clone, Serialize, Deserialize)]
#[serde(tag = "typ")]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub enum ICError {
#[error("error compiling code: {0}")]
Expand All @@ -162,8 +163,12 @@ pub enum ICError {
LogicError(#[from] LogicError),
#[error("{0}")]
MemoryError(#[from] MemoryError),
#[error("duplicate label {0}")]
DuplicateLabel(String),
#[error("duplicate label {label}: first encountered on line {source_line}")]
DuplicateLabel {
label: String,
line: u32,
source_line: u32,
},
#[error("instruction pointer out of range: '{0}'")]
InstructionPointerOutOfRange(usize),
#[error("register pointer out of range: '{0}'")]
Expand All @@ -176,8 +181,8 @@ pub enum ICError {
SlotIndexOutOfRange(f64),
#[error("pin index {0} out of range 0-6")]
PinIndexOutOfRange(usize),
#[error("connection index {0} out of range {1}")]
ConnectionIndexOutOfRange(usize, usize),
#[error("connection index {index} out of range {range}")]
ConnectionIndexOutOfRange { index: usize, range: usize },
#[error("unknown device ID '{0}'")]
UnknownDeviceID(f64),
#[error("too few operands!: provide: '{provided}', desired: '{desired}'")]
Expand Down Expand Up @@ -240,11 +245,16 @@ pub enum ICError {
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),
#[error("IC with id {0} is not sloted into a circuit holder")]
#[error(
"generated Enum {enum_name}'s value does not parse as {parse_type} . Report this error."
)]
BadGeneratedValueParse {
enum_name: String,
parse_type: String,
},
#[error("IC with id {0} is not slotted into a circuit holder")]
NoCircuitHolder(ObjectID),
#[error("IC with id {0} is sloted into a circuit holder with no logic interface?")]
#[error("IC with id {0} is slotted into a circuit holder with no logic interface?")]
CircuitHolderNotLogicable(ObjectID),
#[error("object {0} is not slot writeable")]
NotSlotWriteable(ObjectID),
Expand All @@ -254,8 +264,12 @@ pub enum ICError {
NotLogicable(ObjectID),
#[error("{0} is not a valid number of sleep seconds")]
SleepDurationError(f64),
#[error("{0} can not be added to {1} ")]
SleepAddtionError(time::Duration, #[cfg_attr(feature = "tsify", tsify(type = "Date"))] time::OffsetDateTime),
#[error("{duration} can not be added to {time} ")]
SleepAdditionError {
duration: time::Duration,
#[cfg_attr(feature = "tsify", tsify(type = "Date"))]
time: time::OffsetDateTime,
},
}

impl ICError {
Expand Down
20 changes: 17 additions & 3 deletions ic10emu/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ pub enum ICState {
Running,
Yield,
Sleep(
#[cfg_attr(feature = "tsify", tsify(type = "Date"))] time::OffsetDateTime,
#[cfg_attr(feature = "tsify", tsify(type = "string"))]
#[serde(with = "time::serde::rfc3339")]
time::OffsetDateTime,
f64,
),
Error(LineError),
Expand Down Expand Up @@ -119,7 +121,13 @@ impl Program {
Some(code) => match code {
grammar::Code::Label(label) => {
if labels_set.contains(&label.id.name) {
Err(ICError::DuplicateLabel(label.id.name))
let source_line =
labels.get(&label.id.name).copied().unwrap_or_default();
Err(ICError::DuplicateLabel {
label: label.id.name,
line: line_number as u32,
source_line,
})
} else {
labels_set.insert(label.id.name.clone());
labels.insert(label.id.name, line_number as u32);
Expand Down Expand Up @@ -157,7 +165,13 @@ impl Program {
Some(code) => match code {
grammar::Code::Label(label) => {
if labels_set.contains(&label.id.name) {
errors.push(ICError::DuplicateLabel(label.id.name));
let source_line =
labels.get(&label.id.name).copied().unwrap_or_default();
errors.push(ICError::DuplicateLabel {
label: label.id.name,
line: line_number as u32,
source_line,
});
} else {
labels_set.insert(label.id.name.clone());
labels.insert(label.id.name, line_number as u32);
Expand Down
54 changes: 48 additions & 6 deletions ic10emu/src/interpreter/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2485,6 +2485,7 @@ impl<T: IC10Marker> LrInstruction for T {
indirection,
target,
} = r.as_register(self)?;
let vm = self.get_vm();
let (device, connection) = d.as_device(self)?;
let reagent_mode = reagent_mode.as_reagent_mode(self)?;
let int = int.as_value(self)?;
Expand Down Expand Up @@ -2526,7 +2527,7 @@ impl<T: IC10Marker> LrInstruction for T {
}
LogicReagentMode::Required => {
let reagent_interface = logicable
.as_reagent_interface()
.as_reagent_requirer()
.ok_or(ICError::NotReagentReadable(*logicable.get_id()))?;
reagent_interface
.get_current_required()
Expand All @@ -2537,13 +2538,26 @@ impl<T: IC10Marker> LrInstruction for T {
}
LogicReagentMode::Recipe => {
let reagent_interface = logicable
.as_reagent_interface()
.as_reagent_requirer()
.ok_or(ICError::NotReagentReadable(*logicable.get_id()))?;
reagent_interface
.get_current_recipe()
.iter()
.find(|(hash, _)| *hash as f64 == int)
.map(|(_, quantity)| *quantity)
.and_then(|recipe_order| {
recipe_order
.recipe
.reagents
.iter()
.map(|(name, quantity)| {
(
vm.lookup_reagent_by_name(name)
.map(|reagent| reagent.hash)
.unwrap_or(0),
quantity,
)
})
.find(|(hash, _)| *hash as f64 == int)
.map(|(_, quantity)| *quantity)
})
.unwrap_or(0.0)
}
};
Expand Down Expand Up @@ -2709,6 +2723,34 @@ impl<T: IC10Marker> RmapInstruction for T {
d: &crate::vm::instructions::operands::InstOperand,
reagent_hash: &crate::vm::instructions::operands::InstOperand,
) -> Result<(), crate::errors::ICError> {
todo!()
let RegisterSpec {
indirection,
target,
} = r.as_register(self)?;
let (device, connection) = d.as_device(self)?;

let reagent_hash = reagent_hash.as_value_i32(self, true)?;
let val = self
.get_circuit_holder()
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
.borrow()
.as_circuit_holder()
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
.get_logicable_from_index(device, connection)
.ok_or(ICError::DeviceNotSet)
.and_then(|obj| {
obj.map(|obj_ref| {
obj_ref
.as_reagent_requirer()
.ok_or(ICError::NotReagentReadable(*obj_ref.get_id()))
.map(|reagent_interface| {
reagent_interface
.get_prefab_hash_from_reagent_hash(reagent_hash)
.unwrap_or(0)
})
})
})?;
self.set_register(indirection, target, val as f64)?;
Ok(())
}
}
16 changes: 13 additions & 3 deletions ic10emu/src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub enum CableConnectionType {
PowerAndData,
}

#[serde_with::skip_serializing_none]
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub enum Connection {
Expand Down Expand Up @@ -146,7 +147,7 @@ impl Connection {
},
Self::RoboticArmRail { role } => ConnectionInfo {
typ: ConnectionType::RoboticArmRail,
role: *role
role: *role,
},
}
}
Expand Down Expand Up @@ -181,6 +182,9 @@ pub struct CableNetwork {
}

impl Storage for CableNetwork {
fn debug_storage(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "UNIMPLEMENTED") //TODO: Implement
}
fn slots_count(&self) -> usize {
0
}
Expand All @@ -190,15 +194,18 @@ impl Storage for CableNetwork {
fn get_slot_mut(&mut self, _index: usize) -> Option<&mut crate::vm::object::Slot> {
None
}
fn get_slots(&self) -> Vec<&crate::vm::object::Slot> {
fn get_slots(&self) -> Vec<(usize, &crate::vm::object::Slot)> {
vec![]
}
fn get_slots_mut(&mut self) -> Vec<&mut crate::vm::object::Slot> {
fn get_slots_mut(&mut self) -> Vec<(usize, &mut crate::vm::object::Slot)> {
vec![]
}
}

impl Logicable for CableNetwork {
fn debug_logicable(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "UNIMPLEMENTED") //TODO: Implement
}
fn prefab_hash(&self) -> i32 {
0
}
Expand Down Expand Up @@ -282,6 +289,9 @@ impl Logicable for CableNetwork {
}

impl Network for CableNetwork {
fn debug_network(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "UNIMPLEMENTED") //TODO: Implement
}
fn contains(&self, id: &ObjectID) -> bool {
self.devices.contains(id) || self.power_only.contains(id)
}
Expand Down
Loading

0 comments on commit 08c42a2

Please sign in to comment.