more working syscalls

This commit is contained in:
2025-11-25 22:54:05 -07:00
parent 97b462eac8
commit 1579d9f905
4 changed files with 199 additions and 22 deletions

View File

@@ -13,6 +13,8 @@ use tokenizer::{
};
use tree_node::*;
use crate::sys_call::System;
#[macro_export]
/// A macro to create a boxed value.
macro_rules! boxed {
@@ -63,6 +65,12 @@ macro_rules! token_from_option {
None => return Err(Error::UnexpectedEOF),
}
};
(owned $token:expr) => {
match $token {
Some(token) => token,
None => return Err(Error::UnexpectedEOF),
}
};
}
macro_rules! extract_token_data {
@@ -1039,9 +1047,22 @@ impl Parser {
}
"sleep" => {
check_length(self, &invocation.arguments, 1)?;
let mut arg = invocation.arguments.iter();
let argument = literal_or_variable!(arg.next());
Ok(SysCall::System(sys_call::System::Sleep(argument)))
let mut arg = invocation.arguments.into_iter();
let expr = token_from_option!(owned arg.next());
Ok(SysCall::System(System::Sleep(boxed!(expr))))
}
"hash" => {
check_length(self, &invocation.arguments, 1)?;
let mut args = invocation.arguments.into_iter();
let lit_str = literal_or_variable!(args.next());
let LiteralOrVariable::Literal(lit_str) = lit_str else {
return Err(Error::UnexpectedToken(
token_from_option!(self.current_token).clone(),
));
};
Ok(SysCall::System(System::Hash(lit_str)))
}
"loadFromDevice" => {
check_length(self, &invocation.arguments, 2)?;
@@ -1076,23 +1097,23 @@ impl Parser {
}
"loadBatchNamed" => {
check_length(self, &invocation.arguments, 4)?;
let mut args = invocation.arguments.iter();
let mut args = invocation.arguments.into_iter();
let device_hash = literal_or_variable!(args.next());
let name_hash = get_arg!(Literal, literal_or_variable!(args.next()));
let name_hash = token_from_option!(owned args.next());
let logic_type = get_arg!(Literal, literal_or_variable!(args.next()));
let batch_mode = get_arg!(Literal, literal_or_variable!(args.next()));
Ok(SysCall::System(sys_call::System::LoadBatchNamed(
device_hash,
name_hash,
boxed!(name_hash),
logic_type,
batch_mode,
)))
}
"setOnDevice" => {
check_length(self, &invocation.arguments, 3)?;
let mut args = invocation.arguments.iter();
let mut args = invocation.arguments.into_iter();
let device = literal_or_variable!(args.next());
@@ -1104,12 +1125,54 @@ impl Parser {
));
};
let variable = literal_or_variable!(args.next());
let variable = token_from_option!(owned args.next());
Ok(SysCall::System(sys_call::System::SetOnDevice(
device,
Literal::String(logic_type),
variable,
boxed!(variable),
)))
}
"setOnDeviceBatched" => {
check_length(self, &invocation.arguments, 3)?;
let mut args = invocation.arguments.into_iter();
let device = literal_or_variable!(args.next());
let Literal::String(logic_type) =
get_arg!(Literal, literal_or_variable!(args.next()))
else {
return Err(Error::UnexpectedToken(
token_from_option!(self.current_token).clone(),
));
};
let variable = token_from_option!(owned args.next());
Ok(SysCall::System(System::SetOnDeviceBatched(
device,
Literal::String(logic_type),
boxed!(variable),
)))
}
"setOnDeviceBatchedNamed" => {
check_length(self, &invocation.arguments, 4)?;
let mut args = invocation.arguments.into_iter();
let device = literal_or_variable!(args.next());
let name = literal_or_variable!(args.next());
let Literal::String(logic_type) =
get_arg!(Literal, literal_or_variable!(args.next()))
else {
return Err(Error::UnexpectedToken(
token_from_option!(self.current_token).clone(),
));
};
let variable = token_from_option!(owned args.next());
Ok(SysCall::System(System::SetOnDeviceBatchedNamed(
device,
name,
Literal::String(logic_type),
boxed!(variable),
)))
}
// math calls

