From 042127239ebb09d53aec13881f97b4a1df20bf94 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Sat, 7 May 2022 15:48:53 +0200 Subject: [PATCH] AST idea --- ast.c | 53 +------- build.bat | 1 + dllqueue.c | 55 ++++++++ generate.c | 48 +++++-- generated.c | 49 +++++++ new_ast.c | 356 +++++++++++++++++++++++++++++++++++++------------- new_lex.c | 4 + new_parse.c | 169 ++++++++++++++++++++---- new_print.c | 19 ++- test.cc | 139 ++++++++------------ token_array.c | 2 + 11 files changed, 629 insertions(+), 266 deletions(-) create mode 100644 dllqueue.c create mode 100644 generated.c diff --git a/ast.c b/ast.c index 9da9d4a..43a0ac7 100644 --- a/ast.c +++ b/ast.c @@ -21,7 +21,7 @@ decl_struct(Parser *p, Decl_Kind kind, Token *pos, Intern_String name, Decl_Stru function Decl * decl_typedef(Parser *p, Token *pos, Intern_String name, Typespec *type){ Decl *result = decl_new(p, DECL_Typedef, pos, name); - result->typedef_decl.type = type; + result->typedef_decl.typespec = type; return result; } @@ -227,57 +227,6 @@ typespec_require_name_string(Typespec *type){ return string_empty; } -//----------------------------------------------------------------------------- -// Statements -//----------------------------------------------------------------------------- -function Stmt * -stmt_new(Parser *p, Stmt_Kind kind, Token *pos){ - Stmt *result = arena_push_struct(&p->main_arena, Stmt); - result->kind = kind; - result->pos = pos; - return result; -} - -function Stmt * -stmt_decl(Parser *p, Token *pos, Decl *decl){ - Stmt *result = stmt_new(p, STMT_Decl, pos); - result->decl = decl; - return result; -} - -function Stmt * -stmt_expr(Parser *p, Token *pos, Expr *expr){ - Stmt *result = stmt_new(p, STMT_Expr, pos); - result->expr = expr; - return result; -} - -function Stmt * -stmt_list(Parser *p, Token *pos){ - Stmt *result = stmt_new(p, STMT_List, pos); - return result; -} - -function Stmt * -stmt_return(Parser *p, Token *pos, Expr *expr){ - Stmt *result = stmt_new(p, STMT_Return, pos); - result->ret.expr = expr; - return result; -} - -function Stmt * -stmt_if(Parser *p, Token *pos, Stmt *body, Expr *cond){ - Stmt *result = stmt_new(p, STMT_If, pos); - result->stmt_if.cond = cond; - result->stmt_if.body = body; - return result; -} - -function void -stmt_push(Stmt *stmt, Stmt *child){ - SLLQueuePush(stmt->list.first, stmt->list.last, child); -} - //----------------------------------------------------------------------------- // Pointer Array //----------------------------------------------------------------------------- diff --git a/build.bat b/build.bat index 00412ef..58d1092 100644 --- a/build.bat +++ b/build.bat @@ -2,5 +2,6 @@ rem clang generate.c -fdiagnostics-absolute-paths -std=c99 -g -o generate.exe -Wl,user32.lib rem generate.exe + clang main.c -Wall -Wno-unused-function -fdiagnostics-absolute-paths -std=c17 -g -o main.exe -Wl,user32.lib rem cl main.c -std:c17 diff --git a/dllqueue.c b/dllqueue.c new file mode 100644 index 0000000..4a7f5e5 --- /dev/null +++ b/dllqueue.c @@ -0,0 +1,55 @@ +function void +push(Type *l, Type *node){ + if(l->first == 0){ + l->first = l->last = node; + node->prev = 0; + node->next = 0; + } + else{ + l->last->next = node; + node->prev = l->last; + node->next = 0; + l->last = node; + } + node->parent = l; +} + +function void +push_front(Type *l, Type *node){ + if(l->first == 0){ + l->first = l->last = node; + node->prev = 0; + node->next = 0; + } + else{ + node->next = l->first; + l->first->prev = node; + node->prev = 0; + l->first = node; + } + node->parent = l; +} + +function void +remove(Type *l, Type *node){ + if(l->first == l->last){ + assert(node == l->last); + l->first = l->last = 0; + } + else if(l->last == node){ + l->last = l->last->prev; + l->last->next = 0; + } + else if(l->first == node){ + l->first = l->first->next; + l->first->prev = 0; + } + else{ + node->prev->next = node->next; + node->next->prev = node->prev; + } + + node->parent = 0; + node->prev = 0; + node->next = 0; +} diff --git a/generate.c b/generate.c index ef384a6..330fbb3 100644 --- a/generate.c +++ b/generate.c @@ -13,24 +13,54 @@ #include "new_lex.c" -int main(){ - - FILE *f = fopen("generated.c", "w"); - assert(f); - +//----------------------------------------------------------------------------- +// String replacing util +//----------------------------------------------------------------------------- +typedef struct String_Map String_Map; +struct String_Map{ + String replace; + String with; +}; + +function void +output_template(FILE *f, String filename, String_Map *map, SizeU map_cap){ Arena *scratch = arena_begin_scratch(); - String file = os_read_file(scratch, lit("token_array.c")); - Token_Array array = lex_stream(scratch, file, lit("token_array.c")); - for(Token *t = token_array_iter_begin(&array); t; t = token_array_iter_next(&array)){ + String file = os_read_file(scratch, filename); + Token_Array array = lex_stream(scratch, file, filename); + for(Token *t = token_array_iter_begin(&array); t->kind != TK_End; t = token_array_iter_next(&array)){ + String string = t->string; + for(SizeU i = 0; i < map_cap; i++){ + if(string_compare(string, map[i].replace)){ + string = map[i].with; + break; + } + } - fprintf(f, "%.*s", (int)t->len, t->str); + + fprintf(f, "%.*s", (int)string.len, string.str); if(t->kind == TK_OpenBrace) fprintf(f, "\n"); if(t->kind == TK_CloseBrace && token_array_iter_peek(&array, 0)->kind != TK_Semicolon) fprintf(f, "\n"); if(t->kind == TK_Semicolon) fprintf(f, "\n"); + if(t->kind == TK_Keyword) fprintf(f, " "); if(t[0].kind == TK_Identifier && token_array_iter_peek(&array, 0)->kind == TK_Identifier) fprintf(f, " "); token_array_iter_peek(&array, 1); } arena_end_scratch(); +} + +int main(){ + + FILE *f = fopen("generated.c", "w"); + assert(f); + String_Map map[] = { + {lit("Type"), lit("Decl")}, + {lit("first"), lit("list_decl.first")}, + {lit("last"), lit("list_decl.last")}, + {lit("remove"), lit("decl_list_remove")}, + {lit("push_front"), lit("decl_dll_list_push_front")}, + {lit("push"), lit("decl_dll_list_push")}, + }; + output_template(f, lit("dllqueue.c"), map, buff_cap(map)); fclose(f); } \ No newline at end of file diff --git a/generated.c b/generated.c new file mode 100644 index 0000000..9e94d39 --- /dev/null +++ b/generated.c @@ -0,0 +1,49 @@ +function void decl_dll_list_push(Decl*l,Decl*node){ +if (l->list_decl.first==0){ +l->list_decl.first=l->list_decl.last=node; +node->prev=0; +node->next=0; +} +else { +l->list_decl.last->next=node; +node->prev=l->list_decl.last; +node->next=0; +l->list_decl.last=node; +} +node->parent=l; +} +function void decl_dll_list_push_front(Decl*l,Decl*node){ +if (l->list_decl.first==0){ +l->list_decl.first=l->list_decl.last=node; +node->prev=0; +node->next=0; +} +else { +node->next=l->list_decl.first; +l->list_decl.first->prev=node; +node->prev=0; +l->list_decl.first=node; +} +node->parent=l; +} +function void decl_list_remove(Decl*l,Decl*node){ +if (l->list_decl.first==l->list_decl.last){ +assert(node==l->list_decl.last); +l->list_decl.first=l->list_decl.last=0; +} +else if (l->list_decl.last==node){ +l->list_decl.last=l->list_decl.last->prev; +l->list_decl.last->next=0; +} +else if (l->list_decl.first==node){ +l->list_decl.first=l->list_decl.first->next; +l->list_decl.first->prev=0; +} +else { +node->prev->next=node->next; +node->next->prev=node->prev; +} +node->parent=0; +node->prev=0; +node->next=0; +} diff --git a/new_ast.c b/new_ast.c index 36f52f9..22c29ba 100644 --- a/new_ast.c +++ b/new_ast.c @@ -4,11 +4,86 @@ typedef struct Decl Decl; typedef struct Stmt Stmt; typedef struct Stmt_If Stmt_If; typedef struct Typespec Typespec; -typedef struct Typespec_Function_Arg Typespec_Function_Arg; typedef struct Decl_Enum_Child Decl_Enum_Child; typedef struct Decl_Function_Arg Decl_Function_Arg; typedef struct Expr_Compound_Field Expr_Compound_Field; +typedef struct AST AST; +typedef struct AST_Parent AST_Parent; + +typedef enum AST_Kind{ + AST_None, + + AST_Decl_Struct, // + AST_Decl_SubStruct, + AST_Decl_SubUnion, + AST_Decl_Union, + AST_Decl_Enum, + AST_Decl_Note, + AST_Decl_Func, + AST_List, + AST_Stmt_If, + AST_Stmt_Decl, + AST_Stmt_Expr, + AST_Stmt_Return, + AST_Stmt_For, + AST_FirstParent = AST_Decl_Struct, + AST_LastParent = AST_Stmt_For, + + AST_Decl_Func_Arg, + + AST_Decl_Variable, +}AST_Kind; + +#define AST_FIELDS AST *next, *prev; AST *notes; AST_Parent *parent; Token *pos; AST_Kind kind +#define AST_PARENT_FIELDS AST *first, *last +#define AST_UNION union{ struct{ AST_FIELDS; }; AST ast; } +#define AST_PARENT_UNION union{ struct{ AST_PARENT_FIELDS; }; AST_Parent child; } + +struct AST{ + AST_FIELDS; +}; + +typedef struct AST_Parent{ + AST_UNION; + AST_PARENT_FIELDS; +} AST_Parent; + +typedef struct AST_Note{ + AST_PARENT_UNION; + Intern_String name; + Expr *expr; +}AST_Note; + +typedef struct Decl_Struct{ + AST_PARENT_UNION; + Intern_String name; +}Decl_Struct; + +typedef struct Decl_Func_Arg{ + AST_UNION; + Intern_String name; + Typespec *typespec; +}Decl_Func_Arg; + +typedef struct AST_Decl_Enum_Child{ + AST_UNION; + Intern_String name; + Expr *expr; +}AST_Decl_Enum_Child; + +typedef struct Decl_Enum{ + AST_PARENT_UNION; + Typespec *typespec; +}Decl_Enum; + +typedef struct Decl_Func{ + AST_PARENT_UNION; + Typespec *ret; + AST *body; +}Decl_Func; + + //----------------------------------------------------------------------------- // Expressions //----------------------------------------------------------------------------- @@ -168,11 +243,13 @@ typedef enum Decl_Kind{ DECL_SubUnion, DECL_Enum, DECL_Variable, + DECL_Const, DECL_Typedef, DECL_Function, DECL_List, }Decl_Kind; + struct Decl{ Decl_Kind kind; Decl *next; @@ -197,11 +274,11 @@ struct Decl{ Decl *last; }struct_decl; struct{ - Typespec *type; + Typespec *typespec; Expr *expr; }var_decl; struct{ - Typespec *type; + Typespec *typespec; }typedef_decl; struct{ Decl_Function_Arg *first; @@ -570,7 +647,15 @@ decl_struct(Arena *p, Decl_Kind kind, Token *pos, Intern_String name){ function Decl * decl_typedef(Arena *p, Token *pos, Intern_String name, Typespec *type){ Decl *result = decl_new(p, DECL_Typedef, pos, name); - result->typedef_decl.type = type; + result->typedef_decl.typespec = type; + return result; +} + +function Decl * +decl_const(Arena *arena, Token *pos, Intern_String name, Expr *expr, Typespec *typespec){ + Decl *result = decl_new(arena, DECL_Const, pos, name); + result->var_decl.expr = expr; + result->var_decl.typespec = typespec; return result; } @@ -584,7 +669,7 @@ decl_enum(Arena *p, Token *pos, Intern_String name, Typespec *typespec){ function Decl * decl_variable(Arena *p, Token *pos, Intern_String name, Typespec *typespec, Expr *expr){ Decl *result = decl_new(p, DECL_Variable, pos, name); - result->var_decl.type = typespec; + result->var_decl.typespec = typespec; result->var_decl.expr = expr; return result; } @@ -630,108 +715,203 @@ decl_list_push(Decl *parent, Decl *child){ SLLQueuePush(parent->list_decl.first, parent->list_decl.last, child); } +//----------------------------------------------------------------------------- +// Statements +//----------------------------------------------------------------------------- +function Stmt * +stmt_new(Arena *p, Stmt_Kind kind, Token *pos){ + Stmt *result = arena_push_struct(p, Stmt); + result->kind = kind; + result->pos = pos; + return result; +} +function Stmt * +stmt_decl(Arena *p, Token *pos, Decl *decl){ + Stmt *result = stmt_new(p, STMT_Decl, pos); + result->decl = decl; + return result; +} + +function Stmt * +stmt_expr(Arena *p, Token *pos, Expr *expr){ + Stmt *result = stmt_new(p, STMT_Expr, pos); + result->expr = expr; + return result; +} + +function Stmt * +stmt_list(Arena *p, Token *pos){ + Stmt *result = stmt_new(p, STMT_List, pos); + return result; +} + +function Stmt * +stmt_return(Arena *p, Token *pos, Expr *expr){ + Stmt *result = stmt_new(p, STMT_Return, pos); + result->ret.expr = expr; + return result; +} + +function Stmt * +stmt_if(Arena *p, Token *pos, Stmt *body, Expr *cond){ + Stmt *result = stmt_new(p, STMT_If, pos); + result->stmt_if.cond = cond; + result->stmt_if.body = body; + return result; +} + +function void +stmt_push(Stmt *stmt, Stmt *child){ + SLLQueuePush(stmt->list.first, stmt->list.last, child); +} //----------------------------------------------------------------------------- // Double linked list //----------------------------------------------------------------------------- function void -decl_dll_list_push(Decl *l, Decl *node){ - if(l->list_decl.first == 0){ - l->list_decl.first = l->list_decl.last = node; - node->prev = 0; - node->next = 0; - } - else{ - l->list_decl.last->next = node; - node->prev = l->list_decl.last; - node->next = 0; - l->list_decl.last = node; - } - node->parent = l; -} - -function void -decl_dll_list_push_front(Decl *l, Decl *node){ - if(l->list_decl.first == 0){ - l->list_decl.first = l->list_decl.last = node; - node->prev = 0; - node->next = 0; - } - else{ - node->next = l->list_decl.first; - l->list_decl.first->prev = node; - node->prev = 0; - l->list_decl.first = node; - } - node->parent = l; -} - -function void -decl_list_remove(Decl *l, Decl *node){ - if(l->list_decl.first == l->list_decl.last){ - assert(node == l->list_decl.last); - l->list_decl.first = l->list_decl.last = 0; - } - else if(l->list_decl.last == node){ - l->list_decl.last = l->list_decl.last->prev; - l->list_decl.last->next = 0; - } - else if(l->list_decl.first == node){ - l->list_decl.first = l->list_decl.first->next; - l->list_decl.first->prev = 0; - } - else{ - node->prev->next = node->next; - node->next->prev = node->prev; - } - - node->parent = 0; - node->prev = 0; - node->next = 0; -} - -function void -list_print(Decl *decls){ - +list_print(AST_Parent *decls){ + printf("\n"); printf("next:"); - for(Decl *n = decls[0].list_decl.first; n; n=n->next){ + for(AST *n = decls->first; n; n=n->next){ printf("%d", n->kind); } printf("prev:"); - for(Decl *n = decls[0].list_decl.last; n; n=n->prev){ + for(AST *n = decls->last; n; n=n->prev){ printf("%d", n->kind); } printf("parent:"); - for(Decl *n = decls[0].list_decl.first; n; n=n->next){ + for(AST *n = decls->first; n; n=n->next){ printf("%d", n->parent->kind); } } +function void +ast_remove(AST *node){ + AST_Parent *l = node->parent; + assert(l); + if (l->first==l->last){ + assert(node==l->last); + l->first=l->last=0; + } + else if (l->last==node){ + l->last=l->last->prev; + l->last->next=0; + } + else if (l->first==node){ + l->first=l->first->next; + l->first->prev=0; + } + else { + node->prev->next=node->next; + node->next->prev=node->prev; + } + node->parent=0; + node->prev=0; + node->next=0; +} + +function void +ast_push_first(AST_Parent *l, AST *node){ + if (l->first==0){ + l->first=l->last=node; + node->prev=0; + node->next=0; + } + else { + l->last->next=node; + node->prev=l->last; + node->next=0; + l->last=node; + } + node->parent=l; +} + +function void +ast_push_last(AST_Parent *l, AST *node){ + if(l->first == 0){ + l->first = l->last = node; + node->prev = 0; + node->next = 0; + } + else { + node->next = l->first; + l->first->prev = node; + node->prev = 0; + l->first = node; + } + node->parent = l; +} + function void -ast_test(){ - Decl decls[16] = {0}; - decls[0].kind = 9; - decls[1].kind = 1; - decls[2].kind = 2; - decls[3].kind = 3; - decls[4].kind = 4; - decl_dll_list_push(decls, decls+1); - decl_dll_list_push(decls, decls+2); - decl_dll_list_push(decls, decls+3); - decl_dll_list_push_front(decls, decls+4); +ast_push_after(AST *in_list, AST *node){ + AST_Parent *parent = in_list->parent; + assert(parent); + assert(parent->first && parent->last); - //list_print(decls); - decl_list_remove(decls, decls+1); - //list_print(decls); - decl_list_remove(decls, decls+2); - //list_print(decls); - decl_list_remove(decls, decls+3); - //list_print(decls); - decl_list_remove(decls, decls+4); - //list_print(decls); - assert(decls[0].list_decl.first == 0); - assert(decls[0].list_decl.last == 0); + node->prev = in_list; + if(in_list == parent->last){ + in_list->next = node; + parent->last = node; + } + else { + node->next = in_list->next; + in_list->next = node; + node->next->prev = node; + } + node->parent=parent; +} + +function void +ast_push_before(AST *in_list, AST *node){ + AST_Parent *parent = in_list->parent; + assert(parent); + assert(parent->first && parent->last); + + node->next = in_list; + if(parent->first == in_list){ + in_list->prev = node; + parent->first = node; + } + else{ + node->prev = in_list->prev; + in_list->prev = node; + node->prev->next = node; + } + node->parent = parent; +} + + +function void +ast_test(){ + printf("\nAST_Size = %u", (U32)sizeof(AST)); + printf("\nAST_Struct_Size = %u", (U32)sizeof(Decl_Struct)); + + AST_Parent parent = {0}; + AST decls[16] = {0}; + parent.kind = 0; + for(int i = 0; i < buff_cap(decls); i++){ + decls[i].kind = i+1; + } + + ast_push_first(&parent, decls); + ast_push_first(&parent, decls+1); + ast_push_first(&parent, decls+2); + ast_push_before(decls, decls+3); + ast_push_before(decls, decls+4); + ast_push_after(decls, decls+5); + ast_push_after(decls+5, decls+6); + + //list_print(&parent); + ast_remove(decls); + ast_remove(decls+1); + ast_remove(decls+2); + ast_remove(decls+3); + ast_remove(decls+4); + ast_remove(decls+5); + ast_remove(decls+6); + assert(parent.first == 0); + assert(parent.last == 0); } diff --git a/new_lex.c b/new_lex.c index e9f990f..9cc3a3b 100644 --- a/new_lex.c +++ b/new_lex.c @@ -5,6 +5,8 @@ global Intern_String keyword_else; 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; @@ -31,7 +33,9 @@ init_default_keywords(Intern_Table *t){ 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")); diff --git a/new_parse.c b/new_parse.c index 5eb716f..3c47b4b 100644 --- a/new_parse.c +++ b/new_parse.c @@ -31,7 +31,7 @@ parser_push_error(Parser *p, Token *token, char *str, ...){ // @Note(Krzosa): Print nice error message { - printf("Error: %s %s:%d\n", string.str, token->file.str, (S32)token->line); + printf("\nError: %s %s:%d\n", string.str, token->file.str, (S32)token->line); // @Note(Krzosa): Print error line { @@ -171,7 +171,6 @@ Compound literals - { } */ - function Expr_Compound_Field * parse_expr_compound_field(Parser *p){ Token *token = token_get(p); @@ -554,7 +553,6 @@ name::const = 4254; // data: [24]U32; // } // } - */ function void parse_note_list(Parser *p, Note *parent) { @@ -602,34 +600,37 @@ parse_assign_expr(Parser *p){ } function Typespec * -parse_optional_type(Parser *p){ +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), intern_int); + result = typespec_name(p->arena, token_get(p), type); } return result; } function Decl * parse_enum(Parser *p, Token *name){ - Typespec *typespec = parse_optional_type(p); + Typespec *typespec = parse_optional_type(p, intern_int); Decl *result = decl_enum(p->arena, name, name->intern_val, typespec); token_expect(p, TK_OpenBrace); - do{ + do { Note 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, ¬es); - } while(token_match(p, TK_Comma)); + 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 *parent, Token *name){ +parse_var_decl(Parser *p, Decl *parent, Token *name, Note *notes){ Token *name_stack[64]; S64 name_stack_len = 0; name_stack[name_stack_len++] = name; @@ -640,6 +641,7 @@ parse_var_decl(Parser *p, Decl *parent, Token *name){ token_expect(p, TK_Semicolon); for(S64 i = 0; i < name_stack_len; i++){ Decl *decl = decl_variable(p->arena, name_stack[i], name_stack[i]->intern_val, typespec, 0); + decl_pass_notes(decl, notes); decl_struct_push(parent, decl); } } @@ -651,35 +653,38 @@ parse_struct(Parser *p, Token *name, Decl_Kind struct_kind){ Decl *result = decl_struct(p->arena, struct_kind, token, intern_name); token_expect(p, TK_OpenBrace); do { + Note notes = parse_notes(p); Token *token = token_get(p); if(token_match_keyword(p, keyword_union)){ Decl *decl = parse_struct(p, 0, DECL_SubUnion); + decl_pass_notes(decl, ¬es); decl_struct_push(result, decl); } else if(token_match_keyword(p, keyword_struct)){ Decl *decl = parse_struct(p, 0, DECL_SubStruct); + decl_pass_notes(decl, ¬es); decl_struct_push(result, 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); + token_next(p); token_next(p); Decl *decl = parse_struct(p, token, DECL_SubUnion); + decl_pass_notes(decl, ¬es); decl_struct_push(result, decl); } else if(token_peek_is_keyword(p, keyword_struct, 1)){ - token_next(p); - token_next(p); + token_next(p); token_next(p); Decl *decl = parse_struct(p, token, DECL_SubStruct); + decl_pass_notes(decl, ¬es); decl_struct_push(result, decl); } else{ - parse_var_decl(p, result, token); + parse_var_decl(p, result, token, ¬es); } } else{ - parse_var_decl(p, result, token); + parse_var_decl(p, result, token, ¬es); } } else{ @@ -690,9 +695,47 @@ parse_struct(Parser *p, Token *name, Decl_Kind struct_kind){ } function Decl * -parse_decl(Parser *p){ - Decl *result = 0; +parse_typedef(Parser *p, Token *name){ + token_expect(p, TK_Assign); + Typespec *typespec = parse_typespec(p); + token_expect(p, TK_Semicolon); + Decl *result = decl_typedef(p->arena, name, name->intern_val, typespec); + return result; +} + +function Decl * +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 *result = decl_const(p->arena, name, name->intern_val, expr, typespec); + return result; +} + +function Decl * +parse_function(Parser *p, Token *name){ + Decl *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->func_decl.ret = parse_optional_type(p, intern_void); + token_expect(p, TK_Semicolon); + return result; +} + +function B32 +parse_decl(Parser *p, Decl *parent){ Token *name = 0; + Decl *result = 0; Note note = parse_notes(p); if((name = token_match(p, TK_Identifier))){ if(token_match(p, TK_DoubleColon)){ @@ -706,31 +749,91 @@ parse_decl(Parser *p){ else if((token = token_match_keyword(p, keyword_struct))){ result = parse_struct(p, name, DECL_Struct); } + else if((token = token_match_keyword(p, keyword_typedef))){ + result = parse_typedef(p, name); + } else if((token = token_match_keyword(p, keyword_const))){ - // Const value + result = parse_const(p, name); } else if((token = token_match(p, TK_OpenParen))){ - // Function + result = parse_function(p, name); } else{ - parser_push_error(p, token_get(p), "Expected token of kind todo:decl_tokens"); + token = token_get(p); + parser_push_error(p, token, "Expected a declaration keyword. Got instead: %s", token_kind_string[token->kind]); } } else{ - parser_push_error(p, token_get(p), "Expected token of kind '::'"); + 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){ decl_pass_notes(result, ¬e); + decl_list_push(parent, result); + return true; + } + return false; +} + +function Decl +parse_decls(Parser *p){ + Decl decl_list = {.kind=DECL_List}; + while(!token_is(p, TK_End)){ + B32 success = parse_decl(p, &decl_list); + if(!success){ + parser_push_error(p, token_get(p), "Failed to parse decls, unexpected token!"); + } + } + return decl_list; +} + +//----------------------------------------------------------------------------- +// Statement parsing +//----------------------------------------------------------------------------- +/* +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 Stmt * +parse_stmt(Parser *p){ + Note notes = parse_notes(p); + Stmt *result = 0; + if(token_match_keyword(p, keyword_if)){ + + } + else if(token_match_keyword(p, keyword_for)){ + + } + else if(token_match_keyword(p, keyword_while)){ + + } + else if(token_match_keyword(p, keyword_return)){ + + } + else if(token_match(p, TK_OpenBrace)){ + // Scope + } + else{ + // Expr } - return result; } //----------------------------------------------------------------------------- // Test code //----------------------------------------------------------------------------- - function S64 eval_expr(Expr *expr){ switch(expr->kind){ @@ -875,15 +978,27 @@ parse_test_decls(){ }; for(SizeU i = 0; i < buff_cap(decls); i++){ parser_restream(&p, decls[i], lit("Decl_Test")); - Decl *decl = parse_decl(&p); - assert(decl); - decl_print(decl); + Decl decl = parse_decls(&p); + assert(decl.list_decl.first); + decl_print(decl.list_decl.first); } - + 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); + Decl d = parse_decls(&p); + decl_print(&d); + arena_end_scratch(); } function void parse_test(){ parse_test_expr(); parse_test_decls(); + parse_test_from_file(); } \ No newline at end of file diff --git a/new_print.c b/new_print.c index eb71961..a30634a 100644 --- a/new_print.c +++ b/new_print.c @@ -202,19 +202,32 @@ decl_print(Decl *node){ } } break; + case DECL_Const: case DECL_Variable:{ println("%s: ", node->name.s.str); - B32 r = typespec_print(node->var_decl.type); + if(node->var_decl.typespec) typespec_print(node->var_decl.typespec); print_assign_expr(node->var_decl.expr); - if(r) printf(";"); } break; case DECL_Typedef:{ println("typedef %s ", node->name.s.str); - typespec_print(node->typedef_decl.type); + typespec_print(node->typedef_decl.typespec); printf(";"); } break; + case DECL_Function:{ + println(""); + typespec_print(node->func_decl.ret); + printf(" %s", node->name.s.str); + printf("("); + for(Decl_Function_Arg *arg = node->func_decl.first; arg; arg=arg->next){ + printf("%s: ", arg->name.s.str); + typespec_print(arg->typespec); + if(arg != node->func_decl.last) + printf(", "); + } + printf(");"); + } break; case DECL_Struct: case DECL_Union :{ diff --git a/test.cc b/test.cc index 511eedb..c77efec 100644 --- a/test.cc +++ b/test.cc @@ -1,57 +1,23 @@ -#if 0 +Thing :: const: *U32 = 0; +CONST_VAL::const = 185210591; - -@register -@param_expr(size) -@param_type(Type) -test::struct{ - Array_Block::struct{ - next: Array_Block*; - data: Type[size]; - } - - @inline Array::struct{ - first: Array_Block; - last : Array_Block*; - block: S64; - len : S64; - } - - array_make::(arena: Arena*) Type { - thing: Test_Type; - result: Type; - result.arena = arena; - result.last = &result.first; - return result; - } - - array_push::(array: Array*, item: Type*){ - if array->len+1 > size{ - assert(array->len); - block: Array_Block* = cast(Thing)arena_push_struct(array->arena, sizeof(:Array_Block)); - array->last = array->last.next = block; - array->len = 0; - array->block += 1; - } - array->last.data[array->len++] = *item; - } -} +new_function::(Thing:[32]U32): U32; @test(size = 4096) OpenGL :: struct{ - glVertexAttribPointer: (GLuint, GLint, GLenum, GLboolean, GLsizei, GLvoid*); + glVertexAttribPointer: (GLuint, GLint, GLenum, GLboolean, GLsizei, *GLvoid); glBindTexture: (GLenum, GLuint); glDrawArrays: (GLenum, GLint, GLsizei); - test_array: int*[10]; + test_array: [10]*int; - thing : Things*; + thing : *Things; thing_cap: S64; thing_len: S64; } OS_Memory::struct{ - data: void*; + data: *void; commit: SizeU; reserve: SizeU; } @@ -63,10 +29,11 @@ Arena::struct{ } String::struct{ - str: U8*; + str: *U8; len: S64; } -Intern_String::typedef String; +Intern_String::typedef = String; +//CONST_VALUE::const = 121591; @stringify @prefix="TK_" @@ -147,12 +114,12 @@ Token::struct{ } file:String; line:S64; - line_begin:U8*; + line_begin:*U8; } Lex_Stream::struct{ - stream: U8*; - line_begin: U8*; + stream: *U8; + line_begin: *U8; filename: String; line: S64; } @@ -172,36 +139,36 @@ Expr_Kind::enum{ Expr:: struct{ kind: Expr_Kind; - token: Token*; - next : Expr*; + token: *Token; + next : *Expr; union{ cast_val: struct{ - type: AST_Node*; - expr: Expr*; + type: *AST_Node; + expr: *Expr; } list: struct{ - first: Expr *; - last: Expr *; + first: *Expr; + last: *Expr; } call: struct{ - atom: Expr *; - list: Expr *; + atom: *Expr; + list: *Expr; } index: struct{ - atom: Expr *; - index: Expr *; + atom: *Expr; + index: *Expr; } unary: struct{ - expr: Expr* ; + expr: *Expr ; } binary: struct{ - left: Expr* ; - right: Expr* ; + left: *Expr ; + right: *Expr ; } ternary: struct{ - cond: Expr* ; - on_true: Expr*; - on_false: Expr*; + cond: *Expr ; + on_true: *Expr; + on_false: *Expr; } } } @@ -225,36 +192,36 @@ AST_Kind::enum{ AST_Node::struct{ kind: AST_Kind; - pos : Token*; + pos : *Token; name: Intern_String; - next: AST_Node*; - next_scope: AST_Node*; + next: *AST_Node; + next_scope: *AST_Node; - first_note: AST_Node*; - last_note: AST_Node*; + first_note: *AST_Node; + last_note: *AST_Node; - first_child: AST_Node*; - last_child: AST_Node*; + first_child: *AST_Node; + last_child: *AST_Node; union{ base_type_size: SizeU; - pointer: AST_Node*; - typedef_type: AST_Node*; - variable_type: AST_Node*; - func_return_type: AST_Node*; + pointer: *AST_Node; + typedef_type: *AST_Node; + variable_type: *AST_Node; + func_return_type: *AST_Node; } } Parser_Error :: struct{ - next: Parser_Error*; + next: *Parser_Error; message: String; - token : Token *; + token : *Token; } Scope :: struct{ - next : Scope*; - first: AST_Node*; - last : AST_Node*; + next : *Scope; + first: *AST_Node; + last : *AST_Node; } @@ -263,21 +230,21 @@ Parser :: struct{ intern_table_arena: Arena; symbol_table_arena: Arena; - scope_free_list: Scope *; - scope_stack: Scope *; - global_scope: Scope *; + scope_free_list: Scope; + scope_stack: Scope; + global_scope: Scope; symbols_inserted: S64; symbols_count: S64; - symbols: AST_Node *; + symbols: AST_Node; - interns: Intern_String *; + interns: Intern_String; interns_in_bytes: S64; interns_inserted: S64; interns_count: S64; - first_keyword: U8 *; - last_keyword: U8 *; + first_keyword: U8; + last_keyword: U8; //@map(type="sparse") symbols: AST_Node; @@ -305,5 +272,3 @@ struct_type_lower_var_name_lower_push(struct_type *parent, var_type *child){ } } */ - -#endif diff --git a/token_array.c b/token_array.c index 67943dd..c603cbf 100644 --- a/token_array.c +++ b/token_array.c @@ -71,6 +71,8 @@ token_array_iter_next(Token_Array *array){ function Token * token_array_iter_peek(Token_Array *array, S64 i){ + // @Todo(Krzosa): Simplify, too many calculations here + // Why even change state? S64 save_len = array->iter_len; S64 save_block = array->iter_block; Token_Bucket *save_bucket = array->iter_bucket;