Commiting at end of day. Working on rewriting the bh_string library to include better...
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 12 May 2020 23:33:38 +0000 (18:33 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 12 May 2020 23:33:38 +0000 (18:33 -0500)
bh.h
docs/plan
onyx
onyx.c
onyxlex.c
onyxlex.h
progs/mvp.onyx

diff --git a/bh.h b/bh.h
index c322aa80c9e501a7d725de771694f4b7590a6373..f6574665d720557392d1aa83c15aa600e6ad676b 100644 (file)
--- a/bh.h
+++ b/bh.h
@@ -1,7 +1,6 @@
 #ifndef BH_H
 #define BH_H
 
-#include <stdio.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -43,15 +42,19 @@ i64 chars_match(char* ptr1, char* ptr2);
 #define bh_max(a, b)           ((a) > (b) ? (a) : (b))
 #define bh_min(a, b)           ((a) < (b) ? (a) : (b))
 #define bh_clamp(v, a, b)      (bh_min((b), bh_max((a), (v))))
+#define bh_abs(x)                      ((x) < 0 ? -(x) : (x))
 
 //-------------------------------------------------------------------------------------
 // Better strings
 //-------------------------------------------------------------------------------------
-typedef struct bh_string {
-       u8* data;
+typedef struct bh__string {
        u64 length;
        u64 capacity;
-} bh_string;
+} bh__string;
+
+typedef char bh_string;
+
+#define bh__stringhead(x)              (((bh__string *)(x)) - 1)
 
 #define bh_string_new(x) _Generic((x), \
        unsigned long: bh_string_new_cap, \
@@ -266,47 +269,52 @@ i64 chars_match(char* ptr1, char* ptr2) {
 //-------------------------------------------------------------------------------------
 // STRING IMPLEMENTATION
 //-------------------------------------------------------------------------------------
-bh_string bh_string_new_cap(unsigned long cap) {
-       bh_string str;
-       str.data = (u8*) malloc(sizeof(u8) * cap);
-       str.length = 0;
-       str.capacity = cap;
-       return str;
+bh_string* bh_string_new_cap(unsigned long cap) {
+       bh__string* str;
+       str = (bh__string*) malloc(sizeof(*str) + sizeof(char) * cap + 1);
+       str[0] = 0;
+       return str + 1;
 }
 
-bh_string bh_string_new_str(const char* cstr) {
+bh_string* bh_string_new_str(const char* cstr) {
        const i32 len = strlen(cstr);
-       bh_string str;
+       bh__string* str;
        i32 i;
 
-       str.data = (u8*) malloc(sizeof(u8) * len);
+       str = malloc(sizeof(*str) + sizeof(char) * len + 1);
+       char* data = (char*) (str + 1);
        for (i = 0; i < len; i++) {
-               str.data[i] = cstr[i];
+               data[i] = cstr[i];
        }
 
-       str.length = len;
-       str.capacity = len;
-       return str;
+       data[i] = 0; // Always null terminate the string
+
+       str->length = len;
+       str->capacity = len;
+       return str + 1;
 }
 
-b32 bh_string_delete(bh_string* str) {
-       free(str->data);
+b32 bh_string_delete(bh_string** str) {
+       bh__string* strptr = bh__stringhead(*str);
+       free(strptr);
        str->length = 0;
        str->capacity = 0;
        return 1;
 }
 
-b32 bh_string_ensure_capacity(bh_string* str, u64 cap) {
-       if (str->capacity >= cap) return 1;
+b32 bh_string_grow(bh_string** str, u64 cap) {
+       bh__string* strptr = bh__stringhead(*str);
+       if (strptr->capacity >= cap) return 1;
+
+       void* p;
+       p = realloc(strptr, sizeof(*strptr) + sizeof(char) * cap + 1);
 
-       //TODO: This could fail
-       str->data = (u8*) realloc((void*) str->data, sizeof(u8) * cap);
-       str->capacity = cap;
+       strptr->capacity = cap;
 
        return 1;
 }
 
-void bh_string_append_bh_string(bh_string* str1, bh_string* str2) {
+void bh_string_append_bh_string(bh_string** str1, bh_string** str2) {
        if (!bh_string_ensure_capacity(str1, str1->length + str2->length)) return;
 
        //TODO: Replace with custom memory management
index 70cd353e6a8cbe3ee5877ce0cb269645ff09cbae..666e18db47478aa696944b1932e39a9e001e80b3 100644 (file)
--- a/docs/plan
+++ b/docs/plan
@@ -40,14 +40,15 @@ foo :: (a: i32) -> Foo {
 
 MVP CODE:
 
-// Comments need to be parsed
+/* Comments need to be parsed */
 
-export add :: (a: i32, b: i32) -> i32 {
+export proc add :: (a i32, b i32) -> i32 {
        return a + b;
 }
 
-export max :: (a: i32, b: i32) -> i32 {
-       // Curly braces are required
+export proc max :: (a i32, b i32) -> i32 {
+       /* Curly braces are required */
+
        if a > b {
                return a;
        } else {
diff --git a/onyx b/onyx
index 690a2c823d61c7cd3aca2909c5a31d6a81f43638..e6cb94a24b220508298f7e54c473440ad335c933 100755 (executable)
Binary files a/onyx and b/onyx differ
diff --git a/onyx.c b/onyx.c
index d4b8f88e8d78b99b0a1997a4ae9f4a9537a1bd54..32e38f5baed81a9b4454c37b9fc6a931b77103eb 100644 (file)
--- a/onyx.c
+++ b/onyx.c
@@ -15,7 +15,7 @@ bh_arr(Token) parse_tokens(bh_file_contents *fc) {
        };
 
        bh_arr(Token) token_arr = NULL;
-       bh_arr_grow(token_arr, 1024);
+       bh_arr_grow(token_arr, 512);
 
        Token tk;
        do {
@@ -41,6 +41,10 @@ int main(int argc, char *argv[]) {
 
        printf("There are %d tokens (Allocated space for %d tokens)\n", bh_arr_length(token_arr), bh_arr_capacity(token_arr));
 
+       for (Token* it = token_arr; !bh_arr_end(token_arr, it); it++) {
+               printf("%s\n", get_token_type_name(*it));
+       }
+
        bh_file_contents_delete(&fc);
        bh_arr_free(token_arr);
 
index 38c54c4cbd09d380fb4787f9e9370c7a3bfd2639..af930ded9ad0496f5cc48d3185856a076f65ac7a 100644 (file)
--- a/onyxlex.c
+++ b/onyxlex.c
@@ -13,8 +13,11 @@ static const char* TokenTypeNames[] = {
        "TOKEN_TYPE_KEYWORD_IF",
        "TOKEN_TYPE_KEYWORD_ELSE",
        "TOKEN_TYPE_KEYWORD_FOR",
+       "TOKEN_TYPE_KEYWORD_DO",
        "TOKEN_TYPE_KEYWORD_RETURN",
        "TOKEN_TYPE_KEYWORD_FOREIGN",
+       "TOKEN_TYPE_KEYWORD_PROC",
+       "TOKEN_TYPE_KEYWORD_GLOBAL",
 
        "TOKEN_TYPE_RIGHT_ARROW",
        "TOKEN_TYPE_LEFT_ARROW",
@@ -33,6 +36,7 @@ static const char* TokenTypeNames[] = {
        "TOKEN_TYPE_SYM_PERCENT",
        "TOKEN_TYPE_SYM_FSLASH",
        "TOKEN_TYPE_SYM_BSLASH",
+       "TOKEN_TYPE_SYM_TYPE_SIGNATURE",
        "TOKEN_TYPE_SYM_COLON",
        "TOKEN_TYPE_SYM_SEMICOLON",
        "TOKEN_TYPE_SYM_COMMA",
@@ -40,6 +44,8 @@ static const char* TokenTypeNames[] = {
        "TOKEN_TYPE_SYM_GRAVE",
        "TOKEN_TYPE_SYM_TILDE",
        "TOKEN_TYPE_SYM_BANG",
+       "TOKEN_TYPE_SYM_CARET",
+       "TOKEN_TYPE_SYM_AMPERSAND",
 
        "TOKEN_TYPE_SYMBOL",
        "TOKEN_TYPE_LITERAL_STRING",
@@ -142,6 +148,9 @@ Token get_token(Tokenizer* tokenizer) {
        LITERAL_TOKEN("foreign", TOKEN_TYPE_KEYWORD_FOREIGN);
        LITERAL_TOKEN("for", TOKEN_TYPE_KEYWORD_FOR);
        LITERAL_TOKEN("return", TOKEN_TYPE_KEYWORD_RETURN);
+       LITERAL_TOKEN("do", TOKEN_TYPE_KEYWORD_DO);
+       LITERAL_TOKEN("proc", TOKEN_TYPE_KEYWORD_PROC);
+       LITERAL_TOKEN("global", TOKEN_TYPE_KEYWORD_GLOBAL);
        LITERAL_TOKEN("->", TOKEN_TYPE_RIGHT_ARROW);
        LITERAL_TOKEN("<-", TOKEN_TYPE_RIGHT_ARROW);
        LITERAL_TOKEN("(", TOKEN_TYPE_OPEN_PAREN);
@@ -158,6 +167,7 @@ Token get_token(Tokenizer* tokenizer) {
        LITERAL_TOKEN("/", TOKEN_TYPE_SYM_FSLASH);
        LITERAL_TOKEN("%", TOKEN_TYPE_SYM_PERCENT);
        LITERAL_TOKEN("\\", TOKEN_TYPE_SYM_BSLASH);
+       LITERAL_TOKEN("::", TOKEN_TYPE_SYM_TYPE_SIGNATURE);
        LITERAL_TOKEN(":", TOKEN_TYPE_SYM_COLON);
        LITERAL_TOKEN(";", TOKEN_TYPE_SYM_SEMICOLON);
        LITERAL_TOKEN(",", TOKEN_TYPE_SYM_COMMA);
@@ -165,6 +175,8 @@ Token get_token(Tokenizer* tokenizer) {
        LITERAL_TOKEN("`", TOKEN_TYPE_SYM_GRAVE);
        LITERAL_TOKEN("~", TOKEN_TYPE_SYM_TILDE);
        LITERAL_TOKEN("!", TOKEN_TYPE_SYM_BANG);
+       LITERAL_TOKEN("^", TOKEN_TYPE_SYM_CARET);
+       LITERAL_TOKEN("&", TOKEN_TYPE_SYM_AMPERSAND);
 
        // Symbols
        if (char_is_alpha(*tk.token)) {
index 8fb15967af2217ec41600310314f9f61410c0db4..608d133bbb9ca427f073114158dfc20f5f58bf7d 100644 (file)
--- a/onyxlex.h
+++ b/onyxlex.h
@@ -23,8 +23,11 @@ typedef enum TokenType {
        TOKEN_TYPE_KEYWORD_IF,
        TOKEN_TYPE_KEYWORD_ELSE,
        TOKEN_TYPE_KEYWORD_FOR,
+       TOKEN_TYPE_KEYWORD_DO,
        TOKEN_TYPE_KEYWORD_RETURN,
        TOKEN_TYPE_KEYWORD_FOREIGN,
+       TOKEN_TYPE_KEYWORD_PROC,
+       TOKEN_TYPE_KEYWORD_GLOBAL,
 
        TOKEN_TYPE_RIGHT_ARROW,
        TOKEN_TYPE_LEFT_ARROW,
@@ -43,6 +46,7 @@ typedef enum TokenType {
        TOKEN_TYPE_SYM_PERCENT,
        TOKEN_TYPE_SYM_FSLASH,
        TOKEN_TYPE_SYM_BSLASH,
+       TOKEN_TYPE_SYM_TYPE_SIGNATURE,
        TOKEN_TYPE_SYM_COLON,
        TOKEN_TYPE_SYM_SEMICOLON,
        TOKEN_TYPE_SYM_COMMA,
@@ -50,6 +54,8 @@ typedef enum TokenType {
        TOKEN_TYPE_SYM_GRAVE,
        TOKEN_TYPE_SYM_TILDE,
        TOKEN_TYPE_SYM_BANG,
+       TOKEN_TYPE_SYM_CARET,
+       TOKEN_TYPE_SYM_AMPERSAND,
 
        TOKEN_TYPE_SYMBOL,
        TOKEN_TYPE_LITERAL_STRING,
index cf693c37a22d21bc277072f770143bbdb61a7c41..1a8d8c00ae90e193c06c198815fe5a39d06518e6 100644 (file)
@@ -2,13 +2,13 @@
  /* nested comments /* are /* okay */ */ */
 */
 
-foreign "console" "log" :: (ptr, i32) -> void;
+foreign proc "console" "log" :: (data ptr, length i32) -> void;
 
-export add :: (a i32, b i32) -> i32 {
+export proc add :: (a i32, b i32) -> i32 {
        return a + b;
-}
+};
 
-export max :: (a i32, b i32) -> i32 {
+export proc max :: (a i32, b i32) -> i32 {
        /* Curly braces are required */
        x := "String literal! HERE \\\"Woot Woot\" done";
 
@@ -17,4 +17,4 @@ export max :: (a i32, b i32) -> i32 {
        } else {
                return b;
        }
-}
\ No newline at end of file
+};
\ No newline at end of file