AST idea
This commit is contained in:
356
new_ast.c
356
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user