Almost works
This commit is contained in:
2
ast.c
2
ast.c
@@ -1,3 +1,4 @@
|
|||||||
|
/*
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Decls
|
// 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 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(){
|
||||||
|
|||||||
123
new_parse.c
123
new_parse.c
@@ -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, ¬es);
|
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, ¬es);
|
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, ¬es);
|
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, ¬es);
|
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, ¬es);
|
decl->notes = notes;
|
||||||
decl_struct_push(result, decl);
|
decl_struct_push(result, (AST *)decl);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
parse_var_decl(p, result, token, ¬es);
|
parse_var_decl(p, result, token, notes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
parse_var_decl(p, result, token, ¬es);
|
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, ¬e);
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
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 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);
|
||||||
|
|||||||
Reference in New Issue
Block a user