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 ""
|
||||||
echo "--- Output Start ---"
|
echo "--- Output Start ---"
|
||||||
pushd bin
|
pushd bin > /dev/null
|
||||||
./slime
|
./slime --run-tests
|
||||||
popd
|
popd > /dev/null
|
||||||
echo "--- Output End ---"
|
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)
|
#define if_debug if constexpr (is_debug_build)
|
||||||
|
|
||||||
// #ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# define debug_break() if_debug __debugbreak()
|
# define debug_break() if_debug __debugbreak()
|
||||||
// #else
|
#else
|
||||||
// # define debug_break() if_debug __builtin_trap()
|
# include <signal.h>
|
||||||
// #endif
|
# define debug_break() if_debug raise(SIGTRAP)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define assert(cond) \
|
#define assert(cond) \
|
||||||
if_debug { \
|
if_debug { \
|
||||||
|
|||||||
+1
-2
@@ -9,9 +9,8 @@ proc delete_error() -> void {
|
|||||||
|
|
||||||
proc create_error(Error_Type type, Source_Code_Location* location) -> void {
|
proc create_error(Error_Type type, Source_Code_Location* location) -> void {
|
||||||
delete_error();
|
delete_error();
|
||||||
if_debug {
|
|
||||||
debug_break();
|
debug_break();
|
||||||
}
|
|
||||||
error = new(Error);
|
error = new(Error);
|
||||||
error->type = type;
|
error->type = type;
|
||||||
error->location = location;
|
error->location = location;
|
||||||
|
|||||||
+1
-2
@@ -388,8 +388,7 @@ proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* {
|
|||||||
|
|
||||||
// check for c function
|
// check for c function
|
||||||
if (lispOperator->type == Lisp_Object_Type::CFunction) {
|
if (lispOperator->type == Lisp_Object_Type::CFunction) {
|
||||||
Lisp_Object* result = lispOperator->value.lambdaWrapper->function(arguments, env);
|
Lisp_Object* result = lispOperator->value.cFunction->function(arguments, env);
|
||||||
// Lisp_Object* result = (*lispOperator->value.lambdaWrapper)(arguments, env);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -2,13 +2,17 @@
|
|||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
if (Slime::string_equal(argv[1], "--run-tests")) {
|
||||||
|
Slime::run_all_tests();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Slime::interprete_file(argv[1]);
|
Slime::interprete_file(argv[1]);
|
||||||
if (Slime::error) {
|
if (Slime::error) {
|
||||||
Slime::log_error();
|
Slime::log_error();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Slime::run_all_tests();
|
|
||||||
Slime::interprete_stdin();
|
Slime::interprete_stdin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -154,10 +154,12 @@ namespace Memory {
|
|||||||
Memory::create_string(keyword));
|
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();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Lisp_Object_Type::CFunction;
|
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;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#define _CRT_SECURE_NO_DEPRECATE
|
#define _CRT_SECURE_NO_DEPRECATE
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <cmath>
|
||||||
// #include <type_traits>
|
// #include <type_traits>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
|||||||
+3
-55
@@ -7,56 +7,6 @@ define_array_list(String*, String);
|
|||||||
define_array_list(int, Int);
|
define_array_list(int, Int);
|
||||||
define_array_list(void*, Void_Ptr);
|
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 {
|
enum struct Lisp_Object_Type {
|
||||||
Nil,
|
Nil,
|
||||||
T,
|
T,
|
||||||
@@ -157,10 +107,8 @@ struct Function {
|
|||||||
Environment* parent_environment; // we are doing closures now!!
|
Environment* parent_environment; // we are doing closures now!!
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct cFunction {
|
||||||
struct Lambda_Wrapper {
|
std::function<Lisp_Object* (Lisp_Object*, Environment*)> function;
|
||||||
Lambda_Wrapper(TransientFunction<Lisp_Object* (Lisp_Object*, Environment*)> f) : function(f) {}
|
|
||||||
TransientFunction<Lisp_Object* (Lisp_Object*, Environment*)> function;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Lisp_Object {
|
struct Lisp_Object {
|
||||||
@@ -173,7 +121,7 @@ struct Lisp_Object {
|
|||||||
String* string;
|
String* string;
|
||||||
Pair* pair;
|
Pair* pair;
|
||||||
Function* function;
|
Function* function;
|
||||||
Lambda_Wrapper* lambdaWrapper;
|
cFunction* cFunction;
|
||||||
} value;
|
} value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user