test out profiling
This commit is contained in:
+13
-73
@@ -2,26 +2,26 @@
|
||||
#define proc auto
|
||||
|
||||
#ifdef _DEBUG
|
||||
constexpr bool is_debug_build = true;
|
||||
# define if_debug if constexpr (true)
|
||||
#else
|
||||
constexpr bool is_debug_build = false;
|
||||
# define if_debug if constexpr (false)
|
||||
#endif
|
||||
|
||||
#define if_debug if constexpr (is_debug_build)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define if_windows if constexpr (1)
|
||||
# define if_linux if constexpr (0)
|
||||
# define debug_break() if_debug __debugbreak()
|
||||
# define if_windows if constexpr (true)
|
||||
# define if_linux if constexpr (false)
|
||||
#else
|
||||
# define debug_break() if_debug raise(SIGTRAP)
|
||||
# define if_windows if (0)
|
||||
# define if_linux if (1)
|
||||
# define if_windows if constexpr (false)
|
||||
# define if_linux if constexpr (true)
|
||||
#endif
|
||||
|
||||
#define concat_( a, b) a##b
|
||||
#define label(prefix, lnum) concat_(prefix,lnum)
|
||||
#define try \
|
||||
|
||||
#define try_or_else_return(val) \
|
||||
if (1) \
|
||||
goto label(body,__LINE__); \
|
||||
else \
|
||||
@@ -31,46 +31,17 @@ constexpr bool is_debug_build = false;
|
||||
if (Globals::log_level == Log_Level::Debug) { \
|
||||
printf("in %s:%d\n", __FILE__, __LINE__); \
|
||||
} \
|
||||
return 0; \
|
||||
return val; \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
else label(body,__LINE__):
|
||||
|
||||
#define try_void \
|
||||
if (1) \
|
||||
goto label(body,__LINE__); \
|
||||
else \
|
||||
while (1) \
|
||||
if (1) { \
|
||||
if (Globals::error) { \
|
||||
if (Globals::log_level == Log_Level::Debug) { \
|
||||
printf("in %s:%d\n", __FILE__, __LINE__); \
|
||||
} \
|
||||
return; \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
else label(body,__LINE__):
|
||||
|
||||
;
|
||||
#define without_logging \
|
||||
if (0) \
|
||||
label(finished,__LINE__): ; \
|
||||
else \
|
||||
for (Log_Level log_level_before = Globals::log_level;;) \
|
||||
for(Globals::log_level = Log_Level::None;;) \
|
||||
if (1) { \
|
||||
goto label(body,__LINE__); \
|
||||
} \
|
||||
else \
|
||||
while (1) \
|
||||
if (1) { \
|
||||
Globals::log_level = log_level_before; \
|
||||
goto label(finished,__LINE__); \
|
||||
} \
|
||||
else label(body,__LINE__):
|
||||
#define try_void try_or_else_return()
|
||||
#define try try_or_else_return(0)
|
||||
|
||||
#define dont_break_on_errors fluid_let(Globals::breaking_on_errors, false)
|
||||
#define ignore_logging fluid_let(Globals::log_level, Log_Level::None)
|
||||
|
||||
|
||||
#define define_array_list(type, name) \
|
||||
@@ -170,39 +141,8 @@ constexpr bool is_debug_build = false;
|
||||
}
|
||||
|
||||
|
||||
template<typename F>
|
||||
class defer_finalizer {
|
||||
F f;
|
||||
bool moved;
|
||||
public:
|
||||
template<typename T>
|
||||
defer_finalizer(T && f_) : f(std::forward<T>(f_)), moved(false) { }
|
||||
|
||||
defer_finalizer(const defer_finalizer &) = delete;
|
||||
|
||||
defer_finalizer(defer_finalizer && other) : f(std::move(other.f)), moved(other.moved) {
|
||||
other.moved = true;
|
||||
}
|
||||
|
||||
~defer_finalizer() {
|
||||
if (!moved) f();
|
||||
}
|
||||
};
|
||||
|
||||
struct {
|
||||
template<typename F>
|
||||
defer_finalizer<F> operator<<(F && f) {
|
||||
return defer_finalizer<F>(std::forward<F>(f));
|
||||
}
|
||||
} deferrer;
|
||||
|
||||
#define TOKENPASTE(x, y) x ## y
|
||||
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
|
||||
#define defer auto TOKENPASTE2(__deferred_lambda_call, __COUNTER__) = deferrer << [&]
|
||||
|
||||
/*
|
||||
Usage of the create_error_macros:
|
||||
|
||||
*/
|
||||
#define __create_error(keyword, ...) \
|
||||
create_error( \
|
||||
|
||||
+4
-2
@@ -8,12 +8,14 @@ proc delete_error() -> void {
|
||||
}
|
||||
|
||||
proc create_error(const char* c_file_name, int c_file_line, Lisp_Object* type, String* message) -> void {
|
||||
|
||||
if (Globals::log_level > Log_Level::None)
|
||||
printf("Error created in:\n%s:%d\n", c_file_name, c_file_line);
|
||||
|
||||
delete_error();
|
||||
debug_break();
|
||||
|
||||
if (Globals::breaking_on_errors) {
|
||||
debug_break();
|
||||
}
|
||||
// visualize_lisp_machine();
|
||||
|
||||
using Globals::error;
|
||||
|
||||
+2
-6
@@ -1,4 +1,6 @@
|
||||
proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> Lisp_Object* {
|
||||
profile_this;
|
||||
|
||||
Environment* new_env;
|
||||
try new_env = Memory::create_child_environment(function->parent_environment);
|
||||
push_environment(new_env);
|
||||
@@ -17,10 +19,6 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
|
||||
create_wrong_number_of_arguments_error(function->positional_arguments->next_index, i);
|
||||
return;
|
||||
}
|
||||
// TODO(Felix): here we create new lisp_object_symbols from
|
||||
// their identifiers but before we converted them to
|
||||
// strings from symbols... Wo maybe just use the symbols?
|
||||
|
||||
// NOTE(Felix): We have to copy all the arguments, otherwise
|
||||
// we change the program code.
|
||||
try_void sym = function->positional_arguments->symbols[i];
|
||||
@@ -527,8 +525,6 @@ proc interprete_stdin() -> void {
|
||||
return;
|
||||
}
|
||||
|
||||
Parser::environment_for_macros = user_env;
|
||||
|
||||
printf("Welcome to the lispy interpreter.\n");
|
||||
|
||||
char* line;
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Memory {
|
||||
}
|
||||
|
||||
namespace Parser {
|
||||
extern Environment* environment_for_macros;
|
||||
// extern Environment* environment_for_macros;
|
||||
|
||||
extern String* standard_in;
|
||||
extern String* parser_file;
|
||||
@@ -46,5 +46,7 @@ namespace Globals {
|
||||
Environment_Array_List* envi_stack = create_Environment_array_list();
|
||||
}
|
||||
|
||||
bool breaking_on_errors = true;
|
||||
Error* error = nullptr;
|
||||
|
||||
}
|
||||
|
||||
Submodule
+1
Submodule src/ftb added at 5d6da78c90
+4
-2
@@ -295,8 +295,10 @@ proc print(Lisp_Object* node, bool print_repr = false, FILE* file = stdout) -> v
|
||||
fputs(Memory::get_c_str(node->value.string), file);
|
||||
} break;
|
||||
case (Lisp_Object_Type::Vector): {
|
||||
fputs("[vector", file);
|
||||
for (int i = 0; i < node->value.vector.length; ++i) {
|
||||
fputs("[", file);
|
||||
if (node->value.vector.length > 0)
|
||||
print(node->value.vector.data);
|
||||
for (int i = 1; i < node->value.vector.length; ++i) {
|
||||
fputs(" ", file);
|
||||
print(node->value.vector.data+i);
|
||||
}
|
||||
|
||||
@@ -402,8 +402,6 @@ namespace Memory {
|
||||
|
||||
load_built_ins_into_environment();
|
||||
|
||||
Parser::environment_for_macros = ret;
|
||||
|
||||
// save the current working directory
|
||||
char* cwd = get_cwd();
|
||||
defer {
|
||||
|
||||
+24
-16
@@ -4,23 +4,31 @@ namespace Parser {
|
||||
int parser_line;
|
||||
int parser_col;
|
||||
|
||||
// NOTE(Felix): In this environment, the build in functions will
|
||||
// be loaded, and the macros will be stored in form of
|
||||
// special-lambdas, that get executed in this environment at
|
||||
// read-time. This should always be the global environment.
|
||||
Environment* environment_for_macros;
|
||||
proc maybe_expand_reader_macro() -> Lisp_Object* {
|
||||
// static Lisp_Object* quote_sym = Memory::get_or_create_lisp_object_symbol("quote");
|
||||
// static Lisp_Object* qquote_sym = Memory::get_or_create_lisp_object_symbol("quasiquote");
|
||||
// static Lisp_Object* unquote_sym = Memory::get_or_create_lisp_object_symbol("unquote");
|
||||
// static Lisp_Object* us_sym = Memory::get_or_create_lisp_object_symbol("unquote-splicing");
|
||||
|
||||
// proc set_environment_for_macros(Environment* env) -> void {
|
||||
// // NOTE(Felix): it is important to keep the parser environment
|
||||
// // up to date with the global environment. When doing tests,
|
||||
// // or running a programm we have to reload it.
|
||||
// if (text[*index_in_text] == '\'') {
|
||||
// *index_in_text++;
|
||||
// return quote_sym;
|
||||
// }
|
||||
// if (text[*index_in_text] == '`') {
|
||||
// *index_in_text++;
|
||||
// return qquote_sym;
|
||||
// }
|
||||
// if (text[*index_in_text] == ',') {
|
||||
// *index_in_text++;
|
||||
// return unquote_sym;
|
||||
// }
|
||||
// if (text[*index_in_text] == ',' && text[*index_in_text] == '@') {
|
||||
// *index_in_text += 2;
|
||||
// return us_sym;
|
||||
// }
|
||||
|
||||
// // NOTE(Felix): For now we just allow executing built-ins at
|
||||
// // read-time (while creating macros). If later we want to
|
||||
// // change that, we have to define some funcions in this
|
||||
// // environment.
|
||||
// environment_for_macros = env;
|
||||
// }
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
proc inject_scl(Lisp_Object* lo) -> void {
|
||||
lo->sourceCodeLocation = new(Source_Code_Location);
|
||||
@@ -387,7 +395,7 @@ namespace Parser {
|
||||
Lisp_Object* macro;
|
||||
try macro = Memory::create_lisp_object();
|
||||
Memory::set_type(macro, Lisp_Object_Type::Function);
|
||||
macro->value.function.parent_environment = environment_for_macros;
|
||||
macro->value.function.parent_environment = get_current_environment();
|
||||
macro->value.function.type = Function_Type::Macro;
|
||||
|
||||
// if parameters were specified
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
// namespace Profiler {
|
||||
// proc init() -> void {
|
||||
// out_file = fopen("profiler.report", "w");
|
||||
// if (!out_file)
|
||||
// create_generic_error("couldnt create prfiler file.");
|
||||
// }
|
||||
// proc exit() -> void {
|
||||
// fclose(out_file);
|
||||
// }
|
||||
|
||||
// proc log_entry(const char* func, const char* file, int line) -> void {
|
||||
// fprintf(out_file,"%d -> %s %s %d %ld\n", Globals::thread_type, func, file, line, clock());
|
||||
// }
|
||||
// proc log_exit() -> void {
|
||||
// fprintf(out_file, "%d <- %ld\n", Globals::thread_type, clock());
|
||||
// }
|
||||
// }
|
||||
@@ -24,11 +24,15 @@
|
||||
#undef _CRT_SECURE_NO_DEPRECATE
|
||||
#undef _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#include "./ftb/macros.h"
|
||||
#include "./ftb/profiler.hpp"
|
||||
|
||||
namespace Slime {
|
||||
# include "./defines.cpp"
|
||||
# include "./platform.cpp"
|
||||
# include "./structs.cpp"
|
||||
# include "./forward_decls.cpp"
|
||||
# include "./profiler.cpp"
|
||||
# include "./memory.cpp"
|
||||
# include "./lisp_object.cpp"
|
||||
# include "./error.cpp"
|
||||
|
||||
@@ -8,6 +8,13 @@ define_array_list(String*, String);
|
||||
define_array_list(int, Int);
|
||||
define_array_list(void*, Void_Ptr);
|
||||
|
||||
|
||||
enum struct Thread_Type {
|
||||
Main,
|
||||
GarbageCollection
|
||||
};
|
||||
|
||||
|
||||
enum struct Lisp_Object_Type {
|
||||
Nil,
|
||||
T,
|
||||
|
||||
+4
-2
@@ -517,8 +517,10 @@ proc test_built_in_type() -> testresult {
|
||||
char exp_string3[] = "(begin (set-type a \"wrong tpye\")(type a))";
|
||||
expression = Parser::parse_single_expression(exp_string3);
|
||||
|
||||
without_logging {
|
||||
result = eval_expr(expression);
|
||||
ignore_logging {
|
||||
dont_break_on_errors {
|
||||
result = eval_expr(expression);
|
||||
}
|
||||
}
|
||||
|
||||
assert_error();
|
||||
|
||||
Reference in New Issue
Block a user