From 8e4942f5aedbbd8fb1199af3166dcb1410c876a7 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Thu, 26 May 2022 18:15:27 +0200 Subject: [PATCH] Delete old version files --- common.c | 365 ---------------- lang.h | 86 ---- lex.c | 642 ---------------------------- memory.c | 136 ------ memory.h | 20 - os.h | 11 - os_win32.c | 36 -- parse.c | 1184 ---------------------------------------------------- print.c | 365 ---------------- 9 files changed, 2845 deletions(-) delete mode 100644 common.c delete mode 100644 lang.h delete mode 100644 lex.c delete mode 100644 memory.c delete mode 100644 memory.h delete mode 100644 os.h delete mode 100644 os_win32.c delete mode 100644 parse.c delete mode 100644 print.c diff --git a/common.c b/common.c deleted file mode 100644 index 504de93..0000000 --- a/common.c +++ /dev/null @@ -1,365 +0,0 @@ - -function S64 -clamp_top_s64(S64 val, S64 max){ - if(val>max)return max; - return val; -} - -function SizeU -max_sizeu(SizeU a, SizeU b){ - if(a>b) return a; - return b; -} - -function U64 -hash_fnv(String string) { - U64 hash = (U64)14695981039346656037ULL; - for (U64 i = 0; i < string.len; i++) { - hash = hash ^ (U64)(string.str[i]); - hash = hash * (U64)1099511628211ULL; - } - return hash; -} - -function U64 -hash_u64(U64 x) { - x *= 0xff51afd7ed558ccd; - x ^= x >> 32; - return x; -} - -function U64 -hash_ptr(const void *ptr) { - return hash_u64((uintptr_t)ptr); -} - -function U64 -hash_mix(U64 x, U64 y) { - x ^= y; - x *= 0xff51afd7ed558ccd; - x ^= x >> 32; - return x; -} - -function U64 -is_pow2(U64 x) { - assert(x != 0); - B32 result = (x & (x - 1llu)) == 0; - return result; -} - -function U64 -wrap_around_pow2(U64 x, U64 power_of_2) { - assert(is_pow2(power_of_2)); - U64 r = (((x)&((power_of_2)-1llu))); - return r; -} - -//----------------------------------------------------------------------------- -// Strings -//----------------------------------------------------------------------------- -global String string_empty; - -function B32 -string_compare(String a, String b){ - if(a.len != b.len) - return false; - for(S64 i = 0; i < a.len; i++){ - if(a.str[i] != b.str[i]) - return false; - } - return true; -} - -function U8 -char_to_lower(U8 c){ - if(c >= 'A' && c <= 'Z') - c += 32; - return c; -} - -function U8 -char_to_upper(U8 c){ - if(c >= 'a' && c <= 'z') - c -= 32; - return c; -} - -function B32 -string_is_empty(String a){ - B32 result = a.len == 0; - return result; -} - -function String -string_to_lower(Arena *arena, String string){ - String result = arena_push_string_copy(arena, string); - for(S64 i = 0; i < string.len; i++){ - result.str[i] = char_to_lower(result.str[i]); - } - return result; -} - -//----------------------------------------------------------------------------- -// Per Vognsen's like Map to pointers -//----------------------------------------------------------------------------- -typedef struct Map_Key_Val{ - U64 key; - void *value; -}Map_Key_Val; - -typedef struct Map{ - Map_Key_Val *data; - int len; - int cap; -}Map; - -function void map_insert_u64(Map *map, U64 key, void *val); -function int max_int(int a, int b); - - -#include -function void -map_grow(Map *map, int new_size){ - new_size = max_int(16, new_size); - assert(new_size > map->cap); - assert(is_pow2(new_size)); - Map new_map = { - .data = calloc(new_size, sizeof(Map_Key_Val)), - .cap = new_size, - }; - for(int i = 0; i < map->cap; i++){ - if(map->data[i].key){ - map_insert_u64(&new_map, map->data[i].key, map->data[i].value); - } - } - if(map->data) free(map->data); - *map = new_map; -} - -function void -map_insert_u64(Map *map, U64 key, void *val){ - assert(val); - if(key == 0) key++; - if((2*map->len) + 1 > map->cap){ - map_grow(map, 2*map->cap); - } - U64 hash = hash_u64(key); - U64 index = wrap_around_pow2(hash, map->cap); - U64 i = index; - for(;;){ - if(map->data[i].key == 0){ - map->len++; - map->data[i].key = key; - map->data[i].value = val; - return; - } - else if(map->data[i].key == key){ - map->data[i].value = val; - return; - } - - i = wrap_around_pow2(i+1, map->cap); - if(i == map->cap){ - return; - } - } -} - -function void * -map_get_u64(Map *map, U64 key){ - if(map->len == 0) return 0; - if(key == 0) key++; - U64 hash = hash_u64(key); - U64 index = wrap_around_pow2(hash, map->cap); - U64 i = index; - for(;;){ - if(map->data[i].key == key){ - return map->data[i].value; - } - else if(map->data[i].key == 0){ - return 0; - } - - i = wrap_around_pow2(i+1, map->cap); - if(i == map->cap){ - return 0; - } - } -} - -function void * -map_get(Map *map, void *pointer){ - return map_get_u64(map, (U64)pointer); -} - -function void -map_insert(Map *map, void *key, void *value){ - map_insert_u64(map, (U64)key, value); -} - -function void -map_test(){ - Map map = {0}; - const SizeU size = 1025; - for(SizeU i = 1; i < size; i++){ - map_insert_u64(&map, i, (void *)i); - } - for(SizeU i = 1; i < size; i++){ - SizeU val = (SizeU)map_get_u64(&map, i); - assert(val == i); - } -} - -//----------------------------------------------------------------------------- -// Array -//----------------------------------------------------------------------------- -typedef struct Array_Head{ - int cap, len; -}Array_Head; - -#define array_get_head(x) (((Array_Head *)(x)) - 1) -#define array_cap(x) array_get_head(x)->cap -#define array_len(x) array_get_head(x)->len -#define array_push(arr,i) (array_grow((void **)&arr, sizeof(arr[0])), (arr)[array_len(arr)++] = (i)) -#define array_init(arr,cap) array__init((void **)&arr,sizeof(arr[0]), cap) - - -function void -array__init(void **array, SizeU sizeof_item, int cap){ - Array_Head *head = malloc(sizeof_item*cap + sizeof(Array_Head)); - head->cap = cap; - head->len = 0; - *array = head + 1; -} - -function void -array_grow(void **array, SizeU sizeof_item){ - if(*array == 0){ - array__init(array, sizeof_item, 16); - } - else if(array_len(*array) + 1 > array_cap(*array)){ - Array_Head *head = array_get_head(*array); - SizeU len = head->len; - SizeU cap = head->cap * 2; - head = realloc(head, sizeof_item*cap + sizeof(Array_Head)); - head->cap = cap; - head->len = len; - *array = head + 1; - } -} - -function void -array_test(){ - int *array = 0; - for(int i = 0; i < 100; i++){ - array_push(array, i); - } - for(int i = 0; i < 100; i++){ - assert(array[i] == i); - } -} - -//----------------------------------------------------------------------------- -// String interning -//----------------------------------------------------------------------------- -typedef struct Table_Index{ - U64 hash; - U64 index; - U64 iter; - U64 max_size; -}Table_Index; - -typedef struct Intern_String{ - String s; -}Intern_String; - -typedef struct Intern_Table{ - S64 interns_in_bytes; - S64 interns_inserted; - S64 interns_max; - Intern_String *interns; - Arena *arena; -}Intern_Table; - -function Intern_Table -intern_table(Arena *arena, SizeU size){ - Intern_Table result = {0}; - result.arena = arena; - result.interns = arena_push_array(arena, Intern_String, size); - result.interns_max = size; - return result; -} - -function Table_Index -table_index_from_hash(U64 hash, U64 max_size){ - Table_Index result = {0}; - result.hash = hash; - result.index = result.hash % max_size; - result.iter = result.index; - result.max_size = max_size; - return result; -} - -function Table_Index -table_index_from_string(String string, U64 max_size){ - U64 hash = hash_fnv(string); - Table_Index result = table_index_from_hash(hash, max_size); - return result; -} - -function B32 -table_index_advance(Table_Index *index){ - index->iter = wrap_around_pow2(index->iter + 1, index->max_size); - B32 result = index->iter == index->index; - return result; -} - -function Intern_String -intern_string(Intern_Table *p, String string){ - Intern_String result = {0}; - Table_Index index = table_index_from_string(string, p->interns_max); - for(;;){ - Intern_String *intern = p->interns + index.iter; - if(intern->s.str == 0){ - result.s = arena_push_string_copy(p->arena, string); - p->interns_in_bytes += string.len; - p->interns_inserted += 1; - *intern = result; - break; - } - else if(string_compare(intern->s, string)){ - result = *intern; - break; - } - - if (table_index_advance(&index)) - break; - - } - - return result; -} - -function B32 -intern_compare(Intern_String a, Intern_String b){ - B32 result = a.s.str == b.s.str; - return result; -} - -function void -intern_test(){ - Arena *scratch = arena_begin_scratch(); - Intern_Table table = intern_table(scratch, 512); - assert(intern_compare(intern_string(&table, lit("Thing")), - intern_string(&table, lit("Thing")))); - assert(!intern_compare(intern_string(&table, lit("Thing")), - intern_string(&table, lit("No_Thing")))); - assert(intern_compare(intern_string(&table, lit("No_Thing")), - intern_string(&table, lit("No_Thing")))); - -} - - - - diff --git a/lang.h b/lang.h deleted file mode 100644 index 464b017..0000000 --- a/lang.h +++ /dev/null @@ -1,86 +0,0 @@ -#pragma once - -#define global static -#define function static - -#define assert(x) do{if(!(x)) __debugbreak();}while(0) -#define assert_msg(x,...) assert(x) -#define not_implemented assert_msg(0, "Not implemented") -#define invalid_codepath assert_msg(0, "Invalid codepath") - -#define buff_cap(x) (sizeof(x)/sizeof((x)[0])) -#define lit(x) ((String){(U8*)x,buff_cap(x)-1}) -#define meta(x) - -#include -typedef int8_t S8; -typedef int16_t S16; -typedef int32_t S32; -typedef int64_t S64; -typedef uint8_t U8; -typedef uint16_t U16; -typedef uint32_t U32; -typedef uint64_t U64; -typedef S8 B8; -typedef S16 B16; -typedef S32 B32; -typedef S64 B64; -typedef uint64_t SizeU; -typedef int64_t SizeI; -typedef float F32; -typedef double F64; - -#include -//const B32 true = 1; -//const B32 false = 0; -#define kib(x) ((x)*1024llu) -#define mib(x) (kib(x)*1024llu) -#define gib(x) (mib(x)*1024llu) -#define string_expand(x) (int)x.len, x.str - -typedef struct String_Node String_Node; -typedef struct String_List String_List; -typedef struct String{ - U8 *str; - S64 len; -}String; - -struct String_Node{ - String_Node *next; - union{ - String string; - struct{U8*str; S64 len;}; - }; -}; - -struct String_List{ - String_Node *first; - String_Node *last; - S64 char_count; - S64 node_count; -}; - -#define SLLQueuePushMod(f,l,n,next) do{\ -if((f)==0){\ -(f)=(l)=(n);\ -}\ -else{\ -(l)=(l)->next=(n);\ -} \ -}while(0) - -#define SLLQueuePush(f,l,n) SLLQueuePushMod(f,l,n,next) - - -#define SLLStackPush(l,n) do{\ -(n)->next = (l);\ -(l) = (n);\ -}while(0) - -#define SLLStackPop(l,n) do{\ -if(l){\ -(n) = (l);\ -(l) = (l)->next;\ -(n)->next = 0;\ -}\ -}while(0) diff --git a/lex.c b/lex.c deleted file mode 100644 index 225c2c7..0000000 --- a/lex.c +++ /dev/null @@ -1,642 +0,0 @@ -global Intern_String keyword_if; -global Intern_String keyword_for; -global Intern_String keyword_cast; -global Intern_String keyword_else; -global Intern_String keyword_defer; -global Intern_String keyword_do; -global Intern_String keyword_size_type; -global Intern_String keyword_size_expr; -global Intern_String keyword_const; -global Intern_String keyword_typedef; -global Intern_String keyword_return; -global Intern_String keyword_typeof; -global Intern_String keyword_while; -global Intern_String keyword_switch; -global Intern_String keyword_case; -global Intern_String keyword_struct; -global Intern_String keyword_enum; -global Intern_String keyword_union; -global U8 *first_keyword; -global U8 *last_keyword; - -global Intern_String intern_char; -global Intern_String intern_void; -global Intern_String intern_int; - -function void -init_default_keywords(Intern_Table *t){ - keyword_if = intern_string(t, lit("if")); - first_keyword = keyword_if.s.str; - - keyword_cast = intern_string(t, lit("cast")); - keyword_for = intern_string(t, lit("for")); - keyword_else = intern_string(t, lit("else")); - keyword_defer = intern_string(t, lit("defer")); - keyword_do = intern_string(t, lit("do")); - keyword_size_type = intern_string(t, lit("size_type")); - keyword_size_expr = intern_string(t, lit("size_expr")); - keyword_typeof = intern_string(t, lit("typeof")); - keyword_const = intern_string(t, lit("const")); - keyword_while = intern_string(t, lit("while")); - keyword_return = intern_string(t, lit("return")); - keyword_switch = intern_string(t, lit("switch")); - keyword_typedef = intern_string(t, lit("typedef")); - keyword_case = intern_string(t, lit("case")); - keyword_struct = intern_string(t, lit("struct")); - keyword_enum = intern_string(t, lit("enum")); - - keyword_union = intern_string(t, lit("union")); - last_keyword = keyword_union.s.str; - - intern_char = intern_string(t, lit("char")); - intern_void = intern_string(t, lit("void")); - intern_int = intern_string(t, lit("int")); -} - -function B32 -lex_is_keyword(Intern_String str){ - B32 result = str.s.str >= first_keyword && str.s.str <= last_keyword; - return result; -} - -typedef enum Token_Kind{ - TK_End, - - TK_Mul, - TK_Div, - TK_Mod, - TK_LeftShift, - TK_RightShift, - TK_FirstMul = TK_Mul, - TK_LastMul = TK_RightShift, - - TK_Add, - TK_Sub, - TK_FirstAdd = TK_Add, - TK_LastAdd = TK_Sub, - - TK_Equals, - TK_LesserThenOrEqual, - TK_GreaterThenOrEqual, - TK_LesserThen, - TK_GreaterThen, - TK_NotEquals, - TK_FirstCompare = TK_Equals, - TK_LastCompare = TK_NotEquals, - - TK_BitAnd, - TK_BitOr, - TK_Pointer, - TK_And, - TK_Or, - TK_FirstLogical = TK_BitAnd, - TK_LastLogical = TK_Or, - - TK_Neg, - TK_Not, - TK_OpenParen, - TK_CloseParen, - TK_OpenBrace, - TK_CloseBrace, - TK_OpenBracket, - TK_CloseBracket, - TK_Comma, - TK_Pound, - TK_Question, - TK_ThreeDots, - TK_Semicolon, - TK_Dot, - - TK_Colon, - - TK_Assign, - TK_ColonAssign, - TK_DivAssign, - TK_MulAssign, - TK_ModAssign, - TK_SubAssign, - TK_AddAssign, - TK_AndAssign, - TK_OrAssign, - TK_XorAssign, - TK_LeftShiftAssign, - TK_RightShiftAssign, - TK_FirstAssign = TK_Assign, - TK_LastAssign = TK_RightShiftAssign, - - TK_DoubleColon, - TK_At, - TK_Decrement, - TK_Increment, - TK_PostDecrement, - TK_PostIncrement, - - TK_Arrow, - TK_ExprSizeof, - TK_DocComment, - TK_Comment, - TK_Identifier, - TK_StringLit, - TK_Character, - TK_Error, - TK_Float, - TK_Integer, - TK_Keyword, -}Token_Kind; - -typedef struct Token{ - Token_Kind kind; - union{ - String string; - struct{U8 *str; S64 len;}; - }; - - union { - U64 int_val; - F64 float_val; - String error_val; - Intern_String intern_val; - }; - - String file; - S32 line; - U8 *line_begin; -}Token; -#include "token_array.c" - -typedef struct Lex_Stream{ - String stream; - S64 iter; - - U8 *line_begin; - String file; - S32 line; -}Lex_Stream; - - -function U8 -lexc(Lex_Stream *s){ - return s->stream.str[s->iter]; -} - -function U8 -lexci(Lex_Stream *s, S32 i){ - return s->stream.str[s->iter+i]; -} - -function U8 * -lexcp(Lex_Stream *s){ - return s->stream.str + s->iter; -} - -function B32 -lex_is_whitespace(U8 c){ - B32 result = c == '\n' || c == '\r' || c == ' ' || c == '\r'; - return result; -} - -function B32 -lex_is_alphabetic(U8 c){ - B32 result = (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); - return result; -} - -function B32 -lex_is_numeric(U8 c){ - B32 result = c >= '0' && c <= '9'; - return result; -} - -function B32 -lex_is_alphanumeric(U8 c){ - B32 result = lex_is_numeric(c) || lex_is_alphabetic(c); - return result; -} - -function void -lex_set_len(Lex_Stream *s, Token *token){ - assert(lexcp(s) >= token->str); - token->len = lexcp(s) - token->str; -} - -function void -token_error(Token *t, String error_val){ - t->kind = TK_Error; - t->error_val = error_val; -} - -function void -lex_parse_u64(Token *t){ - U64 result = 0; - U64 m = 1; - for(S64 i = t->len - 1; i >= 0; --i){ - U64 val = t->str[i] - '0'; - U64 new_val = val * m; - if((result + new_val) < result){ - token_error(t, lit("Integer overflow")); - return; - } - result+=new_val; - m *= 10; - } - t->int_val = result; -} - -function void -lex_advance(Lex_Stream *s){ - if(s->iter >= s->stream.len){ - return; - } - else if(lexc(s) == '\n'){ - s->iter++; - s->line++; - s->line_begin = lexcp(s); - } - else{ - s->iter++; - } -} - -function void -lex_parse_string(Lex_Stream *s, Token *t, U8 c){ - for(;;){ - if(lexc(s) == '\\') lex_advance(s); - else if(lexc(s) == c) break; - else if(lexc(s) == 0){ - token_error(t, lit("Unterminated string, reached end of file")); - break; - } - lex_advance(s); - } - if(t->kind != TK_Error){ - lex_advance(s); - lex_set_len(s,t); - } -} - -#define CASE2(op, OpName, Assign) \ -case op: \ -if (lexc(s) == '=') { \ -lex_advance(s); \ -t.kind = Assign; \ -} else { \ -t.kind = OpName; \ -} \ -break -#define CASE3(op, OpName, Assign, Incr) \ -case op: \ -if (lexc(s) == '=') { \ -lex_advance(s); \ -t.kind = Assign; \ -} else if (lexc(s) == op) { \ -lex_advance(s); \ -t.kind = Incr; \ -} else { \ -t.kind = OpName; \ -} \ -break - -function void -lex__stream(Token_Array *array, Lex_Stream *s){ - while(lexc(s)){ - while(lex_is_whitespace(lexc(s))) - lex_advance(s); - - Token t = {0}; - t.str = lexcp(s); - t.file = s->file; - t.line = s->line; - t.line_begin = s->line_begin; - lex_advance(s); - - switch(*t.str){ - case 0: break; - case '@': t.kind = TK_At; break; - case '(': t.kind = TK_OpenParen; break; - case ')': t.kind = TK_CloseParen; break; - case '{': t.kind = TK_OpenBrace; break; - case '}': t.kind = TK_CloseBrace; break; - case '[': t.kind = TK_OpenBracket; break; - case ']': t.kind = TK_CloseBracket; break; - case ',': t.kind = TK_Comma; break; - case '~': t.kind = TK_Neg; break; - case '?': t.kind = TK_Question; break; - case ';': t.kind = TK_Semicolon; break; - case '#': t.kind = TK_Pound; break; - CASE2('!', TK_Not, TK_NotEquals); - CASE2('^', TK_Pointer, TK_XorAssign); - CASE2('=', TK_Assign, TK_Equals); - CASE2('*', TK_Mul, TK_MulAssign); - CASE2('%', TK_Mod, TK_ModAssign); - CASE3('+', TK_Add, TK_AddAssign, TK_Increment); - CASE3('&', TK_BitAnd, TK_AndAssign, TK_And); - CASE3('|', TK_BitOr, TK_OrAssign, TK_Or); -#undef CASE2 -#undef CASE3 - case '.': { - if(lexc(s) == '.' && lexci(s,1) == '.') { - lex_advance(s); lex_advance(s); - t.kind = TK_ThreeDots; - } - else { - t.kind = TK_Dot; - } - } break; - - - case '<': { - if (lexc(s) == '<') { - lex_advance(s); - if (lexc(s) == '=') { - lex_advance(s); - t.kind = TK_LeftShiftAssign; - } - else { - t.kind = TK_LeftShift; - } - } - else if (lexc(s) == '=') { - lex_advance(s); - t.kind = TK_LesserThenOrEqual; - } - else { - t.kind = TK_LesserThen; - } - } break; - - case '>': { - if (lexc(s) == '>') { - lex_advance(s); - if (lexc(s) == '=') { - lex_advance(s); - t.kind = TK_RightShiftAssign; - } - else { - t.kind = TK_RightShift; - } - } - else if (lexc(s) == '=') { - lex_advance(s); - t.kind = TK_GreaterThenOrEqual; - } - else { - t.kind = TK_GreaterThen; - } - } break; - - case ':': { - if (lexc(s) == ':') { - lex_advance(s); - t.kind = TK_DoubleColon; - } - else if(lexc(s) == '='){ - lex_advance(s); - t.kind = TK_ColonAssign; - } - else { - t.kind = TK_Colon; - } - } break; - - case '-':{ - if (lexc(s) == '=') { - lex_advance(s); - t.kind = TK_SubAssign; - } - else if (lexc(s) == '-') { - lex_advance(s); - t.kind = TK_Decrement; - } - else if (lexc(s) == '>') { - lex_advance(s); - t.kind = TK_Arrow; - } - else { - t.kind = TK_Sub; - } - } break; - - - case '\'':{not_implemented;} break; - case '"': { - t.kind = TK_StringLit; - lex_parse_string(s,&t,'"'); - if(t.kind != TK_Error){ - t.str += 1; - t.len -= 2; - } - t.intern_val = intern_string(&array->interns, t.string); - } break; - - case '/': { - if(lexc(s) == '='){ - t.kind = TK_DivAssign; - lex_advance(s); - } - else if(lexc(s) == '/'){ - lex_advance(s); - t.kind = TK_Comment; - for(;;){ - if(lexc(s) == '\n' || lexc(s) == 0) break; - lex_advance(s); - } - continue; - } - else if(lexc(s) == '*'){ - lex_advance(s); - t.kind = TK_Comment; - for(;;){ - if(lexc(s) == '*' && lexci(s,1) == '/'){ - lex_advance(s); - lex_advance(s); - break; - } - else if(lexc(s) == 0){ - token_error(&t, lit("Unterminated block comment")); - goto skip_continue; - } - lex_advance(s); - } - continue; - skip_continue:; - } - else { - t.kind = TK_Div; - } - } break; - - case '0':case '1':case '2':case '3':case '4': - case '5':case '6':case '7':case '8':case '9':{ - t.kind = TK_Integer; - while(lex_is_numeric(lexc(s))) - lex_advance(s); - lex_set_len(s, &t); - lex_parse_u64(&t); - } break; - - case 'A':case 'a':case 'M':case 'm':case 'B': - case 'b':case 'N':case 'n':case 'C':case 'c':case 'O': - case 'o':case 'D':case 'd':case 'P':case 'p':case 'E': - case 'e':case 'Q':case 'q':case 'F':case 'f':case 'R': - case 'r':case 'G':case 'g':case 'S':case 's':case 'H': - case 'h':case 'T':case 't':case 'I':case 'i':case 'U': - case 'u':case 'J':case 'j':case 'V':case 'v':case 'K': - case 'k':case 'W':case 'w':case 'L':case 'X':case 'l': - case 'x':case 'Z':case 'z':case 'Y':case 'y':case '_': { - t.kind = TK_Identifier; - while(lex_is_alphanumeric(lexc(s)) || lexc(s) == '_') - lex_advance(s); - lex_set_len(s,&t); - t.intern_val = intern_string(&array->interns, t.string); - if(lex_is_keyword(t.intern_val)){ - t.kind = TK_Keyword; - } - } break; - - default: { - token_error(&t, lit("Unknown token")); - } - } - - if(t.len==0) - lex_set_len(s,&t); - - token_array_push(array, &t); - } -} - -function void -lex_add_stream(Token_Array *array, String stream, String file){ - Lex_Stream s = {stream, 0, stream.str, file, 0}; - lex__stream(array, &s); -} - -function Token_Array -lex_make_token_array(Arena *arena){ - Token_Array array = token_array_make(arena); - init_default_keywords(&array.interns); - return array; -} - -function Token_Array -lex_stream(Arena *arena, String stream, String file){ - Token_Array array = lex_make_token_array(arena); - lex_add_stream(&array, stream, file); - return array; -} - -function void -lex_restream(Token_Array *array, String stream, String file){ - token_array_reset(array); - lex_add_stream(array, stream, file); -} - -function void -lex_test(){ - Arena *scratch = arena_begin_scratch(); - String test = lit("18446744073709551616{})(@?&+-;....->,:::/**/\"Thing\"//R\n Thingy" - "\"Test_Meme\"+=-===42524 4294967295 18446744073709551615" - "for if while switch :="); - Token_Array array = lex_stream(scratch, test, lit("Test1")); - - Token_Kind kind[] = { - TK_Error,TK_OpenBrace,TK_CloseBrace,TK_CloseParen,TK_OpenParen, - TK_At,TK_Question,TK_BitAnd,TK_Add,TK_Sub,TK_Semicolon, - TK_ThreeDots, TK_Dot, TK_Arrow, TK_Comma, TK_DoubleColon, TK_Colon, - TK_StringLit, TK_Identifier, TK_StringLit, TK_AddAssign, TK_SubAssign, - TK_Equals, TK_Integer, TK_Integer, TK_Integer, TK_Keyword, TK_Keyword, - TK_Keyword, TK_Keyword, TK_ColonAssign, TK_End - }; - String strs[] = { - lit("18446744073709551616"),lit("{"),lit("}"),lit(")"),lit("("), - lit("@"),lit("?"),lit("&"),lit("+"),lit("-"),lit(";"), - lit("..."),lit("."),lit("->"),lit(","),lit("::"),lit(":"), - lit("Thing"),lit("Thingy"),lit("Test_Meme"), lit("+="),lit("-="), - lit("=="),lit("42524"),lit("4294967295"),lit("18446744073709551615"), - lit("for"), lit("if"), lit("while"), lit("switch"), lit(":="), lit(""), - }; - U64 vals[] = { - 42524, 4294967295, 18446744073709551615llu - }; - - int i = 0; - int ui = 0; - for(Token *t = token_array_iter_begin(&array); t->kind != TK_End; t = token_array_iter_next(&array)){ - assert(t->kind == kind[i]); - assert(string_compare(t->string, strs[i++])); - if(t->kind == TK_Integer){ - assert(t->int_val == vals[ui++]); - } - } - arena_end_scratch(); - -} - -//----------------------------------------------------------------------------- -// Token metadata -//----------------------------------------------------------------------------- -global const char *token_kind_string[] = { - [TK_End] = "End of stream", - [TK_Mul] = "*", - [TK_Div] = "/", - [TK_Add] = "+", - [TK_Sub] = "-", - [TK_Mod] = "%", - [TK_BitAnd] = "&", - [TK_BitOr] = "|", - [TK_Pointer] = "^", - [TK_Neg] = "~", - [TK_Not] = "!", - [TK_OpenParen] = "(", - [TK_CloseParen] = " ", - [TK_OpenBrace] = "{", - [TK_CloseBrace] = "}", - [TK_OpenBracket] = "[", - [TK_CloseBracket] = "]", - [TK_Comma] = ",", - [TK_Pound] = "#", - [TK_Question] = "?", - [TK_ThreeDots] = "...", - [TK_Semicolon] = ";", - [TK_Dot] = ".", - [TK_LesserThen] = "<", - [TK_GreaterThen] = ">", - [TK_Colon] = ":", - [TK_Assign] = "=", - [TK_ColonAssign] = ":=", - [TK_DivAssign] = "/=", - [TK_MulAssign] = "*=", - [TK_ModAssign] = "%=", - [TK_SubAssign] = "-=", - [TK_AddAssign] = "+=", - [TK_AndAssign] = "&=", - [TK_OrAssign] = "|=", - [TK_XorAssign] = "^=", - [TK_LeftShiftAssign] = "<<=", - [TK_RightShiftAssign] = ">>=", - [TK_DoubleColon] = "::", - [TK_At] = "@", - [TK_Decrement] = "--", - [TK_Increment] = "++", - [TK_PostDecrement] = "--", - [TK_PostIncrement] = "++", - [TK_LesserThenOrEqual] = "<=", - [TK_GreaterThenOrEqual] = ">=", - [TK_Equals] = "==", - [TK_And] = "&&", - [TK_Or] = "||", - [TK_NotEquals] = "!=", - [TK_LeftShift] = "<<", - [TK_RightShift] = ">>", - [TK_Arrow] = "->", - [TK_ExprSizeof] = "sizeof", - [TK_DocComment] = "DocComment", - [TK_Comment] = "Comment", - [TK_Identifier] = "Identifier", - [TK_StringLit] = "StringLit", - [TK_Character] = "Character", - [TK_Error] = "Error", - [TK_Float] = "Float", - [TK_Integer] = "Int", - [TK_Keyword] = "Keyword", -}; diff --git a/memory.c b/memory.c deleted file mode 100644 index c7a6e01..0000000 --- a/memory.c +++ /dev/null @@ -1,136 +0,0 @@ -global const SizeU default_reserve_size = gib(4); -global const SizeU default_alignment = 8; -global const SizeU additional_commit_size = mib(1); -function SizeU align_up(SizeU size, SizeU align); - -function void -memory_copy(void *dst, void *src, SizeU size){ - U8 *d = (U8*)dst; - U8 *s = (U8*)src; - for(SizeU i = 0; i < size; i++){ - d[i] = s[i]; - } -} - -function void -memory_zero(void *p, SizeU size){ - U8 *pp = (U8 *)p; - for(SizeU i = 0; i < size; i++) - pp[i] = 0; -} - -function int -max_int(int a, int b){ - if(a>b) return a; - return b; -} - -function void -arena_init(Arena *a){ - a->memory = os_reserve(default_reserve_size); - a->alignment = default_alignment; -} - -function void * -arena_push_size(Arena *a, SizeU size){ - SizeU generous_size = size; - if(a->memory.commit+generous_size>a->memory.commit){ - if(a->memory.reserve == 0){ - arena_init(a); - } - os_commit(&a->memory, generous_size+additional_commit_size); - } - - a->len = align_up(a->len, a->alignment); - void *result = (U8*)a->memory.data + a->len; - a->len += size; - - memory_zero(result, size); - return result; -} - -function void * -arena_push_copy(Arena *a, void *pointer, SizeU size){ - void *result = arena_push_size(a, size); - memory_copy(result, pointer, size); - return result; -} - -function SizeU -clamp_top_sizeu(SizeU val, SizeU max){ - if(val>max)return max; - return val; -} - -function void -arena_pop_pos(Arena *arena, SizeU pos){ - pos = clamp_top_sizeu(pos, arena->len); - arena->len = pos; -} - -function Arena_Checkpoint -arena_checkpoint(Arena *arena){ - Arena_Checkpoint result = {arena, arena->len}; - return result; -} - -function void -arena_restore(Arena_Checkpoint checkpoint){ - arena_pop_pos(checkpoint.arena, checkpoint.pos); -} - -function String -arena_push_string_copy(Arena *arena, String string){ - U8 *copy = arena_push_array(arena, U8, string.len+1); - memory_copy(copy, string.str, string.len); - copy[string.len] = 0; - return (String){copy, string.len}; -} - -function String -string_fmtv(Arena *arena, const char *str, va_list args1) { - va_list args2; - va_copy(args2, args1); - S64 len = vsnprintf(0, 0, str, args2); - va_end(args2); - - char *result = (char *)arena_push_size(arena, len + 1); - vsnprintf(result, len + 1, str, args1); - if (arena->len > 0) - arena->len -= 1; - - String res = {(U8 *)result, len}; - return res; -} - -#define STRING_FMT(arena, str, result) \ -va_list args1; \ -va_start(args1, str); \ -String result = string_fmtv(arena, str, args1); \ -va_end(args1) - -function String -string_fmt(Arena *arena, const char *str, ...) { - STRING_FMT(arena, str, result); - return result; -} - -function void -string_listf(Arena *arena, String_List *list, const char *str, ...){ - STRING_FMT(arena, str, string); - String_Node *node = arena_push_struct(arena, String_Node); - node->string = string; - SLLQueuePush(list->first, list->last, node); - list->char_count += node->string.len; - list->node_count += 1; -} - -function String -string_list_flatten(Arena *arena, String_List *list){ - String result = {(U8 *)arena_push_size(arena, list->char_count + 1)}; - for(String_Node *node = list->first; node; node=node->next){ - memory_copy(result.str+result.len, node->str, node->len); - result.len += node->len; - } - return result; -} diff --git a/memory.h b/memory.h deleted file mode 100644 index 87808b3..0000000 --- a/memory.h +++ /dev/null @@ -1,20 +0,0 @@ - -typedef struct Arena{ - OS_Memory memory; - U64 len; - U64 alignment; -}Arena; - -typedef struct Arena_Checkpoint{ - Arena *arena; - SizeU pos; -} Arena_Checkpoint; - -function B32 string_compare(String a, String b); -function void *arena_push_size(Arena *a, SizeU size); -function String arena_push_string_copy(Arena *arena, String string); -#define arena_push_array(a,T,c) (T *)arena_push_size(a,sizeof(T)*(c)) -#define arena_push_struct(a,T) arena_push_array(a,T,1) - -function Arena *arena_begin_scratch(); -function void arena_end_scratch(); \ No newline at end of file diff --git a/os.h b/os.h deleted file mode 100644 index f14e644..0000000 --- a/os.h +++ /dev/null @@ -1,11 +0,0 @@ - -typedef struct OS_Memory{ - void *data; - SizeU commit; - SizeU reserve; -}OS_Memory; -typedef struct Arena Arena; - -function OS_Memory os_reserve(SizeU size); -function void os_commit(OS_Memory *m, SizeU size); -function String os_read_file(Arena *arena, String file); \ No newline at end of file diff --git a/os_win32.c b/os_win32.c deleted file mode 100644 index 116d7a8..0000000 --- a/os_win32.c +++ /dev/null @@ -1,36 +0,0 @@ -function S32 os_main(); -const SizeU page_size = 4096; - -function SizeU -get_align_offset(SizeU size, SizeU align){ - SizeU mask = align - 1; - SizeU val = size & mask; - if(val){ - val = align - val; - } - return val; -} - -function SizeU -align_up(SizeU size, SizeU align){ - SizeU result = size + get_align_offset(size, align); - return result; -} - -function OS_Memory -os_reserve(SizeU size){ - OS_Memory result = {0}; - SizeU adjusted_size = align_up(size, page_size); - result.data = VirtualAlloc(0, adjusted_size, MEM_RESERVE, PAGE_READWRITE); - assert_msg(result.data, "Failed to reserve virtual memory"); - result.reserve = adjusted_size; - return result; -} - -function void -os_commit(OS_Memory *m, SizeU size){ - SizeU commit = align_up(size, page_size); - void *p = VirtualAlloc((U8 *)m->data + m->commit, commit, MEM_COMMIT, PAGE_READWRITE); - assert_msg(p, "Failed to commit more memory"); - m->commit += commit; -} \ No newline at end of file diff --git a/parse.c b/parse.c deleted file mode 100644 index 3db6dcd..0000000 --- a/parse.c +++ /dev/null @@ -1,1184 +0,0 @@ -typedef struct Parser_Error Parser_Error; - -struct Parser_Error{ - Parser_Error *next; - String message; - Token *token; -}; - -typedef struct Parser{ - Token_Array tokens; - Arena *arena; - - Parser_Error *first_error; - Parser_Error *last_error; -}Parser; - -__thread Parser *global_parser; -__thread Arena global_scratch; -__thread Arena_Checkpoint global_scratch_checkpoint; - -function Arena * -arena_begin_scratch(){ - global_scratch_checkpoint = arena_checkpoint(&global_scratch); - return &global_scratch; -} - -function void -arena_end_scratch(){ - arena_restore(global_scratch_checkpoint); -} - -function void -parser_push_error(Parser *p, Token *token, char *str, ...){ - String string; - { - va_list args1, args2; - va_start(args1, str); - va_copy(args2, args1); - string.len = vsnprintf(0, 0, str, args2); - va_end(args2); - - string.str = arena_push_size(p->arena, string.len + 1); - vsnprintf((char*)string.str, string.len + 1, str, args1); - va_end(args1); - } - - // @Note(Krzosa): Print nice error message - printf("\nError: %s", string.str); - if(token){ - printf(" %s:%d\n", token->file.str, (S32)token->line); - - // @Note(Krzosa): Print error line - { - int i = 0; - while(token->line_begin[i]!='\n' && token->line_begin[i]!=0) i++; - printf("%.*s\n", i, token->line_begin); - - // @Note(Krzosa): Print error marker - int token_i = token->str - token->line_begin; - for(int i = 0; i < token_i-2; i++) printf(" "); - printf("^^^^^^\n"); - } - } - - Parser_Error *error = arena_push_struct(p->arena, Parser_Error); - error->message = string; - error->next = 0; - error->token = token; - SLLQueuePush(p->first_error, p->last_error, error); - - __debugbreak(); -} - -//----------------------------------------------------------------------------- -// Parsing helpers -//----------------------------------------------------------------------------- -function Token * -token_get(Parser *p){ - Token *result = token_array_iter_peek(&p->tokens, 0); - return result; -} - -function Token * -token_peek(Parser *p, S64 i){ - Token *result = token_array_iter_peek(&p->tokens, i); - return result; -} - -function Token * -token_peek_is(Parser *p, Token_Kind kind, S64 i){ - Token *result = token_peek(p, i); - if(result->kind == kind) - return result; - return 0; -} - -function Token * -token_peek_is_keyword(Parser *p, Intern_String keyword, S64 i){ - assert(lex_is_keyword(keyword)); - Token *result = token_peek(p, i); - if(result->kind == TK_Keyword && intern_compare(result->intern_val, keyword)) - return result; - return 0; -} - -function Token * -token_is(Parser *p, Token_Kind kind){ - Token *result = token_get(p); - if(result->kind == kind) - return result; - return 0; -} - -function Token * -token_next(Parser *p){ - Token *result = token_array_iter_next(&p->tokens); - return result; -} - -function Token * -token_match(Parser *p, Token_Kind kind){ - Token *token = token_get(p); - if(token->kind == kind){ - token = token_next(p); - return token; - } - return 0; -} - -function Token * -token_match_keyword(Parser *p, Intern_String string){ - Token *token = token_get(p); - if(token->kind == TK_Keyword){ - if(intern_compare(token->intern_val, string)){ - token = token_next(p); - return token; - } - } - return 0; -} - -function Token * -token_expect(Parser *p, Token_Kind kind){ - Token *token = token_get(p); - if(token->kind == kind){ - token = token_next(p); - return token; - } - parser_push_error(p, token, "Expected token of kind: %s, got instead token of kind: %s.", token_kind_string[kind], token_kind_string[token->kind]); - return 0; -} - -function Typespec *parse_typespec(Parser *p); -function Expr *parse_expr(Parser *p); -//----------------------------------------------------------------------------- -// Expression parsing -//----------------------------------------------------------------------------- -/* -add = [+-] -mul = [/%*] -compare = == | != | >= | > | <= | < -logical = [&|^] | && | || -unary = [&*-!~+] | ++ | -- - -atom_expr = Int -| Float -| String -| Identifier -| 'cast' '(' typespec ',' expr ')' -| 'size_type' '(' typespec ')' -| 'size_expr' '(' expr ')' -| '{' compound_expr '}' -| '(' expr ')' -| '(' ':' typespec ')' '{' compound_expr '}' -postfix_expr = atom_expr ('[' expr ']' | '.' Identifier | ++ | -- | '(' expr_list ')')* -unary_expr = unary ? unary_expr : atom_expr -mul_expr = atom_expr (mul atom_expr)* -add_expr = mul_expr (add mul_expr)* -logical_expr = add_expr (logical add_expr)* -compare_expr = logical_expr (compare logical_expr)* -ternary_expr = compare_expr ('?' ternary_expr ':' ternary_expr)? -expr = logical_expr - -Compound literals -- (:[23]*Type){} - - Type{} -- { } - -*/ -function Expr_Compound_Field * -parse_expr_compound_field(Parser *p){ - Token *token = token_get(p); - Expr_Compound_Field *result = 0; - if(token_match(p, TK_OpenBracket)){ - Expr *index = parse_expr(p); - token_expect(p, TK_CloseBracket); - token_expect(p, TK_Assign); - Expr *expr = parse_expr(p); - result = expr_compound_index(p->arena, token, index, expr); - } - else{ - Expr *expr = parse_expr(p); - if((token = token_match(p, TK_Assign))){ - if(expr->kind != EK_Identifier){ - parser_push_error(p, token, "Failed to parse compound literal, required identifier as left value"); - } - result = expr_compound_named(p->arena, token, expr->intern_val, parse_expr(p)); - - } - else{ - result = expr_compound_default(p->arena, token, expr); - } - } - return result; -} - -function Expr * -parse_expr_compound(Parser *p, Typespec *typespec){ - Token *token = token_expect(p, TK_OpenBrace); - Expr *expr = expr_compound(p->arena, token, typespec); - while(!token_is(p, TK_CloseBrace)){ - Expr_Compound_Field *field = parse_expr_compound_field(p); - expr_compound_push(expr, field); - if(!token_match(p, TK_Comma)){ - break; - } - } - token_expect(p, TK_CloseBrace); - return expr; -} - -function Expr * -parse_expr_atom(Parser *p){ - Expr *result = 0; - Token *token = token_get(p); - if(token_match(p, TK_StringLit)){ - result = expr_str(p->arena, token); - } - else if(token_match(p, TK_Identifier)){ - if(token_is(p, TK_OpenBrace)){ - Typespec *typespec = typespec_name(p->arena, token, token->intern_val); - result = parse_expr_compound(p, typespec); - } - else{ - result = expr_identifier(p->arena, token); - } - } - else if(token_match(p, TK_Integer)){ - result = expr_int(p->arena, token); - } - else if(token_is(p, TK_OpenBrace)){ - result = parse_expr_compound(p, 0); - } - - else if(token_match(p, TK_OpenParen)){ - if(token_match(p, TK_Colon)){ - Typespec *typespec = parse_typespec(p); - token_expect(p, TK_CloseParen); - result = parse_expr_compound(p, typespec); - } - else{ - Expr *expr = parse_expr(p); - token_expect(p, TK_CloseParen); - result = expr_paren(p->arena, token, expr); - } - } - else if(token_match_keyword(p, keyword_cast)){ - token_expect(p, TK_OpenParen); - Typespec *typespec = parse_typespec(p); - token_expect(p, TK_Comma); - Expr *expr = parse_expr(p); - token_expect(p, TK_CloseParen); - result = expr_cast(p->arena, token, typespec, expr); - } - else{ - parser_push_error(p, token, "Failed to parse expression"); - } - return result; -} - -function B32 -token_is_postfix(Parser *p){ - Token *token = token_get(p); - B32 result = token->kind == TK_OpenBracket - || token->kind == TK_OpenParen - || token->kind == TK_Dot - || token->kind == TK_Increment - || token->kind == TK_Decrement; - return result; -} - -function Expr_Compound_Field * -parse_expr_function_argument(Parser *p){ - Token *token = token_get(p); - Expr_Compound_Field *result = 0; - Expr *expr1 = parse_expr(p); - if(token_match(p, TK_Assign)){ - if(expr1->kind != EK_Identifier){ - parser_push_error(p, token, "Failed to parse named function argument, required identifier as left value"); - } - Expr *expr2 = parse_expr(p); - result = expr_compound_named(p->arena, token, expr1->intern_val, expr2); - } - else{ - result = expr_compound_default(p->arena, token, expr1); - } - return result; -} - -function Expr * -parse_expr_postfix(Parser *p){ - Expr *left = parse_expr_atom(p); - while(token_is_postfix(p)){ - Token *token = 0; - if((token = token_match(p, TK_OpenBracket))){ - Expr *size = parse_expr(p); - token_expect(p, TK_CloseBracket); - left = expr_index(p->arena, token, left, size); - } - else if((token = token_match(p, TK_OpenParen))){ - left = expr_call(p->arena, token, left); - if(!token_is(p, TK_CloseParen)){ - do { - Expr_Compound_Field *field = parse_expr_function_argument(p); - expr_call_push(left, field); - } while(token_match(p, TK_Comma)); - } - token_expect(p, TK_CloseParen); - } - else if(token_match(p, TK_Dot)){ - token = token_expect(p, TK_Identifier); - left = expr_field(p->arena, token, left); - } - else{ - token = token_next(p); - assert(token->kind == TK_Increment || token->kind == TK_Decrement); - left = expr_postfix_unary(p->arena, token, left); - } - } - return left; -} - -function B32 -token_is_unary(Parser *p){ - Token *token = token_get(p); - B32 result = token->kind == TK_Add - || token->kind == TK_Increment - || token->kind == TK_Decrement - || token->kind == TK_Sub - || token->kind == TK_Mul - || token->kind == TK_BitAnd - || token->kind == TK_Neg - || token->kind == TK_Not; - return result; -} - -function Expr * -parse_expr_unary(Parser *p){ - if(token_is_unary(p)){ - Token *op = token_next(p); - Expr *right = parse_expr_unary(p); - Expr *result = expr_unary(p->arena, op, right); - return result; - } - else{ - return parse_expr_postfix(p); - } -} - -function B32 -token_is_mul(Parser *p){ - Token *token = token_get(p); - B32 result = token->kind >= TK_FirstMul && token->kind <= TK_LastMul; - return result; -} - -function Expr * -parse_expr_mul(Parser *p){ - Expr *left = parse_expr_unary(p); - while(token_is_mul(p)){ - Token *op = token_next(p); - Expr *right = parse_expr_unary(p); - left = expr_binary(p->arena, op, left, right); - } - return left; -} - -function B32 -token_is_add(Parser *p){ - Token *token = token_get(p); - B32 result = token->kind >= TK_FirstAdd && token->kind <= TK_LastAdd; - return result; -} - -function Expr * -parse_expr_add(Parser *p){ - Expr *left = parse_expr_mul(p); - while(token_is_add(p)){ - Token *op = token_next(p); - Expr *right = parse_expr_mul(p); - left = expr_binary(p->arena, op, left, right); - } - return left; -} - -function B32 -token_is_logical(Parser *p){ - Token *token = token_get(p); - B32 result = token->kind >= TK_FirstLogical && token->kind <= TK_LastLogical; - return result; -} - -function Expr * -parse_expr_logical(Parser *p){ - Expr *left = parse_expr_add(p); - while(token_is_logical(p)){ - Token *op = token_next(p); - Expr *right = parse_expr_add(p); - left = expr_binary(p->arena, op, left, right); - } - return left; -} - -function B32 -token_is_compare(Parser *p){ - Token *token = token_get(p); - B32 result = token->kind >= TK_FirstCompare && token->kind <= TK_LastCompare; - return result; -} - -function Expr * -parse_expr_compare(Parser *p){ - Expr *left = parse_expr_logical(p); - while(token_is_compare(p)){ - Token *op = token_next(p); - Expr *right = parse_expr_logical(p); - left = expr_binary(p->arena, op, left, right); - } - return left; -} - -function Expr * -parse_expr_ternary(Parser *p){ - Expr *cond = parse_expr_compare(p); - Token *token = 0; - if((token = token_match(p, TK_Question))){ - Expr *on_true = parse_expr_ternary(p); - token_expect(p, TK_Colon); - Expr *on_false = parse_expr_ternary(p); - Expr *result = expr_ternary(p->arena, token, cond, on_true, on_false); - return result; - } - return cond; -} - -function Expr * -parse_expr(Parser *p){ - return parse_expr_ternary(p); -} - -//----------------------------------------------------------------------------- -// Type specifier parsing -//----------------------------------------------------------------------------- -/* - base_type = NAME -| '(' type_list? ')' type? - -type = ('*' | '[' expr ']')* base_type - -Examples: -[32]*U32 - Array of 32 pointers to U32 -**CustomDataType - Pointer to pointer of CustomDataType -(*U32, S64) **S64 - Function pointer -(CoolType: optional, S32) - Implicit void return value - -*/ - -function Typespec * -parse_optional_type(Parser *p, Intern_String type){ - Typespec *result = 0; - if(token_match(p, TK_Colon)){ - result = parse_typespec(p); - } - else{ - result = typespec_name(p->arena, token_get(p), type); - } - return result; -} - -function Typespec * -parse_typespec_function(Parser *p, Token *token){ - Typespec *result = typespec_function(p->arena, token, 0); - if(!token_is(p, TK_CloseParen)) - for(;;) { - - // Optional name - Token *name = 0; - if((token = token_is(p, TK_Identifier))){ - if(token_peek_is(p, TK_Colon, 1)){ - token_next(p); - token_next(p); - name = token; - } - } - - // Parse type - Typespec *arg = parse_typespec(p); - if(name) - arg = typespec_named_argument(p->arena, name, arg, name->intern_val); - typespec_function_push(result, arg); - - if(!token_match(p, TK_Comma)){ - break; - } - } - token_expect(p, TK_CloseParen); - - result->func.ret = parse_optional_type(p, intern_void); - - return result; -} - -// [10]*int - Array of 10 pointers to ints -function Typespec * -parse_typespec_recurse(Parser *p){ - Token *token = token_get(p); - if(token_match(p, TK_Mul)){ - Typespec *result = parse_typespec_recurse(p); - result = typespec_pointer(p->arena, token, result); - return result; - } - else if(token_match(p, TK_OpenBracket)){ - Expr *expr = parse_expr(p); - token_expect(p, TK_CloseBracket); - Typespec *result = parse_typespec_recurse(p); - result = typespec_array(p->arena, token, result, expr); - return result; - } - else if(token_match(p, TK_OpenParen)){ - Typespec *result = parse_typespec_function(p, token); - return result; - } - else if(token_match(p, TK_Identifier)){ - Typespec *result = typespec_name(p->arena, token, token->intern_val); - return result; - } - else{ - parser_push_error(p, token, "Failed to parse type, unexpected token"); - return 0; - } -} - -function Typespec * -parse_typespec(Parser *p){ - Typespec *result = parse_typespec_recurse(p); - return result; -} - -//----------------------------------------------------------------------------- -// Parsing decls -//----------------------------------------------------------------------------- -/* -name::(param:U32)*U32{} -name::struct{} -name::union{} -name::enum{} - -name::typedef = name2; -name::const = 4254; - -// Thing::struct{ -// var1, var2: U32; -// union { -// thing: *S64; - // } -// named: union { -// data: [24]U32; -// } -// } -*/ -function void -parse_note_list(Parser *p, AST_Parent *parent) { - if(token_match(p, TK_OpenParen)) { - if(token_match(p, TK_CloseParen)){ - return; - } - do { - Token *name = token_expect(p, TK_Identifier); - Note *current = note_push_new(p->arena, parent, name, name->intern_val, 0); - parse_note_list(p, (AST_Parent *)current); - if(token_match(p, TK_Assign)) { - current->expr = parse_expr(p); - } - } while(token_match(p, TK_Comma)); - token_expect(p, TK_CloseParen); - } -} - -function void -parse__notes(Parser *p, AST_Parent *result) { - while(token_match(p, TK_At)) { - Token *name = token_expect(p, TK_Identifier); - Note *current = note_push_new(p->arena, result, name, name->intern_val, 0); - parse_note_list(p, (AST_Parent *)current); - if(token_match(p, TK_Assign)) { - current->expr = parse_expr(p); - } - token_match(p, TK_Semicolon); - } -} - -function Note_List * -parse_notes(Parser *p){ - Note_List result = (Note_List){.pos=token_get(p), .kind=AST_Note_List}; - parse__notes(p, &result); - if(result.first){ - Note_List *ast = (Note_List *)ast_shallow_copy(p->arena, (AST *)&result); - return ast; - } - return 0; -} - -function Expr * -parse_assign_expr(Parser *p){ - if(token_match(p, TK_Assign)) - return parse_expr(p); - return 0; -} - -function Decl_Enum * -parse_enum(Parser *p, Token *name){ - Typespec *typespec = parse_optional_type(p, intern_int); - Decl_Enum *result = decl_enum(p->arena, name, name->intern_val, typespec); - token_expect(p, TK_OpenBrace); - do { - Note_List *notes = parse_notes(p); - Token *val = token_expect(p, TK_Identifier); - Expr *expr = parse_assign_expr(p); - decl_enum_push(p->arena, result, val, val->intern_val, expr, notes); - if(!token_match(p, TK_Comma)){ - break; - } - }while(!token_is(p, TK_CloseBrace)); - token_expect(p, TK_CloseBrace); - return result; -} - -function void -parse_var_decl(Parser *p, Decl_Struct *parent, Token *name, Note_List *notes){ - Token *name_stack[64]; - S64 name_stack_len = 0; - name_stack[name_stack_len++] = name; - while(token_match(p, TK_Comma)) - name_stack[name_stack_len++] = token_expect(p, TK_Identifier); - token_expect(p, TK_Colon); - Typespec *typespec = parse_typespec(p); - token_expect(p, TK_Semicolon); - for(S64 i = 0; i < name_stack_len; i++){ - Decl_Var *decl = decl_variable(p->arena, name_stack[i], name_stack[i]->intern_val, 0, typespec, notes); - decl_struct_push(parent, (AST *)decl); - } -} - -function Decl_Struct * -parse_struct(Parser *p, Token *name, AST_Kind struct_kind){ - Intern_String intern_name = name ? name->intern_val : (Intern_String){0}; - Token *token = name ? name : token_get(p); - Decl_Struct *result = decl_struct(p->arena, struct_kind, token, intern_name); - token_expect(p, TK_OpenBrace); - do { - Note_List *notes = parse_notes(p); - Token *token = token_get(p); - if(token_match_keyword(p, keyword_union)){ - Decl_Struct *decl = parse_struct(p, 0, AST_Decl_SubUnion); - decl->notes = notes; - decl_struct_push(result, (AST *)decl); - } - else if(token_match_keyword(p, keyword_struct)){ - Decl_Struct *decl = parse_struct(p, 0, AST_Decl_SubStruct); - decl->notes = notes; - decl_struct_push(result, (AST *)decl); - } - else if(token_match(p, TK_Identifier)){ - if(token_is(p, TK_Colon)){ - if(token_peek_is_keyword(p, keyword_union, 1)){ - token_next(p); token_next(p); - Decl_Struct *decl = parse_struct(p, token, AST_Decl_SubUnion); - decl->notes = notes; - decl_struct_push(result, (AST *)decl); - } - else if(token_peek_is_keyword(p, keyword_struct, 1)){ - token_next(p); token_next(p); - Decl_Struct *decl = parse_struct(p, token, AST_Decl_SubStruct); - decl->notes = notes; - decl_struct_push(result, (AST *)decl); - } - else{ - parse_var_decl(p, result, token, notes); - } - } - else{ - parse_var_decl(p, result, token, notes); - } - } - else{ - parser_push_error(p, token, "Failed to parse struct, unexpected token of kind '%s'", token_kind_string[token->kind]); - } - } while(!token_match(p, TK_CloseBrace)); - return result; -} - -function Decl_Typedef * -parse_typedef(Parser *p, Token *name){ - token_expect(p, TK_Assign); - Typespec *typespec = parse_typespec(p); - token_expect(p, TK_Semicolon); - Decl_Typedef *result = decl_typedef(p->arena, name, name->intern_val, typespec); - return result; -} - -function Decl_Const * -parse_const(Parser *p, Token *name){ - Typespec *typespec = 0; - if(token_match(p, TK_Colon)) - typespec = parse_typespec(p); - token_expect(p, TK_Assign); - Expr *expr = parse_expr(p); - token_expect(p, TK_Semicolon); - Decl_Const *result = decl_const(p->arena, name, name->intern_val, expr, typespec); - return result; -} - -function void parse_stmt_block(Parser *p, AST_Parent *parent); -function Decl_Func * -parse_function(Parser *p, Token *name){ - Decl_Func *result = decl_function(p->arena, name, name->intern_val, 0); - if(!token_is(p, TK_CloseParen)){ - do{ - name = token_expect(p, TK_Identifier); - token_expect(p, TK_Colon); - Typespec *typespec = parse_typespec(p); - decl_func_push(p->arena, result, name, name->intern_val, typespec); - } while(token_match(p, TK_Comma)); - } - token_expect(p, TK_CloseParen); - result->ret = parse_optional_type(p, intern_void); - if(token_is(p, TK_OpenBrace)){ - result->body = stmt_block(p->arena, token_get(p)); - parse_stmt_block(p, (AST_Parent *)result->body); - } - else if(token_match(p, TK_Semicolon)){ - result->is_incomplete = true; - } - return result; -} - -function AST * -parse_decl(Parser *p, AST_Parent *parent){ - Token *name = 0; - AST *result = 0; - Note_List *note = parse_notes(p); - if((name = token_match(p, TK_Identifier))){ - if(token_match(p, TK_DoubleColon)){ - Token *token = 0; - if((token = token_match_keyword(p, keyword_enum))){ - result = (AST *)parse_enum(p, name); - } - else if((token = token_match_keyword(p, keyword_union))){ - result = (AST *)parse_struct(p, name, AST_Decl_Union); - } - else if((token = token_match_keyword(p, keyword_struct))){ - result = (AST *)parse_struct(p, name, AST_Decl_Struct); - } - else if((token = token_match_keyword(p, keyword_typedef))){ - result = (AST *)parse_typedef(p, name); - } - else if((token = token_match_keyword(p, keyword_const))){ - result = (AST *)parse_const(p, name); - } - else if((token = token_match(p, TK_OpenParen))){ - result = (AST *)parse_function(p, name); - } - else{ - token = token_get(p); - parser_push_error(p, token, "Expected a declaration keyword. Got instead: %s", token_kind_string[token->kind]); - } - } - else{ - Token *token = token_get(p); - parser_push_error(p, token, "Expected a declaration which starts with token '::' got instead" - "token '%s'", token_kind_string[token->kind]); - } - } - - if(result){ - result->notes = note; - ast_push_last(parent, result); - return result; - } - return 0; -} - -//----------------------------------------------------------------------------- -// Statement parsing -//----------------------------------------------------------------------------- -function AST *parse_stmt(Parser *p); -/* -stmt_list = '{' stmt* '}' -stmt = -| stmt_list - | 'return' expr ';' - | 'if' expr stmt_list - | 'for' simple_stmt_list ';' expr ';' simple_stmt_list stmt_list -| 'for' expr stmt_list -| expr assign? ';' -//| 'while' expr stmt_or_stmt_list - -*/ - -function void -parse_stmt_block(Parser *p, AST_Parent *parent){ - token_expect(p, TK_OpenBrace); - while(!token_is(p, TK_End) && !token_is(p, TK_CloseBrace)){ - AST *stmt = parse_stmt(p); - ast_push_last(parent, stmt); - } - token_expect(p, TK_CloseBrace); -} - -function AST * -parse_stmt_if(Parser *p){ - Expr *expr = parse_expr(p); - Stmt_If *result = stmt_if(p->arena, token_get(p), expr); - parse_stmt_block(p, (AST_Parent *)result->body); - Token *token = 0; - while((token = token_match_keyword(p, keyword_else))){ - if(!token_match_keyword(p, keyword_if)){ - Stmt_Else *stmt_else = stmt_else_push(p->arena, result, token); - parse_stmt_block(p, (AST_Parent *)stmt_else->body); - break; - } - Expr *expr = parse_expr(p); - Stmt_ElseIf *stmt_else_if = stmt_else_if_push(p->arena, result, token, expr); - parse_stmt_block(p, (AST_Parent *)stmt_else_if->body); - } - return (AST *)result; -} - -function Stmt_Init * -parse_stmt_init(Parser *p, Expr *left){ - Stmt_Init *result = 0; - if(token_match(p, TK_ColonAssign)){ - if(left->kind != EK_Identifier){ - parser_push_error(p, token_get(p), "Expected an identifier before ':='"); - } - Expr *expr = parse_expr(p); - result = stmt_init(p->arena, left->token, left->token->intern_val, 0, expr); - } - else if(token_match(p, TK_Colon)){ - if(left->kind != EK_Identifier){ - parser_push_error(p, token_get(p), "Expected an identifier before ':'"); - } - Typespec *typespec = parse_typespec(p); - Expr *expr = parse_assign_expr(p); - result = stmt_init(p->arena, left->token, left->token->intern_val, typespec, expr); - } - return result; -} - -function Token * -token_is_assignment(Parser *p){ - Token *t = token_get(p); - if(t->kind >= TK_FirstAssign && t->kind <= TK_LastAssign) - return t; - return 0; -} - -function AST * -parse_simple_stmt(Parser *p){ - Token *token = token_get(p); - Expr *left = parse_expr(p); - Stmt_Init *init = parse_stmt_init(p, left); - if(init){ - return (AST *)init; - } - if(token_is_assignment(p)){ - token = token_next(p); - Expr *right = parse_expr(p); - Stmt_Assign *result = stmt_assign(p->arena, token, token->kind, left, right); - return (AST *)result; - } - else{ - Stmt_Expr *result = stmt_expr(p->arena, token, left); - return (AST *)result; - } -} - -function AST * -parse_stmt_return(Parser *p){ - Token *token = token_get(p); - Expr *expr = parse_expr(p); - token_expect(p, TK_Semicolon); - Stmt_Return *result = stmt_return(p->arena, token, expr); - return (AST *)result; -} - -function AST * -parse_stmt_defer(Parser *p){ - Token *token = token_get(p); - Stmt_Defer *result = stmt_defer(p->arena, token); - parse_stmt_block(p, result->body); - return (AST *)result; -} - -function AST * -parse_stmt_for(Parser *p){ - Token *token = token_get(p); - AST *on_begin = 0; - AST *on_iter = 0; - Expr*condition = 0; - if(!token_is(p, TK_OpenBrace)){ - if(!token_is(p, TK_Semicolon)){ - on_begin = parse_simple_stmt(p); - } - if(token_match(p, TK_Semicolon)){ - if(!token_is(p, TK_Semicolon)){ - condition = parse_expr(p); - } - if(token_match(p, TK_Semicolon)){ - if(!token_is(p, TK_OpenBrace)){ - on_iter = parse_simple_stmt(p); - if(on_iter->kind == AST_Stmt_Init){ - parser_push_error(p, token_get(p), "Init statements are not allowed in for on_iter"); - } - } - } - } - } - Stmt_For *result = stmt_for(p->arena, token, token_get(p), on_begin, condition, on_iter); - parse_stmt_block(p, (AST_Parent *)result->body); - return (AST*)result; -} - -function AST * -parse_stmt(Parser *p){ - Note_List *notes = parse_notes(p); - AST *result = 0; - if(token_match_keyword(p, keyword_if)){ - result = (AST *)parse_stmt_if(p); - } - else if(token_match_keyword(p, keyword_for)){ - result = parse_stmt_for(p); - } - else if(token_match_keyword(p, keyword_while)){ - not_implemented; - } - else if(token_match_keyword(p, keyword_defer)){ - result = parse_stmt_defer(p); - } - else if(token_match_keyword(p, keyword_return)){ - result = parse_stmt_return(p); - } - else if(token_is(p, TK_OpenBrace)){ - Stmt_Block *block = stmt_block(p->arena, token_get(p)); - parse_stmt_block(p, block); - result = (AST *)block; - } - else{ - result = parse_simple_stmt(p); - token_expect(p, TK_Semicolon); - } - - if(result){ - result->notes = notes; - } - - return result; -} - -//----------------------------------------------------------------------------- -// Test code -//----------------------------------------------------------------------------- -function S64 -eval_expr(Expr *expr){ - switch(expr->kind){ - case EK_Int: return expr->int_val; break; - case EK_Unary:{ - S64 left = eval_expr(expr->unary.expr); - switch(expr->unary.op){ - case TK_Not: return !left; break; - case TK_Neg: return ~left; break; - case TK_Sub: return -left; break; - case TK_Add: return +left; break; - default: invalid_codepath; - } - } break; - case EK_Ternary:{ - S64 cond = eval_expr(expr->ternary.cond); - if(cond) return eval_expr(expr->ternary.on_true); - else return eval_expr(expr->ternary.on_false); - } break; - case EK_Paren: return eval_expr(expr->paren.expr); break; - case EK_Binary: { - S64 left = eval_expr(expr->binary.left); - S64 right = eval_expr(expr->binary.right); - switch(expr->binary.op){ - case TK_Add: return left + right; break; - case TK_Sub: return left - right; break; - case TK_Mul: return left * right; break; - case TK_Div: return left / right; break; - case TK_Mod: return left % right; break; - case TK_Equals: return left == right; break; - case TK_NotEquals: return left != right; break; - case TK_GreaterThenOrEqual: return left >= right; break; - case TK_LesserThenOrEqual: return left <= right; break; - case TK_GreaterThen: return left > right; break; - case TK_LesserThen: return left < right; break; - case TK_BitAnd: return left & right; break; - case TK_BitOr: return left | right; break; - case TK_Pointer: return left ^ right; break; - case TK_And: return left && right; break; - case TK_Or: return left || right; break; - case TK_LeftShift: return left << right; break; - case TK_RightShift: return left >> right; break; - default: invalid_codepath; - } - } break; - default: invalid_codepath; - } - return 0; -} - -function Parser -parser_make(Arena *arena){ - Parser result = { - .tokens = lex_make_token_array(arena), - .arena = arena, - }; - global_parser = &result; - return result; -} - -function void -parser_restream(Parser *p, String stream, String file){ - lex_restream(&p->tokens, stream, file); -} - -function Parser -parser_make_stream(Arena *arena, String stream, String file){ - Parser parser = parser_make(arena); - lex_restream(&parser.tokens, stream, file); - return parser; -} - -function void -parser_add_stream(Parser *p, String string, String file){ - lex_add_stream(&p->tokens, string, file); -} - -function Program * -test_parse_decls(Parser *p){ - Program *decl_list = ast_program(p->arena, token_get(p)); - while(!token_is(p, TK_End)){ - AST *success = parse_decl(p, decl_list); - if(!success){ - parser_push_error(p, token_get(p), "Failed to parse decls, unexpected token!"); - break; - } - } - return decl_list; -} - -function void -parse_test_expr(){ - Arena *scratch = arena_begin_scratch(); - String test_case = lit("32+52-242*2/424%5-23" - " 1<<5>>6<<2 " - " 5*(4/3)*(2+5) " - " 0&1 == 1&0 " - " 1&&5*3 " - " 1&&5||0 " - " 1>5>=5==0 " - " 1>5 ? 1 : 2 " - " !!!!!1 " - " ~~1 + -!2 " - " 1 + ++Thing[12]++ + ++Thing[12].expr +" - ); - Parser parser = parser_make_stream(scratch, test_case, lit("Big_Expr")); - Parser *p = &parser; - - S64 t = 5; - S64 test_val[] = { - (32+52-242*2/424%5-23), - (((1<<5)>>6)<<2), - 5*(4/3)*(2+5), - (0&1) == (1&0), - 1&&(t*3), - (1&&t)||0, - 1>t>=t==0, - 1>t ? 1 : 2, - !!!!!1, - ~~1 + -!2, - }; - for(int i = 0; i < buff_cap(test_val); i++){ - Expr *expr = parse_expr(p); - S64 val = eval_expr(expr); - assert(val == test_val[i]); - } - - String exprs[] = { - lit("cast([12](thing: U32, qwe: *U32): [32]Result, (123+234))"), - lit("cast((thing: U32, qwe: *U32), (123+234))"), - lit("(:(U32,U32)){Thing=10}"), - lit("--Not_Thing[156](Thing) + test_func(asd=func1, af=func2, gg=func3)"), - lit("(:[23]*Type){Thing=10}"), - lit("cast(**Data,{Thing=10})"), - lit("(:[64]S64){1,2,3,4,5}"), - lit("Data_Type{1,2,3,4,5}"), - }; - for(SizeU i = 0; i < buff_cap(exprs); i++){ - parser_restream(p, exprs[i], lit("Test_Exprs")); - Expr *expr = parse_expr(p); - expr_print(expr); - printf("\n"); - } - - arena_end_scratch(); -} - -function void -parse_test_decls(){ - Arena *scratch = arena_begin_scratch(); - Parser p = parser_make(scratch); - - String decls[] = { - lit("Thing::enum: U64{ Thing_1 = 1<<1, Thing_2 = 2 }"), - lit("Struct::struct{ thing, thing2: *S64; struct { thing:U32; thing2: [64]Vec2; } inner: struct {i:U32;} }"), - }; - for(SizeU i = 0; i < buff_cap(decls); i++){ - parser_restream(&p, decls[i], lit("Decl_Test")); - Program *decl = test_parse_decls(&p); - assert(decl->first); - ast_print((AST *)decl); - } - arena_end_scratch(); -} - -function void -parse_test_from_file(){ - const String FILENAME = lit("test.cc"); - Arena *scratch = arena_begin_scratch(); - String file = os_read_file(scratch, FILENAME); - Parser p = parser_make_stream(scratch, file, FILENAME); - Program *d = test_parse_decls(&p); - ast_print((AST *)d); - arena_end_scratch(); -} - -function void -parse_test_stmt(){ - Arena *scratch = arena_begin_scratch(); - Parser p = parser_make(scratch); - String stmts[] = { - lit("if thing > 10 { thing++; }"), - lit("thing := 23;"), - lit("thing+=245;"), - lit("thing++;"), - lit("return thing;"), - }; - for(SizeU i = 0; i < buff_cap(stmts); i++){ - parser_restream(&p, stmts[i], lit("Stmt_Test")); - AST *stmt = parse_stmt(&p); - ast_print(stmt); - } - arena_end_scratch(); -} - -function void -parse_test(){ - parse_test_expr(); - parse_test_decls(); - parse_test_from_file(); - parse_test_stmt(); -} \ No newline at end of file diff --git a/print.c b/print.c deleted file mode 100644 index 83b2af2..0000000 --- a/print.c +++ /dev/null @@ -1,365 +0,0 @@ -function void expr_print(Expr *expr); -function void typespec_print(Typespec *spec); - -global S64 indent; - -#define println(...) do{ printf("\n"); print_indent(); printf(__VA_ARGS__); }while(0) - - -function void -print_indent(){ - for(S64 i = 0; i < indent*2; i++) - printf(" "); -} - -function void -token_print(Token *token){ - printf("%.*s", (S32)token->len, token->str); -} - -function void -expr_compound_print(Expr_Compound_Field *field){ - switch(field->kind){ - case COMPOUND_Default: { - expr_print(field->init); - }break; - case COMPOUND_Named: { - printf(".%s = ", field->name.s.str); - expr_print(field->init); - }break; - case COMPOUND_Index: { - printf("["); - expr_print(field->index); - printf("] = "); - expr_print(field->init); - }break; - default: invalid_codepath; - } -} - -function void -expr_print(Expr *expr){ - switch(expr->kind) { - case EK_Int:case EK_String:case EK_Identifier: { - token_print(expr->token); - } break; - - case EK_SizeExpr:{ - printf("sizeof("); - expr_print(expr->size_expr.expr); - printf(")"); - }break; - - case EK_Compound:{ - if(expr->compound.typespec){ - printf("("); - typespec_print(expr->compound.typespec); - printf(")"); - } - printf("{"); - for(Expr_Compound_Field *n = expr->compound.first; n; n=n->next){ - expr_compound_print(n); - if(n!=expr->compound.last) printf(","); - } - printf("}"); - } break; - - case EK_SizeType:{ - printf("sizeof("); - typespec_print(expr->size_type.typespec); - printf(")"); - }break; - - case EK_Paren:{ - printf("("); - expr_print(expr->paren.expr); - printf(")"); - } break; - - case EK_Field:{ - expr_print(expr->field.expr); - printf(".%s", expr->field.name.s.str); - } break; - - case EK_Binary:{ - printf("("); - expr_print(expr->binary.left); - printf("%s", token_kind_string[expr->binary.op]); - expr_print(expr->binary.right); - printf(")"); - } break; - - case EK_PostfixUnary:{ - printf("("); - expr_print(expr->unary.expr); - token_print(expr->token); - printf(")"); - } break; - - case EK_Unary:{ - printf("("); - token_print(expr->token); - expr_print(expr->unary.expr); - printf(")"); - } break; - - case EK_Ternary:{ - printf("("); - expr_print(expr->ternary.cond); - printf("?"); - expr_print(expr->ternary.on_true); - printf(":"); - expr_print(expr->ternary.on_false); - printf(")"); - } break; - - case EK_Cast:{ - printf("("); - printf("("); - typespec_print(expr->cast.typespec); - printf(")"); - expr_print(expr->cast.expr); - printf(")"); - } break; - - case EK_Index:{ - expr_print(expr->index.atom); - printf("["); - expr_print(expr->index.index); - printf("]"); - }break; - - case EK_Call:{ - expr_print(expr->call.atom); - printf("("); - for(Expr_Compound_Field *n = expr->call.first; n; n=n->next){ - expr_compound_print(n); - if(n!=expr->call.last) printf(","); - } - printf(")"); - }break; - default: {invalid_codepath;} break; - } -} - -function void -typespec_print(Typespec *spec){ - switch(spec->kind) { - case TS_Name: { - printf("%s", spec->name.s.str); - } break; - - case TS_NamedArgument: { - printf("%s: ", spec->named.name.s.str); - typespec_print(spec->named.base); - }break; - - case TS_Pointer: { - typespec_print(spec->base); - printf("*"); - } break; - - case TS_Array: { - typespec_print(spec->arr.base); - printf("["); - expr_print(spec->arr.size); - printf("]"); - } break; - - case TS_Function: { - printf("("); - for(Typespec *n = spec->func.first; n; n=n->next){ - typespec_print(n); - if(n!=spec->func.last) - printf(", "); - } - - printf(")"); - typespec_print(spec->func.ret); - } break; - default: {invalid_codepath;} break; - } -} - -function void -print_assign_expr(Expr *expr){ - if(expr){ - printf(" = "); - expr_print(expr); - } -} - -function void -ast_print(AST *in){ - switch(in->kind) { - case AST_Program: { - Program *node = (Program *)in; - for(AST *n = node->first; n; n=n->next){ - ast_print(n); - printf("\n"); - } - } break; - - case AST_Decl_Const: - case AST_Decl_Var:{ - Decl_Var *node = (Decl_Var *)in; - println(""); - if(node->typespec) typespec_print(node->typespec); - printf(" %s", node->name.s.str); - print_assign_expr(node->expr); - } break; - - case AST_Decl_Typedef:{ - Decl_Typedef *node = (Decl_Typedef *)in; - println("typedef %s ", node->name.s.str); - typespec_print(node->typespec); - printf(";"); - } break; - - case AST_Decl_Func:{ - Decl_Func *node = (Decl_Func *)in; - println("function "); - typespec_print(node->ret); - printf("\n%s", node->name.s.str); - printf("("); - AST_IterT(node, arg, Decl_Func_Arg){ - typespec_print(arg->typespec); - printf(" %s", arg->name.s.str); - if((AST *)arg != node->last) - printf(", "); - } - printf(")"); - if(!node->is_incomplete){ - ast_print((AST *)node->body); - } - } break; - - case AST_Decl_Struct: - case AST_Decl_Union :{ - Decl_Struct *node = (Decl_Struct *)in; - const char *struct_name = node->kind==AST_Decl_Struct ? "struct" : "union"; - println("%s %s{", struct_name, node->name.s.str?(char*)node->name.s.str:""); - indent++; - for(AST *n = node->first; n; n=n->next){ - ast_print(n); - printf(";"); - } - indent--; - println("};"); - } break; - - case AST_Decl_SubStruct: - case AST_Decl_SubUnion :{ - Decl_Struct *node = (Decl_Struct *)in; - const char *struct_name = node->kind==AST_Decl_Struct ? "struct" : "union"; - println("%s %s{", struct_name, node->name.s.str?(char*)node->name.s.str:""); - indent++; - for(AST *n = node->first; n; n=n->next){ - ast_print(n); - } - indent--; - println("};"); - } break; - - case AST_Decl_Enum:{ - Decl_Enum *node = (Decl_Enum *)in; - println("enum %s : ", node->name.s.str); - typespec_print(node->typespec); - printf("{"); - indent++; - AST_IterT(node, n, Decl_Enum_Child){ - //print_notes(p, n->first_note); - println("%s", n->name.s.str); - print_assign_expr(n->expr); - printf(","); - } - indent--; - println("};"); - } break; - - case AST_Stmt_Init:{ - Stmt_Init *node = (Stmt_Init *)in; - if(node->typespec) typespec_print(node->typespec); - printf(" %s", node->name.s.str); - print_assign_expr(node->expr); - }break; - - case AST_Stmt_Assign:{ - Stmt_Assign *node = (Stmt_Assign *)in; - expr_print(node->left); - token_print(node->pos); - expr_print(node->right); - }break; - - case AST_Stmt_Expr:{ - Stmt_Expr *node = (Stmt_Expr *)in; - expr_print(node->expr); - }break; - - case AST_Stmt_Defer:{ - Stmt_Defer *node = (Stmt_Defer *)in; - printf("defer "); - ast_print((AST *)node->body); - }break; - - case AST_Stmt_Return:{ - Stmt_Return *node = (Stmt_Return *)in; - printf("return "); - expr_print(node->expr); - }break; - - case AST_Stmt_Block:{ - Stmt_Block *node = (Stmt_Block *)in; - printf(" {"); - indent++; - AST_IterT(node, n, AST){ - println(""); - ast_print(n); - if(n->kind != AST_Stmt_If && n->kind != AST_Stmt_For && n->kind != AST_Stmt_Else && - n->kind != AST_Stmt_ElseIf) - printf(";"); - } - indent--; - println("}"); - }break; - - - case AST_Stmt_Else:{ - Stmt_Else *node = (Stmt_Else *)in; - printf("else "); - ast_print((AST *)node->body); - }break; - - case AST_Stmt_ElseIf:{ - Stmt_ElseIf *node = (Stmt_ElseIf *)in; - printf("else if "); - expr_print(node->condition); - ast_print((AST *)node->body); - }break; - - case AST_Stmt_If:{ - Stmt_If *node = (Stmt_If *)in; - printf("if "); - expr_print(node->condition); - ast_print((AST *)node->body); - AST_IterT(node, n, AST){ - ast_print(n); - } - }break; - - case AST_Stmt_For:{ - Stmt_For *node = (Stmt_For *)in; - printf("for("); - if(node->on_begin) ast_print(node->on_begin); - printf(";"); - if(node->condition) expr_print(node->condition); - printf(";"); - if(node->on_iter) ast_print(node->on_iter); - printf(")"); - ast_print((AST *)node->body); - }break; - - default: {invalid_codepath;} break; - } -} -