From: Brendan Hansen Date: Fri, 5 Mar 2021 00:18:56 +0000 (-0600) Subject: started working on logging X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=de137ffe79370fb838e416660f8f9b3ea590ee0b;p=onyx.git started working on logging --- diff --git a/bin/onyx b/bin/onyx index 09501951..19ad013c 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/core/builtin.onyx b/core/builtin.onyx index 2cb9c2a9..cfa31b3e 100644 --- a/core/builtin.onyx +++ b/core/builtin.onyx @@ -1,4 +1,5 @@ package builtin +use package build_opts as build_opts str :: #type []u8; cstr :: #type ^u8; @@ -47,9 +48,23 @@ OnyxContext :: struct { allocator : Allocator; temp_allocator : Allocator; + logger : Logger = .{ default_logger, null }; + assert_handler : (msg: str, file: str) -> void; } +#if build_opts.Runtime != build_opts.Runtime_Custom { + #private_file default_logger :: (data: rawptr, msg: str) { + use package core + println(msg); + } + +} else { + #private_file default_logger :: (data: rawptr, msg: str) { + // In a custom runtime, there is no way to know how to log something. + } +} + // @Robustness // Currently, because the only compilation target is WebAssembly, which is only // single threaded for the moment, it is safe to store the context in a global @@ -64,6 +79,20 @@ assert :: (cond: bool, msg: str, file: str = null_str) { } +// +// Basic logging +// + +Logger :: struct { + func : (data: rawptr, msg: str) -> void; + data : rawptr; +} + +log :: (msg: str, use logger: Logger = context.logger) { + func(data, msg); +} + + // // Basic allocation structures. // The implementations of all of the allocators can be found in core/alloc/. @@ -78,6 +107,7 @@ AllocationAction :: enum { Resize; } +#private_file allocator_proc :: #type (data: rawptr, action: AllocationAction, size: u32, align: u32, old_ptr: rawptr) -> rawptr; Allocator :: struct { @@ -102,7 +132,6 @@ calloc :: (size: u32) -> rawptr do return raw_alloc(context.allocator, size); cresize :: (ptr: rawptr, size: u32) -> rawptr do return raw_resize(context.allocator, ptr, size); cfree :: (ptr: rawptr) do raw_free(context.allocator, ptr); -use package build_opts as build_opts #if build_opts.Runtime != build_opts.Runtime_Custom { use package core.intrinsics.wasm { __initialize } diff --git a/core/io/file.onyx b/core/io/file.onyx index 3451d8f8..8d4f66d4 100644 --- a/core/io/file.onyx +++ b/core/io/file.onyx @@ -279,3 +279,29 @@ file_stream_vtable := Stream_Vtable.{ return ~~ file_stat.size; }, } + + + + +file_logger_open :: (filename: str, allocator := context.allocator) -> Logger { + file := new(File, allocator); + success := false; + + *file, success = file_open(filename, mode=OpenMode.Append); + assert(success, "Unable to open file for logging."); + + return .{ file_logger_proc, file }; +} + +file_logger_close :: (logger := context.logger) { + file_close(*cast(^File) logger.data); + + // @Robustness: this could be the wrong allocator if the context allocator wasn't used. + cfree(logger.data); +} + +#private_file +file_logger_proc :: (data: ^File, msg: str) { + file_write(*data, msg); + file_write(*data, "\n"); +} diff --git a/core/sys/js.onyx b/core/sys/js.onyx index 4c6ea40d..727eddc9 100644 --- a/core/sys/js.onyx +++ b/core/sys/js.onyx @@ -2,6 +2,7 @@ package system use package core use package main as main +use package core.intrinsics.wasm { __initialize } output_str :: (s: str) -> u32 #foreign "host" "print_str" --- @@ -25,6 +26,7 @@ assert_handler :: (msg: str, file: str) { proc () #export "_start" { alloc.init(); + __initialize(^context); context.allocator = alloc.heap_allocator; context.temp_allocator = alloc.temp_allocator; context.assert_handler = assert_handler; diff --git a/core/sys/wasi.onyx b/core/sys/wasi.onyx index 15337577..ebfbf06e 100644 --- a/core/sys/wasi.onyx +++ b/core/sys/wasi.onyx @@ -5,6 +5,7 @@ package system use package wasi use package core use package main as main +use package core.intrinsics.wasm { __initialize } STDOUT_FILENO :: 1 @@ -35,6 +36,7 @@ assert_handler :: (msg: str, file: str) { proc () #export "_start" { alloc.init(); + __initialize(^context); context.allocator = alloc.heap_allocator; context.temp_allocator = alloc.temp_allocator; context.assert_handler = assert_handler; diff --git a/docs/compile_time_vars b/docs/compile_time_vars index 1427edfd..b784f619 100644 --- a/docs/compile_time_vars +++ b/docs/compile_time_vars @@ -11,4 +11,21 @@ set the variables described below to their value. There should be an #error directive that when hit just produces a compile time error and prevents compilation. It would be useful to ensure certain files that are only for a particular -backend will not compile with the wrong one, such as webgl.onyx. \ No newline at end of file +backend will not compile with the wrong one, such as webgl.onyx. + +Another thing to think about is having things like 'defined(...)' in C. In other words, a +method for knowing whether or not a symbol exists. Other things similar to this idea: + - defined(...) if the symbol is defined as anything + - is_procedure(...) if the symbol is a procedure + - argument_count(...) the number of required arguments the procedure has + + main :: () { + .... + } + + #if argument_count(main) > 0 { + main(args); + } else { + main(); + } + diff --git a/src/onyxparser.c b/src/onyxparser.c index f455f6c0..7baaf1c5 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -1325,14 +1325,15 @@ static AstNode* parse_statement(OnyxParser* parser) { assignment2->left = builtin_context_variable; assignment2->right = (AstTyped *) context_tmp; + AstBlock* context_block = parse_block(parser); + assignment->next = (AstNode *) context_block; + AstDefer* defer_node = make_node(AstDefer, Ast_Kind_Defer); defer_node->stmt = (AstNode *) assignment2; - assignment->next = (AstNode *) defer_node; + defer_node->next = context_block->body; + context_block->body = (AstNode *) defer_node; - AstBlock* context_block = parse_block(parser); needs_semicolon = 0; - defer_node->next = (AstNode *) context_block; - retval = (AstNode *) context_tmp; break; }