View File

@@ -1,4 +1,4 @@
use crate::tree_node::Literal;
use crate::tree_node::{Expression, Literal};
use super::LiteralOrVariable;
@@ -102,11 +102,11 @@ pub enum System {
/// Represents a function that can be called to sleep for a certain amount of time.
/// ## In Game
/// `sleep a(r?|num)`
Sleep(LiteralOrVariable),
Sleep(Box<Expression>),
/// Gets the in-game hash for a specific prefab name.
/// ## In Game
/// `HASH("prefabName")`
Hash(LiteralOrVariable),
Hash(Literal),
/// Represents a function which loads a device variable into a register.
/// ## In Game
/// `l r? d? var`
@@ -120,7 +120,7 @@ pub enum System {
/// lbn r? deviceHash nameHash logicType batchMode
/// ## Examples
/// lbn r0 HASH("StructureWallLight") HASH("wallLight") On Minimum
LoadBatchNamed(LiteralOrVariable, Literal, Literal, Literal),
LoadBatchNamed(LiteralOrVariable, Box<Expression>, Literal, Literal),
/// Loads a LogicType from all connected network devices, aggregating them via a
/// batchMode
/// ## In Game
@@ -133,7 +133,26 @@ pub enum System {
/// `s d? logicType r?`
/// ## Example
/// `s d0 Setting r0`
SetOnDevice(LiteralOrVariable, Literal, LiteralOrVariable),
SetOnDevice(LiteralOrVariable, Literal, Box<Expression>),
/// Represents a function which stores a setting to all devices that match
/// the given deviceHash
/// ## In Game
/// `sb deviceHash logictype r?`
/// ## Example
/// `sb HASH("Doors") Lock 1`
SetOnDeviceBatched(LiteralOrVariable, Literal, Box<Expression>),
/// Represents a function which stores a setting to all devices that match
/// both the given deviceHash AND the given nameHash
/// ## In Game
/// `sbn deviceHash nameHash logicType r?`
/// ## Example
/// `sbn HASH("Doors") HASH("Exterior") Lock 1`
SetOnDeviceBatchedNamed(
LiteralOrVariable,
LiteralOrVariable,
Literal,
Box<Expression>,
),
}
impl std::fmt::Display for System {
@@ -141,13 +160,19 @@ impl std::fmt::Display for System {
match self {
System::Yield => write!(f, "yield()"),
System::Sleep(a) => write!(f, "sleep({})", a),
System::Hash(a) => write!(f, "HASH({})", a),
System::Hash(a) => write!(f, "hash({})", a),
System::LoadFromDevice(a, b) => write!(f, "loadFromDevice({}, {})", a, b),
System::LoadBatch(a, b, c) => write!(f, "loadBatch({}, {}, {})", a, b, c),
System::LoadBatchNamed(a, b, c, d) => {
write!(f, "loadBatchNamed({}, {}, {}, {})", a, b, c, d)
}
System::SetOnDevice(a, b, c) => write!(f, "setOnDevice({}, {}, {})", a, b, c),
System::SetOnDeviceBatched(a, b, c) => {
write!(f, "setOnDeviceBatched({}, {}, {})", a, b, c)
}
System::SetOnDeviceBatchedNamed(a, b, c, d) => {
write!(f, "setOnDeviceBatchedNamed({}, {}, {}, {})", a, b, c, d)
}
}
}
}
@@ -175,9 +200,11 @@ impl SysCall {
identifier,
"yield"
| "sleep"
| "HASH"
| "hash"
| "loadFromDevice"
| "setOnDevice"
| "setOnDeviceBatched"
| "setOnDeviceBatchedNamed"
| "acos"
| "asin"
| "atan"