Improved speed of lexer slightly; started profiling
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 21 Aug 2020 03:15:46 +0000 (22:15 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 21 Aug 2020 03:16:31 +0000 (22:16 -0500)
Makefile
core/math.onyx [new file with mode: 0644]
docs/plan
include/bh.h
onyx
src/onyxlex.c
src/onyxsymres.c
src/onyxwasm.c

index bf49f2a03cc027e8f5141d9eb0d79cc12d682958..740b434b32fd974a9aa5534e59995f57eb0a3365 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-RELEASE=1
+RELEASE=0
 
 OBJ_FILES=\
        build/onyxlex.o \
@@ -21,7 +21,7 @@ TARGET=./onyx
 ifeq ($(RELEASE), 1)
        FLAGS=-O2
 else
-       FLAGS=-g
+       FLAGS=-g -O2
 endif
 
 build/%.o: src/%.c include/bh.h
diff --git a/core/math.onyx b/core/math.onyx
new file mode 100644 (file)
index 0000000..8151c32
--- /dev/null
@@ -0,0 +1,49 @@
+package math
+
+PI  :: 3.14159265f;
+TAU :: 6.28318330f;
+
+// Simple taylor series approximation of sin(t)
+sin :: proc (t_: f32) -> f32 {
+       t := t_;
+       while t >=  PI do t -= TAU;
+       while t <= -PI do t += TAU;
+
+       res := 0.0f;
+
+       plus_minus := 1.0f;
+       n := 13;
+       while n > 1 {
+               res += plus_minus;
+               res *= t * t / cast(f32) (n * n - n);
+
+               plus_minus = -plus_minus;
+               n -= 2;
+       }
+
+       res += 1.0f;
+       res *= t;
+       return res;
+}
+
+// Simple taylor series approximation of cos(t)
+cos :: proc (t_: f32) -> f32 {
+       t := t_;
+       while t >=  PI do t -= TAU;
+       while t <= -PI do t += TAU;
+
+       res := 0.0f;
+
+       plus_minus := 1.0f;
+       n := 12;
+       while n > 1 {
+               res += plus_minus;
+               res *= t * t / cast(f32) (n * n - n);
+
+               plus_minus = -plus_minus;
+               n -= 2;
+       }
+
+       res += 1.0f;
+       return res;
+}
\ No newline at end of file
index 50f6ee14e5c0f00dd4916fec27769727d2df21f0..8bcf3262e801f437a45401971f82f5de1e3df4a7 100644 (file)
--- a/docs/plan
+++ b/docs/plan
@@ -187,6 +187,23 @@ HOW:
         [X] returning structs
             - This will put forward a lot of the work that will be done for multiple return values
 
+        [ ] Put type info in data section so it is runtime accessible
+            - type name
+            - size
+            - alignment
+            - struct member names
+            - array length
+
+        [ ] convert to using an 'atom' like table
+            - All identifier tokens are given a unique atom ptr, up to string equality.
+            - This means identifiers can be compared using ptr comparison, instead of string comparison
+            - This mean no more token_toggle_end!! Woo!!
+
+        [ ] Make the lexer much faster
+            - Technically it isn't slow right now
+            - But, profiling says we are spending 50% of the program execution time in the lexer
+            - That is awful
+
         [ ] Add slices
             - Arrays without a size
             - Converted to a struct that looks like:    
@@ -213,12 +230,6 @@ HOW:
 
         [ ] All code paths return correct value
 
-        [ ] Put type info in data section so it is runtime accessible
-            - size
-            - alignment
-            - struct member names
-            - array length
-
         [ ] Type parameterized structs
 
         [ ] Arrays need to be much better
index 4a57248a642ddd122666ae4131cf8f17dd90c5d6..b0633fc414f9d8b652ea7635cc17bf2facf74636 100644 (file)
@@ -228,16 +228,6 @@ BH_ALLOCATOR_PROC(bh_heap_allocator_proc);
 
 
 
-// MANAGED HEAP ALLOCATOR
-typedef struct bh_managed_heap {
-    ptr* pointers; // Actually a bh_arr
-} bh_managed_heap;
-
-void bh_managed_heap_init(bh_managed_heap* mh);
-void bh_managed_heap_free(bh_managed_heap* mh);
-bh_allocator bh_managed_heap_allocator(bh_managed_heap* mh);
-BH_ALLOCATOR_PROC(bh_managed_heap_allocator_proc);
-
 
 
 // ARENA ALLOCATOR
@@ -734,6 +724,16 @@ void bh_imap_clear(bh_imap* imap);
 
 
 
+// MANAGED HEAP ALLOCATOR
+typedef struct bh_managed_heap {
+    bh_imap ptrs;
+} bh_managed_heap;
+
+void bh_managed_heap_init(bh_managed_heap* mh);
+void bh_managed_heap_free(bh_managed_heap* mh);
+bh_allocator bh_managed_heap_allocator(bh_managed_heap* mh);
+BH_ALLOCATOR_PROC(bh_managed_heap_allocator_proc);
+
 
 
 
@@ -870,17 +870,15 @@ BH_ALLOCATOR_PROC(bh_heap_allocator_proc) {
 
 // MANAGED HEAP ALLOCATOR IMPLEMENTATION
 void bh_managed_heap_init(bh_managed_heap* mh) {
-    mh->pointers = NULL;
-
-    bh_arr_new(bh_heap_allocator(), mh->pointers, 4);
+    bh_imap_init(&mh->ptrs, bh_heap_allocator(), 512);
 }
 
 void bh_managed_heap_free(bh_managed_heap* mh) {
-    bh_arr_each(ptr, p, mh->pointers) {
-        free(*p);
+    bh_arr_each(bh__imap_entry, p, mh->ptrs.entries) {
+        free((void *) p->key);
     }
 
-    bh_arr_free(mh->pointers);
+    bh_imap_free(&mh->ptrs);
 }
 
 bh_allocator bh_managed_heap_allocator(bh_managed_heap* mh) {
@@ -903,40 +901,17 @@ BH_ALLOCATOR_PROC(bh_managed_heap_allocator_proc) {
         }
 
         if (retval != NULL)
-            bh_arr_push(mh->pointers, retval);
+            bh_imap_put(&mh->ptrs, (u64) retval, 1);
     } break;
 
     case bh_allocator_action_resize: {
-        i32 replace_idx = 0;
-        b32 found = 0;
-
-        bh_arr_each(ptr, p, mh->pointers) {
-            if (*p == prev_memory) {
-                found = 1;
-                break;
-            }
-
-            replace_idx++;
-        }
-
+        bh_imap_delete(&mh->ptrs, (u64) prev_memory);
         retval = realloc(prev_memory, size);
-        mh->pointers[replace_idx] = retval;
+        bh_imap_put(&mh->ptrs, (u64) retval, 1);
     } break;
 
     case bh_allocator_action_free: {
-        i32 free_idx = 0;
-        b32 found = 0;
-
-        bh_arr_each(ptr, p, mh->pointers) {
-            if (*p == prev_memory) {
-                found = 1;
-                break;
-            }
-
-            free_idx++;
-        }
-
-        bh_arr_fastdelete(mh->pointers, free_idx);
+        bh_imap_delete(&mh->ptrs, (u64) prev_memory);
         free(prev_memory);
     } break;
     }
diff --git a/onyx b/onyx
index ba5c54d50cb564f7322979da83fa5f7d5d6fa0c1..776bc7649c4310526a9f9e22618537cdbdb08572 100755 (executable)
Binary files a/onyx and b/onyx differ
index 153606e48c435872f43ec76302d842e6a120b2f0..fdbfb8b1681630bd3fe618d35652b9aba080cc9e 100644 (file)
@@ -80,23 +80,27 @@ static const char* token_type_names[] = {
 }
 #endif
 
-static b32 token_lit(OnyxTokenizer* tokenizer, OnyxToken* tk, char* lit, b32 is_word, TokenType type) {
-    i64 len = chars_match(tokenizer->curr, lit);
-    if (len > 0) {
-        if (is_word && char_is_alphanum(*(tokenizer->curr + len)) || charset_contains("_$", *(tokenizer->curr + len)))
-            return 0;
+#define char_is_alphanum(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z') || ((c) >= '0' && (c) <= '9'))
 
-        tk->type = type;
-        tk->text = tokenizer->curr;
-        tk->length = len;
-        tk->pos.line = tokenizer->line_number;
-        tk->pos.column = (i32)(tokenizer->curr - tokenizer->line_start) + 1;
+static inline b32 token_lit(OnyxTokenizer* tokenizer, OnyxToken* tk, char* lit, b32 is_word, TokenType type) {
+    i64 len = 0;
+    char* ptr1 = tokenizer->curr;
+    char* ptr2 = lit;
+    while (*ptr2 != '\0' && *ptr1 == *ptr2) ptr1++, ptr2++, len++;
+    if (*ptr2 != '\0') return 0;
 
-        tokenizer->curr += len;
+    if (is_word && char_is_alphanum(*ptr1) || *ptr1 == '_' || *ptr1 == '$')
+        return 0;
 
-        return 1;
-    }
-    return 0;
+    tk->type = type;
+    tk->text = tokenizer->curr;
+    tk->length = len;
+    tk->pos.line = tokenizer->line_number;
+    tk->pos.column = (i32)(tokenizer->curr - tokenizer->line_start) + 1;
+
+    tokenizer->curr += len;
+
+    return 1;
 }
 
 const char* token_name(TokenType tkn_type) {
@@ -148,66 +152,6 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) {
         goto token_parsed;
     }
 
-    LITERAL_TOKEN("package",    1, Token_Type_Keyword_Package);
-    LITERAL_TOKEN("struct",     1, Token_Type_Keyword_Struct);
-    LITERAL_TOKEN("enum"  ,     1, Token_Type_Keyword_Enum);
-    LITERAL_TOKEN("use",        1, Token_Type_Keyword_Use);
-    LITERAL_TOKEN("if",         1, Token_Type_Keyword_If);
-    LITERAL_TOKEN("elseif",     1, Token_Type_Keyword_Elseif);
-    LITERAL_TOKEN("else",       1, Token_Type_Keyword_Else);
-    LITERAL_TOKEN("global",     1, Token_Type_Keyword_Global);
-    LITERAL_TOKEN("return",     1, Token_Type_Keyword_Return);
-    LITERAL_TOKEN("proc",       1, Token_Type_Keyword_Proc);
-    LITERAL_TOKEN("as",         1, Token_Type_Keyword_As);
-    LITERAL_TOKEN("cast",       1, Token_Type_Keyword_Cast);
-    LITERAL_TOKEN("while",      1, Token_Type_Keyword_While);
-    LITERAL_TOKEN("for",        1, Token_Type_Keyword_For);
-    LITERAL_TOKEN("break",      1, Token_Type_Keyword_Break);
-    LITERAL_TOKEN("continue",   1, Token_Type_Keyword_Continue);
-    LITERAL_TOKEN("sizeof",     1, Token_Type_Keyword_Sizeof);
-    LITERAL_TOKEN("alignof",    1, Token_Type_Keyword_Alignof);
-    LITERAL_TOKEN("defer",      1, Token_Type_Keyword_Defer);
-    LITERAL_TOKEN("do",         1, Token_Type_Keyword_Do);
-    LITERAL_TOKEN("true",       1, Token_Type_Literal_True);
-    LITERAL_TOKEN("false",      1, Token_Type_Literal_False);
-    LITERAL_TOKEN("->",         0, Token_Type_Right_Arrow);
-    LITERAL_TOKEN("<-",         0, Token_Type_Right_Arrow);
-    LITERAL_TOKEN("---",        0, Token_Type_Empty_Block);
-    LITERAL_TOKEN("|>",         0, Token_Type_Pipe);
-    LITERAL_TOKEN("&&",         0, Token_Type_And_And);
-    LITERAL_TOKEN("||",         0, Token_Type_Or_Or);
-    LITERAL_TOKEN(">>>=",       0, Token_Type_Sar_Equal);
-    LITERAL_TOKEN(">>=",        0, Token_Type_Shr_Equal);
-    LITERAL_TOKEN("<<=",        0, Token_Type_Shl_Equal);
-    LITERAL_TOKEN(">>>",        0, Token_Type_Shift_Arith_Right);
-    LITERAL_TOKEN(">>",         0, Token_Type_Shift_Right);
-    LITERAL_TOKEN("<<",         0, Token_Type_Shift_Left);
-    LITERAL_TOKEN("&=",         0, Token_Type_And_Equal);
-    LITERAL_TOKEN("|=",         0, Token_Type_Or_Equal);
-    LITERAL_TOKEN("^=",         0, Token_Type_Xor_Equal);
-    LITERAL_TOKEN("<=",         0, Token_Type_Less_Equal);
-    LITERAL_TOKEN(">=",         0, Token_Type_Greater_Equal);
-    LITERAL_TOKEN("==",         0, Token_Type_Equal_Equal);
-    LITERAL_TOKEN("!=",         0, Token_Type_Not_Equal);
-    LITERAL_TOKEN("+=",         0, Token_Type_Plus_Equal);
-    LITERAL_TOKEN("-=",         0, Token_Type_Minus_Equal);
-    LITERAL_TOKEN("*=",         0, Token_Type_Star_Equal);
-    LITERAL_TOKEN("/=",         0, Token_Type_Fslash_Equal);
-    LITERAL_TOKEN("%=",         0, Token_Type_Percent_Equal);
-
-    // Symbols
-    if (char_is_alpha(*tk.text) || *tokenizer->curr == '_') {
-        u64 len = 0;
-        while (char_is_alphanum(*tokenizer->curr) || charset_contains("_$", *tokenizer->curr)) {
-            len++;
-            INCREMENT_CURR_TOKEN(tokenizer);
-        }
-
-        tk.length = len;
-        tk.type = Token_Type_Symbol;
-        goto token_parsed;
-    }
-
     // String literal
     if (*tk.text == '"') {
         u64 len = 0;
@@ -290,6 +234,67 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) {
         goto token_parsed;
     }
 
+    LITERAL_TOKEN("package",    1, Token_Type_Keyword_Package);
+    LITERAL_TOKEN("struct",     1, Token_Type_Keyword_Struct);
+    LITERAL_TOKEN("enum"  ,     1, Token_Type_Keyword_Enum);
+    LITERAL_TOKEN("use",        1, Token_Type_Keyword_Use);
+    LITERAL_TOKEN("if",         1, Token_Type_Keyword_If);
+    LITERAL_TOKEN("elseif",     1, Token_Type_Keyword_Elseif);
+    LITERAL_TOKEN("else",       1, Token_Type_Keyword_Else);
+    LITERAL_TOKEN("global",     1, Token_Type_Keyword_Global);
+    LITERAL_TOKEN("return",     1, Token_Type_Keyword_Return);
+    LITERAL_TOKEN("proc",       1, Token_Type_Keyword_Proc);
+    LITERAL_TOKEN("as",         1, Token_Type_Keyword_As);
+    LITERAL_TOKEN("cast",       1, Token_Type_Keyword_Cast);
+    LITERAL_TOKEN("while",      1, Token_Type_Keyword_While);
+    LITERAL_TOKEN("for",        1, Token_Type_Keyword_For);
+    LITERAL_TOKEN("break",      1, Token_Type_Keyword_Break);
+    LITERAL_TOKEN("continue",   1, Token_Type_Keyword_Continue);
+    LITERAL_TOKEN("sizeof",     1, Token_Type_Keyword_Sizeof);
+    LITERAL_TOKEN("alignof",    1, Token_Type_Keyword_Alignof);
+    LITERAL_TOKEN("defer",      1, Token_Type_Keyword_Defer);
+    LITERAL_TOKEN("do",         1, Token_Type_Keyword_Do);
+    LITERAL_TOKEN("true",       1, Token_Type_Literal_True);
+    LITERAL_TOKEN("false",      1, Token_Type_Literal_False);
+    LITERAL_TOKEN("->",         0, Token_Type_Right_Arrow);
+    LITERAL_TOKEN("<-",         0, Token_Type_Right_Arrow);
+    LITERAL_TOKEN("---",        0, Token_Type_Empty_Block);
+    LITERAL_TOKEN("|>",         0, Token_Type_Pipe);
+    LITERAL_TOKEN("&&",         0, Token_Type_And_And);
+    LITERAL_TOKEN("||",         0, Token_Type_Or_Or);
+    LITERAL_TOKEN(">>>=",       0, Token_Type_Sar_Equal);
+    LITERAL_TOKEN(">>=",        0, Token_Type_Shr_Equal);
+    LITERAL_TOKEN("<<=",        0, Token_Type_Shl_Equal);
+    LITERAL_TOKEN(">>>",        0, Token_Type_Shift_Arith_Right);
+    LITERAL_TOKEN(">>",         0, Token_Type_Shift_Right);
+    LITERAL_TOKEN("<<",         0, Token_Type_Shift_Left);
+    LITERAL_TOKEN("&=",         0, Token_Type_And_Equal);
+    LITERAL_TOKEN("|=",         0, Token_Type_Or_Equal);
+    LITERAL_TOKEN("^=",         0, Token_Type_Xor_Equal);
+    LITERAL_TOKEN("<=",         0, Token_Type_Less_Equal);
+    LITERAL_TOKEN(">=",         0, Token_Type_Greater_Equal);
+    LITERAL_TOKEN("==",         0, Token_Type_Equal_Equal);
+    LITERAL_TOKEN("!=",         0, Token_Type_Not_Equal);
+    LITERAL_TOKEN("+=",         0, Token_Type_Plus_Equal);
+    LITERAL_TOKEN("-=",         0, Token_Type_Minus_Equal);
+    LITERAL_TOKEN("*=",         0, Token_Type_Star_Equal);
+    LITERAL_TOKEN("/=",         0, Token_Type_Fslash_Equal);
+    LITERAL_TOKEN("%=",         0, Token_Type_Percent_Equal);
+
+    // Symbols
+    if (char_is_alpha(*tk.text) || *tokenizer->curr == '_') {
+        u64 len = 0;
+        while (char_is_alphanum(*tokenizer->curr) || charset_contains("_$", *tokenizer->curr)) {
+            len++;
+            INCREMENT_CURR_TOKEN(tokenizer);
+        }
+
+        tk.length = len;
+        tk.type = Token_Type_Symbol;
+        goto token_parsed;
+    }
+
+
     tk.type = (TokenType) *tokenizer->curr;
     INCREMENT_CURR_TOKEN(tokenizer);
 
index d0de2ea847b6d0cfe5e37dde2bcf9d256c8858c4..ced78907794546d35e30496d2eab1023e65243e3 100644 (file)
@@ -121,7 +121,7 @@ static void symres_local(AstLocal** local) {
 
     bh_arr_push(bh_arr_last(semstate.block_stack)->locals, *local);
     bh_arr_push(semstate.curr_function->locals, *local);
-    
+
     symbol_introduce(semstate.curr_scope, (*local)->token, (AstNode *) *local);
 }
 
index fe96ce897cc488d83ac1cfede783285726a922cf..0f635fdd11466b14293dcd2ea083d3c5e7b46f80 100644 (file)
@@ -331,9 +331,9 @@ static u64 local_lookup_idx(LocalAllocator* la, u64 value) {
     assert(value & LOCAL_IS_WASM);
 
     u32 idx = value & 0xFFFFFFFF;
-    if (value & 0x100000000) idx += la->allocated[0]; 
-    if (value & 0x200000000) idx += la->allocated[1]; 
-    if (value & 0x400000000) idx += la->allocated[2]; 
+    if (value & 0x100000000) idx += la->allocated[0];
+    if (value & 0x200000000) idx += la->allocated[1];
+    if (value & 0x400000000) idx += la->allocated[2];
 
     return (u64) idx;
 }
@@ -1217,11 +1217,11 @@ COMPILE_FUNC(expression, AstTyped* expr) {
 
             if (expr->type->kind == Type_Kind_Struct) {
                 TypeStruct* st = &expr->type->Struct;
-                
+
                 fori (idx, 0, st->mem_count) {
                     WIL(WI_LOCAL_GET, localidx + idx);
                 }
-                
+
             } else {
                 WIL(WI_LOCAL_GET, localidx);
             }
@@ -1593,7 +1593,7 @@ COMPILE_FUNC(return, AstReturn* ret) {
         while (i >= 0) {
             compile_statement(mod, &code, mod->deferred_stmts[i].stmt);
             i--;
-        } 
+        }
     }
 
     if (mod->has_stack_locals)
@@ -2005,7 +2005,7 @@ static void compile_file_contents(OnyxWasmModule* mod, AstFileContents* fc) {
         onyx_message_add(Msg_Type_File_Not_Found,
                 fc->filename->pos,
                 fc->filename->text);
-        
+
         token_toggle_end(fc->filename);
         return;
     }