Browse Source

Env: Add max/min/cos/sin math functions

master
Riyyi 1 year ago
parent
commit
287c2457e7
  1. 1
      src/blaze/env/environment.cpp
  2. 1
      src/blaze/env/environment.h
  3. 82
      src/blaze/env/functions/math.cpp
  4. 39
      src/blaze/env/functions/other.cpp
  5. 18
      src/blaze/env/functions/repl.cpp

1
src/blaze/env/environment.cpp vendored

@ -88,6 +88,7 @@ void Environment::loadFunctions()
loadCompare();
loadConvert();
loadFormat();
loadMath();
loadMeta();
loadMutable();
loadOperators();

1
src/blaze/env/environment.h vendored

@ -51,6 +51,7 @@ private:
static void loadCompare();
static void loadConvert();
static void loadFormat();
static void loadMath();
static void loadMeta();
static void loadMutable();
static void loadOperators();

82
src/blaze/env/functions/math.cpp vendored

@ -0,0 +1,82 @@
/*
* Copyright (C) 2023 Riyyi
*
* SPDX-License-Identifier: MIT
*/
#include <cmath> // std::sin
#include <limits> // sdt::numeric_limits
#include <memory> // std::static_pointer_cast
#include "blaze/ast.h"
#include "blaze/env/macro.h"
#include "blaze/util.h"
namespace blaze {
void Environment::loadMath()
{
#define MATH_MAX_MIN(variant, limit, operator) \
{ \
CHECK_ARG_COUNT_AT_LEAST(#variant, SIZE(), 1); \
\
int64_t number = std::numeric_limits<int64_t>::limit(); \
double decimal = std::numeric_limits<double>::limit(); \
\
for (auto it = begin; it != end; ++it) { \
IS_VALUE(Numeric, (*it)); \
if (is<Number>(it->get())) { \
auto it_numeric = std::static_pointer_cast<Number>(*it)->number(); \
if (it_numeric operator number) { \
number = it_numeric; \
} \
} \
else { \
auto it_numeric = std::static_pointer_cast<Decimal>(*it)->decimal(); \
if (it_numeric operator decimal) { \
decimal = it_numeric; \
} \
} \
} \
\
if (number operator decimal) { \
return makePtr<Number>(number); \
} \
\
return makePtr<Decimal>(decimal); \
}
ADD_FUNCTION(
"max", "number...",
"Return largest of all arguments, where NUMBER is a number or decimal.",
MATH_MAX_MIN(max, lowest, >));
ADD_FUNCTION(
"min", "number...",
"Return smallest of all arguments, where NUMBER is a number or decimal.",
MATH_MAX_MIN(min, max, <));
#define MATH_COS_SIN(variant) \
{ \
CHECK_ARG_COUNT_IS(#variant, SIZE(), 1); \
\
auto value = *begin; \
IS_VALUE(Numeric, value); \
if (is<Number>(begin->get())) { \
return makePtr<Decimal>(std::variant((double)std::static_pointer_cast<Number>(value)->number())); \
} \
\
return makePtr<Decimal>(std::variant(std::static_pointer_cast<Decimal>(value)->decimal())); \
}
ADD_FUNCTION(
"cos", "arg",
"Return the cosine of ARG.",
MATH_COS_SIN(cos));
ADD_FUNCTION(
"sin", "arg",
"Return the sine of ARG.",
MATH_COS_SIN(sin));
}
} // namespace blaze

39
src/blaze/env/functions/other.cpp vendored

@ -4,8 +4,11 @@
* SPDX-License-Identifier: MIT
*/
#include <chrono> // std::chrono::sytem_clock
#include <cstdint> // int64_t
#include <chrono> // std::chrono::sytem_clock
#include <cstdint> // int64_t
#include <filesystem> // std::filesystem::current_path
#include "ruc/file.h"
#include "blaze/ast.h"
#include "blaze/env/macro.h"
@ -17,10 +20,35 @@ namespace blaze {
void Environment::loadOther()
{
ADD_FUNCTION(
"pwd", "",
"Return the full filename of the current working directory.",
{
CHECK_ARG_COUNT_IS("pwd", SIZE(), 0);
auto path = std::filesystem::current_path().string();
return makePtr<String>(path);
});
ADD_FUNCTION(
"slurp", "",
"Read file contents",
{
CHECK_ARG_COUNT_IS("slurp", SIZE(), 1);
VALUE_CAST(node, String, (*begin));
std::string path = node->data();
auto file = ruc::File(path);
return makePtr<String>(file.data());
});
// -----------------------------------------
// (throw x)
ADD_FUNCTION(
"throw",
"",
"throw", "",
"",
{
CHECK_ARG_COUNT_IS("throw", SIZE(), 1);
@ -34,8 +62,7 @@ void Environment::loadOther()
// (time-ms)
ADD_FUNCTION(
"time-ms",
"",
"time-ms", "",
"",
{
CHECK_ARG_COUNT_IS("time-ms", SIZE(), 0);

18
src/blaze/env/functions/repl.cpp vendored

@ -6,8 +6,6 @@
#include <string>
#include "ruc/file.h"
#include "blaze/ast.h"
#include "blaze/env/macro.h"
#include "blaze/repl.h"
@ -31,22 +29,6 @@ void Environment::loadRepl()
return Repl::read(input);
});
// Read file contents
ADD_FUNCTION(
"slurp",
"",
"",
{
CHECK_ARG_COUNT_IS("slurp", SIZE(), 1);
VALUE_CAST(node, String, (*begin));
std::string path = node->data();
auto file = ruc::File(path);
return makePtr<String>(file.data());
});
// Prompt readline
ADD_FUNCTION(
"readline",

Loading…
Cancel
Save