Almost works

This commit is contained in:
Krzosa Karol
2022-05-07 20:56:03 +02:00
parent 042127239e
commit feae74b0b9
5 changed files with 477 additions and 595 deletions

2
ast.c
View File

@@ -1,3 +1,4 @@
/*
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Decls // Decls
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -575,3 +576,4 @@ decl_deep_copy(Arena *arena){
} }
*/

View File

@@ -1,225 +0,0 @@
typedef struct Typespec Typespec;
typedef struct Note Note;
typedef struct Decl_Function_Arg Decl_Function_Arg;
typedef struct Decl_Enum_Child Decl_Enum_Child;
typedef struct Decl Decl;
typedef struct Stmt_If Stmt_If;
typedef struct Stmt Stmt;
typedef struct Pointer Pointer;
typedef struct Pointer_Bucket Pointer_Bucket;
typedef struct Pointer_Array Pointer_Array;
typedef enum Typespec_Kind{
TS_None,
TS_Name,
TS_Pointer,
TS_Array,
TS_Function,
}Typespec_Kind;
struct Typespec{
Typespec_Kind kind;
Typespec (*next);
Token (*pos);
union{
Intern_String name;
Typespec (*base);
struct{
Typespec (*first);
Typespec (*last);
Typespec (*ret);
}function_spec;
struct{
Typespec (*base);
Expr (*size);
}array_spec;
};
};
struct Note{
Token (*pos);
Intern_String name;
Expr (*expr);
Note (*next);
Note (*first);
Note (*last);
};
typedef enum Decl_Kind{
DECL_None,
DECL_Struct,
DECL_Union,
DECL_Enum,
DECL_Variable,
DECL_Typedef,
DECL_Function,
DECL_List,
}Decl_Kind;
typedef enum Decl_Struct_Kind{
STRUCT_Nested,
STRUCT_Base,
}Decl_Struct_Kind;
struct Decl_Function_Arg{
Decl_Function_Arg (*next);
Intern_String name;
Token (*pos);
Typespec (*typespec);
};
struct Decl_Enum_Child{
Decl_Enum_Child (*next);
Intern_String name;
Token (*pos);
Expr (*expr);
Note (*first_note);
Note (*last_note);
};
struct Decl{
Decl_Kind kind;
Decl (*next);
Intern_String name;
Token (*pos);
Note (*first_note);
Note (*last_note);
union{
struct{
Decl_Enum_Child (*first);
Decl_Enum_Child (*last);
Typespec (*typespec);
}enum_decl;
struct{
Decl (*first);
Decl (*last);
Decl_Struct_Kind kind;
}struct_decl;
struct{
Typespec (*type);
Expr (*expr);
}variable_decl;
struct{
Typespec (*type);
}typedef_decl;
struct{
Decl_Function_Arg (*first);
Decl_Function_Arg (*last);
Typespec (*ret);
Stmt (*body);
}function_decl;
struct{
Decl (*first);
Decl (*last);
}list;
};
};
typedef enum Stmt_Kind{
STMT_None,
STMT_Decl,
STMT_Expr,
STMT_List,
STMT_Return,
STMT_If,
STMT_For,
}Stmt_Kind;
struct Stmt_If{
Stmt_If (*next);
Expr (*cond);
Stmt (*body);
};
struct Stmt{
Stmt_Kind kind;
Stmt (*next);
Token (*pos);
union{
Stmt_If stmt_if;
Decl (*decl);
Expr (*expr);
struct{
Stmt (*first);
Stmt (*last);
}list;
struct{
Expr (*expr);
}ret;
};
};
typedef enum Pointer_Kind{
PK_None,
PK_Typespec,
PK_Expr,
PK_Decl,
PK_Stmt,
PK_Enum_Child,
PK_Func_Arg,
PK_Intern_String,
}Pointer_Kind;
struct Pointer{
Pointer_Kind kind;
union{
Typespec (*typespec);
Decl (*decl);
Expr (*expr);
Stmt (*stmt);
Decl_Function_Arg (*func_arg);
Decl_Enum_Child (*enum_child);
Intern_String (*string);
};
};
struct Pointer_Bucket{
Pointer_Bucket (*next);
Pointer (data[4096]);
};
struct Pointer_Array{
Pointer_Bucket first;
Pointer_Bucket (*last);
S64 len;
S64 block;
Arena (*arena);
Pointer_Bucket (*iter_bucket);
S64 iter_len;
S64 iter_block;
};
typedef enum Gather_Flag{
GATHER_None = 0,
GATHER_Typespec = 1,
GATHER_Expr = 2,
GATHER_Decl = 4,
GATHER_Stmt = 8,
GATHER_Enum_Child = 16,
GATHER_Func_Arg = 32,
}Gather_Flag;
typedef enum Traversal_Flag{
TRAVERS_None,
TRAVERS_Typespec = 1,
TRAVERS_Expr = 2,
TRAVERS_Stmt = 8,
TRAVERS_All = ((TRAVERS_Typespec|TRAVERS_Expr)|TRAVERS_Stmt),
}Traversal_Flag;

