diff --git a/rust_compiler/libs/parser/src/lib.rs b/rust_compiler/libs/parser/src/lib.rs index 1f26db9..b720174 100644 --- a/rust_compiler/libs/parser/src/lib.rs +++ b/rust_compiler/libs/parser/src/lib.rs @@ -4,7 +4,7 @@ mod test; pub mod sys_call; pub mod tree_node; -use crate::sys_call::System; +use crate::sys_call::{Math, System}; use quick_error::quick_error; use std::io::SeekFrom; use sys_call::SysCall; @@ -1649,6 +1649,7 @@ impl<'a> Parser<'a> { let invocation = self.invocation()?; match invocation.name.node.as_str() { + // System SysCalls "yield" => { check_length(self, &invocation.arguments, 0)?; Ok(SysCall::System(sys_call::System::Yield)) @@ -1822,6 +1823,119 @@ impl<'a> Parser<'a> { expr, ))) } + // Math SysCalls + "acos" => { + check_length(self, &invocation.arguments, 1)?; + let mut args = invocation.arguments.into_iter(); + let tmp = args.next().ok_or(Error::UnexpectedEOF)?; + + Ok(SysCall::Math(Math::Acos(boxed!(tmp)))) + } + "asin" => { + check_length(self, &invocation.arguments, 1)?; + let mut args = invocation.arguments.into_iter(); + let tmp = args.next().ok_or(Error::UnexpectedEOF)?; + + Ok(SysCall::Math(Math::Asin(boxed!(tmp)))) + } + "atan" => { + check_length(self, &invocation.arguments, 1)?; + let mut args = invocation.arguments.into_iter(); + let expr = args.next().ok_or(Error::UnexpectedEOF)?; + + Ok(SysCall::Math(Math::Atan(boxed!(expr)))) + } + "atan2" => { + check_length(self, &invocation.arguments, 2)?; + let mut args = invocation.arguments.into_iter(); + let arg1 = args.next().ok_or(Error::UnexpectedEOF)?; + let arg2 = args.next().ok_or(Error::UnexpectedEOF)?; + + Ok(SysCall::Math(Math::Atan2(boxed!(arg1), boxed!(arg2)))) + } + "abs" => { + check_length(self, &invocation.arguments, 1)?; + let mut args = invocation.arguments.into_iter(); + let expr = args.next().ok_or(Error::UnexpectedEOF)?; + + Ok(SysCall::Math(Math::Abs(boxed!(expr)))) + } + "ceil" => { + check_length(self, &invocation.arguments, 1)?; + let mut args = invocation.arguments.into_iter(); + let arg = args.next().ok_or(Error::UnexpectedEOF)?; + + Ok(SysCall::Math(Math::Ceil(boxed!(arg)))) + } + "cos" => { + check_length(self, &invocation.arguments, 1)?; + let mut args = invocation.arguments.into_iter(); + let arg = args.next().ok_or(Error::UnexpectedEOF)?; + + Ok(SysCall::Math(Math::Cos(boxed!(arg)))) + } + "floor" => { + check_length(self, &invocation.arguments, 1)?; + let mut args = invocation.arguments.into_iter(); + let arg = args.next().ok_or(Error::UnexpectedEOF)?; + + Ok(SysCall::Math(Math::Floor(boxed!(arg)))) + } + "log" => { + check_length(self, &invocation.arguments, 1)?; + let mut args = invocation.arguments.into_iter(); + let arg = args.next().ok_or(Error::UnexpectedEOF)?; + + Ok(SysCall::Math(Math::Log(boxed!(arg)))) + } + "max" => { + check_length(self, &invocation.arguments, 1)?; + let mut args = invocation.arguments.into_iter(); + let arg1 = args.next().ok_or(Error::UnexpectedEOF)?; + let arg2 = args.next().ok_or(Error::UnexpectedEOF)?; + + Ok(SysCall::Math(Math::Max(boxed!(arg1), boxed!(arg2)))) + } + "min" => { + check_length(self, &invocation.arguments, 2)?; + let mut args = invocation.arguments.into_iter(); + let arg1 = args.next().ok_or(Error::UnexpectedEOF)?; + let arg2 = args.next().ok_or(Error::UnexpectedEOF)?; + + Ok(SysCall::Math(Math::Min(boxed!(arg1), boxed!(arg2)))) + } + "rand" => { + check_length(self, &invocation.arguments, 0)?; + Ok(SysCall::Math(Math::Rand)) + } + "sin" => { + check_length(self, &invocation.arguments, 1)?; + let mut args = invocation.arguments.into_iter(); + let arg = args.next().ok_or(Error::UnexpectedEOF)?; + + Ok(SysCall::Math(Math::Sin(boxed!(arg)))) + } + "sqrt" => { + check_length(self, &invocation.arguments, 1)?; + let mut args = invocation.arguments.into_iter(); + let arg = args.next().ok_or(Error::UnexpectedEOF)?; + + Ok(SysCall::Math(Math::Sqrt(boxed!(arg)))) + } + "tan" => { + check_length(self, &invocation.arguments, 1)?; + let mut args = invocation.arguments.into_iter(); + let arg = args.next().ok_or(Error::UnexpectedEOF)?; + + Ok(SysCall::Math(Math::Tan(boxed!(arg)))) + } + "trunc" => { + check_length(self, &invocation.arguments, 1)?; + let mut args = invocation.arguments.into_iter(); + let arg = args.next().ok_or(Error::UnexpectedEOF)?; + + Ok(SysCall::Math(Math::Trunc(boxed!(arg)))) + } _ => Err(Error::UnsupportedKeyword( self.current_span(), self.current_token.clone().ok_or(Error::UnexpectedEOF)?, diff --git a/rust_compiler/libs/parser/src/sys_call.rs b/rust_compiler/libs/parser/src/sys_call.rs index 8102644..cb6e85b 100644 --- a/rust_compiler/libs/parser/src/sys_call.rs +++ b/rust_compiler/libs/parser/src/sys_call.rs @@ -10,67 +10,67 @@ documented! { /// `acos r? a(r?|num)` /// ## Slang /// `(number|var).acos();` - Acos(LiteralOrVariable), + Acos(Box>), /// Returns the angle in radians whose sine is the specified number. /// ## IC10 /// `asin r? a(r?|num)` /// ## Slang /// `(number|var).asin();` - Asin(LiteralOrVariable), + Asin(Box>), /// Returns the angle in radians whose tangent is the specified number. /// ## IC10 /// `atan r? a(r?|num)` /// ## Slang /// `(number|var).atan();` - Atan(LiteralOrVariable), + Atan(Box>), /// 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), + Atan2(Box>, Box>), /// Gets the absolute value of a number. /// ## IC10 /// `abs r? a(r?|num)` /// ## Slang /// `(number|var).abs();` - Abs(LiteralOrVariable), + Abs(Box>), /// Rounds a number up to the nearest whole number. /// ## IC10 /// `ceil r? a(r?|num)` /// ## Slang /// `(number|var).ceil();` - Ceil(LiteralOrVariable), + Ceil(Box>), /// Returns the cosine of the specified angle in radians. /// ## IC10 /// `cos r? a(r?|num)` /// ## Slang /// `(number|var).cos();` - Cos(LiteralOrVariable), + Cos(Box>), /// Rounds a number down to the nearest whole number. /// ## IC10 /// `floor r? a(r?|num)` /// ## Slang /// `(number|var).floor();` - Floor(LiteralOrVariable), + Floor(Box>), /// Computes the natural logarithm of a number. /// ## IC10 /// `log r? a(r?|num)` /// ## Slang /// `(number|var).log();` - Log(LiteralOrVariable), + Log(Box>), /// Computes the maximum of two numbers. /// ## IC10 /// `max r? a(r?|num) b(r?|num)` /// ## Slang /// `(number|var).max((number|var));` - Max(LiteralOrVariable, LiteralOrVariable), + Max(Box>, Box>), /// Computes the minimum of two numbers. /// ## IC10 /// `min r? a(r?|num) b(r?|num)` /// ## Slang /// `(number|var).min((number|var));` - Min(LiteralOrVariable, LiteralOrVariable), + Min(Box>, Box>), /// Gets a random number between 0 and 1. /// ## IC10 /// `rand r?` @@ -82,25 +82,25 @@ documented! { /// `sin r? a(r?|num)` /// ## Slang /// `(number|var).sin();` - Sin(LiteralOrVariable), + Sin(Box>), /// Computes the square root of a number. /// ## IC10 /// `sqrt r? a(r?|num)` /// ## Slang /// `(number|var).sqrt();` - Sqrt(LiteralOrVariable), + Sqrt(Box>), /// Returns the tangent of the specified angle in radians. /// ## IC10 /// `tan r? a(r?|num)` /// ## Slang /// `(number|var).tan();` - Tan(LiteralOrVariable), + Tan(Box>), /// Truncates a number by removing the decimal portion. /// ## IC10 /// `trunc r? a(r?|num)` /// ## Slang /// `(number|var).trunc();` - Trunc(LiteralOrVariable), + Trunc(Box>), } } @@ -231,6 +231,7 @@ impl std::fmt::Display for System { } } +#[allow(clippy::large_enum_variant)] #[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 {