use super::LiteralOrVariable; use crate::tree_node::{Expression, Literal, Spanned}; use crate::{Documentation, documented}; documented! { #[derive(Debug, PartialEq, Eq)] pub enum Math { /// Returns the angle in radians whose cosine is the specified number. /// ## IC10 /// `acos r? a(r?|num)` /// ## Slang /// `(number|var).acos();` Acos(LiteralOrVariable), /// Returns the angle in radians whose sine is the specified number. /// ## IC10 /// `asin r? a(r?|num)` /// ## Slang /// `(number|var).asin();` Asin(LiteralOrVariable), /// Returns the angle in radians whose tangent is the specified number. /// ## IC10 /// `atan r? a(r?|num)` /// ## Slang /// `(number|var).atan();` Atan(LiteralOrVariable), /// Returns the angle in radians whose tangent is the quotient of the specified numbers. /// ## IC10 /// `atan2 r? a(r?|num) b(r?|num)` /// ## Slang /// `(number|var).atan2((number|var));` Atan2(LiteralOrVariable, LiteralOrVariable), /// Gets the absolute value of a number. /// ## IC10 /// `abs r? a(r?|num)` /// ## Slang /// `(number|var).abs();` Abs(LiteralOrVariable), /// Rounds a number up to the nearest whole number. /// ## IC10 /// `ceil r? a(r?|num)` /// ## Slang /// `(number|var).ceil();` Ceil(LiteralOrVariable), /// Returns the cosine of the specified angle in radians. /// ## IC10 /// `cos r? a(r?|num)` /// ## Slang /// `(number|var).cos();` Cos(LiteralOrVariable), /// Rounds a number down to the nearest whole number. /// ## In Game /// `floor r? a(r?|num)` /// ## Slang /// `(number|var).floor();` Floor(LiteralOrVariable), /// Computes the natural logarithm of a number. /// ## IC10 /// `log r? a(r?|num)` /// ## Slang /// `(number|var).log();` Log(LiteralOrVariable), /// Computes the maximum of two numbers. /// ## IC10 /// `max r? a(r?|num) b(r?|num)` /// ## Slang /// `(number|var).max((number|var));` Max(LiteralOrVariable, LiteralOrVariable), /// Computes the minimum of two numbers. /// ## IC10 /// `min r? a(r?|num) b(r?|num)` /// ## Slang /// `(number|var).min((number|var));` Min(LiteralOrVariable, LiteralOrVariable), /// Gets a random number between 0 and 1. /// ## IC10 /// `rand r?` /// ## Slang /// `rand();` Rand, /// Returns the sine of the specified angle in radians. /// ## IC10 /// `sin r? a(r?|num)` /// ## Slang /// `(number|var).sin();` Sin(LiteralOrVariable), /// Computes the square root of a number. /// ## IC10 /// `sqrt r? a(r?|num)` /// ## Slang /// `(number|var).sqrt();` Sqrt(LiteralOrVariable), /// Returns the tangent of the specified angle in radians. /// ## IC10 /// `tan r? a(r?|num)` /// ## Slang /// `(number|var).tan();` Tan(LiteralOrVariable), /// Truncates a number by removing the decimal portion. /// ## IC10 /// `trunc r? a(r?|num)` /// ## Slang /// `(number|var).trunc();` Trunc(LiteralOrVariable), } } impl std::fmt::Display for Math { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Math::Acos(a) => write!(f, "acos({})", a), Math::Asin(a) => write!(f, "asin({})", a), Math::Atan(a) => write!(f, "atan({})", a), Math::Atan2(a, b) => write!(f, "atan2({}, {})", a, b), Math::Abs(a) => write!(f, "abs({})", a), Math::Ceil(a) => write!(f, "ceil({})", a), Math::Cos(a) => write!(f, "cos({})", a), Math::Floor(a) => write!(f, "floor({})", a), Math::Log(a) => write!(f, "log({})", a), Math::Max(a, b) => write!(f, "max({}, {})", a, b), Math::Min(a, b) => write!(f, "min({}, {})", a, b), Math::Rand => write!(f, "rand()"), Math::Sin(a) => write!(f, "sin({})", a), Math::Sqrt(a) => write!(f, "sqrt({})", a), Math::Tan(a) => write!(f, "tan({})", a), Math::Trunc(a) => write!(f, "trunc({})", a), } } } documented! { #[derive(Debug, PartialEq, Eq)] pub enum System { /// Pauses execution for exactly 1 tick and then resumes. /// ## In Game /// yield Yield, /// Represents a function that can be called to sleep for a certain amount of time. /// ## In Game /// `sleep a(r?|num)` Sleep(Box>), /// Gets the in-game hash for a specific prefab name. /// ## In Game /// `HASH("prefabName")` Hash(Literal), /// Represents a function which loads a device variable into a register. /// ## In Game /// `l r? d? var` /// ## Examples /// `l r0 d0 Setting` /// `l r1 d5 Pressure` LoadFromDevice(LiteralOrVariable, Literal), /// Function which gets a LogicType from all connected network devices that match /// the provided device hash and name, aggregating them via a batchMode /// ## In Game /// lbn r? deviceHash nameHash logicType batchMode /// ## Examples /// lbn r0 HASH("StructureWallLight") HASH("wallLight") On Minimum LoadBatchNamed( LiteralOrVariable, Box>, Literal, Literal, ), /// Loads a LogicType from all connected network devices, aggregating them via a /// batchMode /// ## In Game /// lb r? deviceHash logicType batchMode /// ## Examples /// lb r0 HASH("StructureWallLight") On Minimum LoadBatch(LiteralOrVariable, Literal, Literal), /// Represents a function which stores a setting into a specific device. /// ## In Game /// `s d? logicType r?` /// ## Example /// `s d0 Setting r0` SetOnDevice(LiteralOrVariable, Literal, Box>), /// 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>), /// 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>, ), } } impl std::fmt::Display for System { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { System::Yield => write!(f, "yield()"), System::Sleep(a) => write!(f, "sleep({})", 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) } } } } #[derive(Debug, PartialEq, Eq)] /// This represents built in functions that cannot be overwritten, but can be invoked by the user as functions. pub enum SysCall { System(System), /// Represents any mathmatical function that can be called. Math(Math), } impl std::fmt::Display for SysCall { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { SysCall::System(s) => write!(f, "{}", s), SysCall::Math(m) => write!(f, "{}", m), } } } impl SysCall { pub fn is_syscall(identifier: &str) -> bool { matches!( identifier, "yield" | "sleep" | "hash" | "loadFromDevice" | "setOnDevice" | "setOnDeviceBatched" | "setOnDeviceBatchedNamed" | "acos" | "asin" | "atan" | "atan2" | "abs" | "ceil" | "cos" | "floor" | "log" | "max" | "min" | "rand" | "sin" | "sqrt" | "tan" | "trunc" ) } }