652
new_ast.c
View File

@@ -11,79 +11,6 @@ typedef struct Expr_Compound_Field Expr_Compound_Field;
typedef struct AST AST; typedef struct AST AST;
typedef struct AST_Parent AST_Parent; 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
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -232,6 +159,116 @@ struct Typespec{
}; };
}; };
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
typedef enum AST_Kind{
AST_None,
AST_Decl_Enum_Child,
AST_Decl_Var,
AST_Decl_Const,
AST_Decl_Typedef,
AST_Decl_Func_Arg,
AST_Decl_Variable,
AST_Decl_Struct, // //
AST_Decl_SubStruct,
AST_Decl_SubUnion,
AST_Decl_Union, //
AST_Decl_Enum,
AST_Decl_Func,
AST_Program,
AST_Note,
AST_Note_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_FirstStruct = AST_Decl_Struct,
AST_LastStruct = AST_Decl_Union,
}AST_Kind;
#define AST_FIELDS AST *next, *prev; AST_Parent *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_FIELDS; AST_PARENT_FIELDS; }; AST_Parent child; }
struct AST{
AST_FIELDS;
};
typedef struct AST_Parent{
AST_UNION;
AST_PARENT_FIELDS;
} AST_Parent;
typedef AST_Parent Note_List;
typedef AST_Parent Program;
typedef struct Note{
AST_PARENT_UNION;
Intern_String name;
Expr *expr;
}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 Decl_Enum_Child{
AST_UNION;
Intern_String name;
Expr *expr;
}Decl_Enum_Child;
typedef struct Decl_Enum{
AST_PARENT_UNION;
Typespec *typespec;
Intern_String name;
}Decl_Enum;
typedef struct Decl_Func{
AST_PARENT_UNION;
Intern_String name;
Typespec *ret;
AST *body;
}Decl_Func;
typedef struct Decl_Typedef{
AST_PARENT_UNION;
Typespec *typespec;
Intern_String name;
}Decl_Typedef;
typedef struct Decl_Var{
AST_PARENT_UNION;
Typespec *typespec;
Intern_String name;
Expr *expr;
}Decl_Var;
typedef struct Decl_Const{
AST_PARENT_UNION;
Typespec *typespec;
Intern_String name;
Expr *expr;
}Decl_Const;
/*
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Declarations // Declarations
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -292,7 +329,9 @@ struct Decl{
}list_decl; }list_decl;
}; };
}; };
*/
/*
struct Note{ struct Note{
Token *pos; Token *pos;
Intern_String name; Intern_String name;
@@ -317,7 +356,9 @@ struct Decl_Enum_Child{
Note *first_note; Note *first_note;
Note *last_note; Note *last_note;
}; };
*/
/*
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Statements // Statements
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -355,6 +396,7 @@ struct Stmt{
}; };
}; };
*/
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Expression constructors // Expression constructors
@@ -576,215 +618,10 @@ function void
typespec_function_push(Typespec *func, Typespec *arg){ typespec_function_push(Typespec *func, Typespec *arg){
SLLQueuePush(func->func.first, func->func.last, arg); SLLQueuePush(func->func.first, func->func.last, arg);
} }
//-----------------------------------------------------------------------------
// Notes
//-----------------------------------------------------------------------------
function void
decl_pass_notes(Decl *a, Note *b){
a->first_note = b->first;
a->last_note = b->last;
}
function Note *
note_push_new(Arena *p, Note *parent, Token *pos, Intern_String name, Expr *expr){
Note *result = arena_push_struct(p, Note);
result->pos = pos;
result->name = name;
result->expr = expr;
SLLQueuePush(parent->first, parent->last, result);
return result;
}
function Note *
find_note(Note *first, String string){
for(Note *n = first; n; n=n->next){
if(string_compare(string, n->name.s)){
return n;
}
}
return 0;
}
function String
find_string_note(Note *first, String string, String default_string){
Note *note = find_note(first, string);
if(note){
return note->expr->token->intern_val.s;
}
return default_string;
}
function Note *
decl_find_note(Decl *decl, String string){
return find_note(decl->first_note, string);
}
function String
decl_find_string_note(Decl *decl, String string, String default_string){
return find_string_note(decl->first_note, string, default_string);
}
//-----------------------------------------------------------------------------
// Declarations
//-----------------------------------------------------------------------------
function Decl *
decl_new(Arena *p, Decl_Kind kind, Token *pos, Intern_String name){
Decl *result = arena_push_struct(p, Decl);
result->kind = kind;
result->pos = pos;
result->name = name;
return result;
}
function Decl *
decl_struct(Arena *p, Decl_Kind kind, Token *pos, Intern_String name){
assert(kind == DECL_Struct || kind == DECL_Union || kind == DECL_SubUnion || kind == DECL_SubStruct);
Decl *result = decl_new(p, kind, pos, name);
return result;
}
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.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;
}
function Decl *
decl_enum(Arena *p, Token *pos, Intern_String name, Typespec *typespec){
Decl *result = decl_new(p, DECL_Enum, pos, name);
result->enum_decl.typespec = typespec;
return result;
}
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.typespec = typespec;
result->var_decl.expr = expr;
return result;
}
function Decl *
decl_function(Arena *p, Token *pos, Intern_String name, Typespec *ret){
Decl *result = decl_new(p, DECL_Function, pos, name);
result->func_decl.ret = ret;
return result;
}
function void
decl_func_push(Arena *p, Decl *parent, Token *pos, Intern_String name, Typespec *type){
assert(parent->kind == DECL_Function);
Decl_Function_Arg *result = arena_push_struct(p, Decl_Function_Arg);
result->name = name;
result->typespec = type;
result->pos = pos;
SLLQueuePush(parent->func_decl.first, parent->func_decl.last, result);
}
function void
decl_enum_push(Arena *p, Decl *parent, Token *pos, Intern_String name, Expr *expr, Note *notes){
assert(parent->kind == DECL_Enum);
Decl_Enum_Child *child = arena_push_struct(p, Decl_Enum_Child);
child->pos = pos;
child->name = name;
child->expr = expr;
child->first_note = notes->first;
child->last_note = notes->last;
SLLQueuePush(parent->enum_decl.first, parent->enum_decl.last, child);
}
function void
decl_struct_push(Decl *parent, Decl *child){
assert(parent->kind == DECL_Struct || parent->kind == DECL_Union || parent->kind == DECL_SubUnion || parent->kind == DECL_SubStruct);
SLLQueuePush(parent->struct_decl.first, parent->struct_decl.last, child);
}
function void
decl_list_push(Decl *parent, Decl *child){
assert(parent->kind == DECL_List);
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
list_print(AST_Parent *decls){
printf("\n");
printf("next:");
for(AST *n = decls->first; n; n=n->next){
printf("%d", n->kind);
}
printf("prev:");
for(AST *n = decls->last; n; n=n->prev){
printf("%d", n->kind);
}
printf("parent:");
for(AST *n = decls->first; n; n=n->next){
printf("%d", n->parent->kind);
}
}
function void function void
ast_remove(AST *node){ ast_remove(AST *node){
@@ -881,6 +718,265 @@ ast_push_before(AST *in_list, AST *node){
node->parent = parent; node->parent = parent;
} }
//-----------------------------------------------------------------------------
// Notes
//-----------------------------------------------------------------------------
/*
function Note *
find_note(Note *first, String string){
for(Note *n = first; n; n=n->next){
if(string_compare(string, n->name.s)){
return n;
}
}
return 0;
}
*/
/*
function String
find_string_note(Note *first, String string, String default_string){
Note *note = find_note(first, string);
if(note){
return note->expr->token->intern_val.s;
}
return default_string;
}
function Note *
decl_find_note(Decl *decl, String string){
return find_note(decl->first_note, string);
}
function String
decl_find_string_note(Decl *decl, String string, String default_string){
return find_string_note(decl->first_note, string, default_string);
}
*/
//-----------------------------------------------------------------------------
// Declarations
//-----------------------------------------------------------------------------
#define ast_parent_new(arena, T, pos) (T *)ast__parent_new(arena, sizeof(T), AST_##T, pos)
#define ast_new(arena, T, pos) (T *)ast__new(arena, sizeof(T), AST_##T, pos)
function B32
ast_kind_is_parent(AST_Kind kind){
B32 result = kind >= AST_FirstParent && kind <= AST_LastParent;
return result;
}
function B32
ast_kind_is_struct(AST_Kind kind){
B32 result = kind >= AST_FirstStruct && kind <= AST_LastStruct;
return result;
}
function AST *
ast__new(Arena *p, SizeU size, AST_Kind kind, Token *pos){
assert(!ast_kind_is_parent(kind));
AST *result = arena_push_size(p, size);
result->pos = pos;
result->kind = kind;
return result;
}
function AST_Parent *
ast__parent_new(Arena *p, SizeU size, AST_Kind kind, Token *pos){
assert(ast_kind_is_parent(kind));
AST_Parent *result = arena_push_size(p, size);
result->pos = pos;
result->kind = kind;
return result;
}
function Note *
note_push_new(Arena *p, AST_Parent *parent, Token *pos, Intern_String name, Expr *expr){
Note *result = ast_parent_new(p, Note, pos);
result->name = name;
result->expr = expr;
ast_push_last(parent, (AST *)result);
return result;
}
function Note_List *
note_list(Arena *p, Token *pos){
Note_List *result = ast_parent_new(p, Note_List, pos);
return result;
}
function Decl_Struct *
decl_struct(Arena *p, AST_Kind kind, Token *pos, Intern_String name){
assert(ast_kind_is_struct(kind));
Decl_Struct *result = ast_parent_new(p, Decl_Struct, pos);
result->name = name;
return result;
}
function Decl_Typedef *
decl_typedef(Arena *p, Token *pos, Intern_String name, Typespec *type){
Decl_Typedef *result = ast_new(p, Decl_Typedef, pos);
result->typespec = type;
result->name = name;
return result;
}
function Decl_Const *
decl_const(Arena *arena, Token *pos, Intern_String name, Expr *expr, Typespec *typespec){
Decl_Const *result = ast_new(arena, Decl_Const, pos);
result->expr = expr;
result->name = name;
result->typespec = typespec;
return result;
}
function Decl_Enum *
decl_enum(Arena *p, Token *pos, Intern_String name, Typespec *typespec){
Decl_Enum *result = ast_parent_new(p, Decl_Enum, pos);
result->typespec = typespec;
return result;
}
function Decl_Var *
decl_variable(Arena *arena, Token *pos, Intern_String name, Expr *expr, Typespec *typespec, Note_List *notes){
Decl_Var *result = ast_new(arena, Decl_Var, pos);
result->expr = expr;
result->name = name;
result->typespec = typespec;
result->notes = notes;
return result;
}
function Decl_Func *
decl_function(Arena *p, Token *pos, Intern_String name, Typespec *ret){
Decl_Func *result = ast_parent_new(p, Decl_Func, pos);
result->ret = ret;
return result;
}
function Decl_Func_Arg *
decl_func_arg(Arena *arena, Token *pos, Intern_String name, Typespec *type){
Decl_Func_Arg *result = ast_new(arena, Decl_Func_Arg, pos);
result->name = name;
result->typespec = type;
return result;
}
function Decl_Enum_Child *
decl_enum_child(Arena *p, Token *pos, Intern_String name, Expr *expr, Note_List *note){
Decl_Enum_Child *result = ast_new(p, Decl_Enum_Child, pos);
result->name = name;
result->expr = expr;
result->notes = (AST_Parent *)note;
return result;
}
function void
decl_func_push(Arena *p, Decl_Func *parent, Token *pos, Intern_String name, Typespec *type){
assert(parent->kind == AST_Decl_Func);
Decl_Func_Arg *func_arg = decl_func_arg(p, pos, name, type);
ast_push_last((AST_Parent *)parent, (AST *)func_arg);
}
function void
decl_enum_push(Arena *p, Decl_Enum *parent, Token *pos, Intern_String name, Expr *expr, Note_List *notes){
assert(parent->kind == AST_Decl_Enum);
Decl_Enum_Child *child = decl_enum_child(p, pos, name, expr, notes);
ast_push_last((AST_Parent *)parent, (AST *)child);
}
function void
decl_struct_push(Decl_Struct *parent, AST *child){
assert(ast_kind_is_struct(parent->kind));
ast_push_last((AST_Parent *)parent, child);
}
function Program *
ast_program(Arena *arena, Token *token){
Program *result = ast_parent_new(arena, Program, token);
return result;
}
function void
ast_program_push(AST_Parent *parent, AST *child){
assert(parent->kind == AST_Program);
ast_push_last((AST_Parent *)parent, 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);
}
*/
//-----------------------------------------------------------------------------
// Test stuff
//-----------------------------------------------------------------------------
function void
list_print(AST_Parent *decls){
printf("\n");
printf("next:");
for(AST *n = decls->first; n; n=n->next){
printf("%d", n->kind);
}
printf("prev:");
for(AST *n = decls->last; n; n=n->prev){
printf("%d", n->kind);
}
printf("parent:");
for(AST *n = decls->first; n; n=n->next){
printf("%d", n->parent->kind);
}
}
function void function void
ast_test(){ ast_test(){

View File

@@ -555,7 +555,7 @@ name::const = 4254;
// } // }
*/ */
function void function void
parse_note_list(Parser *p, Note *parent) { parse_note_list(Parser *p, AST_Parent *parent) {
if(token_match(p, TK_OpenParen)) { if(token_match(p, TK_OpenParen)) {
if(token_match(p, TK_CloseParen)){ if(token_match(p, TK_CloseParen)){
return; return;
@@ -563,7 +563,7 @@ parse_note_list(Parser *p, Note *parent) {
do { do {
Token *name = token_expect(p, TK_Identifier); Token *name = token_expect(p, TK_Identifier);
Note *current = note_push_new(p->arena, parent, name, name->intern_val, 0); Note *current = note_push_new(p->arena, parent, name, name->intern_val, 0);
parse_note_list(p, current); parse_note_list(p, (AST_Parent *)current);
if(token_match(p, TK_Assign)) { if(token_match(p, TK_Assign)) {
current->expr = parse_expr(p); current->expr = parse_expr(p);
} }
@@ -573,11 +573,11 @@ parse_note_list(Parser *p, Note *parent) {
} }
function void function void
parse__notes(Parser *p, Note *result) { parse__notes(Parser *p, AST_Parent *result) {
while(token_match(p, TK_At)) { while(token_match(p, TK_At)) {
Token *name = token_expect(p, TK_Identifier); Token *name = token_expect(p, TK_Identifier);
Note *current = note_push_new(p->arena, result, name, name->intern_val, 0); Note *current = note_push_new(p->arena, result, name, name->intern_val, 0);
parse_note_list(p, current); parse_note_list(p, (AST_Parent *)current);
if(token_match(p, TK_Assign)) { if(token_match(p, TK_Assign)) {
current->expr = parse_expr(p); current->expr = parse_expr(p);
} }
@@ -585,10 +585,10 @@ parse__notes(Parser *p, Note *result) {
} }
} }
function Note function Note_List *
parse_notes(Parser *p){ parse_notes(Parser *p){
Note result = {0}; Note_List *result = note_list(p->arena, token_get(p));
parse__notes(p, &result); parse__notes(p, result);
return result; return result;
} }
@@ -611,16 +611,16 @@ parse_optional_type(Parser *p, Intern_String type){
return result; return result;
} }
function Decl * function Decl_Enum *
parse_enum(Parser *p, Token *name){ parse_enum(Parser *p, Token *name){
Typespec *typespec = parse_optional_type(p, intern_int); Typespec *typespec = parse_optional_type(p, intern_int);
Decl *result = decl_enum(p->arena, name, name->intern_val, typespec); Decl_Enum *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_List *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);
if(!token_match(p, TK_Comma)){ if(!token_match(p, TK_Comma)){
break; break;
} }
@@ -630,7 +630,7 @@ parse_enum(Parser *p, Token *name){
} }
function void function void
parse_var_decl(Parser *p, Decl *parent, Token *name, Note *notes){ parse_var_decl(Parser *p, Decl_Struct *parent, Token *name, Note_List *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,51 +640,50 @@ parse_var_decl(Parser *p, Decl *parent, Token *name, Note *notes){
Typespec *typespec = parse_typespec(p); Typespec *typespec = parse_typespec(p);
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_Var *decl = decl_variable(p->arena, name_stack[i], name_stack[i]->intern_val, 0, typespec, notes);
decl_pass_notes(decl, notes); decl_struct_push(parent, (AST *)decl);
decl_struct_push(parent, decl);
} }
} }
function Decl * function Decl_Struct *
parse_struct(Parser *p, Token *name, Decl_Kind struct_kind){ parse_struct(Parser *p, Token *name, AST_Kind struct_kind){
Intern_String intern_name = name ? name->intern_val : (Intern_String){0}; Intern_String intern_name = name ? name->intern_val : (Intern_String){0};
Token *token = name ? name : token_get(p); Token *token = name ? name : token_get(p);
Decl *result = decl_struct(p->arena, struct_kind, token, intern_name); Decl_Struct *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); Note_List *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_Struct *decl = parse_struct(p, 0, AST_Decl_SubUnion);
decl_pass_notes(decl, &notes); decl->notes = notes;
decl_struct_push(result, decl); decl_struct_push(result, (AST *)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_Struct *decl = parse_struct(p, 0, AST_Decl_SubStruct);
decl_pass_notes(decl, &notes); decl->notes = notes;
decl_struct_push(result, decl); decl_struct_push(result, (AST *)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_Struct *decl = parse_struct(p, token, AST_Decl_SubUnion);
decl_pass_notes(decl, &notes); decl->notes = notes;
decl_struct_push(result, decl); decl_struct_push(result, (AST *)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_Struct *decl = parse_struct(p, token, AST_Decl_SubStruct);
decl_pass_notes(decl, &notes); decl->notes = notes;
decl_struct_push(result, decl); decl_struct_push(result, (AST *)decl);
} }
else{ else{
parse_var_decl(p, result, token, &notes); parse_var_decl(p, result, token, notes);
} }
} }
else{ else{
parse_var_decl(p, result, token, &notes); parse_var_decl(p, result, token, notes);
} }
} }
else{ else{
@@ -694,16 +693,16 @@ parse_struct(Parser *p, Token *name, Decl_Kind struct_kind){
return result; return result;
} }
function Decl * function Decl_Typedef *
parse_typedef(Parser *p, Token *name){ parse_typedef(Parser *p, Token *name){
token_expect(p, TK_Assign); token_expect(p, TK_Assign);
Typespec *typespec = parse_typespec(p); Typespec *typespec = parse_typespec(p);
token_expect(p, TK_Semicolon); token_expect(p, TK_Semicolon);
Decl *result = decl_typedef(p->arena, name, name->intern_val, typespec); Decl_Typedef *result = decl_typedef(p->arena, name, name->intern_val, typespec);
return result; return result;
} }
function Decl * function Decl_Const *
parse_const(Parser *p, Token *name){ parse_const(Parser *p, Token *name){
Typespec *typespec = 0; Typespec *typespec = 0;
if(token_match(p, TK_Colon)) if(token_match(p, TK_Colon))
@@ -711,13 +710,13 @@ parse_const(Parser *p, Token *name){
token_expect(p, TK_Assign); token_expect(p, TK_Assign);
Expr *expr = parse_expr(p); Expr *expr = parse_expr(p);
token_expect(p, TK_Semicolon); token_expect(p, TK_Semicolon);
Decl *result = decl_const(p->arena, name, name->intern_val, expr, typespec); Decl_Const *result = decl_const(p->arena, name, name->intern_val, expr, typespec);
return result; return result;
} }
function Decl * function Decl_Func *
parse_function(Parser *p, Token *name){ parse_function(Parser *p, Token *name){
Decl *result = decl_function(p->arena, name, name->intern_val, 0); Decl_Func *result = decl_function(p->arena, name, name->intern_val, 0);
if(!token_is(p, TK_CloseParen)){ if(!token_is(p, TK_CloseParen)){
do{ do{
name = token_expect(p, TK_Identifier); name = token_expect(p, TK_Identifier);
@@ -727,36 +726,36 @@ parse_function(Parser *p, Token *name){
} while(token_match(p, TK_Comma)); } while(token_match(p, TK_Comma));
} }
token_expect(p, TK_CloseParen); token_expect(p, TK_CloseParen);
result->func_decl.ret = parse_optional_type(p, intern_void); result->ret = parse_optional_type(p, intern_void);
token_expect(p, TK_Semicolon); token_expect(p, TK_Semicolon);
return result; return result;
} }
function B32 function B32
parse_decl(Parser *p, Decl *parent){ parse_decl(Parser *p, AST_Parent *parent){
Token *name = 0; Token *name = 0;
Decl *result = 0; AST *result = 0;
Note note = parse_notes(p); Note_List *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)){
Token *token = 0; Token *token = 0;
if((token = token_match_keyword(p, keyword_enum))){ if((token = token_match_keyword(p, keyword_enum))){
result = parse_enum(p, name); result = (AST *)parse_enum(p, name);
} }
else if((token = token_match_keyword(p, keyword_union))){ else if((token = token_match_keyword(p, keyword_union))){
result = parse_struct(p, name, DECL_Union); result = (AST *)parse_struct(p, name, AST_Decl_Union);
} }
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 = (AST *)parse_struct(p, name, AST_Decl_Struct);
} }
else if((token = token_match_keyword(p, keyword_typedef))){ else if((token = token_match_keyword(p, keyword_typedef))){
result = parse_typedef(p, name); result = (AST *)parse_typedef(p, name);
} }
else if((token = token_match_keyword(p, keyword_const))){ else if((token = token_match_keyword(p, keyword_const))){
result = parse_const(p, name); result = (AST *)parse_const(p, name);
} }
else if((token = token_match(p, TK_OpenParen))){ else if((token = token_match(p, TK_OpenParen))){
result = parse_function(p, name); result = (AST *)parse_function(p, name);
} }
else{ else{
token = token_get(p); token = token_get(p);
@@ -771,18 +770,18 @@ parse_decl(Parser *p, Decl *parent){
} }
if(result){ if(result){
decl_pass_notes(result, &note); result->notes = note;
decl_list_push(parent, result); ast_push_last(parent, result);
return true; return true;
} }
return false; return false;
} }
function Decl function Program *
parse_decls(Parser *p){ parse_decls(Parser *p){
Decl decl_list = {.kind=DECL_List}; Program *decl_list = ast_program(p->arena, token_get(p));
while(!token_is(p, TK_End)){ while(!token_is(p, TK_End)){
B32 success = parse_decl(p, &decl_list); B32 success = parse_decl(p, decl_list);
if(!success){ if(!success){
parser_push_error(p, token_get(p), "Failed to parse decls, unexpected token!"); parser_push_error(p, token_get(p), "Failed to parse decls, unexpected token!");
} }
@@ -806,10 +805,10 @@ stmt =
*/ */
function Stmt * function AST_Parent *
parse_stmt(Parser *p){ parse_stmt(Parser *p){
Note notes = parse_notes(p); Note_List *notes = parse_notes(p);
Stmt *result = 0; AST_Parent *result = 0;
if(token_match_keyword(p, keyword_if)){ if(token_match_keyword(p, keyword_if)){
} }
@@ -978,9 +977,9 @@ 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_decls(&p); Program *decl = parse_decls(&p);
assert(decl.list_decl.first); assert(decl->first);
decl_print(decl.list_decl.first); ast_print((AST *)decl);
} }
arena_end_scratch(); arena_end_scratch();
} }
@@ -991,8 +990,8 @@ parse_test_from_file(){
Arena *scratch = arena_begin_scratch(); Arena *scratch = arena_begin_scratch();
String file = os_read_file(scratch, FILENAME); String file = os_read_file(scratch, FILENAME);
Parser p = parser_make_stream(scratch, file, FILENAME); Parser p = parser_make_stream(scratch, file, FILENAME);
Decl d = parse_decls(&p); Program *d = parse_decls(&p);
decl_print(&d); ast_print((AST *)d);
arena_end_scratch(); arena_end_scratch();
} }

View File

@@ -5,6 +5,11 @@ global S64 indent;
#define println(...) do{ printf("\n"); print_indent(); printf(__VA_ARGS__); }while(0) #define println(...) do{ printf("\n"); print_indent(); printf(__VA_ARGS__); }while(0)
#define AST_CAST(item, T) T *item = (T *)item; assert(item->kind == AST_##Kind
#define AST_Iter(parent, name, T) for(T *name = (T *)(parent)->first; name; name=(T *)name->next) // , assert(name->kind == AST_##type
function void function void
print_indent(){ print_indent(){
for(S64 i = 0; i < indent*2; i++) for(S64 i = 0; i < indent*2; i++)
@@ -190,76 +195,81 @@ print_assign_expr(Expr *expr){
} }
function void function void
decl_print(Decl *node){ ast_print(AST *in){
//print_notes(p, node->first_note); //print_notes(p, node->first_note);
switch(node->kind) { switch(in->kind) {
case AST_Program: {
case DECL_List: { AST_Parent *node = (AST_Parent *)in;
for(Decl *n = node->list_decl.first; n; n=n->next){ for(AST *n = node->first; n; n=n->next){
decl_print(n); ast_print(n);
printf("\n"); printf("\n");
} }
} break; } break;
case DECL_Const: case AST_Decl_Const:
case DECL_Variable:{ case AST_Decl_Var:{
Decl_Var *node = (Decl_Var *)in;
println("%s: ", node->name.s.str); println("%s: ", node->name.s.str);
if(node->var_decl.typespec) typespec_print(node->var_decl.typespec); if(node->typespec) typespec_print(node->typespec);
print_assign_expr(node->var_decl.expr); print_assign_expr(node->expr);
} break; } break;
case DECL_Typedef:{ case AST_Decl_Typedef:{
Decl_Typedef *node = (Decl_Typedef *)in;
println("typedef %s ", node->name.s.str); println("typedef %s ", node->name.s.str);
typespec_print(node->typedef_decl.typespec); typespec_print(node->typespec);
printf(";"); printf(";");
} break; } break;
case DECL_Function:{ case AST_Decl_Func:{
Decl_Func *node = (Decl_Func *)in;
println(""); println("");
typespec_print(node->func_decl.ret); typespec_print(node->ret);
printf(" %s", node->name.s.str); printf(" %s", node->name.s.str);
printf("("); printf("(");
for(Decl_Function_Arg *arg = node->func_decl.first; arg; arg=arg->next){ AST_Iter(node, arg, Decl_Func_Arg){
printf("%s: ", arg->name.s.str); printf("%s: ", arg->name.s.str);
typespec_print(arg->typespec); typespec_print(arg->typespec);
if(arg != node->func_decl.last) if((AST *)arg != node->last)
printf(", "); printf(", ");
} }
printf(");"); printf(");");
} break; } break;
case DECL_Struct: case AST_Decl_Struct:
case DECL_Union :{ case AST_Decl_Union :{
const char *struct_name = node->kind==DECL_Struct ? "struct" : "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:""); println("%s %s{", struct_name, node->name.s.str?(char*)node->name.s.str:"");
indent++; indent++;
for(Decl *n = node->struct_decl.first; n; n=n->next){ for(AST *n = node->first; n; n=n->next){
decl_print(n); ast_print(n);
} }
indent--; indent--;
println("};"); println("};");
} break; } break;
case DECL_SubStruct: case AST_Decl_SubStruct:
case DECL_SubUnion :{ case AST_Decl_SubUnion :{
const char *struct_name = node->kind==DECL_SubStruct ? "struct" : "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:""); println("%s %s{", struct_name, node->name.s.str?(char*)node->name.s.str:"");
indent++; indent++;
for(Decl *n = node->struct_decl.first; n; n=n->next){ for(AST *n = node->first; n; n=n->next){
decl_print(n); ast_print(n);
} }
indent--; indent--;
println("};"); println("};");
} break; } break;
case AST_Decl_Enum:{
case DECL_Enum:{ Decl_Enum *node = (Decl_Enum *)in;
println("enum %s : ", node->name.s.str); println("enum %s : ", node->name.s.str);
typespec_print(node->enum_decl.typespec); typespec_print(node->typespec);
printf("{"); printf("{");
indent++; indent++;
for(Decl_Enum_Child *n = node->enum_decl.first; n; n=n->next){ AST_Iter(node, n, Decl_Enum_Child){
//print_notes(p, n->first_note); //print_notes(p, n->first_note);
println("%s", n->name.s.str); println("%s", n->name.s.str);
print_assign_expr(n->expr); print_assign_expr(n->expr);