#ifndef BH_H
#define BH_H
-#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#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, \
//-------------------------------------------------------------------------------------
// 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
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 {
};
bh_arr(Token) token_arr = NULL;
- bh_arr_grow(token_arr, 1024);
+ bh_arr_grow(token_arr, 512);
Token tk;
do {
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);
"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",
"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",
"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",
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);
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);
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)) {
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,
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,
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,
/* 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";
} else {
return b;
}
-}
\ No newline at end of file
+};
\ No newline at end of file