more working syscalls
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user