This commit is contained in:
Krzosa Karol
2022-05-07 15:48:53 +02:00
parent d3ede16bab
commit 042127239e
11 changed files with 629 additions and 266 deletions

53
ast.c
View File

@@ -21,7 +21,7 @@ decl_struct(Parser *p, Decl_Kind kind, Token *pos, Intern_String name, Decl_Stru
function Decl * function Decl *
decl_typedef(Parser *p, Token *pos, Intern_String name, Typespec *type){ decl_typedef(Parser *p, Token *pos, Intern_String name, Typespec *type){
Decl *result = decl_new(p, DECL_Typedef, pos, name); Decl *result = decl_new(p, DECL_Typedef, pos, name);
result->typedef_decl.type = type; result->typedef_decl.typespec = type;
return result; return result;
} }
@@ -227,57 +227,6 @@ typespec_require_name_string(Typespec *type){
return string_empty; 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 // Pointer Array
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@@ -2,5 +2,6 @@
rem clang generate.c -fdiagnostics-absolute-paths -std=c99 -g -o generate.exe -Wl,user32.lib rem clang generate.c -fdiagnostics-absolute-paths -std=c99 -g -o generate.exe -Wl,user32.lib
rem generate.exe rem generate.exe
clang main.c -Wall -Wno-unused-function -fdiagnostics-absolute-paths -std=c17 -g -o main.exe -Wl,user32.lib 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 rem cl main.c -std:c17

55
dllqueue.c Normal file
View File

@@ -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;
}

View File

@@ -13,24 +13,54 @@
#include "new_lex.c" #include "new_lex.c"
int main(){ //-----------------------------------------------------------------------------
// String replacing util
FILE *f = fopen("generated.c", "w"); //-----------------------------------------------------------------------------
assert(f); 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(); Arena *scratch = arena_begin_scratch();
String file = os_read_file(scratch, lit("token_array.c")); String file = os_read_file(scratch, filename);
Token_Array array = lex_stream(scratch, file, lit("token_array.c")); Token_Array array = lex_stream(scratch, file, filename);
for(Token *t = token_array_iter_begin(&array); t; t = token_array_iter_next(&array)){ 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_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_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_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, " "); if(t[0].kind == TK_Identifier && token_array_iter_peek(&array, 0)->kind == TK_Identifier) fprintf(f, " ");
token_array_iter_peek(&array, 1); token_array_iter_peek(&array, 1);
} }
arena_end_scratch(); 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); fclose(f);
} }

49
generated.c Normal file
View File

@@ -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;
}

356
new_ast.c
View File

