Add support in the parser for the various Math syscalls
This commit is contained in:
@@ -4,7 +4,7 @@ mod test;
|
|||||||
pub mod sys_call;
|
pub mod sys_call;
|
||||||
pub mod tree_node;
|
pub mod tree_node;
|
||||||
|
|
||||||
use crate::sys_call::System;
|
use crate::sys_call::{Math, System};
|
||||||
use quick_error::quick_error;
|
use quick_error::quick_error;
|
||||||
use std::io::SeekFrom;
|
use std::io::SeekFrom;
|
||||||
use sys_call::SysCall;
|
use sys_call::SysCall;
|
||||||
@@ -1649,6 +1649,7 @@ impl<'a> Parser<'a> {
|
|||||||
let invocation = self.invocation()?;
|
let invocation = self.invocation()?;
|
||||||
|
|
||||||
match invocation.name.node.as_str() {
|
match invocation.name.node.as_str() {
|
||||||
|
// System SysCalls
|
||||||
"yield" => {
|
"yield" => {
|
||||||
check_length(self, &invocation.arguments, 0)?;
|
check_length(self, &invocation.arguments, 0)?;
|
||||||
Ok(SysCall::System(sys_call::System::Yield))
|
Ok(SysCall::System(sys_call::System::Yield))
|
||||||
@@ -1822,6 +1823,119 @@ impl<'a> Parser<'a> {
|
|||||||
expr,
|
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(
|
_ => Err(Error::UnsupportedKeyword(
|
||||||
self.current_span(),
|
self.current_span(),
|
||||||
self.current_token.clone().ok_or(Error::UnexpectedEOF)?,
|
self.current_token.clone().ok_or(Error::UnexpectedEOF)?,
|
||||||
|
|||||||
@@ -10,67 +10,67 @@ documented! {
|
|||||||
/// `acos r? a(r?|num)`
|
/// `acos r? a(r?|num)`
|
||||||
/// ## Slang
|
/// ## Slang
|
||||||
/// `(number|var).acos();`
|
/// `(number|var).acos();`
|
||||||
Acos(LiteralOrVariable),
|
Acos(Box<Spanned<Expression>>),
|
||||||
/// Returns the angle in radians whose sine is the specified number.
|
/// Returns the angle in radians whose sine is the specified number.
|
||||||
/// ## IC10
|
/// ## IC10
|
||||||
/// `asin r? a(r?|num)`
|
/// `asin r? a(r?|num)`
|
||||||
/// ## Slang
|
/// ## Slang
|
||||||
/// `(number|var).asin();`
|
/// `(number|var).asin();`
|
||||||
Asin(LiteralOrVariable),
|
Asin(Box<Spanned<Expression>>),
|
||||||
/// Returns the angle in radians whose tangent is the specified number.
|
/// Returns the angle in radians whose tangent is the specified number.
|
||||||
/// ## IC10
|
/// ## IC10
|
||||||
/// `atan r? a(r?|num)`
|
/// `atan r? a(r?|num)`
|
||||||
/// ## Slang
|
/// ## Slang
|
||||||
/// `(number|var).atan();`
|
/// `(number|var).atan();`
|
||||||
Atan(LiteralOrVariable),
|
Atan(Box<Spanned<Expression>>),
|
||||||
/// Returns the angle in radians whose tangent is the quotient of the specified numbers.
|
/// Returns the angle in radians whose tangent is the quotient of the specified numbers.
|
||||||
/// ## IC10
|
/// ## IC10
|
||||||
/// `atan2 r? a(r?|num) b(r?|num)`
|
/// `atan2 r? a(r?|num) b(r?|num)`
|
||||||
/// ## Slang
|
/// ## Slang
|
||||||
/// `(number|var).atan2((number|var));`
|
/// `(number|var).atan2((number|var));`
|
||||||
Atan2(LiteralOrVariable, LiteralOrVariable),
|
Atan2(Box<Spanned<Expression>>, Box<Spanned<Expression>>),
|
||||||
/// Gets the absolute value of a number.
|
/// Gets the absolute value of a number.
|
||||||
/// ## IC10
|
/// ## IC10
|
||||||
/// `abs r? a(r?|num)`
|
/// `abs r? a(r?|num)`
|
||||||
/// ## Slang
|
/// ## Slang
|
||||||
/// `(number|var).abs();`
|
/// `(number|var).abs();`
|
||||||
Abs(LiteralOrVariable),
|
Abs(Box<Spanned<Expression>>),
|
||||||
/// Rounds a number up to the nearest whole number.
|
/// Rounds a number up to the nearest whole number.
|
||||||
/// ## IC10
|
/// ## IC10
|
||||||
/// `ceil r? a(r?|num)`
|
/// `ceil r? a(r?|num)`
|
||||||
/// ## Slang
|
/// ## Slang
|
||||||
/// `(number|var).ceil();`
|
/// `(number|var).ceil();`
|
||||||
Ceil(LiteralOrVariable),
|
Ceil(Box<Spanned<Expression>>),
|
||||||
/// Returns the cosine of the specified angle in radians.
|
/// Returns the cosine of the specified angle in radians.
|
||||||
/// ## IC10
|
/// ## IC10
|
||||||
/// `cos r? a(r?|num)`
|
/// `cos r? a(r?|num)`
|
||||||
/// ## Slang
|
/// ## Slang
|
||||||
/// `(number|var).cos();`
|
/// `(number|var).cos();`
|
||||||
Cos(LiteralOrVariable),
|
Cos(Box<Spanned<Expression>>),
|
||||||
/// Rounds a number down to the nearest whole number.
|
/// Rounds a number down to the nearest whole number.
|
||||||
/// ## IC10
|
/// ## IC10
|
||||||
/// `floor r? a(r?|num)`
|
/// `floor r? a(r?|num)`
|
||||||
/// ## Slang
|
/// ## Slang
|
||||||
/// `(number|var).floor();`
|
/// `(number|var).floor();`
|
||||||
Floor(LiteralOrVariable),
|
Floor(Box<Spanned<Expression>>),
|
||||||
/// Computes the natural logarithm of a number.
|
/// Computes the natural logarithm of a number.
|
||||||
/// ## IC10
|
/// ## IC10
|
||||||
/// `log r? a(r?|num)`
|
/// `log r? a(r?|num)`
|
||||||
/// ## Slang
|
/// ## Slang
|
||||||
/// `(number|var).log();`
|
/// `(number|var).log();`
|
||||||
Log(LiteralOrVariable),
|
Log(Box<Spanned<Expression>>),
|
||||||
/// Computes the maximum of two numbers.
|
/// Computes the maximum of two numbers.
|
||||||
/// ## IC10
|
/// ## IC10
|
||||||
/// `max r? a(r?|num) b(r?|num)`
|
/// `max r? a(r?|num) b(r?|num)`
|
||||||
/// ## Slang
|
/// ## Slang
|
||||||
/// `(number|var).max((number|var));`
|
/// `(number|var).max((number|var));`
|
||||||
Max(LiteralOrVariable, LiteralOrVariable),
|
Max(Box<Spanned<Expression>>, Box<Spanned<Expression>>),
|
||||||
/// Computes the minimum of two numbers.
|
/// Computes the minimum of two numbers.
|
||||||
/// ## IC10
|
/// ## IC10
|
||||||
/// `min r? a(r?|num) b(r?|num)`
|
/// `min r? a(r?|num) b(r?|num)`
|
||||||
/// ## Slang
|
/// ## Slang
|
||||||
/// `(number|var).min((number|var));`
|
/// `(number|var).min((number|var));`
|
||||||
Min(LiteralOrVariable, LiteralOrVariable),
|
Min(Box<Spanned<Expression>>, Box<Spanned<Expression>>),
|
||||||
/// Gets a random number between 0 and 1.
|
/// Gets a random number between 0 and 1.
|
||||||
/// ## IC10
|
/// ## IC10
|
||||||
/// `rand r?`
|
/// `rand r?`
|
||||||
@@ -82,25 +82,25 @@ documented! {
|
|||||||
/// `sin r? a(r?|num)`
|
/// `sin r? a(r?|num)`
|
||||||
/// ## Slang
|
/// ## Slang
|
||||||
/// `(number|var).sin();`
|
/// `(number|var).sin();`
|
||||||
Sin(LiteralOrVariable),
|
Sin(Box<Spanned<Expression>>),
|
||||||
/// Computes the square root of a number.
|
/// Computes the square root of a number.
|
||||||
/// ## IC10
|
/// ## IC10
|
||||||
/// `sqrt r? a(r?|num)`
|
/// `sqrt r? a(r?|num)`
|
||||||
/// ## Slang
|
/// ## Slang
|
||||||
/// `(number|var).sqrt();`
|
/// `(number|var).sqrt();`
|
||||||
Sqrt(LiteralOrVariable),
|
Sqrt(Box<Spanned<Expression>>),
|
||||||
/// Returns the tangent of the specified angle in radians.
|
/// Returns the tangent of the specified angle in radians.
|
||||||
/// ## IC10
|
/// ## IC10
|
||||||
/// `tan r? a(r?|num)`
|
/// `tan r? a(r?|num)`
|
||||||
/// ## Slang
|
/// ## Slang
|
||||||
/// `(number|var).tan();`
|
/// `(number|var).tan();`
|
||||||
Tan(LiteralOrVariable),
|
Tan(Box<Spanned<Expression>>),
|
||||||
/// Truncates a number by removing the decimal portion.
|
/// Truncates a number by removing the decimal portion.
|
||||||
/// ## IC10
|
/// ## IC10
|
||||||
/// `trunc r? a(r?|num)`
|
/// `trunc r? a(r?|num)`
|
||||||
/// ## Slang
|
/// ## Slang
|
||||||
/// `(number|var).trunc();`
|
/// `(number|var).trunc();`
|
||||||
Trunc(LiteralOrVariable),
|
Trunc(Box<Spanned<Expression>>),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,6 +231,7 @@ impl std::fmt::Display for System {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
/// This represents built in functions that cannot be overwritten, but can be invoked by the user as functions.
|
/// This represents built in functions that cannot be overwritten, but can be invoked by the user as functions.
|
||||||
pub enum SysCall {
|
pub enum SysCall {
|
||||||
|
|||||||
Reference in New Issue
Block a user