| @@ -1,5 +1,7 @@ | |||||
| @echo off | @echo off | ||||
| mkdir bin | |||||
| set EXE_RAW=test | set EXE_RAW=test | ||||
| set BINDIR_RAW=bin | set BINDIR_RAW=bin | ||||
| set SRC=test.cpp | set SRC=test.cpp | ||||
| @@ -11,12 +13,12 @@ set BINDIR_LINUX=./%BINDIR_RAW% | |||||
| echo. | echo. | ||||
| echo clang: | echo clang: | ||||
| clang %SRC% -o %BINDIR_WIN%\clang_%EXE_WIN% | |||||
| clang -std=c++17 %SRC% -o %BINDIR_WIN%\clang_%EXE_WIN% | |||||
| %BINDIR_WIN%\clang_%EXE_WIN% | %BINDIR_WIN%\clang_%EXE_WIN% | ||||
| echo. | echo. | ||||
| echo g++: | echo g++: | ||||
| g++ %SRC% -o %BINDIR_WIN%\g++_%EXE_WIN% | |||||
| g++ -std=c++17 %SRC% -o %BINDIR_WIN%\g++_%EXE_WIN% | |||||
| %BINDIR_WIN%\g++_%EXE_WIN% | %BINDIR_WIN%\g++_%EXE_WIN% | ||||
| echo. | echo. | ||||
| @@ -26,8 +28,8 @@ cl %SRC% /nologo /Zi /Fd: %BINDIR_WIN%\cl_%EXE_WIN%.pdb /Fo: %BINDIR_WIN%\ /Fe: | |||||
| echo. | echo. | ||||
| echo bash_clang: | echo bash_clang: | ||||
| bash -c "clang -std=c++11 %SRC% -o %BINDIR_LINUX%/bash_clang_%EXE_LINUX% && %BINDIR_LINUX%/bash_clang_%EXE_LINUX%" | |||||
| bash -c "clang -std=c++17 %SRC% -o %BINDIR_LINUX%/bash_clang_%EXE_LINUX% && %BINDIR_LINUX%/bash_clang_%EXE_LINUX%" | |||||
| echo. | echo. | ||||
| echo bash_g++: | echo bash_g++: | ||||
| bash -c "g++ -std=c++11 %SRC% -o %BINDIR_LINUX%/bash_g++_%EXE_LINUX% && %BINDIR_LINUX%/bash_g++_%EXE_LINUX%" | |||||
| bash -c "g++ -std=c++17 %SRC% -o %BINDIR_LINUX%/bash_g++_%EXE_LINUX% && %BINDIR_LINUX%/bash_g++_%EXE_LINUX%" | |||||
| @@ -0,0 +1,104 @@ | |||||
| #pragma once | |||||
| #include "stdio.h" | |||||
| #include "math.h" | |||||
| #include "stdarg.h" | |||||
| #include "stdlib.h" | |||||
| #include "types.hpp" | |||||
| #include "print.hpp" | |||||
| struct Error { | |||||
| String type; | |||||
| String message; | |||||
| }; | |||||
| Error* error = nullptr; | |||||
| auto delete_error() -> void { | |||||
| free(error); | |||||
| error = nullptr; | |||||
| } | |||||
| auto create_error(const char* c_func_name, const char* c_file_name, | |||||
| u32 c_file_line, String type, const char* format, ...) -> void { | |||||
| error = new Error; | |||||
| error->type = type; | |||||
| va_list args; | |||||
| va_start(args, format); | |||||
| error->message.length = print_va_args_to_string(&(error->message.data), format, &args); | |||||
| va_end(args); | |||||
| print("\n%{color<}%{->Str} error:%{>color} %{->Str}\n", | |||||
| console_red, &(error->type), &(error->message)); | |||||
| printf("in"); | |||||
| s32 spacing = 30-((s32)strlen(c_file_name) + (s32)log10(c_file_line)); | |||||
| if (spacing < 1) spacing = 1; | |||||
| for (s32 i = 0; i < spacing; ++i) | |||||
| printf(" "); | |||||
| printf("%s (%u) ", c_file_name, c_file_line); | |||||
| printf("-> %s\n", c_func_name); | |||||
| } | |||||
| #define __create_error(keyword, ...) \ | |||||
| create_error( \ | |||||
| __FUNCTION__, __FILE__, __LINE__, \ | |||||
| make_heap_string(keyword), \ | |||||
| __VA_ARGS__) | |||||
| #define create_assertion_error(...) \ | |||||
| __create_error("assert", __VA_ARGS__) | |||||
| #define create_generic_error(...) \ | |||||
| __create_error("generic", __VA_ARGS__) | |||||
| #define assert(condition, format, ...) \ | |||||
| do { \ | |||||
| if (!(condition)) { \ | |||||
| char* msg; \ | |||||
| print_to_string(&msg, format, __VA_ARGS__); \ | |||||
| create_assertion_error("Assertion-error: %s\n" \ | |||||
| " condition: %s\n" \ | |||||
| " in: %s:%d", \ | |||||
| msg, #condition, \ | |||||
| __FILE__, __LINE__ ); \ | |||||
| } \ | |||||
| } while(0) | |||||
| #define log_location() \ | |||||
| do { \ | |||||
| printf("in"); \ | |||||
| s32 spacing = 30-((s32)strlen(__FILE__) + (s32)log10(__LINE__)); \ | |||||
| if (spacing < 1) spacing = 1; \ | |||||
| for (s32 i = 0; i < spacing;++i) \ | |||||
| printf(" "); \ | |||||
| printf("%s (%d) ", __FILE__, __LINE__); \ | |||||
| printf("-> %s\n", __FUNCTION__); \ | |||||
| } while(0) | |||||
| #define if_error_log_location_and_return(val) \ | |||||
| do { \ | |||||
| if (error) { \ | |||||
| log_location(); \ | |||||
| return val; \ | |||||
| } \ | |||||
| } while(0) | |||||
| #define try_or_else_return(val) \ | |||||
| if (1) \ | |||||
| goto label(body,__LINE__); \ | |||||
| else \ | |||||
| while (1) \ | |||||
| if (1) { \ | |||||
| if (error) { \ | |||||
| log_location(); \ | |||||
| return val; \ | |||||
| } \ | |||||
| break; \ | |||||
| } \ | |||||
| else label(body,__LINE__): | |||||
| #define check_error_struct try_or_else_return({}) | |||||
| #define check_error_void try_or_else_return(;) | |||||
| #define check_error try_or_else_return(0) | |||||
| @@ -1,8 +1,8 @@ | |||||
| #pragma once | #pragma once | ||||
| #define proc auto | #define proc auto | ||||
| #define TOKENPASTE(x, y) x ## y | |||||
| #define TOKENPASTE2(x, y) TOKENPASTE(x, y) | |||||
| #define concat(x, y) x ## y | |||||
| #define label(x, y) concat(x, y) | |||||
| /** | /** | ||||
| @@ -34,7 +34,7 @@ static struct { | |||||
| } | } | ||||
| } deferrer; | } deferrer; | ||||
| #define defer auto TOKENPASTE2(__deferred_lambda_call, __COUNTER__) = deferrer << [&] | |||||
| #define defer auto label(__deferred_lambda_call, __COUNTER__) = deferrer << [&] | |||||
| #define defer_free(var) defer { free(var); } | #define defer_free(var) defer { free(var); } | ||||
| @@ -57,13 +57,13 @@ expands to: | |||||
| #define fluid_let(var, val) \ | #define fluid_let(var, val) \ | ||||
| if (0) \ | if (0) \ | ||||
| TOKENPASTE2(finished,__LINE__): ; \ | |||||
| label(finished,__LINE__): ; \ | |||||
| else \ | else \ | ||||
| for (auto TOKENPASTE2(fluid_let_, __LINE__) = var;;) \ | |||||
| for (defer{var = TOKENPASTE2(fluid_let_, __LINE__);};;) \ | |||||
| for (auto label(fluid_let_, __LINE__) = var;;) \ | |||||
| for (defer{var = label(fluid_let_, __LINE__);};;) \ | |||||
| for(var = val;;) \ | for(var = val;;) \ | ||||
| if (1) { \ | if (1) { \ | ||||
| goto TOKENPASTE2(body,__LINE__); \ | |||||
| goto label(body,__LINE__); \ | |||||
| } \ | } \ | ||||
| else \ | else \ | ||||
| while (1) \ | while (1) \ | ||||
| @@ -11,6 +11,11 @@ | |||||
| #define str_eq(s1, s2) (strcmp(s1, s2) == 0) | #define str_eq(s1, s2) (strcmp(s1, s2) == 0) | ||||
| #define console_normal "\x1B[0m" | |||||
| #define console_red "\x1B[31m" | |||||
| #define console_green "\x1B[32m" | |||||
| #define console_cyan "\x1B[36m" | |||||
| typedef const char* static_string; | typedef const char* static_string; | ||||
| typedef int (*printer_function_32b)(FILE*, u32); | typedef int (*printer_function_32b)(FILE*, u32); | ||||
| typedef int (*printer_function_64b)(FILE*, u64); | typedef int (*printer_function_64b)(FILE*, u64); | ||||
| @@ -27,13 +32,14 @@ enum struct Printer_Function_Type { | |||||
| _void | _void | ||||
| }; | }; | ||||
| Hash_Map<char*, printer_function_32b> printer_map = {0}; | |||||
| Array_List<char*> color_stack = {0}; | |||||
| Hash_Map<char*, printer_function_ptr> printer_map = {0}; | |||||
| Hash_Map<char*, int> type_map = {0}; | Hash_Map<char*, int> type_map = {0}; | ||||
| #define register_printer(spec, fun, type) \ | |||||
| register_printer_32(spec, (printer_function_32b)fun, type) | |||||
| #define register_printer(spec, fun, type) \ | |||||
| register_printer_ptr(spec, (printer_function_ptr)fun, type) | |||||
| void register_printer_32(const char* spec, printer_function_32b fun, Printer_Function_Type type) { | |||||
| void register_printer_ptr(const char* spec, printer_function_ptr fun, Printer_Function_Type type) { | |||||
| printer_map.set_object((char*)spec, fun); | printer_map.set_object((char*)spec, fun); | ||||
| type_map.set_object((char*)spec, (int)type); | type_map.set_object((char*)spec, (int)type); | ||||
| } | } | ||||
| @@ -69,14 +75,15 @@ int maybe_special_print(FILE* file, static_string format, int* pos, va_list* arg | |||||
| } printer; | } printer; | ||||
| // just grab it, it will have the correct type | // just grab it, it will have the correct type | ||||
| printer.printer_32b = printer_map.get_object(spec, spec_hash); | |||||
| free(spec); | |||||
| printer.printer_ptr = printer_map.get_object(spec, spec_hash); | |||||
| if (type == Printer_Function_Type::unknown) { | if (type == Printer_Function_Type::unknown) { | ||||
| printf("ERROR: %s printer not found\n", spec); | |||||
| free(spec); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| free(spec); | |||||
| if (format[end_pos] == ',') { | if (format[end_pos] == ',') { | ||||
| int element_count; | int element_count; | ||||
| @@ -399,28 +406,63 @@ int print_str(FILE* f, char* str) { | |||||
| return print_to_file(f, "%s", str); | return print_to_file(f, "%s", str); | ||||
| } | } | ||||
| int print_color_start(FILE* f, char* str) { | |||||
| color_stack.append(str); | |||||
| return print_to_file(f, "%s", str); | |||||
| } | |||||
| int print_color_end(FILE* f) { | |||||
| --color_stack.next_index; | |||||
| if (color_stack.next_index == 0) { | |||||
| return print_to_file(f, "%s", console_normal); | |||||
| } else { | |||||
| return print_to_file(f, "%s", color_stack[color_stack.next_index-1]); | |||||
| } | |||||
| } | |||||
| int print_ptr(FILE* f, void* ptr) { | int print_ptr(FILE* f, void* ptr) { | ||||
| if (ptr) | if (ptr) | ||||
| return print_to_file(f, "%#0*X", sizeof(void*)*2+2, ptr); | return print_to_file(f, "%#0*X", sizeof(void*)*2+2, ptr); | ||||
| return print_to_file(f, "nullptr"); | return print_to_file(f, "nullptr"); | ||||
| } | } | ||||
| auto print_Str(FILE* f, String* str) -> s32 { | |||||
| return print_to_file(f, "%.*s", str->length, str->data); | |||||
| } | |||||
| auto print_str_line(FILE* f, char* str) -> s32 { | |||||
| u32 length = 0; | |||||
| char* str_cpy = str; | |||||
| while (str[length] != '\0') { | |||||
| if (str[length] == '\n') | |||||
| break; | |||||
| length++; | |||||
| } | |||||
| return print_to_file(f, "%.*s", length, str); | |||||
| } | |||||
| void deinit_printer() { | void deinit_printer() { | ||||
| printer_map.dealloc(); | printer_map.dealloc(); | ||||
| type_map.dealloc(); | type_map.dealloc(); | ||||
| } | } | ||||
| void init_printer() { | void init_printer() { | ||||
| color_stack.alloc(); | |||||
| printer_map.alloc(); | printer_map.alloc(); | ||||
| type_map.alloc(); | type_map.alloc(); | ||||
| register_printer("u32", print_u32, Printer_Function_Type::_32b); | |||||
| register_printer("u64", print_u64, Printer_Function_Type::_64b); | |||||
| register_printer("bool", print_bool, Printer_Function_Type::_32b); | |||||
| register_printer("s64", print_s64, Printer_Function_Type::_64b); | |||||
| register_printer("s32", print_s32, Printer_Function_Type::_32b); | |||||
| register_printer("f32", print_flt, Printer_Function_Type::_flt); | |||||
| register_printer("f64", print_flt, Printer_Function_Type::_flt); | |||||
| register_printer("str", print_str, Printer_Function_Type::_ptr); | |||||
| register_printer("ptr", print_ptr, Printer_Function_Type::_ptr); | |||||
| register_printer("u32", print_u32, Printer_Function_Type::_32b); | |||||
| register_printer("u64", print_u64, Printer_Function_Type::_64b); | |||||
| register_printer("bool", print_bool, Printer_Function_Type::_32b); | |||||
| register_printer("s64", print_s64, Printer_Function_Type::_64b); | |||||
| register_printer("s32", print_s32, Printer_Function_Type::_32b); | |||||
| register_printer("f32", print_flt, Printer_Function_Type::_flt); | |||||
| register_printer("f64", print_flt, Printer_Function_Type::_flt); | |||||
| register_printer("->char", print_str, Printer_Function_Type::_ptr); | |||||
| register_printer("->", print_ptr, Printer_Function_Type::_ptr); | |||||
| register_printer("color<", print_color_start, Printer_Function_Type::_ptr); | |||||
| register_printer(">color", print_color_end, Printer_Function_Type::_void); | |||||
| register_printer("->Str", print_Str, Printer_Function_Type::_ptr); | |||||
| register_printer("->char_line", print_str_line, Printer_Function_Type::_ptr); | |||||
| } | } | ||||
| @@ -6,6 +6,7 @@ | |||||
| #include "./hooks.hpp" | #include "./hooks.hpp" | ||||
| #include "./error.hpp" | |||||
| #include "./print.hpp" | #include "./print.hpp" | ||||
| @@ -13,25 +14,25 @@ int print_dots(FILE* f) { | |||||
| return print_to_file(f, "..."); | return print_to_file(f, "..."); | ||||
| } | } | ||||
| s32 main(s32 argc, char* argv[]) { | |||||
| u32 arr[] = {1,2,3,4,1,1,3}; | |||||
| f32 f_arr[] = {1.1,2.1,3.2}; | |||||
| void test_printer() { | |||||
| // u32 arr[] = {1,2,3,4,1,1,3}; | |||||
| // f32 f_arr[] = {1.1,2.1,3.2}; | |||||
| init_printer(); | |||||
| register_printer("dots", print_dots, Printer_Function_Type::_void); | |||||
| // init_printer(); | |||||
| // register_printer("dots", print_dots, Printer_Function_Type::_void); | |||||
| u32 u1 = -1; | |||||
| u64 u2 = -1; | |||||
| // u32 u1 = -1; | |||||
| // u64 u2 = -1; | |||||
| char* str; | |||||
| print_to_string(&str, " - %{dots[5]} %{ptr} <> %{ptr,2}\n", &u1, &arr, nullptr); | |||||
| print("---> %{str}", str); | |||||
| // char* str; | |||||
| // print_to_string(&str, " - %{dots[5]} %{->} <> %{->,2}\n", &u1, &arr, nullptr); | |||||
| // print("---> %{->char}", str); | |||||
| // print(" - %{dots[3]}\n"); | // print(" - %{dots[3]}\n"); | ||||
| // print(" - %{u32} %{u64}\n", u1, u2); | // print(" - %{u32} %{u64}\n", u1, u2); | ||||
| // print(" - %{u32} %{u32} %{u32}\n", 2, 5, 7); | // print(" - %{u32} %{u32} %{u32}\n", 2, 5, 7); | ||||
| // print(" - %{f32} %{f32} %{f32}\n", 2.0, 5.0, 7.0); | // print(" - %{f32} %{f32} %{f32}\n", 2.0, 5.0, 7.0); | ||||
| // print(" - %{u32} %{bool} %{str}\n", 2, true, "hello"); | |||||
| // print(" - %{u32} %{bool} %{->char}\n", 2, true, "hello"); | |||||
| // print(" - %{f32[3]}\n", f_arr); | // print(" - %{f32[3]}\n", f_arr); | ||||
| // print(" - %{f32,3}\n", 44.9, 55.1, 66.2); | // print(" - %{f32,3}\n", 44.9, 55.1, 66.2); | ||||
| // print(" - %{u32[5]}\n", arr); | // print(" - %{u32[5]}\n", arr); | ||||
| @@ -39,8 +40,33 @@ s32 main(s32 argc, char* argv[]) { | |||||
| // print(" - %{u32,5}\n", 1,2,3,4,1,2); | // print(" - %{u32,5}\n", 1,2,3,4,1,2); | ||||
| // print(" - %{unknown%d}\n", 1); | // print(" - %{unknown%d}\n", 1); | ||||
| // print(" - %{s32,3}\n", -1,200,-300); | // print(" - %{s32,3}\n", -1,200,-300); | ||||
| // print(" - %{ptr} <> %{ptr,2}\n", &u1, &arr, nullptr); | |||||
| // print(" - %{->} <> %{->,2}\n", &u1, &arr, nullptr); | |||||
| } | |||||
| s32 main(s32 argc, char* argv[]) { | |||||
| // test_printer(); | |||||
| init_printer(); | |||||
| // create_generic_error("nothing to lex was found:\n" | |||||
| // " in %{color<}%{->char}%{>color}\n" | |||||
| // " at %{color<}%{->char}%{>color}\n" | |||||
| // "bottom text\n", | |||||
| // console_green, | |||||
| // "some file name", | |||||
| // console_cyan, | |||||
| // "yesssssss"); | |||||
| create_error(__FUNCTION__, __FILE__, __LINE__, | |||||
| make_heap_string("generic"), | |||||
| "nothing to lex was found:\n" | |||||
| " in %{color<}%{->char}%{>color}\n" | |||||
| " at %{color<}%{->char}%{>color}\n" | |||||
| "bottom text\n", | |||||
| console_green, | |||||
| "some file name", | |||||
| console_cyan, | |||||
| "yesssssss"); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -1,6 +1,7 @@ | |||||
| #pragma once | #pragma once | ||||
| #include <stdint.h> | #include <stdint.h> | ||||
| #include <string.h> | |||||
| typedef int8_t s8; | typedef int8_t s8; | ||||
| typedef int16_t s16; | typedef int16_t s16; | ||||
| @@ -20,3 +21,15 @@ typedef wchar_t path_char; | |||||
| #else | #else | ||||
| typedef char path_char; | typedef char path_char; | ||||
| #endif | #endif | ||||
| struct String { | |||||
| u32 length; | |||||
| char* data; | |||||
| }; | |||||
| inline String make_heap_string(const char* str) { | |||||
| String ret; | |||||
| ret.length = strlen(str); | |||||
| ret.data = _strdup(str); | |||||
| return ret; | |||||
| } | |||||