@@ -4,11 +4,86 @@ typedef struct Decl Decl;
typedef struct Stmt Stmt; typedef struct Stmt Stmt;
typedef struct Stmt_If Stmt_If; typedef struct Stmt_If Stmt_If;
typedef struct Typespec Typespec; typedef struct Typespec Typespec;
typedef struct Typespec_Function_Arg Typespec_Function_Arg;
typedef struct Decl_Enum_Child Decl_Enum_Child; typedef struct Decl_Enum_Child Decl_Enum_Child;
typedef struct Decl_Function_Arg Decl_Function_Arg; typedef struct Decl_Function_Arg Decl_Function_Arg;
typedef struct Expr_Compound_Field Expr_Compound_Field; 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 // Expressions
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -168,11 +243,13 @@ typedef enum Decl_Kind{
DECL_SubUnion, DECL_SubUnion,
DECL_Enum, DECL_Enum,
DECL_Variable, DECL_Variable,
DECL_Const,
DECL_Typedef, DECL_Typedef,
DECL_Function, DECL_Function,
DECL_List, DECL_List,
}Decl_Kind; }Decl_Kind;
struct Decl{ struct Decl{
Decl_Kind kind; Decl_Kind kind;
Decl *next; Decl *next;
@@ -197,11 +274,11 @@ struct Decl{
Decl *last; Decl *last;
}struct_decl; }struct_decl;
struct{ struct{
Typespec *type; Typespec *typespec;
Expr *expr; Expr *expr;
}var_decl; }var_decl;
struct{ struct{
Typespec *type; Typespec *typespec;
}typedef_decl; }typedef_decl;
struct{ struct{
Decl_Function_Arg *first; Decl_Function_Arg *first;
@@ -570,7 +647,15 @@ decl_struct(Arena *p, Decl_Kind kind, Token *pos, Intern_String name){
function Decl * function Decl *
decl_typedef(Arena *p, Token *pos, Intern_String name, Typespec *type){ decl_typedef(Arena *p, Token *pos, Intern_String name, Typespec *type){
Decl *result = decl_new(p, DECL_Typedef, pos, name); 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; return result;
} }
@@ -584,7 +669,7 @@ decl_enum(Arena *p, Token *pos, Intern_String name, Typespec *typespec){
function Decl * function Decl *
decl_variable(Arena *p, Token *pos, Intern_String name, Typespec *typespec, Expr *expr){ decl_variable(Arena *p, Token *pos, Intern_String name, Typespec *typespec, Expr *expr){
Decl *result = decl_new(p, DECL_Variable, pos, name); Decl *result = decl_new(p, DECL_Variable, pos, name);
result->var_decl.type = typespec; result->var_decl.typespec = typespec;
result->var_decl.expr = expr; result->var_decl.expr = expr;
return result; return result;
} }
@@ -630,108 +715,203 @@ decl_list_push(Decl *parent, Decl *child){
SLLQueuePush(parent->list_decl.first, parent->list_decl.last, 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 // Double linked list
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
function void function void
decl_dll_list_push(Decl *l, Decl *node){ list_print(AST_Parent *decls){
if(l->list_decl.first == 0){ printf("\n");
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){
printf("next:"); 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("%d", n->kind);
} }
printf("prev:"); 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("%d", n->kind);
} }
printf("parent:"); 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); 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 function void
ast_test(){ ast_push_after(AST *in_list, AST *node){
Decl decls[16] = {0}; AST_Parent *parent = in_list->parent;
decls[0].kind = 9; assert(parent);
decls[1].kind = 1; assert(parent->first && parent->last);
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);
//list_print(decls); node->prev = in_list;
decl_list_remove(decls, decls+1); if(in_list == parent->last){
//list_print(decls); in_list->next = node;
decl_list_remove(decls, decls+2); parent->last = node;
//list_print(decls); }
decl_list_remove(decls, decls+3); else {
//list_print(decls); node->next = in_list->next;
decl_list_remove(decls, decls+4); in_list->next = node;
//list_print(decls); node->next->prev = node;
assert(decls[0].list_decl.first == 0); }
assert(decls[0].list_decl.last == 0); 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);
} }

View File

@@ -5,6 +5,8 @@ global Intern_String keyword_else;
global Intern_String keyword_size_type; global Intern_String keyword_size_type;
global Intern_String keyword_size_expr; global Intern_String keyword_size_expr;
global Intern_String keyword_const; global Intern_String keyword_const;
global Intern_String keyword_typedef;
global Intern_String keyword_return;
global Intern_String keyword_typeof; global Intern_String keyword_typeof;
global Intern_String keyword_while; global Intern_String keyword_while;
global Intern_String keyword_switch; global Intern_String keyword_switch;
@@ -31,7 +33,9 @@ init_default_keywords(Intern_Table *t){
keyword_typeof = intern_string(t, lit("typeof")); keyword_typeof = intern_string(t, lit("typeof"));
keyword_const = intern_string(t, lit("const")); keyword_const = intern_string(t, lit("const"));
keyword_while = intern_string(t, lit("while")); keyword_while = intern_string(t, lit("while"));
keyword_return = intern_string(t, lit("return"));
keyword_switch = intern_string(t, lit("switch")); keyword_switch = intern_string(t, lit("switch"));
keyword_typedef = intern_string(t, lit("typedef"));
keyword_case = intern_string(t, lit("case")); keyword_case = intern_string(t, lit("case"));
keyword_struct = intern_string(t, lit("struct")); keyword_struct = intern_string(t, lit("struct"));
keyword_enum = intern_string(t, lit("enum")); keyword_enum = intern_string(t, lit("enum"));

View File

@@ -31,7 +31,7 @@ parser_push_error(Parser *p, Token *token, char *str, ...){
// @Note(Krzosa): Print nice error message // @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 // @Note(Krzosa): Print error line
{ {
@@ -171,7 +171,6 @@ Compound literals
- { } - { }
*/ */
function Expr_Compound_Field * function Expr_Compound_Field *
parse_expr_compound_field(Parser *p){ parse_expr_compound_field(Parser *p){
Token *token = token_get(p); Token *token = token_get(p);
@@ -554,7 +553,6 @@ name::const = 4254;
// data: [24]U32; // data: [24]U32;
// } // }
// } // }
*/ */
function void function void
parse_note_list(Parser *p, Note *parent) { parse_note_list(Parser *p, Note *parent) {
@@ -602,34 +600,37 @@ parse_assign_expr(Parser *p){
} }
function Typespec * function Typespec *
parse_optional_type(Parser *p){ parse_optional_type(Parser *p, Intern_String type){
Typespec *result = 0; Typespec *result = 0;
if(token_match(p, TK_Colon)){ if(token_match(p, TK_Colon)){
result = parse_typespec(p); result = parse_typespec(p);
} }
else{ else{
result = typespec_name(p->arena, token_get(p), intern_int); result = typespec_name(p->arena, token_get(p), type);
} }
return result; return result;
} }
function Decl * function Decl *
parse_enum(Parser *p, Token *name){ 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); Decl *result = decl_enum(p->arena, name, name->intern_val, typespec);
token_expect(p, TK_OpenBrace); token_expect(p, TK_OpenBrace);
do{ do {
Note notes = parse_notes(p); Note notes = parse_notes(p);
Token *val = token_expect(p, TK_Identifier); Token *val = token_expect(p, TK_Identifier);
Expr *expr = parse_assign_expr(p); Expr *expr = parse_assign_expr(p);
decl_enum_push(p->arena, result, val, val->intern_val, expr, &notes); decl_enum_push(p->arena, result, val, val->intern_val, expr, &notes);
} while(token_match(p, TK_Comma)); if(!token_match(p, TK_Comma)){
break;
}
}while(!token_is(p, TK_CloseBrace));
token_expect(p, TK_CloseBrace); token_expect(p, TK_CloseBrace);
return result; return result;
} }
function void 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]; Token *name_stack[64];
S64 name_stack_len = 0; S64 name_stack_len = 0;
name_stack[name_stack_len++] = name; name_stack[name_stack_len++] = name;
@@ -640,6 +641,7 @@ parse_var_decl(Parser *p, Decl *parent, Token *name){
token_expect(p, TK_Semicolon); token_expect(p, TK_Semicolon);
for(S64 i = 0; i < name_stack_len; i++){ 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 *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); 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); Decl *result = decl_struct(p->arena, struct_kind, token, intern_name);
token_expect(p, TK_OpenBrace); token_expect(p, TK_OpenBrace);
do { do {
Note notes = parse_notes(p);
Token *token = token_get(p); Token *token = token_get(p);
if(token_match_keyword(p, keyword_union)){ if(token_match_keyword(p, keyword_union)){
Decl *decl = parse_struct(p, 0, DECL_SubUnion); Decl *decl = parse_struct(p, 0, DECL_SubUnion);
decl_pass_notes(decl, &notes);
decl_struct_push(result, decl); decl_struct_push(result, decl);
} }
else if(token_match_keyword(p, keyword_struct)){ else if(token_match_keyword(p, keyword_struct)){
Decl *decl = parse_struct(p, 0, DECL_SubStruct); Decl *decl = parse_struct(p, 0, DECL_SubStruct);
decl_pass_notes(decl, &notes);
decl_struct_push(result, decl); decl_struct_push(result, decl);
} }
else if(token_match(p, TK_Identifier)){ else if(token_match(p, TK_Identifier)){
if(token_is(p, TK_Colon)){ if(token_is(p, TK_Colon)){
if(token_peek_is_keyword(p, keyword_union, 1)){ 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 *decl = parse_struct(p, token, DECL_SubUnion);
decl_pass_notes(decl, &notes);
decl_struct_push(result, decl); decl_struct_push(result, decl);
} }
else if(token_peek_is_keyword(p, keyword_struct, 1)){ 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 *decl = parse_struct(p, token, DECL_SubStruct);
decl_pass_notes(decl, &notes);
decl_struct_push(result, decl); decl_struct_push(result, decl);
} }
else{ else{
parse_var_decl(p, result, token); parse_var_decl(p, result, token, &notes);
} }
} }
else{ else{
parse_var_decl(p, result, token); parse_var_decl(p, result, token, &notes);
} }
} }
else{ else{
@@ -690,9 +695,47 @@ parse_struct(Parser *p, Token *name, Decl_Kind struct_kind){
} }
function Decl * function Decl *
parse_decl(Parser *p){ parse_typedef(Parser *p, Token *name){
Decl *result = 0; 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; Token *name = 0;
Decl *result = 0;
Note note = parse_notes(p); Note note = parse_notes(p);
if((name = token_match(p, TK_Identifier))){ if((name = token_match(p, TK_Identifier))){
if(token_match(p, TK_DoubleColon)){ if(token_match(p, TK_DoubleColon)){
@@ -706,31 +749,91 @@ parse_decl(Parser *p){
else if((token = token_match_keyword(p, keyword_struct))){ else if((token = token_match_keyword(p, keyword_struct))){
result = parse_struct(p, name, DECL_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))){ else if((token = token_match_keyword(p, keyword_const))){
// Const value result = parse_const(p, name);
} }
else if((token = token_match(p, TK_OpenParen))){ else if((token = token_match(p, TK_OpenParen))){
// Function result = parse_function(p, name);
} }
else{ 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{ 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){ if(result){
decl_pass_notes(result, &note); decl_pass_notes(result, &note);
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; return result;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Test code // Test code
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
function S64 function S64
eval_expr(Expr *expr){ eval_expr(Expr *expr){
switch(expr->kind){ switch(expr->kind){
@@ -875,15 +978,27 @@ parse_test_decls(){
}; };
for(SizeU i = 0; i < buff_cap(decls); i++){ for(SizeU i = 0; i < buff_cap(decls); i++){
parser_restream(&p, decls[i], lit("Decl_Test")); parser_restream(&p, decls[i], lit("Decl_Test"));
Decl *decl = parse_decl(&p); Decl decl = parse_decls(&p);
assert(decl); assert(decl.list_decl.first);
decl_print(decl); 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 function void
parse_test(){ parse_test(){
parse_test_expr(); parse_test_expr();
parse_test_decls(); parse_test_decls();
parse_test_from_file();
} }

View File

@@ -202,19 +202,32 @@ decl_print(Decl *node){
} }
} break; } break;
case DECL_Const:
case DECL_Variable:{ case DECL_Variable:{
println("%s: ", node->name.s.str); 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); print_assign_expr(node->var_decl.expr);
if(r) printf(";");
} break; } break;
case DECL_Typedef:{ case DECL_Typedef:{
println("typedef %s ", node->name.s.str); println("typedef %s ", node->name.s.str);
typespec_print(node->typedef_decl.type); typespec_print(node->typedef_decl.typespec);
printf(";"); printf(";");
} break; } 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_Struct:
case DECL_Union :{ case DECL_Union :{

139
test.cc
View File

@@ -1,57 +1,23 @@
#if 0 Thing :: const: *U32 = 0;
CONST_VAL::const = 185210591;
new_function::(Thing:[32]U32): U32;
@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;
}
}
@test(size = 4096) @test(size = 4096)
OpenGL :: struct{ OpenGL :: struct{
glVertexAttribPointer: (GLuint, GLint, GLenum, GLboolean, GLsizei, GLvoid*); glVertexAttribPointer: (GLuint, GLint, GLenum, GLboolean, GLsizei, *GLvoid);
glBindTexture: (GLenum, GLuint); glBindTexture: (GLenum, GLuint);
glDrawArrays: (GLenum, GLint, GLsizei); glDrawArrays: (GLenum, GLint, GLsizei);
test_array: int*[10]; test_array: [10]*int;
thing : Things*; thing : *Things;
thing_cap: S64; thing_cap: S64;
thing_len: S64; thing_len: S64;
} }
OS_Memory::struct{ OS_Memory::struct{
data: void*; data: *void;
commit: SizeU; commit: SizeU;
reserve: SizeU; reserve: SizeU;
} }
@@ -63,10 +29,11 @@ Arena::struct{
} }
String::struct{ String::struct{
str: U8*; str: *U8;
len: S64; len: S64;
} }
Intern_String::typedef String; Intern_String::typedef = String;
//CONST_VALUE::const = 121591;
@stringify @stringify
@prefix="TK_" @prefix="TK_"
@@ -147,12 +114,12 @@ Token::struct{
} }
file:String; file:String;
line:S64; line:S64;
line_begin:U8*; line_begin:*U8;
} }
Lex_Stream::struct{ Lex_Stream::struct{
stream: U8*; stream: *U8;
line_begin: U8*; line_begin: *U8;
filename: String; filename: String;
line: S64; line: S64;
} }
@@ -172,36 +139,36 @@ Expr_Kind::enum{
Expr:: struct{ Expr:: struct{
kind: Expr_Kind; kind: Expr_Kind;
token: Token*; token: *Token;
next : Expr*; next : *Expr;
union{ union{
cast_val: struct{ cast_val: struct{
type: AST_Node*; type: *AST_Node;
expr: Expr*; expr: *Expr;
} }
list: struct{ list: struct{
first: Expr *; first: *Expr;
last: Expr *; last: *Expr;
} }
call: struct{ call: struct{
atom: Expr *; atom: *Expr;
list: Expr *; list: *Expr;
} }
index: struct{ index: struct{
atom: Expr *; atom: *Expr;
index: Expr *; index: *Expr;
} }
unary: struct{ unary: struct{
expr: Expr* ; expr: *Expr ;
} }
binary: struct{ binary: struct{
left: Expr* ; left: *Expr ;
right: Expr* ; right: *Expr ;
} }
ternary: struct{ ternary: struct{
cond: Expr* ; cond: *Expr ;
on_true: Expr*; on_true: *Expr;
on_false: Expr*; on_false: *Expr;
} }
} }
} }
@@ -225,36 +192,36 @@ AST_Kind::enum{
AST_Node::struct{ AST_Node::struct{
kind: AST_Kind; kind: AST_Kind;
pos : Token*; pos : *Token;
name: Intern_String; name: Intern_String;
next: AST_Node*; next: *AST_Node;
next_scope: AST_Node*; next_scope: *AST_Node;
first_note: AST_Node*; first_note: *AST_Node;
last_note: AST_Node*; last_note: *AST_Node;
first_child: AST_Node*; first_child: *AST_Node;
last_child: AST_Node*; last_child: *AST_Node;
union{ union{
base_type_size: SizeU; base_type_size: SizeU;
pointer: AST_Node*; pointer: *AST_Node;
typedef_type: AST_Node*; typedef_type: *AST_Node;
variable_type: AST_Node*; variable_type: *AST_Node;
func_return_type: AST_Node*; func_return_type: *AST_Node;
} }
} }
Parser_Error :: struct{ Parser_Error :: struct{
next: Parser_Error*; next: *Parser_Error;
message: String; message: String;
token : Token *; token : *Token;
} }
Scope :: struct{ Scope :: struct{
next : Scope*; next : *Scope;
first: AST_Node*; first: *AST_Node;
last : AST_Node*; last : *AST_Node;
} }
@@ -263,21 +230,21 @@ Parser :: struct{
intern_table_arena: Arena; intern_table_arena: Arena;
symbol_table_arena: Arena; symbol_table_arena: Arena;
scope_free_list: Scope *; scope_free_list: Scope;
scope_stack: Scope *; scope_stack: Scope;
global_scope: Scope *; global_scope: Scope;
symbols_inserted: S64; symbols_inserted: S64;
symbols_count: S64; symbols_count: S64;
symbols: AST_Node *; symbols: AST_Node;
interns: Intern_String *; interns: Intern_String;
interns_in_bytes: S64; interns_in_bytes: S64;
interns_inserted: S64; interns_inserted: S64;
interns_count: S64; interns_count: S64;
first_keyword: U8 *; first_keyword: U8;
last_keyword: U8 *; last_keyword: U8;
//@map(type="sparse") symbols: AST_Node; //@map(type="sparse") symbols: AST_Node;
@@ -305,5 +272,3 @@ struct_type_lower_var_name_lower_push(struct_type *parent, var_type *child){
} }
} }
*/ */
#endif

View File

@@ -71,6 +71,8 @@ token_array_iter_next(Token_Array *array){
function Token * function Token *
token_array_iter_peek(Token_Array *array, S64 i){ 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_len = array->iter_len;
S64 save_block = array->iter_block; S64 save_block = array->iter_block;
Token_Bucket *save_bucket = array->iter_bucket; Token_Bucket *save_bucket = array->iter_bucket;