diff --git a/build.sh b/build.sh index ee7b0dd..9c6ebb5 100755 --- a/build.sh +++ b/build.sh @@ -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 diff --git a/src/defines.cpp b/src/defines.cpp index 4230ed2..cb922ad 100644 --- a/src/defines.cpp +++ b/src/defines.cpp @@ -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 +# define debug_break() if_debug raise(SIGTRAP) +#endif #define assert(cond) \ if_debug { \ diff --git a/src/error.cpp b/src/error.cpp index 5141eb3..80e60ca 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -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(); - } + debug_break(); + error = new(Error); error->type = type; error->location = location; diff --git a/src/eval.cpp b/src/eval.cpp index fd0481b..8b5f00c 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -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; } diff --git a/src/main.cpp b/src/main.cpp index 88d52b5..66775d7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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(); } } diff --git a/src/memory.cpp b/src/memory.cpp index ca2de6a..6b48beb 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -154,10 +154,12 @@ namespace Memory { Memory::create_string(keyword)); } - proc create_lisp_object_cfunction(TransientFunction function) -> Lisp_Object* { + proc create_lisp_object_cfunction(std::function 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; } diff --git a/src/slime.h b/src/slime.h index d8eaae7..21baf86 100644 --- a/src/slime.h +++ b/src/slime.h @@ -3,6 +3,7 @@ #define _CRT_SECURE_NO_DEPRECATE #include #include +#include // #include #include diff --git a/src/structs.cpp b/src/structs.cpp index 02e1cc5..aafa52c 100644 --- a/src/structs.cpp +++ b/src/structs.cpp @@ -7,56 +7,6 @@ define_array_list(String*, String); define_array_list(int, Int); define_array_list(void*, Void_Ptr); -// ----------------------------- -// -// ----------------------------- -// SOURCE: http://brnz.org/hbr/?p=1767 -template -struct TransientFunction; // intentionally not defined - -template -struct TransientFunction -{ - 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 - static R Dispatch(void* target, Args... args) { - return (*(S*)target)(args...); - } - - template - TransientFunction(T&& target) - : m_Dispatcher(&Dispatch::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) - { - 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...); - } -}; -// ----------------------------- -// -// ----------------------------- - - 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 f) : function(f) {} - TransientFunction function; +struct cFunction { + std::function function; }; struct Lisp_Object { @@ -173,7 +121,7 @@ struct Lisp_Object { String* string; Pair* pair; Function* function; - Lambda_Wrapper* lambdaWrapper; + cFunction* cFunction; } value; };