Browse Source

Env: Allow load order control for native functions

Riyyi 1 year ago
parent
commit
b65482eb68
  1. 16
      src/env/environment.cpp
  2. 15
      src/env/environment.h
  3. 3
      src/env/functions/collection-access.cpp
  4. 3
      src/env/functions/collection-constructor.cpp
  5. 3
      src/env/functions/collection-modify.cpp
  6. 3
      src/env/functions/compare.cpp
  7. 3
      src/env/functions/convert.cpp
  8. 3
      src/env/functions/format.cpp
  9. 3
      src/env/functions/meta.cpp
  10. 3
      src/env/functions/mutable.cpp
  11. 3
      src/env/functions/operators.cpp
  12. 3
      src/env/functions/other.cpp
  13. 3
      src/env/functions/predicate.cpp
  14. 3
      src/env/functions/repl.cpp
  15. 22
      src/env/macro.h
  16. 1
      src/repl.cpp

16
src/env/environment.cpp vendored

@ -72,6 +72,22 @@ EnvironmentPtr Environment::create(const ValuePtr lambda, ValueVector&& argument
// ----------------------------------------- // -----------------------------------------
void Environment::loadFunctions()
{
loadCollectionAccess();
loadCollectionConstructor();
loadCollectionModify();
loadCompare();
loadConvert();
loadFormat();
loadMeta();
loadMutable();
loadOperators();
loadOther();
loadPredicate();
loadRepl();
}
void Environment::registerFunction(const std::string& name, FunctionType function) void Environment::registerFunction(const std::string& name, FunctionType function)
{ {
s_functions.insert_or_assign(name, function); s_functions.insert_or_assign(name, function);

15
src/env/environment.h vendored

@ -24,6 +24,7 @@ public:
static EnvironmentPtr create(EnvironmentPtr outer); static EnvironmentPtr create(EnvironmentPtr outer);
static EnvironmentPtr create(const ValuePtr lambda, ValueVector&& arguments); static EnvironmentPtr create(const ValuePtr lambda, ValueVector&& arguments);
static void loadFunctions();
static void registerFunction(const std::string& name, FunctionType function); static void registerFunction(const std::string& name, FunctionType function);
static void installFunctions(EnvironmentPtr env); static void installFunctions(EnvironmentPtr env);
@ -34,6 +35,20 @@ public:
private: private:
Environment() {} Environment() {}
// Outer environment native functions, "Core"
static void loadCollectionAccess();
static void loadCollectionConstructor();
static void loadCollectionModify();
static void loadCompare();
static void loadConvert();
static void loadFormat();
static void loadMeta();
static void loadMutable();
static void loadOperators();
static void loadOther();
static void loadPredicate();
static void loadRepl();
EnvironmentPtr m_outer { nullptr }; EnvironmentPtr m_outer { nullptr };
std::unordered_map<std::string, ValuePtr> m_values; std::unordered_map<std::string, ValuePtr> m_values;

3
src/env/functions/collection-access.cpp vendored

@ -14,6 +14,8 @@
namespace blaze { namespace blaze {
void Environment::loadCollectionAccess()
{
// (first (list 1 2 3)) -> 1 // (first (list 1 2 3)) -> 1
ADD_FUNCTION( ADD_FUNCTION(
"first", "first",
@ -135,5 +137,6 @@ ADD_FUNCTION(
return makePtr<List>(nodes); return makePtr<List>(nodes);
}); });
}
} // namespace blaze } // namespace blaze

3
src/env/functions/collection-constructor.cpp vendored

@ -14,6 +14,8 @@
namespace blaze { namespace blaze {
void Environment::loadCollectionConstructor()
{
// (list 1 2) -> (1 2) // (list 1 2) -> (1 2)
ADD_FUNCTION( ADD_FUNCTION(
"list", "list",
@ -115,5 +117,6 @@ ADD_FUNCTION(
return makePtr<HashMap>(elements); return makePtr<HashMap>(elements);
}); });
}
} // namespace blaze } // namespace blaze

3
src/env/functions/collection-modify.cpp vendored

@ -16,6 +16,8 @@
namespace blaze { namespace blaze {
void Environment::loadCollectionModify()
{
// (apply + 1 2 (list 3 4)) -> (+ 1 2 3 4) -> 10 // (apply + 1 2 (list 3 4)) -> (+ 1 2 3 4) -> 10
ADD_FUNCTION( ADD_FUNCTION(
"apply", "apply",
@ -261,5 +263,6 @@ ADD_FUNCTION(
return makePtr<HashMap>(elements); return makePtr<HashMap>(elements);
}); });
}
} // namespace blaze } // namespace blaze

3
src/env/functions/compare.cpp vendored

@ -14,6 +14,8 @@
namespace blaze { namespace blaze {
void Environment::loadCompare()
{
#define NUMBER_COMPARE(operator) \ #define NUMBER_COMPARE(operator) \
{ \ { \
bool result = true; \ bool result = true; \
@ -128,5 +130,6 @@ ADD_FUNCTION(
return makePtr<Constant>((result) ? Constant::True : Constant::False); return makePtr<Constant>((result) ? Constant::True : Constant::False);
}); });
}
} // namespace blaze } // namespace blaze

3
src/env/functions/convert.cpp vendored

@ -10,6 +10,8 @@
namespace blaze { namespace blaze {
void Environment::loadConvert()
{
// (symbol "foo") -> foo // (symbol "foo") -> foo
ADD_FUNCTION( ADD_FUNCTION(
"symbol", "symbol",
@ -45,5 +47,6 @@ ADD_FUNCTION(
return makePtr<Keyword>(stringValue->data()); return makePtr<Keyword>(stringValue->data());
}); });
}
} // namespace blaze } // namespace blaze

3
src/env/functions/format.cpp vendored

@ -16,6 +16,8 @@
namespace blaze { namespace blaze {
void Environment::loadFormat()
{
#define PRINTER_STRING(print_readably, concatenation) \ #define PRINTER_STRING(print_readably, concatenation) \
{ \ { \
std::string result; \ std::string result; \
@ -52,5 +54,6 @@ ADD_FUNCTION("pr-str", PRINTER_STRING(true, " "));
ADD_FUNCTION("prn", PRINTER_PRINT(true)); ADD_FUNCTION("prn", PRINTER_PRINT(true));
ADD_FUNCTION("println", PRINTER_PRINT(false)); ADD_FUNCTION("println", PRINTER_PRINT(false));
}
} // namespace blaze } // namespace blaze

3
src/env/functions/meta.cpp vendored

@ -12,6 +12,8 @@
namespace blaze { namespace blaze {
void Environment::loadMeta()
{
// (meta [1 2 3]) // (meta [1 2 3])
ADD_FUNCTION( ADD_FUNCTION(
"meta", "meta",
@ -49,5 +51,6 @@ ADD_FUNCTION(
return front->withMeta(*(begin + 1)); return front->withMeta(*(begin + 1));
}); });
}
} // namespace blaze } // namespace blaze

3
src/env/functions/mutable.cpp vendored

@ -15,6 +15,8 @@
namespace blaze { namespace blaze {
void Environment::loadMutable()
{
// (atom 1) // (atom 1)
ADD_FUNCTION( ADD_FUNCTION(
"atom", "atom",
@ -77,5 +79,6 @@ ADD_FUNCTION(
return atom->reset(value); return atom->reset(value);
}); });
}
} // namespace blaze } // namespace blaze

3
src/env/functions/operators.cpp vendored

@ -12,6 +12,8 @@
namespace blaze { namespace blaze {
void Environment::loadOperators()
{
ADD_FUNCTION( ADD_FUNCTION(
"+", "+",
{ {
@ -87,5 +89,6 @@ ADD_FUNCTION(
return makePtr<Number>(divide->number() % by->number()); return makePtr<Number>(divide->number() % by->number());
}); });
}
} // namespace blaze } // namespace blaze

3
src/env/functions/other.cpp vendored

@ -17,6 +17,8 @@
namespace blaze { namespace blaze {
void Environment::loadOther()
{
// (count '(1 2 3)) -> 3 // (count '(1 2 3)) -> 3
// (count [1 2 3]) -> 3 // (count [1 2 3]) -> 3
ADD_FUNCTION( ADD_FUNCTION(
@ -67,5 +69,6 @@ ADD_FUNCTION(
return makePtr<Number>(elapsed); return makePtr<Number>(elapsed);
}); });
}
} // namespace blaze } // namespace blaze

3
src/env/functions/predicate.cpp vendored

@ -10,6 +10,8 @@
namespace blaze { namespace blaze {
void Environment::loadPredicate()
{
#define IS_CONSTANT(name, constant) \ #define IS_CONSTANT(name, constant) \
{ \ { \
CHECK_ARG_COUNT_IS(name, SIZE(), 1); \ CHECK_ARG_COUNT_IS(name, SIZE(), 1); \
@ -128,5 +130,6 @@ ADD_FUNCTION(
return makePtr<Constant>((result) ? Constant::True : Constant::False); return makePtr<Constant>((result) ? Constant::True : Constant::False);
}); });
}
} // namespace blaze } // namespace blaze

3
src/env/functions/repl.cpp vendored

@ -14,6 +14,8 @@
namespace blaze { namespace blaze {
void Environment::loadRepl()
{
// REPL reader // REPL reader
ADD_FUNCTION( ADD_FUNCTION(
"read-string", "read-string",
@ -59,5 +61,6 @@ ADD_FUNCTION(
return eval(*begin, nullptr); return eval(*begin, nullptr);
}); });
}
} // namespace blaze } // namespace blaze

22
src/env/macro.h vendored

@ -8,25 +8,9 @@
#include "env/environment.h" #include "env/environment.h"
// At the top-level you cant invoke any function, but you can create variables. #define ADD_FUNCTION(symbol, lambda) \
// Using a struct's constructor you can work around this limitation. Environment::registerFunction( \
// Also, the counter macro is used to make the struct names unique.
#define FUNCTION_STRUCT_NAME(unique) __functionStruct##unique
#define ADD_FUNCTION_IMPL(unique, symbol, lambda) \
struct FUNCTION_STRUCT_NAME(unique) { \
FUNCTION_STRUCT_NAME(unique) \
(const std::string& __symbol, FunctionType __lambda) \
{ \
Environment::registerFunction(__symbol, __lambda); \
} \
}; \
static struct FUNCTION_STRUCT_NAME(unique) \
FUNCTION_STRUCT_NAME(unique)( \
symbol, \ symbol, \
[](ValueVectorConstIt begin, ValueVectorConstIt end) -> ValuePtr lambda); [](ValueVectorConstIt begin, ValueVectorConstIt end) -> blaze::ValuePtr lambda);
#define ADD_FUNCTION(symbol, lambda) ADD_FUNCTION_IMPL(__COUNTER__, symbol, lambda);
#define SIZE() std::distance(begin, end) #define SIZE() std::distance(begin, end)

1
src/repl.cpp

@ -149,6 +149,7 @@ auto main(int argc, char* argv[]) -> int
std::signal(SIGINT, blaze::cleanup); std::signal(SIGINT, blaze::cleanup);
std::signal(SIGTERM, blaze::cleanup); std::signal(SIGTERM, blaze::cleanup);
blaze::Environment::loadFunctions();
blaze::Environment::installFunctions(blaze::s_outer_env); blaze::Environment::installFunctions(blaze::s_outer_env);
installLambdas(blaze::s_outer_env); installLambdas(blaze::s_outer_env);
makeArgv(blaze::s_outer_env, arguments); makeArgv(blaze::s_outer_env, arguments);

Loading…
Cancel
Save