From b818a162eeb3ed2ff72cdd5ff4ac6975ea104718 Mon Sep 17 00:00:00 2001 From: Sandu Liviu Catalin Date: Thu, 14 Apr 2016 03:08:06 +0300 Subject: [PATCH] Initial implementation of the standard math library. Implemented utilities to convert between fundamental types. Implemented helper functions to retrieve numeric values from the stack at all costs. Implemented various delegates on the long integer types to mimic the standard types. Moved most of the stack utilities in a separate source. Various other fixes and improvements. --- cbp/Module.cbp | 2 + source/Base/Shared.cpp | 129 ---- source/Base/Shared.hpp | 683 +++++++++++++++----- source/Base/Stack.cpp | 413 ++++++++++++ source/Base/Stack.hpp | 172 +++++ source/Command.cpp | 1 + source/Constants.cpp | 14 + source/Entity/Blip.cpp | 1 + source/Entity/Checkpoint.cpp | 1 + source/Entity/Forcefield.cpp | 1 + source/Entity/Keybind.cpp | 3 +- source/Entity/Object.cpp | 1 + source/Entity/Pickup.cpp | 3 +- source/Entity/Player.cpp | 1 + source/Entity/Sprite.cpp | 1 + source/Entity/Textdraw.cpp | 1 + source/Entity/Vehicle.cpp | 1 + source/Library/Chrono.cpp | 2 +- source/Library/Crypt.cpp | 1 + source/Library/Math.cpp | 1142 ++++++++++++++++++++++++++++++++++ source/Library/Math.hpp | 12 + source/Library/Numeric.cpp | 14 +- source/Library/Numeric.hpp | 82 ++- source/Library/String.cpp | 1 + source/Library/SysEnv.cpp | 1 + source/Library/SysPath.cpp | 1 + source/Register.cpp | 2 + source/Routine.cpp | 1 + 28 files changed, 2402 insertions(+), 285 deletions(-) create mode 100644 source/Base/Stack.cpp create mode 100644 source/Base/Stack.hpp diff --git a/cbp/Module.cbp b/cbp/Module.cbp index cb4a9a2b..a2028a33 100644 --- a/cbp/Module.cbp +++ b/cbp/Module.cbp @@ -431,6 +431,8 @@ + + diff --git a/source/Base/Shared.cpp b/source/Base/Shared.cpp index b140b0bb..e71dd490 100644 --- a/source/Base/Shared.cpp +++ b/source/Base/Shared.cpp @@ -5,16 +5,7 @@ #include "Library/String.hpp" // ------------------------------------------------------------------------------------------------ -#include "Base/AABB.hpp" -#include "Base/Circle.hpp" #include "Base/Color3.hpp" -#include "Base/Color4.hpp" -#include "Base/Quaternion.hpp" -#include "Base/Sphere.hpp" -#include "Base/Vector2.hpp" -#include "Base/Vector2i.hpp" -#include "Base/Vector3.hpp" -#include "Base/Vector4.hpp" // ------------------------------------------------------------------------------------------------ #include @@ -23,9 +14,6 @@ #include #include -// ------------------------------------------------------------------------------------------------ -#include - // ------------------------------------------------------------------------------------------------ namespace SqMod { @@ -67,123 +55,6 @@ Function & NullFunction() return f; } -// ------------------------------------------------------------------------------------------------ -Object BufferToStrObj(const Buffer & b) -{ - // Obtain the initial stack size - const StackGuard sg(DefaultVM::Get()); - // Push the string onto the stack - sq_pushstring(DefaultVM::Get(), b.Data(), b.Position()); - // Obtain the object from the stack and return it - return Var< Object >(DefaultVM::Get(), -1).value; -} - -// -------------------------------------------------------------------------------------------- -Object BufferToStrObj(const Buffer & b, Uint32 size) -{ - // Perform a range check on the specified buffer - if (size > b.Capacity()) - { - STHROWF("The specified buffer size is out of range: %u >= %u", size, b.Capacity()); - } - // Obtain the initial stack size - const StackGuard sg(DefaultVM::Get()); - // Push the string onto the stack - sq_pushstring(DefaultVM::Get(), b.Data(), size); - // Obtain the object from the stack and return it - return Var< Object >(DefaultVM::Get(), -1).value; -} - -// -------------------------------------------------------------------------------------------- -StackStrF::StackStrF(HSQUIRRELVM vm, SQInteger idx, bool fmt) - : mPtr(nullptr) - , mLen(-1) - , mRes(SQ_OK) - , mObj() - , mVM(vm) -{ - const Int32 top = sq_gettop(vm); - // Reset the converted value object - sq_resetobject(&mObj); - // Was the string or value specified? - if (top <= (idx - 1)) - { - mRes = sq_throwerror(vm, "Missing string or value"); - } - // Do we have enough values to call the format function and are we allowed to? - else if (top > idx && fmt) - { - // Pointer to the generated string - SStr str = nullptr; - // Attempt to generate the specified string format - mRes = sqstd_format(vm, idx, &mLen, &str); - // Did the format succeeded but ended up with a null string pointer? - if (SQ_SUCCEEDED(mRes) && !str) - { - mRes = sq_throwerror(vm, "Unable to generate the string"); - } - else - { - mPtr = const_cast< CSStr >(str); - } - } - // Is the value on the stack an actual string? - else if (sq_gettype(vm, idx) == OT_STRING) - { - // Obtain a reference to the string object - mRes = sq_getstackobj(vm, idx, &mObj); - // Could we retrieve the object from the stack? - if (SQ_SUCCEEDED(mRes)) - { - // Keep a strong reference to the object - sq_addref(vm, &mObj); - // Attempt to retrieve the string value from the stack - mRes = sq_getstring(vm, idx, &mPtr); - } - // Did the retrieval succeeded but ended up with a null string pointer? - if (SQ_SUCCEEDED(mRes) && !mPtr) - { - mRes = sq_throwerror(vm, "Unable to retrieve the string"); - } - } - // We have to try and convert it to string - else - { - // Attempt to convert the value from the stack to a string - mRes = sq_tostring(vm, idx); - // Could we convert the specified value to string? - if (SQ_SUCCEEDED(mRes)) - { - // Obtain a reference to the resulted object - mRes = sq_getstackobj(vm, -1, &mObj); - // Could we retrieve the object from the stack? - if (SQ_SUCCEEDED(mRes)) - { - // Keep a strong reference to the object - sq_addref(vm, &mObj); - // Attempt to obtain the string pointer - mRes = sq_getstring(vm, -1, &mPtr); - } - } - // Pop a value from the stack regardless of the result - sq_pop(vm, 1); - // Did the retrieval succeeded but ended up with a null string pointer? - if (SQ_SUCCEEDED(mRes) && !mPtr) - { - mRes = sq_throwerror(vm, "Unable to retrieve the value"); - } - } -} - -// ------------------------------------------------------------------------------------------------ -StackStrF::~StackStrF() -{ - if (mVM && !sq_isnull(mObj)) - { - sq_release(mVM, &mObj); - } -} - // ------------------------------------------------------------------------------------------------ bool SToB(CSStr str) { diff --git a/source/Base/Shared.hpp b/source/Base/Shared.hpp index 151467a7..ed28fce3 100644 --- a/source/Base/Shared.hpp +++ b/source/Base/Shared.hpp @@ -25,107 +25,6 @@ extern PluginFuncs* _Func; extern PluginCallbacks* _Clbk; extern PluginInfo* _Info; -/* ------------------------------------------------------------------------------------------------ - * Implements RAII to restore the VM stack to it's initial size on function exit. -*/ -struct StackGuard -{ - /* -------------------------------------------------------------------------------------------- - * Default constructor. - */ - StackGuard() - : m_VM(DefaultVM::Get()), m_Top(sq_gettop(m_VM)) - { - /* ... */ - } - - /* -------------------------------------------------------------------------------------------- - * Base constructor. - */ - StackGuard(HSQUIRRELVM vm) - : m_VM(vm), m_Top(sq_gettop(vm)) - { - /* ... */ - } - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - StackGuard(const StackGuard &) = delete; - - /* -------------------------------------------------------------------------------------------- - * Move constructor. (disabled) - */ - StackGuard(StackGuard &&) = delete; - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~StackGuard() - { - sq_pop(m_VM, sq_gettop(m_VM) - m_Top); - } - - /* -------------------------------------------------------------------------------------------- - * Copy assignment operator. (disabled) - */ - StackGuard & operator = (const StackGuard &) = delete; - - /* -------------------------------------------------------------------------------------------- - * Move assignment operator. (disabled) - */ - StackGuard & operator = (StackGuard &&) = delete; - -private: - - // -------------------------------------------------------------------------------------------- - HSQUIRRELVM m_VM; // The VM where the stack should be restored. - Int32 m_Top; // The top of the stack when this instance was created. -}; - -/* ------------------------------------------------------------------------------------------------ - * Helper structure for retrieving a value from the stack as a string or a formatted string. -*/ -struct StackStrF -{ - // -------------------------------------------------------------------------------------------- - CSStr mPtr; // Pointer to the C string that was retrieved. - SQInteger mLen; // The string length if it could be retrieved. - SQRESULT mRes; // The result of the retrieval attempts. - HSQOBJECT mObj; // Strong reference to the string object. - HSQUIRRELVM mVM; // The associated virtual machine. - - /* -------------------------------------------------------------------------------------------- - * Base constructor. - */ - StackStrF(HSQUIRRELVM vm, SQInteger idx, bool fmt = true); - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - StackStrF(const StackStrF & o) = delete; - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - StackStrF(StackStrF && o) = delete; - - /* -------------------------------------------------------------------------------------------- - * Destructor. - */ - ~StackStrF(); - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - StackStrF & operator = (const StackStrF & o) = delete; - - /* -------------------------------------------------------------------------------------------- - * Copy constructor. (disabled) - */ - StackStrF & operator = (StackStrF && o) = delete; -}; - /* ------------------------------------------------------------------------------------------------ * Perform an equality comparison between two values taking into account floating point issues. */ @@ -218,31 +117,549 @@ template <> inline bool EpsGtEq(const Float64 a, const Float64 b) return !EpsEq(a, b) || (a - b) > 0.000000001d; } +/* ------------------------------------------------------------------------------------------------ + * +*/ +template < typename T > struct ConvTo +{ + // -------------------------------------------------------------------------------------------- + static constexpr T Min = std::numeric_limits< T >::min(); + static constexpr T Max = std::numeric_limits< T >::max(); + + // -------------------------------------------------------------------------------------------- + template < typename U > static inline T From(U v) + { + if (v > Max) + { + return Max; + } + else if (v < Min) + { + return Min; + } + return static_cast< T >(v); + } +}; + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int8 ConvTo< Int8 >::From< Uint8 >(Uint8 v) +{ + return (v >= static_cast< Uint8 >(Max)) ? Max : static_cast< Int8 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int8 ConvTo< Int8 >::From< Uint16 >(Uint16 v) +{ + return (v >= static_cast< Uint16 >(Max)) ? Max : static_cast< Int8 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int8 ConvTo< Int8 >::From< Uint32 >(Uint32 v) +{ + return (v >= static_cast< Uint32 >(Max)) ? Max : static_cast< Int8 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int8 ConvTo< Int8 >::From< Uint64 >(Uint64 v) +{ + return (v >= static_cast< Uint64 >(Max)) ? Max : static_cast< Int8 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int16 ConvTo< Int16 >::From< Uint8 >(Uint8 v) +{ + return static_cast< Int16 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int16 ConvTo< Int16 >::From< Uint16 >(Uint16 v) +{ + return (v >= static_cast< Uint16 >(Max)) ? Max : static_cast< Int16 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int16 ConvTo< Int16 >::From< Uint32 >(Uint32 v) +{ + return (v >= static_cast< Uint32 >(Max)) ? Max : static_cast< Int16 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int16 ConvTo< Int16 >::From< Uint64 >(Uint64 v) +{ + return (v >= static_cast< Uint64 >(Max)) ? Max : static_cast< Int16 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int32 ConvTo< Int32 >::From< Uint8 >(Uint8 v) +{ + return static_cast< Int32 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int32 ConvTo< Int32 >::From< Uint16 >(Uint16 v) +{ + return static_cast< Int32 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int32 ConvTo< Int32 >::From< Uint32 >(Uint32 v) +{ + return (v >= static_cast< Uint32 >(Max)) ? Max : static_cast< Int32 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int32 ConvTo< Int32 >::From< Uint64 >(Uint64 v) +{ + return (v >= static_cast< Uint64 >(Max)) ? Max : static_cast< Int32 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint8 ConvTo< Uint8 >::From< Int8 >(Int8 v) +{ + return (v <= 0) ? 0 : static_cast< Uint8 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint8 ConvTo< Uint8 >::From< Int16 >(Int16 v) +{ + if (v <= 0) + { + return 0; + } + else if (v >= static_cast< Int16 >(Max)) + { + return Max; + } + return static_cast< Uint8 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint8 ConvTo< Uint8 >::From< Int32 >(Int32 v) +{ + if (v <= 0) + { + return 0; + } + else if (v >= static_cast< Int32 >(Max)) + { + return Max; + } + return static_cast< Uint8 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint8 ConvTo< Uint8 >::From< Int64 >(Int64 v) +{ + if (v <= 0) + { + return 0; + } + else if (v >= static_cast< Int64 >(Max)) + { + return Max; + } + return static_cast< Uint8 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint16 ConvTo< Uint16 >::From< Int8 >(Int8 v) +{ + return (v <= 0) ? 0 : static_cast< Uint16 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint16 ConvTo< Uint16 >::From< Int16 >(Int16 v) +{ + return (v <= 0) ? 0 : static_cast< Uint16 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint16 ConvTo< Uint16 >::From< Int32 >(Int32 v) +{ + if (v <= 0) + { + return 0; + } + else if (v >= static_cast< Int32 >(Max)) + { + return Max; + } + return static_cast< Uint16 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint16 ConvTo< Uint16 >::From< Int64 >(Int64 v) +{ + if (v <= 0) + { + return 0; + } + else if (v >= static_cast< Int64 >(Max)) + { + return Max; + } + return static_cast< Uint16 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint32 ConvTo< Uint32 >::From< Int8 >(Int8 v) +{ + return (v <= 0) ? 0 : static_cast< Uint32 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint32 ConvTo< Uint32 >::From< Int16 >(Int16 v) +{ + return (v <= 0) ? 0 : static_cast< Uint32 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint32 ConvTo< Uint32 >::From< Int32 >(Int32 v) +{ + return (v <= 0) ? 0 : static_cast< Uint32 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint32 ConvTo< Uint32 >::From< Int64 >(Int64 v) +{ + if (v <= 0) + { + return 0; + } + else if (v >= static_cast< Int64 >(Max)) + { + return Max; + } + return static_cast< Uint32 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int8 ConvTo< Int8 >::From< Float32 >(Float32 v) +{ + if (EpsLt(v, static_cast< Float32 >(Min))) + { + return Min; + } + else if (EpsGt(v, static_cast< Float32 >(Max))) + { + return Max; + } + return static_cast< Int8 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int16 ConvTo< Int16 >::From< Float32 >(Float32 v) +{ + if (EpsLt(v, static_cast< Float32 >(Min))) + { + return Min; + } + else if (EpsGt(v, static_cast< Float32 >(Max))) + { + return Max; + } + return static_cast< Int16 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int32 ConvTo< Int32 >::From< Float32 >(Float32 v) +{ + if (EpsLt(v, static_cast< Float32 >(Min))) + { + return Min; + } + else if (EpsGt(v, static_cast< Float32 >(Max))) + { + return Max; + } + return static_cast< Int32 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int8 ConvTo< Int8 >::From< Float64 >(Float64 v) +{ + if (EpsLt(v, static_cast< Float64 >(Min))) + { + return Min; + } + else if (EpsGt(v, static_cast< Float64 >(Max))) + { + return Max; + } + return static_cast< Int8 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int16 ConvTo< Int16 >::From< Float64 >(Float64 v) +{ + if (EpsLt(v, static_cast< Float64 >(Min))) + { + return Min; + } + else if (EpsGt(v, static_cast< Float64 >(Max))) + { + return Max; + } + return static_cast< Int16 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Int32 ConvTo< Int32 >::From< Float64 >(Float64 v) +{ + if (EpsLt(v, static_cast< Float64 >(Min))) + { + return Min; + } + else if (EpsGt(v, static_cast< Float64 >(Max))) + { + return Max; + } + return static_cast< Int32 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint8 ConvTo< Uint8 >::From< Float32 >(Float32 v) +{ + if (EpsLt(v, static_cast< Float32 >(Min))) + { + return Min; + } + else if (EpsGt(v, static_cast< Float32 >(Max))) + { + return Max; + } + return static_cast< Uint8 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint16 ConvTo< Uint16 >::From< Float32 >(Float32 v) +{ + if (EpsLt(v, static_cast< Float32 >(Min))) + { + return Min; + } + else if (EpsGt(v, static_cast< Float32 >(Max))) + { + return Max; + } + return static_cast< Uint16 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint32 ConvTo< Uint32 >::From< Float32 >(Float32 v) +{ + if (EpsLt(v, static_cast< Float32 >(Min))) + { + return Min; + } + else if (EpsGt(v, static_cast< Float32 >(Max))) + { + return Max; + } + return static_cast< Uint32 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint8 ConvTo< Uint8 >::From< Float64 >(Float64 v) +{ + if (EpsLt(v, static_cast< Float64 >(Min))) + { + return Min; + } + else if (EpsGt(v, static_cast< Float64 >(Max))) + { + return Max; + } + return static_cast< Uint8 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint16 ConvTo< Uint16 >::From< Float64 >(Float64 v) +{ + if (EpsLt(v, static_cast< Float64 >(Min))) + { + return Min; + } + else if (EpsGt(v, static_cast< Float64 >(Max))) + { + return Max; + } + return static_cast< Uint16 >(v); +} + +// ------------------------------------------------------------------------------------------------ +template <> template <> inline Uint32 ConvTo< Uint32 >::From< Float64 >(Float64 v) +{ + if (EpsLt(v, static_cast< Float64 >(Min))) + { + return Min; + } + else if (EpsGt(v, static_cast< Float64 >(Max))) + { + return Max; + } + return static_cast< Uint32 >(v); +} + +/* ------------------------------------------------------------------------------------------------ + * Convert other numeric values to signed long long integer. +*/ +template <> struct ConvTo< Int64 > +{ + // -------------------------------------------------------------------------------------------- + static constexpr Int64 Min = std::numeric_limits< Int64 >::min(); + static constexpr Int64 Max = std::numeric_limits< Int64 >::max(); + + // -------------------------------------------------------------------------------------------- + template < typename T > static inline Int64 From(T v) + { + return static_cast< Int64 >(v); + } +}; + +// ------------------------------------------------------------------------------------------------ +template <> inline Int64 ConvTo< Int64 >::From< Uint64 >(Uint64 v) +{ + return (v >= static_cast< Uint64 >(Max)) ? Max : static_cast< Int64 >(v); +} + +/* ------------------------------------------------------------------------------------------------ + * Convert other numeric values to unsigned long long integer. +*/ +template <> struct ConvTo< Uint64 > +{ + // -------------------------------------------------------------------------------------------- + static constexpr Uint64 Min = std::numeric_limits< Uint64 >::min(); + static constexpr Uint64 Max = std::numeric_limits< Uint64 >::max(); + + // -------------------------------------------------------------------------------------------- + template < typename T > static inline Uint64 From(T v) + { + return (v <= static_cast< T >(0)) ? 0 : static_cast< Uint64 >(v); + } +}; + +// ------------------------------------------------------------------------------------------------ +template <> inline Uint64 ConvTo< Uint64 >::From< Float32 >(Float32 v) +{ + return From(ConvTo< Int64 >::From(v)); +} + +// ------------------------------------------------------------------------------------------------ +template <> inline Uint64 ConvTo< Uint64 >::From< Float64 >(Float64 v) +{ + return From(ConvTo< Int64 >::From(v)); +} + +/* ------------------------------------------------------------------------------------------------ + * Convert other numeric values to a floating point value. +*/ +template <> struct ConvTo< Float32 > +{ + // -------------------------------------------------------------------------------------------- + static constexpr Float32 Min = std::numeric_limits< Float32 >::min(); + static constexpr Float32 Max = std::numeric_limits< Float32 >::max(); + + // -------------------------------------------------------------------------------------------- + template < typename T > static inline Float32 From(T v) + { + return static_cast< Float32 >(v); + } +}; + +// ------------------------------------------------------------------------------------------------ +template <> inline Float32 ConvTo< Float32 >::From< Float64 >(Float64 v) +{ + if (EpsGt(v, static_cast< Float64 >(Max))) + { + return Max; + } + else if (EpsLt(v, static_cast< Float64 >(Min))) + { + return Min; + } + return static_cast< Float32 >(v); +} + +/* ------------------------------------------------------------------------------------------------ + * Convert other numeric values to a double floating point value. +*/ +template <> struct ConvTo< Float64 > +{ + // -------------------------------------------------------------------------------------------- + static constexpr Float64 Min = std::numeric_limits< Float64 >::min(); + static constexpr Float64 Max = std::numeric_limits< Float64 >::max(); + + // -------------------------------------------------------------------------------------------- + template < typename T > static inline Float64 From(T v) + { + return static_cast< Float64 >(v); + } +}; + /* ------------------------------------------------------------------------------------------------ * Force a value to be within a certain range. */ template< typename T > inline T Clamp(T val, T min, T max) { - return val < min ? min : (val > max ? max : val); + // Is the specified value bellow the minimum? + if (val < min) + { + return min; + } + // Is the specified value above the maximum? + else if (val > max) + { + return max; + } + // Return the value as is + return val; +} + +/* ------------------------------------------------------------------------------------------------ + * Force a value to be within a certain range. +*/ +template<> inline Float32 Clamp(Float32 val, Float32 min, Float32 max) +{ + // Is the specified value bellow the minimum? + if (EpsLt(val, min)) + { + return min; + } + // Is the specified value above the maximum? + else if (EpsGt(val, max)) + { + return max; + } + // Return the value as is + return val; +} + +/* ------------------------------------------------------------------------------------------------ + * Force a value to be within a certain range. +*/ +template<> inline Float64 Clamp(Float64 val, Float64 min, Float64 max) +{ + // Is the specified value bellow the minimum? + if (EpsLt(val, min)) + { + return min; + } + // Is the specified value above the maximum? + else if (EpsGt(val, max)) + { + return max; + } + // Return the value as is + return val; } /* ------------------------------------------------------------------------------------------------ * Force a value to be the boundaries of the specified type. */ -template< typename T, typename U > inline U ClampL(T val) +template < typename T, typename U > inline U ClampL(T v) { - // Is the specified value bellow the minimum? - if (val < std::numeric_limits< U >::min()) - { - return std::numeric_limits< U >::min(); - } - // Is the specified value above the maximum? - else if (val > std::numeric_limits< U >::max()) - { - return std::numeric_limits< U >::max(); - } - // Return the value as is - return static_cast< U >(val); + return ConvTo< U >::From(v); } /* ------------------------------------------------------------------------------------------------ @@ -289,42 +706,6 @@ Array & NullArray(); */ Function & NullFunction(); -/* ------------------------------------------------------------------------------------------------ - * Create a script string object from a buffer. -*/ -Object BufferToStrObj(const Buffer & b); - -/* ------------------------------------------------------------------------------------------------ - * Create a script string object from a portion of a buffer. -*/ -Object BufferToStrObj(const Buffer & b, Uint32 size); - -/* ------------------------------------------------------------------------------------------------ - * Create a script object from the specified value on the default VM. -*/ -template < typename T > Object MakeObject(const T & v) -{ - // Remember the current stack size - const StackGuard sg; - // Transform the specified value into a script object - PushVar< T >(DefaultVM::Get(), v); - // Get the object from the stack and return it - return Var< Object >(DefaultVM::Get(), -1).value; -} - -/* ------------------------------------------------------------------------------------------------ - * Create a script object from the specified value on the specified VM. -*/ -template < typename T > Object MakeObject(HSQUIRRELVM vm, const T & v) -{ - // Remember the current stack size - const StackGuard sg; - // Transform the specified value into a script object - PushVar< T >(vm, v); - // Get the object from the stack and return it - return Var< Object >(vm, -1).value; -} - /* ------------------------------------------------------------------------------------------------ * Simple function to check whether the specified string can be considered as a boolean value */ diff --git a/source/Base/Stack.cpp b/source/Base/Stack.cpp new file mode 100644 index 00000000..fd4c70f3 --- /dev/null +++ b/source/Base/Stack.cpp @@ -0,0 +1,413 @@ +// ------------------------------------------------------------------------------------------------ +#include "Base/Stack.hpp" +#include "Base/Shared.hpp" +#include "Base/Buffer.hpp" +#include "Library/Numeric.hpp" + +// ------------------------------------------------------------------------------------------------ +#include + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +SQInteger PopStackInteger(HSQUIRRELVM vm, SQInteger idx) +{ + // Identify which type must be extracted + switch (sq_gettype(vm, idx)) + { + case OT_INTEGER: + { + SQInteger val; + sq_getinteger(vm, idx, &val); + return val; + } break; + case OT_FLOAT: + { + SQFloat val; + sq_getfloat(vm, idx, &val); + return ConvTo< SQInteger >::From(val); + } break; + case OT_BOOL: + { + SQBool val; + sq_getbool(vm, idx, &val); + return static_cast< SQInteger >(val); + } break; + case OT_STRING: + { + CSStr val = nullptr; + // Attempt to retrieve and convert the string + if (SQ_SUCCEEDED(sq_getstring(vm, idx, &val)) && val != nullptr && *val != '\0') + { + return ConvTo< SQInteger >::From(std::strtoll(val, nullptr, 10)); + } + } break; + case OT_ARRAY: + case OT_TABLE: + case OT_CLASS: + case OT_USERDATA: + { + return sq_getsize(vm, idx); + } break; + case OT_INSTANCE: + { + // Attempt to treat the value as a signed long instance + try + { + return ConvTo< SQInteger >::From(Var< const SLongInt & >(vm, idx).value.GetNum()); + } + catch (...) + { + // Just ignore it... + } + // Attempt to treat the value as a unsigned long instance + try + { + return ConvTo< SQInteger >::From(Var< const ULongInt & >(vm, idx).value.GetNum()); + } + catch (...) + { + // Just ignore it... + } + // Attempt to get the size of the instance as a fallback + return sq_getsize(vm, idx); + } break; + default: break; + } + // Default to 0 + return 0; +} + +// ------------------------------------------------------------------------------------------------ +SQFloat PopStackFloat(HSQUIRRELVM vm, SQInteger idx) +{ + // Identify which type must be extracted + switch (sq_gettype(vm, idx)) + { + case OT_FLOAT: + { + SQFloat val; + sq_getfloat(vm, idx, &val); + return val; + } break; + case OT_INTEGER: + { + SQInteger val; + sq_getinteger(vm, idx, &val); + return ConvTo< SQFloat >::From(val); + } break; + case OT_BOOL: + { + SQBool val; + sq_getbool(vm, idx, &val); + return ConvTo< SQFloat >::From(val); + } break; + case OT_STRING: + { + CSStr val = nullptr; + // Attempt to retrieve and convert the string + if (SQ_SUCCEEDED(sq_getstring(vm, idx, &val)) && val != nullptr && *val != '\0') + { +#ifdef SQUSEDOUBLE + return std::strtod(val, nullptr); +#else + return std::strtof(val, nullptr); +#endif // SQUSEDOUBLE + } + } break; + case OT_ARRAY: + case OT_TABLE: + case OT_CLASS: + case OT_USERDATA: + { + return ConvTo< SQFloat >::From(sq_getsize(vm, idx)); + } break; + case OT_INSTANCE: + { + // Attempt to treat the value as a signed long instance + try + { + return ConvTo< SQFloat >::From(Var< const SLongInt & >(vm, idx).value.GetNum()); + } + catch (...) + { + // Just ignore it... + } + // Attempt to treat the value as a unsigned long instance + try + { + return ConvTo< SQFloat >::From(Var< const ULongInt & >(vm, idx).value.GetNum()); + } + catch (...) + { + // Just ignore it... + } + // Attempt to get the size of the instance as a fallback + return ConvTo< SQFloat >::From(sq_getsize(vm, idx)); + } break; + default: break; + } + // Default to 0 + return 0.0; +} + +// ------------------------------------------------------------------------------------------------ +Int64 PopStackLong(HSQUIRRELVM vm, SQInteger idx) +{ + // Identify which type must be extracted + switch (sq_gettype(vm, idx)) + { + case OT_INTEGER: + { + SQInteger val; + sq_getinteger(vm, idx, &val); + return static_cast< Int64 >(val); + } break; + case OT_FLOAT: + { + SQFloat val; + sq_getfloat(vm, idx, &val); + return ConvTo< Int64 >::From(val); + } break; + case OT_BOOL: + { + SQBool val; + sq_getbool(vm, idx, &val); + return static_cast< Int64 >(val); + } break; + case OT_STRING: + { + CSStr val = nullptr; + // Attempt to retrieve and convert the string + if (SQ_SUCCEEDED(sq_getstring(vm, idx, &val)) && val != nullptr && *val != '\0') + { + return std::strtoll(val, nullptr, 10); + } + } break; + case OT_ARRAY: + case OT_TABLE: + case OT_CLASS: + case OT_USERDATA: + { + return static_cast< Int64 >(sq_getsize(vm, idx)); + } break; + case OT_INSTANCE: + { + // Attempt to treat the value as a signed long instance + try + { + return Var< const SLongInt & >(vm, idx).value.GetNum(); + } + catch (...) + { + // Just ignore it... + } + // Attempt to treat the value as a unsigned long instance + try + { + return ConvTo< Int64 >::From(Var< const ULongInt & >(vm, idx).value.GetNum()); + } + catch (...) + { + // Just ignore it... + } + // Attempt to get the size of the instance as a fallback + return static_cast< Int64 >(sq_getsize(vm, idx)); + } break; + default: break; + } + // Default to 0 + return 0; +} + +// ------------------------------------------------------------------------------------------------ +Uint64 PopStackULong(HSQUIRRELVM vm, SQInteger idx) +{ + // Identify which type must be extracted + switch (sq_gettype(vm, idx)) + { + case OT_INTEGER: + { + SQInteger val; + sq_getinteger(vm, idx, &val); + return ConvTo< Uint64 >::From(val); + } break; + case OT_FLOAT: + { + SQFloat val; + sq_getfloat(vm, idx, &val); + return ConvTo< Uint64 >::From(val); + } break; + case OT_BOOL: + { + SQBool val; + sq_getbool(vm, idx, &val); + return ConvTo< Uint64 >::From(val); + } break; + case OT_STRING: + { + CSStr val = nullptr; + // Attempt to retrieve and convert the string + if (SQ_SUCCEEDED(sq_getstring(vm, idx, &val)) && val != nullptr && *val != '\0') + { + return std::strtoull(val, nullptr, 10); + } + } break; + case OT_ARRAY: + case OT_TABLE: + case OT_CLASS: + case OT_USERDATA: + { + return ConvTo< Uint64 >::From(sq_getsize(vm, idx)); + } break; + case OT_INSTANCE: + { + // Attempt to treat the value as a signed long instance + try + { + return ConvTo< Uint64 >::From(Var< const SLongInt & >(vm, idx).value.GetNum()); + } + catch (...) + { + // Just ignore it... + } + // Attempt to treat the value as a unsigned long instance + try + { + return Var< const ULongInt & >(vm, idx).value.GetNum(); + } + catch (...) + { + // Just ignore it... + } + // Attempt to get the size of the instance as a fallback + return ConvTo< Uint64 >::From(sq_getsize(vm, idx)); + } break; + default: break; + } + // Default to 0 + return 0; +} + +// -------------------------------------------------------------------------------------------- +StackStrF::StackStrF(HSQUIRRELVM vm, SQInteger idx, bool fmt) + : mPtr(nullptr) + , mLen(-1) + , mRes(SQ_OK) + , mObj() + , mVM(vm) +{ + const Int32 top = sq_gettop(vm); + // Reset the converted value object + sq_resetobject(&mObj); + // Was the string or value specified? + if (top <= (idx - 1)) + { + mRes = sq_throwerror(vm, "Missing string or value"); + } + // Do we have enough values to call the format function and are we allowed to? + else if (top > idx && fmt) + { + // Pointer to the generated string + SStr str = nullptr; + // Attempt to generate the specified string format + mRes = sqstd_format(vm, idx, &mLen, &str); + // Did the format succeeded but ended up with a null string pointer? + if (SQ_SUCCEEDED(mRes) && !str) + { + mRes = sq_throwerror(vm, "Unable to generate the string"); + } + else + { + mPtr = const_cast< CSStr >(str); + } + } + // Is the value on the stack an actual string? + else if (sq_gettype(vm, idx) == OT_STRING) + { + // Obtain a reference to the string object + mRes = sq_getstackobj(vm, idx, &mObj); + // Could we retrieve the object from the stack? + if (SQ_SUCCEEDED(mRes)) + { + // Keep a strong reference to the object + sq_addref(vm, &mObj); + // Attempt to retrieve the string value from the stack + mRes = sq_getstring(vm, idx, &mPtr); + } + // Did the retrieval succeeded but ended up with a null string pointer? + if (SQ_SUCCEEDED(mRes) && !mPtr) + { + mRes = sq_throwerror(vm, "Unable to retrieve the string"); + } + } + // We have to try and convert it to string + else + { + // Attempt to convert the value from the stack to a string + mRes = sq_tostring(vm, idx); + // Could we convert the specified value to string? + if (SQ_SUCCEEDED(mRes)) + { + // Obtain a reference to the resulted object + mRes = sq_getstackobj(vm, -1, &mObj); + // Could we retrieve the object from the stack? + if (SQ_SUCCEEDED(mRes)) + { + // Keep a strong reference to the object + sq_addref(vm, &mObj); + // Attempt to obtain the string pointer + mRes = sq_getstring(vm, -1, &mPtr); + } + } + // Pop a value from the stack regardless of the result + sq_pop(vm, 1); + // Did the retrieval succeeded but ended up with a null string pointer? + if (SQ_SUCCEEDED(mRes) && !mPtr) + { + mRes = sq_throwerror(vm, "Unable to retrieve the value"); + } + } +} + +// ------------------------------------------------------------------------------------------------ +StackStrF::~StackStrF() +{ + if (mVM && !sq_isnull(mObj)) + { + sq_release(mVM, &mObj); + } +} + +// ------------------------------------------------------------------------------------------------ +Object BufferToStrObj(const Buffer & b) +{ + // Obtain the initial stack size + const StackGuard sg(DefaultVM::Get()); + // Push the string onto the stack + sq_pushstring(DefaultVM::Get(), b.Data(), b.Position()); + // Obtain the object from the stack and return it + return Var< Object >(DefaultVM::Get(), -1).value; +} + +// -------------------------------------------------------------------------------------------- +Object BufferToStrObj(const Buffer & b, Uint32 size) +{ + // Perform a range check on the specified buffer + if (size > b.Capacity()) + { + STHROWF("The specified buffer size is out of range: %u >= %u", size, b.Capacity()); + } + // Obtain the initial stack size + const StackGuard sg(DefaultVM::Get()); + // Push the string onto the stack + sq_pushstring(DefaultVM::Get(), b.Data(), size); + // Obtain the object from the stack and return it + return Var< Object >(DefaultVM::Get(), -1).value; +} + +// ------------------------------------------------------------------------------------------------ + + +} // Namespace:: SqMod diff --git a/source/Base/Stack.hpp b/source/Base/Stack.hpp new file mode 100644 index 00000000..5324fa4f --- /dev/null +++ b/source/Base/Stack.hpp @@ -0,0 +1,172 @@ +#ifndef _BASE_STACK_HPP_ +#define _BASE_STACK_HPP_ + +// ------------------------------------------------------------------------------------------------ +#include "SqBase.hpp" + +// ------------------------------------------------------------------------------------------------ +#include + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +/* ------------------------------------------------------------------------------------------------ + * Attempt to pop the value at the specified index on the stack as a native integer. +*/ +SQInteger PopStackInteger(HSQUIRRELVM vm, SQInteger idx); + +/* ------------------------------------------------------------------------------------------------ + * Attempt to pop the value at the specified index on the stack as a native float. +*/ +SQFloat PopStackFloat(HSQUIRRELVM vm, SQInteger idx); + +/* ------------------------------------------------------------------------------------------------ + * Attempt to pop the value at the specified index on the stack as a signed long integer. +*/ +Int64 PopStackLong(HSQUIRRELVM vm, SQInteger idx); + +/* ------------------------------------------------------------------------------------------------ + * Attempt to pop the value at the specified index on the stack as an unsigned long integer. +*/ +Uint64 PopStackULong(HSQUIRRELVM vm, SQInteger idx); + +/* ------------------------------------------------------------------------------------------------ + * Create a script string object from a buffer. +*/ +Object BufferToStrObj(const Buffer & b); + +/* ------------------------------------------------------------------------------------------------ + * Create a script string object from a portion of a buffer. +*/ +Object BufferToStrObj(const Buffer & b, Uint32 size); + +/* ------------------------------------------------------------------------------------------------ + * Implements RAII to restore the VM stack to it's initial size on function exit. +*/ +struct StackGuard +{ + /* -------------------------------------------------------------------------------------------- + * Default constructor. + */ + StackGuard() + : m_VM(DefaultVM::Get()), m_Top(sq_gettop(m_VM)) + { + /* ... */ + } + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + StackGuard(HSQUIRRELVM vm) + : m_VM(vm), m_Top(sq_gettop(vm)) + { + /* ... */ + } + + /* -------------------------------------------------------------------------------------------- + * Copy constructor. (disabled) + */ + StackGuard(const StackGuard &) = delete; + + /* -------------------------------------------------------------------------------------------- + * Move constructor. (disabled) + */ + StackGuard(StackGuard &&) = delete; + + /* -------------------------------------------------------------------------------------------- + * Destructor. + */ + ~StackGuard() + { + sq_pop(m_VM, sq_gettop(m_VM) - m_Top); + } + + /* -------------------------------------------------------------------------------------------- + * Copy assignment operator. (disabled) + */ + StackGuard & operator = (const StackGuard &) = delete; + + /* -------------------------------------------------------------------------------------------- + * Move assignment operator. (disabled) + */ + StackGuard & operator = (StackGuard &&) = delete; + +private: + + // -------------------------------------------------------------------------------------------- + HSQUIRRELVM m_VM; // The VM where the stack should be restored. + Int32 m_Top; // The top of the stack when this instance was created. +}; + +/* ------------------------------------------------------------------------------------------------ + * Helper structure for retrieving a value from the stack as a string or a formatted string. +*/ +struct StackStrF +{ + // -------------------------------------------------------------------------------------------- + CSStr mPtr; // Pointer to the C string that was retrieved. + SQInteger mLen; // The string length if it could be retrieved. + SQRESULT mRes; // The result of the retrieval attempts. + HSQOBJECT mObj; // Strong reference to the string object. + HSQUIRRELVM mVM; // The associated virtual machine. + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + StackStrF(HSQUIRRELVM vm, SQInteger idx, bool fmt = true); + + /* -------------------------------------------------------------------------------------------- + * Copy constructor. (disabled) + */ + StackStrF(const StackStrF & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Copy constructor. (disabled) + */ + StackStrF(StackStrF && o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Destructor. + */ + ~StackStrF(); + + /* -------------------------------------------------------------------------------------------- + * Copy constructor. (disabled) + */ + StackStrF & operator = (const StackStrF & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Copy constructor. (disabled) + */ + StackStrF & operator = (StackStrF && o) = delete; +}; + +/* ------------------------------------------------------------------------------------------------ + * Create a script object from the specified value on the default VM. +*/ +template < typename T > Object MakeObject(const T & v) +{ + // Remember the current stack size + const StackGuard sg; + // Transform the specified value into a script object + PushVar< T >(DefaultVM::Get(), v); + // Get the object from the stack and return it + return Var< Object >(DefaultVM::Get(), -1).value; +} + +/* ------------------------------------------------------------------------------------------------ + * Create a script object from the specified value on the specified VM. +*/ +template < typename T > Object MakeObject(HSQUIRRELVM vm, const T & v) +{ + // Remember the current stack size + const StackGuard sg; + // Transform the specified value into a script object + PushVar< T >(vm, v); + // Get the object from the stack and return it + return Var< Object >(vm, -1).value; +} + +} // Namespace:: SqMod + +#endif // _BASE_STACK_HPP_ diff --git a/source/Command.cpp b/source/Command.cpp index 078791b1..957fe474 100644 --- a/source/Command.cpp +++ b/source/Command.cpp @@ -1,6 +1,7 @@ // ------------------------------------------------------------------------------------------------ #include "Command.hpp" #include "Core.hpp" +#include "Base/Stack.hpp" #include "Entity/Player.hpp" // ------------------------------------------------------------------------------------------------ diff --git a/source/Constants.cpp b/source/Constants.cpp index a528ec08..7b1b1abf 100644 --- a/source/Constants.cpp +++ b/source/Constants.cpp @@ -38,6 +38,20 @@ void Register_Constants(HSQUIRRELVM vm) .Const(_SC("MaxFloat"), std::numeric_limits< SQFloat >::max()) .Const(_SC("MinFloat32"), std::numeric_limits< Float32 >::min()) .Const(_SC("MaxFloat32"), std::numeric_limits< Float32 >::max()) + .Const(_SC("FpNormal"), FP_NORMAL) + .Const(_SC("FpSubnormal"), FP_SUBNORMAL) + .Const(_SC("FpZero"), FP_ZERO) + .Const(_SC("FpInfinite"), FP_INFINITE) + .Const(_SC("FpNan"), FP_NAN) +#ifdef SQUSEDOUBLE + .Const(_SC("HugeVal"), HUGE_VAL) +#else + .Const(_SC("HugeVal"), HUGE_VALF) +#endif // SQUSEDOUBLE + .Const(_SC("Infinity"), static_cast< float >(INFINITY)) + .Const(_SC("Inf"), static_cast< float >(INFINITY)) + .Const(_SC("Nan"), static_cast< float >(NAN)) + ); ConstTable(vm).Enum(_SC("SqArchitectre"), Enumeration(vm) diff --git a/source/Entity/Blip.cpp b/source/Entity/Blip.cpp index d7a8a5ea..34b1cd8b 100644 --- a/source/Entity/Blip.cpp +++ b/source/Entity/Blip.cpp @@ -1,5 +1,6 @@ // ------------------------------------------------------------------------------------------------ #include "Entity/Blip.hpp" +#include "Base/Stack.hpp" #include "Core.hpp" // ------------------------------------------------------------------------------------------------ diff --git a/source/Entity/Checkpoint.cpp b/source/Entity/Checkpoint.cpp index 00cb9a6a..8546a141 100644 --- a/source/Entity/Checkpoint.cpp +++ b/source/Entity/Checkpoint.cpp @@ -3,6 +3,7 @@ #include "Entity/Player.hpp" #include "Base/Color4.hpp" #include "Base/Vector3.hpp" +#include "Base/Stack.hpp" #include "Core.hpp" // ------------------------------------------------------------------------------------------------ diff --git a/source/Entity/Forcefield.cpp b/source/Entity/Forcefield.cpp index 404319af..4b69115b 100644 --- a/source/Entity/Forcefield.cpp +++ b/source/Entity/Forcefield.cpp @@ -3,6 +3,7 @@ #include "Entity/Player.hpp" #include "Base/Color3.hpp" #include "Base/Vector3.hpp" +#include "Base/Stack.hpp" #include "Core.hpp" // ------------------------------------------------------------------------------------------------ diff --git a/source/Entity/Keybind.cpp b/source/Entity/Keybind.cpp index 070638b9..208e79e7 100644 --- a/source/Entity/Keybind.cpp +++ b/source/Entity/Keybind.cpp @@ -1,5 +1,6 @@ // ------------------------------------------------------------------------------------------------ #include "Entity/Keybind.hpp" +#include "Base/Stack.hpp" #include "Core.hpp" // ------------------------------------------------------------------------------------------------ @@ -288,4 +289,4 @@ void Register_CKeybind(HSQUIRRELVM vm) ); } -} // Namespace:: SqMod \ No newline at end of file +} // Namespace:: SqMod diff --git a/source/Entity/Object.cpp b/source/Entity/Object.cpp index b085c0ae..4c430b0b 100644 --- a/source/Entity/Object.cpp +++ b/source/Entity/Object.cpp @@ -3,6 +3,7 @@ #include "Entity/Player.hpp" #include "Base/Quaternion.hpp" #include "Base/Vector3.hpp" +#include "Base/Stack.hpp" #include "Core.hpp" // ------------------------------------------------------------------------------------------------ diff --git a/source/Entity/Pickup.cpp b/source/Entity/Pickup.cpp index cd124db5..c91c24ff 100644 --- a/source/Entity/Pickup.cpp +++ b/source/Entity/Pickup.cpp @@ -2,6 +2,7 @@ #include "Entity/Pickup.hpp" #include "Entity/Player.hpp" #include "Base/Vector3.hpp" +#include "Base/Stack.hpp" #include "Core.hpp" // ------------------------------------------------------------------------------------------------ @@ -490,4 +491,4 @@ void Register_CPickup(HSQUIRRELVM vm) ); } -} // Namespace:: SqMod \ No newline at end of file +} // Namespace:: SqMod diff --git a/source/Entity/Player.cpp b/source/Entity/Player.cpp index f691809d..b06832f4 100644 --- a/source/Entity/Player.cpp +++ b/source/Entity/Player.cpp @@ -3,6 +3,7 @@ #include "Entity/Vehicle.hpp" #include "Base/Color3.hpp" #include "Base/Vector3.hpp" +#include "Base/Stack.hpp" #include "Core.hpp" // ------------------------------------------------------------------------------------------------ diff --git a/source/Entity/Sprite.cpp b/source/Entity/Sprite.cpp index 41397fdc..14be71a4 100644 --- a/source/Entity/Sprite.cpp +++ b/source/Entity/Sprite.cpp @@ -2,6 +2,7 @@ #include "Entity/Sprite.hpp" #include "Entity/Player.hpp" #include "Base/Vector2i.hpp" +#include "Base/Stack.hpp" #include "Core.hpp" // ------------------------------------------------------------------------------------------------ diff --git a/source/Entity/Textdraw.cpp b/source/Entity/Textdraw.cpp index be7f25de..190f89ad 100644 --- a/source/Entity/Textdraw.cpp +++ b/source/Entity/Textdraw.cpp @@ -2,6 +2,7 @@ #include "Entity/Textdraw.hpp" #include "Entity/Player.hpp" #include "Base/Vector2i.hpp" +#include "Base/Stack.hpp" #include "Core.hpp" // ------------------------------------------------------------------------------------------------ diff --git a/source/Entity/Vehicle.cpp b/source/Entity/Vehicle.cpp index bd1c792b..c7802fc2 100644 --- a/source/Entity/Vehicle.cpp +++ b/source/Entity/Vehicle.cpp @@ -3,6 +3,7 @@ #include "Entity/Player.hpp" #include "Base/Quaternion.hpp" #include "Base/Vector4.hpp" +#include "Base/Stack.hpp" #include "Core.hpp" // ------------------------------------------------------------------------------------------------ diff --git a/source/Library/Chrono.cpp b/source/Library/Chrono.cpp index a2c29627..622e1d1a 100644 --- a/source/Library/Chrono.cpp +++ b/source/Library/Chrono.cpp @@ -173,7 +173,7 @@ extern void Register_ChronoTime(HSQUIRRELVM vm, Table & cns); extern void Register_ChronoTimer(HSQUIRRELVM vm, Table & cns); extern void Register_ChronoTimestamp(HSQUIRRELVM vm, Table & cns); -// ------------------------------------------------------------------------------------------------ +// ================================================================================================ void Register_Chrono(HSQUIRRELVM vm) { Table cns(vm); diff --git a/source/Library/Crypt.cpp b/source/Library/Crypt.cpp index a6cd7f20..7acc7e9e 100644 --- a/source/Library/Crypt.cpp +++ b/source/Library/Crypt.cpp @@ -1,6 +1,7 @@ // ------------------------------------------------------------------------------------------------ #include "Library/Crypt.hpp" #include "Base/Shared.hpp" +#include "Base/Stack.hpp" // ------------------------------------------------------------------------------------------------ #include diff --git a/source/Library/Math.cpp b/source/Library/Math.cpp index e69de29b..b3990a7e 100644 --- a/source/Library/Math.cpp +++ b/source/Library/Math.cpp @@ -0,0 +1,1142 @@ +// ------------------------------------------------------------------------------------------------ +#include "Library/Math.hpp" +#include "Library/Numeric.hpp" +#include "Base/Stack.hpp" + +// ------------------------------------------------------------------------------------------------ +#include + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqDiv(HSQUIRRELVM vm) +{ + // The return type of the function +#ifdef _SQ64 + typedef std::lldiv_t DivT; +#else + typedef std::div_t DivT; +#endif // _SQ64 + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + const DivT r = std::div(PopStackInteger(vm, 2), PopStackInteger(vm, 3)); + // Create a new table on the stack + sq_newtable(vm); + // Push the quotient index + sq_pushstring(vm, _SC("quot"), -1); + // Push the quotient value + sq_pushinteger(vm, r.quot); + // Attempt to create the array element + if (SQ_FAILED(sq_rawset(vm, -3))) + { + return sq_throwerror(vm, "Unable to insert the quotient element"); + } + // Push the remainder index + sq_pushstring(vm, _SC("rem"), -1); + // Push the remainder value + sq_pushinteger(vm, r.rem); + // Attempt to create the array element + if (SQ_FAILED(sq_rawset(vm, -3))) + { + return sq_throwerror(vm, "Unable to insert the remainder element"); + } + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqRemainder(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Are we both arguments floats? + if ((sq_gettype(vm, 2) == OT_FLOAT) && sq_gettype(vm, 3) == OT_FLOAT) + { + sq_pushfloat(vm, std::remainder(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + } + // Are we both arguments integers? + else if ((sq_gettype(vm, 2) == OT_INTEGER) && sq_gettype(vm, 3) == OT_INTEGER) + { + sq_pushinteger(vm, std::remainder(PopStackInteger(vm, 2), PopStackInteger(vm, 3))); + } + // Is the first argument float? + else if ((sq_gettype(vm, 2) == OT_FLOAT)) + { + sq_pushfloat(vm, std::remainder(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + } + // Is the first argument integer? + else if ((sq_gettype(vm, 2) == OT_INTEGER)) + { + sq_pushinteger(vm, std::remainder(PopStackInteger(vm, 2), PopStackInteger(vm, 3))); + } + // Default to both arhuments as float so we don't loos precision from the float one + else + { + sq_pushfloat(vm, std::remainder(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + } + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqFma(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 3) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::fma(PopStackFloat(vm, 2), PopStackFloat(vm, 3), PopStackFloat(vm, 4))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqMax(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::fmax(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqMin(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::fmin(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqDim(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::fdim(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqNan(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Attempt to generate the string value + StackStrF val(vm, 2); + // Have we failed to retrieve the string? + if (SQ_FAILED(val.mRes)) + { + return val.mRes; // Propagate the error! + } + // Fetch the arguments from the stack and perform the requested operation +#ifdef _SQ64 + sq_pushfloat(vm, std::nan(val.mPtr)); +#else + sq_pushfloat(vm, std::nanf(val.mPtr)); +#endif // _SQ64 + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqNanL(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Attempt to generate the string value + StackStrF val(vm, 2); + // Have we failed to retrieve the string? + if (SQ_FAILED(val.mRes)) + { + return val.mRes; // Propagate the error! + } + // Fetch the arguments from the stack and perform the requested operation + try + { + Var< SLongInt * >::push(vm, new SLongInt(std::nanl(val.mPtr))); + } + catch (const Sqrat::Exception & e) + { + return sq_throwerror(vm, e.Message().c_str()); + } + catch (const std::exception e) + { + return sq_throwerror(vm, e.what()); + } + catch (...) + { + return sq_throwerror(vm, _SC("Failed to create a long integer instance")); + } + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqExp(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::exp(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqExp2(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::exp2(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqExpm1(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::expm1(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqLog(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::log(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqLog10(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::log10(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqLog2(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::log2(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqLog1p(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::log1p(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqPow(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::pow(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqSqrt(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::sqrt(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqCbrt(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::cbrt(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqHypot(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::hypot(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqSin(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::sin(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqCos(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::cos(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqTan(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::tan(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqAsin(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::asin(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqAcos(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::acos(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqAtan(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::atan(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqAtan2(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::atan2(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqSinh(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::sinh(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqCosh(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::cosh(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqTanh(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::tanh(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqAsinh(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::asinh(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqAcosh(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::acosh(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqAtanh(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::atanh(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqErf(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::erf(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqErfc(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::erfc(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqTgamma(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::tgamma(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqLgamma(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::lgamma(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqCeil(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::ceil(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqFloor(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::floor(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqTrunc(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::trunc(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqRound(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::round(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqRoundI(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + if (sq_gettype(vm, 2) == OT_FLOAT) + { + sq_pushinteger(vm, ConvTo< SQInteger >::From(std::llround(PopStackFloat(vm, 2)))); + } + else + { + sq_pushinteger(vm, ConvTo< SQInteger >::From(std::llround(PopStackInteger(vm, 2)))); + } + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqRoundL(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + try + { + if (sq_gettype(vm, 2) == OT_FLOAT) + { + Var< SLongInt * >::push(vm, new SLongInt(std::llround(PopStackFloat(vm, 2)))); + } + else + { + Var< SLongInt * >::push(vm, new SLongInt(std::llround(PopStackInteger(vm, 2)))); + } + } + catch (const Sqrat::Exception & e) + { + return sq_throwerror(vm, e.Message().c_str()); + } + catch (const std::exception e) + { + return sq_throwerror(vm, e.what()); + } + catch (...) + { + return sq_throwerror(vm, _SC("Failed to create a long integer instance")); + } + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqNearByInt(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::nearbyint(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqFrexp(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Where the exponent is retrieved + Int32 expv = 0; + // Fetch the arguments from the stack and perform the requested operation + const SQFloat sigv = std::frexp(PopStackFloat(vm, 2), &expv); + // Create a new table on the stack + sq_newtable(vm); + // Push the significand index + sq_pushstring(vm, _SC("sig"), -1); + // Push the significand value + sq_pushfloat(vm, sigv); + // Attempt to create the array element + if (SQ_FAILED(sq_rawset(vm, -3))) + { + return sq_throwerror(vm, "Unable to insert the significand element"); + } + // Push the exponent index + sq_pushstring(vm, _SC("exp"), -1); + // Push the exponent value + sq_pushinteger(vm, expv); + // Attempt to create the array element + if (SQ_FAILED(sq_rawset(vm, -3))) + { + return sq_throwerror(vm, "Unable to insert the exponent element"); + } + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqLdexp(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::ldexp(PopStackFloat(vm, 2), PopStackInteger(vm, 3))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqModF(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Where the fractional part is retrieved + SQFloat intv = 0; + // Fetch the arguments from the stack and perform the requested operation + const SQFloat fracv = std::modf(PopStackFloat(vm, 2), &intv); + // Create a new table on the stack + sq_newtable(vm); + // Push the integral index + sq_pushstring(vm, _SC("integral"), -1); + // Push the integral value + sq_pushfloat(vm, intv); + // Attempt to create the array element + if (SQ_FAILED(sq_rawset(vm, -3))) + { + return sq_throwerror(vm, "Unable to insert the integral element"); + } + // Push the fractional index + sq_pushstring(vm, _SC("fractional"), -1); + // Push the fractional value + sq_pushfloat(vm, fracv); + // Attempt to create the array element + if (SQ_FAILED(sq_rawset(vm, -3))) + { + return sq_throwerror(vm, "Unable to insert the fractional element"); + } + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqScalbn(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation +#ifdef _SQ64 + sq_pushfloat(vm, std::scalbln(PopStackFloat(vm, 2), PopStackInteger(vm, 3))); +#else + sq_pushfloat(vm, std::scalbn(PopStackFloat(vm, 2), PopStackInteger(vm, 3))); +#endif // _SQ64 + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqIlogb(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushinteger(vm, std::ilogb(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqLogb(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::logb(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqNextAfter(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::nextafter(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqNextForward(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::nexttoward(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqCopySign(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushfloat(vm, std::copysign(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqFpClassify(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushinteger(vm, std::fpclassify(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqIsFinite(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushbool(vm, std::isfinite(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqIsInf(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushbool(vm, std::isinf(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqIsNan(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushbool(vm, std::isnan(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqIsNormal(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushbool(vm, std::isnormal(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqSignBit(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 1) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushbool(vm, std::signbit(PopStackFloat(vm, 2))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqIsGreater(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushbool(vm, std::isgreater(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqIsGreaterEqual(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushbool(vm, std::isgreaterequal(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqIsLess(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushbool(vm, std::isless(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqIsLessEqual(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushbool(vm, std::islessequal(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqIsLessGreater(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushbool(vm, std::islessgreater(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + // Specify that we have a value on the stack + return 1; +} + +// ------------------------------------------------------------------------------------------------ +static SQInteger SqIsUnordered(HSQUIRRELVM vm) +{ + // Do we have the correct number of arguments? + if (sq_gettop(vm) <= 2) + { + return sq_throwerror(vm, "Wrong number of arguments"); + } + // Fetch the arguments from the stack and perform the requested operation + sq_pushbool(vm, std::isunordered(PopStackFloat(vm, 2), PopStackFloat(vm, 3))); + // Specify that we have a value on the stack + return 1; +} + +// ================================================================================================ +void Register_Math(HSQUIRRELVM vm) +{ + Table mns(vm); + + mns + .SquirrelFunc(_SC("Div"), &SqDiv) + .SquirrelFunc(_SC("Remainder"), &SqRemainder) + .SquirrelFunc(_SC("Fma"), &SqFma) + .SquirrelFunc(_SC("Max"), &SqMax) + .SquirrelFunc(_SC("Min"), &SqMin) + .SquirrelFunc(_SC("Dim"), &SqDim) + .SquirrelFunc(_SC("Nan"), &SqNan) + .SquirrelFunc(_SC("NanL"), &SqNanL) + .SquirrelFunc(_SC("Exp"), &SqExp) + .SquirrelFunc(_SC("Exp2"), &SqExp2) + .SquirrelFunc(_SC("Expm1"), &SqExpm1) + .SquirrelFunc(_SC("Log"), &SqLog) + .SquirrelFunc(_SC("Log10"), &SqLog10) + .SquirrelFunc(_SC("Log2"), &SqLog2) + .SquirrelFunc(_SC("Log1p"), &SqLog1p) + .SquirrelFunc(_SC("Pow"), &SqPow) + .SquirrelFunc(_SC("Sqrt"), &SqSqrt) + .SquirrelFunc(_SC("Cbrt"), &SqCbrt) + .SquirrelFunc(_SC("Hypot"), &SqHypot) + .SquirrelFunc(_SC("Sin"), &SqSin) + .SquirrelFunc(_SC("Cos"), &SqCos) + .SquirrelFunc(_SC("Tan"), &SqTan) + .SquirrelFunc(_SC("Asin"), &SqAsin) + .SquirrelFunc(_SC("Acos"), &SqAcos) + .SquirrelFunc(_SC("Atan"), &SqAtan) + .SquirrelFunc(_SC("Atan2"), &SqAtan2) + .SquirrelFunc(_SC("Sinh"), &SqSinh) + .SquirrelFunc(_SC("Cosh"), &SqCosh) + .SquirrelFunc(_SC("Tanh"), &SqTanh) + .SquirrelFunc(_SC("Asinh"), &SqAsinh) + .SquirrelFunc(_SC("Acosh"), &SqAcosh) + .SquirrelFunc(_SC("Atanh"), &SqAtanh) + .SquirrelFunc(_SC("Erf"), &SqErf) + .SquirrelFunc(_SC("Erfc"), &SqErfc) + .SquirrelFunc(_SC("Tgamma"), &SqTgamma) + .SquirrelFunc(_SC("Lgamma"), &SqLgamma) + .SquirrelFunc(_SC("Ceil"), &SqCeil) + .SquirrelFunc(_SC("Floor"), &SqFloor) + .SquirrelFunc(_SC("Trunc"), &SqTrunc) + .SquirrelFunc(_SC("Round"), &SqRound) + .SquirrelFunc(_SC("RoundI"), &SqRoundI) + .SquirrelFunc(_SC("RoundL"), &SqRoundL) + .SquirrelFunc(_SC("NearByInt"), &SqNearByInt) + .SquirrelFunc(_SC("Frexp"), &SqFrexp) + .SquirrelFunc(_SC("Ldexp"), &SqLdexp) + .SquirrelFunc(_SC("ModF"), &SqModF) + .SquirrelFunc(_SC("Scalbn"), &SqScalbn) + .SquirrelFunc(_SC("Ilogb"), &SqIlogb) + .SquirrelFunc(_SC("Logb"), &SqLogb) + .SquirrelFunc(_SC("NextAfter"), &SqNextAfter) + .SquirrelFunc(_SC("NextForward"), &SqNextForward) + .SquirrelFunc(_SC("CopySign"), &SqCopySign) + .SquirrelFunc(_SC("FpClassify"), &SqFpClassify) + .SquirrelFunc(_SC("IsFinite"), &SqIsFinite) + .SquirrelFunc(_SC("IsInf"), &SqIsInf) + .SquirrelFunc(_SC("IsNan"), &SqIsNan) + .SquirrelFunc(_SC("IsNormal"), &SqIsNormal) + .SquirrelFunc(_SC("SignBit"), &SqSignBit) + .SquirrelFunc(_SC("IsGreater"), &SqIsGreater) + .SquirrelFunc(_SC("IsGreaterEqual"), &SqIsGreaterEqual) + .SquirrelFunc(_SC("IsLess"), &SqIsLess) + .SquirrelFunc(_SC("IsLessEqual"), &SqIsLessEqual) + .SquirrelFunc(_SC("IsLessGreater"), &SqIsLessGreater) + .SquirrelFunc(_SC("IsUnordered"), &SqIsUnordered); + + RootTable(vm).Bind(_SC("SqMath"), mns); +} + + +} // Namespace:: SqMod diff --git a/source/Library/Math.hpp b/source/Library/Math.hpp index e69de29b..6adc5428 100644 --- a/source/Library/Math.hpp +++ b/source/Library/Math.hpp @@ -0,0 +1,12 @@ +#ifndef _LIBRARY_MATH_HPP_ +#define _LIBRARY_MATH_HPP_ + +// ------------------------------------------------------------------------------------------------ +#include "Base/Shared.hpp" + +// ------------------------------------------------------------------------------------------------ +namespace SqMod { + +} // Namespace:: SqMod + +#endif // _LIBRARY_MATH_HPP_ diff --git a/source/Library/Numeric.cpp b/source/Library/Numeric.cpp index 1491fdc8..2c6efc8a 100644 --- a/source/Library/Numeric.cpp +++ b/source/Library/Numeric.cpp @@ -54,7 +54,7 @@ LongInt< Uint64 > & LongInt< Uint64 >::operator = (CSStr text) // ------------------------------------------------------------------------------------------------ CSStr LongInt< Uint64 >::ToString() { - if (snprintf(m_Text, sizeof(m_Text), "%llu", m_Data) < 0) + if (std::snprintf(m_Text, sizeof(m_Text), "%llu", m_Data) < 0) { m_Text[0] = 0; } @@ -82,6 +82,12 @@ void Register_Numeric(HSQUIRRELVM vm) .Func(_SC("_tostring"), &SLongInt::ToString) .Func(_SC("_typename"), &SLongInt::Typename) .Func(_SC("_cmp"), &SLongInt::Cmp) + /* Core Functions */ + .Func(_SC("tointeger"), &SLongInt::ToSqInteger) + .Func(_SC("tofloat"), &SLongInt::ToSqFloat) + .Func(_SC("tostring"), &SLongInt::ToSqString) + .Func(_SC("tobool"), &SLongInt::ToSqBool) + .Func(_SC("tochar"), &SLongInt::ToSqChar) /* Metamethods */ .Func< SLongInt (SLongInt::*)(const SLongInt &) const >(_SC("_add"), &SLongInt::operator +) .Func< SLongInt (SLongInt::*)(const SLongInt &) const >(_SC("_sub"), &SLongInt::operator -) @@ -112,6 +118,12 @@ void Register_Numeric(HSQUIRRELVM vm) .Func(_SC("_tostring"), &ULongInt::ToString) .Func(_SC("_typename"), &ULongInt::Typename) .Func(_SC("_cmp"), &ULongInt::Cmp) + /* Core Functions */ + .Func(_SC("tointeger"), &ULongInt::ToSqInteger) + .Func(_SC("tofloat"), &ULongInt::ToSqFloat) + .Func(_SC("tostring"), &ULongInt::ToSqString) + .Func(_SC("tobool"), &ULongInt::ToSqBool) + .Func(_SC("tochar"), &ULongInt::ToSqChar) /* Metamethods */ .Func< ULongInt (ULongInt::*)(const ULongInt &) const >(_SC("_add"), &ULongInt::operator +) .Func< ULongInt (ULongInt::*)(const ULongInt &) const >(_SC("_sub"), &ULongInt::operator -) diff --git a/source/Library/Numeric.hpp b/source/Library/Numeric.hpp index 68c3cbe1..abb3130e 100644 --- a/source/Library/Numeric.hpp +++ b/source/Library/Numeric.hpp @@ -199,7 +199,7 @@ public: */ SQInteger GetSNum() const { - return (SQInteger)(m_Data); + return ClampL< Type, SQInteger >(m_Data); } /* -------------------------------------------------------------------------------------------- @@ -222,6 +222,46 @@ public: void Random(Type n); void Random(Type m, Type n); + /* -------------------------------------------------------------------------------------------- + * Attempt to convert the long integer to a squirrel integer. + */ + SQInteger ToSqInteger() const + { + return ClampL< Type, SQInteger >(m_Data); + } + + /* -------------------------------------------------------------------------------------------- + * Attempt to convert the long integer to a squirrel float. + */ + SQFloat ToSqFloat() const + { + return ClampL< Float64, SQFloat >(static_cast< Float64 >(m_Data)); + } + + /* -------------------------------------------------------------------------------------------- + * Attempt to convert the long integer to a squirrel string. + */ + CSStr ToSqString() + { + return ToString(); + } + + /* -------------------------------------------------------------------------------------------- + * Attempt to convert the long integer to a squirrel boolean. + */ + bool ToSqBool() const + { + return (m_Data > 0); + } + + /* -------------------------------------------------------------------------------------------- + * Attempt to convert the long integer to a squirrel character. + */ + SQChar ToSqChar() const + { + return ClampL< Type, SQChar >(m_Data); + } + private: // -------------------------------------------------------------------------------------------- @@ -441,6 +481,46 @@ public: void Random(Type n); void Random(Type m, Type n); + /* -------------------------------------------------------------------------------------------- + * Attempt to convert the long integer to a squirrel integer. + */ + SQInteger ToSqInteger() const + { + return ClampL< Type, SQInteger >(m_Data); + } + + /* -------------------------------------------------------------------------------------------- + * Attempt to convert the long integer to a squirrel float. + */ + SQFloat ToSqFloat() const + { + return ClampL< Float64, SQFloat >(static_cast< Float64 >(m_Data)); + } + + /* -------------------------------------------------------------------------------------------- + * Attempt to convert the long integer to a squirrel string. + */ + CSStr ToSqString() + { + return ToString(); + } + + /* -------------------------------------------------------------------------------------------- + * Attempt to convert the long integer to a squirrel boolean. + */ + bool ToSqBool() const + { + return (m_Data > 0); + } + + /* -------------------------------------------------------------------------------------------- + * Attempt to convert the long integer to a squirrel character. + */ + SQChar ToSqChar() const + { + return ClampL< Type, SQChar >(m_Data); + } + private: // -------------------------------------------------------------------------------------------- diff --git a/source/Library/String.cpp b/source/Library/String.cpp index 40f54848..9d4f9b90 100644 --- a/source/Library/String.cpp +++ b/source/Library/String.cpp @@ -2,6 +2,7 @@ #include "Library/String.hpp" #include "Base/Shared.hpp" #include "Base/Buffer.hpp" +#include "Base/Stack.hpp" // ------------------------------------------------------------------------------------------------ #include diff --git a/source/Library/SysEnv.cpp b/source/Library/SysEnv.cpp index 58ac320f..8d6fc49a 100644 --- a/source/Library/SysEnv.cpp +++ b/source/Library/SysEnv.cpp @@ -1,5 +1,6 @@ // ------------------------------------------------------------------------------------------------ #include "Library/SysEnv.hpp" +#include "Base/Stack.hpp" // ------------------------------------------------------------------------------------------------ #include diff --git a/source/Library/SysPath.cpp b/source/Library/SysPath.cpp index c0fc0eb5..b4d5a519 100644 --- a/source/Library/SysPath.cpp +++ b/source/Library/SysPath.cpp @@ -1,6 +1,7 @@ // ------------------------------------------------------------------------------------------------ #include "Library/SysPath.hpp" #include "Library/SysEnv.hpp" +#include "Base/Stack.hpp" // ------------------------------------------------------------------------------------------------ #include diff --git a/source/Register.cpp b/source/Register.cpp index 908de542..0dffc171 100644 --- a/source/Register.cpp +++ b/source/Register.cpp @@ -37,6 +37,7 @@ extern void Register_Entity(HSQUIRRELVM vm); extern void Register_Chrono(HSQUIRRELVM vm); extern void Register_Crypt(HSQUIRRELVM vm); extern void Register_Numeric(HSQUIRRELVM vm); +extern void Register_Math(HSQUIRRELVM vm); extern void Register_Random(HSQUIRRELVM vm); extern void Register_String(HSQUIRRELVM vm); extern void Register_SysEnv(HSQUIRRELVM vm); @@ -82,6 +83,7 @@ bool RegisterAPI(HSQUIRRELVM vm) Register_Crypt(vm); Register_Random(vm); Register_Numeric(vm); + Register_Math(vm); Register_String(vm); Register_SysEnv(vm); Register_SysPath(vm); diff --git a/source/Routine.cpp b/source/Routine.cpp index ccda3299..46059451 100644 --- a/source/Routine.cpp +++ b/source/Routine.cpp @@ -1,5 +1,6 @@ // ------------------------------------------------------------------------------------------------ #include "Routine.hpp" +#include "Base/Stack.hpp" #include "Library/Chrono.hpp" // ------------------------------------------------------------------------------------------------