started working on logging
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 5 Mar 2021 00:18:56 +0000 (18:18 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 5 Mar 2021 00:18:56 +0000 (18:18 -0600)
bin/onyx
core/builtin.onyx
core/io/file.onyx
core/sys/js.onyx
core/sys/wasi.onyx
docs/compile_time_vars
src/onyxparser.c

index 095019512d8c6e779cb6bfc24b50f1b64b262322..19ad013c8390694dc444b5680566182a76489844 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index 2cb9c2a9feb06ae715deb64718db6c2599795962..cfa31b3e8bba12d14b0c031fc5d397e3937386ed 100644 (file)
@@ -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 }
 
index 3451d8f87c699313ab5bf1ad2430329ab4f55afc..8d4f66d47c13841594bf2ace2508dbac74471c83 100644 (file)
@@ -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");
+}
index 4c6ea40da71ea840c7324ccf0d0c636071730050..727eddc9474cbc2351747ad77c522440b435478b 100644 (file)
@@ -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;
index 15337577c013e766f8021b10acd3e86813b925a1..ebfbf06e303542f07f0880ba801f662f0676adc7 100644 (file)
@@ -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;
index 1427edfdaabbcc83fe4a0615f687c4aae03034a7..b784f619ea97cdf10e1f8953e162f24409882087 100644 (file)
@@ -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();
+        }
+
index f455f6c033505e2465bde41597e7ccd841017c6c..7baaf1c571fbaeefcf7d0abe2f450e95c1be9b02 100644 (file)
@@ -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;
             }