Almost works
This commit is contained in:
2
ast.c
2
ast.c
@@ -1,3 +1,4 @@
|
||||
/*
|
||||
//-----------------------------------------------------------------------------
|
||||
// Decls
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -575,3 +576,4 @@ decl_deep_copy(Arena *arena){
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
225
generated_ast.h
225
generated_ast.h
@@ -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
652
new_ast.c
@@ -11,79 +11,6 @@ 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
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -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
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -292,7 +329,9 @@ struct Decl{
|
||||
}list_decl;
|
||||
};
|
||||
};
|
||||
*/
|
||||
|
||||
/*
|
||||
struct Note{
|
||||
Token *pos;
|
||||
Intern_String name;
|
||||
@@ -317,7 +356,9 @@ struct Decl_Enum_Child{
|
||||
Note *first_note;
|
||||
Note *last_note;
|
||||
};
|
||||
*/
|
||||
|
||||
/*
|
||||
//-----------------------------------------------------------------------------
|
||||
// Statements
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -355,6 +396,7 @@ struct Stmt{
|
||||
};
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Expression constructors
|
||||
@@ -576,215 +618,10 @@ function void
|
||||
typespec_function_push(Typespec *func, Typespec *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
|
||||
//-----------------------------------------------------------------------------
|
||||
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
|
||||
ast_remove(AST *node){
|
||||
@@ -881,6 +718,265 @@ ast_push_before(AST *in_list, AST *node){
|
||||
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
|
||||
ast_test(){
|
||||
|
||||
123
new_parse.c
123
new_parse.c
@@ -555,7 +555,7 @@ name::const = 4254;
|
||||
// }
|
||||
*/
|
||||
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_CloseParen)){
|
||||
return;
|
||||
@@ -563,7 +563,7 @@ parse_note_list(Parser *p, Note *parent) {
|
||||
do {
|
||||
Token *name = token_expect(p, TK_Identifier);
|
||||
Note *current = note_push_new(p->arena, parent, name, name->intern_val, 0);
|
||||
parse_note_list(p, current);
|
||||
parse_note_list(p, (AST_Parent *)current);
|
||||
if(token_match(p, TK_Assign)) {
|
||||
current->expr = parse_expr(p);
|
||||
}
|
||||
@@ -573,11 +573,11 @@ parse_note_list(Parser *p, Note *parent) {
|
||||
}
|
||||
|
||||
function void
|
||||
parse__notes(Parser *p, Note *result) {
|
||||
parse__notes(Parser *p, AST_Parent *result) {
|
||||
while(token_match(p, TK_At)) {
|
||||
Token *name = token_expect(p, TK_Identifier);
|
||||
Note *current = note_push_new(p->arena, result, name, name->intern_val, 0);
|
||||
parse_note_list(p, current);
|
||||
parse_note_list(p, (AST_Parent *)current);
|
||||
if(token_match(p, TK_Assign)) {
|
||||
current->expr = parse_expr(p);
|
||||
}
|
||||
@@ -585,10 +585,10 @@ parse__notes(Parser *p, Note *result) {
|
||||
}
|
||||
}
|
||||
|
||||
function Note
|
||||
function Note_List *
|
||||
parse_notes(Parser *p){
|
||||
Note result = {0};
|
||||
parse__notes(p, &result);
|
||||
Note_List *result = note_list(p->arena, token_get(p));
|
||||
parse__notes(p, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -611,16 +611,16 @@ parse_optional_type(Parser *p, Intern_String type){
|
||||
return result;
|
||||
}
|
||||
|
||||
function Decl *
|
||||
function Decl_Enum *
|
||||
parse_enum(Parser *p, Token *name){
|
||||
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);
|
||||
do {
|
||||
Note notes = parse_notes(p);
|
||||
Note_List *notes = parse_notes(p);
|
||||
Token *val = token_expect(p, TK_Identifier);
|
||||
Expr *expr = parse_assign_expr(p);
|
||||
decl_enum_push(p->arena, result, val, val->intern_val, expr, ¬es);
|
||||
decl_enum_push(p->arena, result, val, val->intern_val, expr, notes);
|
||||
if(!token_match(p, TK_Comma)){
|
||||
break;
|
||||
}
|
||||
@@ -630,7 +630,7 @@ parse_enum(Parser *p, Token *name){
|
||||
}
|
||||
|
||||
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];
|
||||
S64 name_stack_len = 0;
|
||||
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);
|
||||
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);
|
||||
Decl_Var *decl = decl_variable(p->arena, name_stack[i], name_stack[i]->intern_val, 0, typespec, notes);
|
||||
decl_struct_push(parent, (AST *)decl);
|
||||
}
|
||||
}
|
||||
|
||||
function Decl *
|
||||
parse_struct(Parser *p, Token *name, Decl_Kind struct_kind){
|
||||
function Decl_Struct *
|
||||
parse_struct(Parser *p, Token *name, AST_Kind struct_kind){
|
||||
Intern_String intern_name = name ? name->intern_val : (Intern_String){0};
|
||||
Token *token = name ? name : token_get(p);
|
||||
Decl *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);
|
||||
do {
|
||||
Note notes = parse_notes(p);
|
||||
Note_List *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);
|
||||
Decl_Struct *decl = parse_struct(p, 0, AST_Decl_SubUnion);
|
||||
decl->notes = notes;
|
||||
decl_struct_push(result, (AST *)decl);
|
||||
}
|
||||
else if(token_match_keyword(p, keyword_struct)){
|
||||
Decl *decl = parse_struct(p, 0, DECL_SubStruct);
|
||||
decl_pass_notes(decl, ¬es);
|
||||
decl_struct_push(result, decl);
|
||||
Decl_Struct *decl = parse_struct(p, 0, AST_Decl_SubStruct);
|
||||
decl->notes = notes;
|
||||
decl_struct_push(result, (AST *)decl);
|
||||
}
|
||||
else if(token_match(p, TK_Identifier)){
|
||||
if(token_is(p, TK_Colon)){
|
||||
if(token_peek_is_keyword(p, keyword_union, 1)){
|
||||
token_next(p); token_next(p);
|
||||
Decl *decl = parse_struct(p, token, DECL_SubUnion);
|
||||
decl_pass_notes(decl, ¬es);
|
||||
decl_struct_push(result, decl);
|
||||
Decl_Struct *decl = parse_struct(p, token, AST_Decl_SubUnion);
|
||||
decl->notes = notes;
|
||||
decl_struct_push(result, (AST *)decl);
|
||||
}
|
||||
else if(token_peek_is_keyword(p, keyword_struct, 1)){
|
||||
token_next(p); token_next(p);
|
||||
Decl *decl = parse_struct(p, token, DECL_SubStruct);
|
||||
decl_pass_notes(decl, ¬es);
|
||||
decl_struct_push(result, decl);
|
||||
Decl_Struct *decl = parse_struct(p, token, AST_Decl_SubStruct);
|
||||
decl->notes = notes;
|
||||
decl_struct_push(result, (AST *)decl);
|
||||
}
|
||||
else{
|
||||
parse_var_decl(p, result, token, ¬es);
|
||||
parse_var_decl(p, result, token, notes);
|
||||
}
|
||||
}
|
||||
else{
|
||||
parse_var_decl(p, result, token, ¬es);
|
||||
parse_var_decl(p, result, token, notes);
|
||||
}
|
||||
}
|
||||
else{
|
||||
@@ -694,16 +693,16 @@ parse_struct(Parser *p, Token *name, Decl_Kind struct_kind){
|
||||
return result;
|
||||
}
|
||||
|
||||
function Decl *
|
||||
function Decl_Typedef *
|
||||
parse_typedef(Parser *p, Token *name){
|
||||
token_expect(p, TK_Assign);
|
||||
Typespec *typespec = parse_typespec(p);
|
||||
token_expect(p, TK_Semicolon);
|
||||
Decl *result = decl_typedef(p->arena, name, name->intern_val, typespec);
|
||||
Decl_Typedef *result = decl_typedef(p->arena, name, name->intern_val, typespec);
|
||||
return result;
|
||||
}
|
||||
|
||||
function Decl *
|
||||
function Decl_Const *
|
||||
parse_const(Parser *p, Token *name){
|
||||
Typespec *typespec = 0;
|
||||
if(token_match(p, TK_Colon))
|
||||
@@ -711,13 +710,13 @@ parse_const(Parser *p, Token *name){
|
||||
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);
|
||||
Decl_Const *result = decl_const(p->arena, name, name->intern_val, expr, typespec);
|
||||
return result;
|
||||
}
|
||||
|
||||
function Decl *
|
||||
function Decl_Func *
|
||||
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)){
|
||||
do{
|
||||
name = token_expect(p, TK_Identifier);
|
||||
@@ -727,36 +726,36 @@ parse_function(Parser *p, Token *name){
|
||||
} while(token_match(p, TK_Comma));
|
||||
}
|
||||
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);
|
||||
return result;
|
||||
}
|
||||
|
||||
function B32
|
||||
parse_decl(Parser *p, Decl *parent){
|
||||
parse_decl(Parser *p, AST_Parent *parent){
|
||||
Token *name = 0;
|
||||
Decl *result = 0;
|
||||
Note note = parse_notes(p);
|
||||
AST *result = 0;
|
||||
Note_List *note = parse_notes(p);
|
||||
if((name = token_match(p, TK_Identifier))){
|
||||
if(token_match(p, TK_DoubleColon)){
|
||||
Token *token = 0;
|
||||
if((token = token_match_keyword(p, keyword_enum))){
|
||||
result = parse_enum(p, name);
|
||||
result = (AST *)parse_enum(p, name);
|
||||
}
|
||||
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))){
|
||||
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))){
|
||||
result = parse_typedef(p, name);
|
||||
result = (AST *)parse_typedef(p, name);
|
||||
}
|
||||
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))){
|
||||
result = parse_function(p, name);
|
||||
result = (AST *)parse_function(p, name);
|
||||
}
|
||||
else{
|
||||
token = token_get(p);
|
||||
@@ -771,18 +770,18 @@ parse_decl(Parser *p, Decl *parent){
|
||||
}
|
||||
|
||||
if(result){
|
||||
decl_pass_notes(result, ¬e);
|
||||
decl_list_push(parent, result);
|
||||
result->notes = note;
|
||||
ast_push_last(parent, result);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function Decl
|
||||
function Program *
|
||||
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)){
|
||||
B32 success = parse_decl(p, &decl_list);
|
||||
B32 success = parse_decl(p, decl_list);
|
||||
if(!success){
|
||||
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){
|
||||
Note notes = parse_notes(p);
|
||||
Stmt *result = 0;
|
||||
Note_List *notes = parse_notes(p);
|
||||
AST_Parent *result = 0;
|
||||
if(token_match_keyword(p, keyword_if)){
|
||||
|
||||
}
|
||||
@@ -978,9 +977,9 @@ parse_test_decls(){
|
||||
};
|
||||
for(SizeU i = 0; i < buff_cap(decls); i++){
|
||||
parser_restream(&p, decls[i], lit("Decl_Test"));
|
||||
Decl decl = parse_decls(&p);
|
||||
assert(decl.list_decl.first);
|
||||
decl_print(decl.list_decl.first);
|
||||
Program *decl = parse_decls(&p);
|
||||
assert(decl->first);
|
||||
ast_print((AST *)decl);
|
||||
}
|
||||
arena_end_scratch();
|
||||
}
|
||||
@@ -991,8 +990,8 @@ parse_test_from_file(){
|
||||
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);
|
||||
Program *d = parse_decls(&p);
|
||||
ast_print((AST *)d);
|
||||
arena_end_scratch();
|
||||
}
|
||||
|
||||
|
||||
70
new_print.c
70
new_print.c
@@ -5,6 +5,11 @@ global S64 indent;
|
||||
|
||||
#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
|
||||
print_indent(){
|
||||
for(S64 i = 0; i < indent*2; i++)
|
||||
@@ -190,76 +195,81 @@ print_assign_expr(Expr *expr){
|
||||
}
|
||||
|
||||
function void
|
||||
decl_print(Decl *node){
|
||||
ast_print(AST *in){
|
||||
//print_notes(p, node->first_note);
|
||||
|
||||
switch(node->kind) {
|
||||
|
||||
case DECL_List: {
|
||||
for(Decl *n = node->list_decl.first; n; n=n->next){
|
||||
decl_print(n);
|
||||
switch(in->kind) {
|
||||
case AST_Program: {
|
||||
AST_Parent *node = (AST_Parent *)in;
|
||||
for(AST *n = node->first; n; n=n->next){
|
||||
ast_print(n);
|
||||
printf("\n");
|
||||
}
|
||||
} break;
|
||||
|
||||
case DECL_Const:
|
||||
case DECL_Variable:{
|
||||
case AST_Decl_Const:
|
||||
case AST_Decl_Var:{
|
||||
Decl_Var *node = (Decl_Var *)in;
|
||||
println("%s: ", node->name.s.str);
|
||||
if(node->var_decl.typespec) typespec_print(node->var_decl.typespec);
|
||||
print_assign_expr(node->var_decl.expr);
|
||||
if(node->typespec) typespec_print(node->typespec);
|
||||
print_assign_expr(node->expr);
|
||||
} break;
|
||||
|
||||
case DECL_Typedef:{
|
||||
case AST_Decl_Typedef:{
|
||||
Decl_Typedef *node = (Decl_Typedef *)in;
|
||||
println("typedef %s ", node->name.s.str);
|
||||
typespec_print(node->typedef_decl.typespec);
|
||||
typespec_print(node->typespec);
|
||||
printf(";");
|
||||
} break;
|
||||
|
||||
case DECL_Function:{
|
||||
case AST_Decl_Func:{
|
||||
Decl_Func *node = (Decl_Func *)in;
|
||||
println("");
|
||||
typespec_print(node->func_decl.ret);
|
||||
typespec_print(node->ret);
|
||||
printf(" %s", node->name.s.str);
|
||||
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);
|
||||
typespec_print(arg->typespec);
|
||||
if(arg != node->func_decl.last)
|
||||
if((AST *)arg != node->last)
|
||||
printf(", ");
|
||||
}
|
||||
printf(");");
|
||||
} break;
|
||||
|
||||
case DECL_Struct:
|
||||
case DECL_Union :{
|
||||
const char *struct_name = node->kind==DECL_Struct ? "struct" : "union";
|
||||
case AST_Decl_Struct:
|
||||
case AST_Decl_Union :{
|
||||
Decl_Struct *node = (Decl_Struct *)in;
|
||||
const char *struct_name = node->kind==AST_Decl_Struct ? "struct" : "union";
|
||||
println("%s %s{", struct_name, node->name.s.str?(char*)node->name.s.str:"");
|
||||
indent++;
|
||||
for(Decl *n = node->struct_decl.first; n; n=n->next){
|
||||
decl_print(n);
|
||||
for(AST *n = node->first; n; n=n->next){
|
||||
ast_print(n);
|
||||
}
|
||||
indent--;
|
||||
println("};");
|
||||
} break;
|
||||
|
||||
case DECL_SubStruct:
|
||||
case DECL_SubUnion :{
|
||||
const char *struct_name = node->kind==DECL_SubStruct ? "struct" : "union";
|
||||
case AST_Decl_SubStruct:
|
||||
case AST_Decl_SubUnion :{
|
||||
Decl_Struct *node = (Decl_Struct *)in;
|
||||
const char *struct_name = node->kind==AST_Decl_Struct ? "struct" : "union";
|
||||
println("%s %s{", struct_name, node->name.s.str?(char*)node->name.s.str:"");
|
||||
indent++;
|
||||
for(Decl *n = node->struct_decl.first; n; n=n->next){
|
||||
decl_print(n);
|
||||
for(AST *n = node->first; n; n=n->next){
|
||||
ast_print(n);
|
||||
}
|
||||
indent--;
|
||||
println("};");
|
||||
} break;
|
||||
|
||||
|
||||
case DECL_Enum:{
|
||||
case AST_Decl_Enum:{
|
||||
Decl_Enum *node = (Decl_Enum *)in;
|
||||
println("enum %s : ", node->name.s.str);
|
||||
typespec_print(node->enum_decl.typespec);
|
||||
typespec_print(node->typespec);
|
||||
printf("{");
|
||||
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);
|
||||
println("%s", n->name.s.str);
|
||||
print_assign_expr(n->expr);
|
||||
|
||||
Reference in New Issue
Block a user