Reverted back to std::functions
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
clang src/main.c -g -o ./bin/slime --std=c99 || exit 1
|
||||
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
|
||||
pushd $SCRIPTPATH > /dev/null
|
||||
|
||||
clang++ src/main.cpp -g -o ./bin/slime --std=c++17 || exit 1
|
||||
|
||||
echo ""
|
||||
echo "--- Output Start ---"
|
||||
pushd bin
|
||||
./slime
|
||||
popd
|
||||
pushd bin > /dev/null
|
||||
./slime --run-tests
|
||||
popd > /dev/null
|
||||
echo "--- Output End ---"
|
||||
popd > /dev/null
|
||||
|
||||
+5
-4
@@ -9,11 +9,12 @@ constexpr bool is_debug_build = false;
|
||||
|
||||
#define if_debug if constexpr (is_debug_build)
|
||||
|
||||
// #ifdef _MSC_VER
|
||||
#ifdef _MSC_VER
|
||||
# define debug_break() if_debug __debugbreak()
|
||||
// #else
|
||||
// # define debug_break() if_debug __builtin_trap()
|
||||
// #endif
|
||||
#else
|
||||
# include <signal.h>
|
||||
# define debug_break() if_debug raise(SIGTRAP)
|
||||
#endif
|
||||
|
||||
#define assert(cond) \
|
||||
if_debug { \
|
||||
|
||||
+1
-2
@@ -9,9 +9,8 @@ proc delete_error() -> void {
|
||||
|
||||
proc create_error(Error_Type type, Source_Code_Location* location) -> void {
|
||||
delete_error();
|
||||
if_debug {
|
||||
debug_break();
|
||||
}
|
||||
|
||||
error = new(Error);
|
||||
error->type = type;
|
||||
error->location = location;
|
||||
|
||||
+1
-2
@@ -388,8 +388,7 @@ proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* {
|
||||
|
||||
// check for c function
|
||||
if (lispOperator->type == Lisp_Object_Type::CFunction) {
|
||||
Lisp_Object* result = lispOperator->value.lambdaWrapper->function(arguments, env);
|
||||
// Lisp_Object* result = (*lispOperator->value.lambdaWrapper)(arguments, env);
|
||||
Lisp_Object* result = lispOperator->value.cFunction->function(arguments, env);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -2,13 +2,17 @@
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc > 1) {
|
||||
if (Slime::string_equal(argv[1], "--run-tests")) {
|
||||
Slime::run_all_tests();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Slime::interprete_file(argv[1]);
|
||||
if (Slime::error) {
|
||||
Slime::log_error();
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
Slime::run_all_tests();
|
||||
Slime::interprete_stdin();
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -154,10 +154,12 @@ namespace Memory {
|
||||
Memory::create_string(keyword));
|
||||
}
|
||||
|
||||
proc create_lisp_object_cfunction(TransientFunction<Lisp_Object* (Lisp_Object*, Environment*)> function) -> Lisp_Object* {
|
||||
proc create_lisp_object_cfunction(std::function<Lisp_Object* (Lisp_Object*, Environment*)> function) -> Lisp_Object* {
|
||||
Lisp_Object* node = create_lisp_object();
|
||||
node->type = Lisp_Object_Type::CFunction;
|
||||
node->value.lambdaWrapper = new Lambda_Wrapper(function);
|
||||
// node->value.lambdaWrapper = new Lambda_Wrapper(function);
|
||||
node->value.cFunction = new(cFunction);
|
||||
node->value.cFunction->function = function;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <cmath>
|
||||
// #include <type_traits>
|
||||
#include <functional>
|
||||
|
||||
|
||||
+3
-55
@@ -7,56 +7,6 @@ define_array_list(String*, String);
|
||||
define_array_list(int, Int);
|
||||
define_array_list(void*, Void_Ptr);
|
||||
|
||||
// -----------------------------
|
||||
// <crazy lambda wrapper>
|
||||
// -----------------------------
|
||||
// SOURCE: http://brnz.org/hbr/?p=1767
|
||||
template<typename>
|
||||
struct TransientFunction; // intentionally not defined
|
||||
|
||||
template<typename R, typename ...Args>
|
||||
struct TransientFunction<R(Args...)>
|
||||
{
|
||||
using Dispatcher = R(*)(void*, Args...);
|
||||
|
||||
Dispatcher m_Dispatcher; // A pointer to the static function that will call the
|
||||
// wrapped invokable object
|
||||
void* m_Target; // A pointer to the invokable object
|
||||
|
||||
// Dispatch() is instantiated by the TransientFunction constructor,
|
||||
// which will store a pointer to the function in m_Dispatcher.
|
||||
template<typename S>
|
||||
static R Dispatch(void* target, Args... args) {
|
||||
return (*(S*)target)(args...);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
TransientFunction(T&& target)
|
||||
: m_Dispatcher(&Dispatch<typename std::decay<T>::type>)
|
||||
, m_Target(&target)
|
||||
{}
|
||||
|
||||
// Specialize for reference-to-function, to ensure that a valid pointer is
|
||||
// stored.
|
||||
using TargetFunctionRef = R(Args...);
|
||||
TransientFunction(TargetFunctionRef target)
|
||||
: m_Dispatcher(Dispatch<TargetFunctionRef>)
|
||||
{
|
||||
static_assert(sizeof(void*) == sizeof target,
|
||||
"It will not be possible to pass functions by reference on this platform. "
|
||||
"Please use explicit function pointers i.e. foo(target) -> foo(&target)");
|
||||
m_Target = (void*)target;
|
||||
}
|
||||
|
||||
R operator()(Args... args) const {
|
||||
return m_Dispatcher(m_Target, args...);
|
||||
}
|
||||
};
|
||||
// -----------------------------
|
||||
// </crazy lambda wrapper>
|
||||
// -----------------------------
|
||||
|
||||
|
||||
enum struct Lisp_Object_Type {
|
||||
Nil,
|
||||
T,
|
||||
@@ -157,10 +107,8 @@ struct Function {
|
||||
Environment* parent_environment; // we are doing closures now!!
|
||||
};
|
||||
|
||||
|
||||
struct Lambda_Wrapper {
|
||||
Lambda_Wrapper(TransientFunction<Lisp_Object* (Lisp_Object*, Environment*)> f) : function(f) {}
|
||||
TransientFunction<Lisp_Object* (Lisp_Object*, Environment*)> function;
|
||||
struct cFunction {
|
||||
std::function<Lisp_Object* (Lisp_Object*, Environment*)> function;
|
||||
};
|
||||
|
||||
struct Lisp_Object {
|
||||
@@ -173,7 +121,7 @@ struct Lisp_Object {
|
||||
String* string;
|
||||
Pair* pair;
|
||||
Function* function;
|
||||
Lambda_Wrapper* lambdaWrapper;
|
||||
cFunction* cFunction;
|
||||
} value;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user