AST idea
This commit is contained in:
53
ast.c
53
ast.c
@@ -21,7 +21,7 @@ decl_struct(Parser *p, Decl_Kind kind, Token *pos, Intern_String name, Decl_Stru
|
|||||||
function Decl *
|
function Decl *
|
||||||
decl_typedef(Parser *p, Token *pos, Intern_String name, Typespec *type){
|
decl_typedef(Parser *p, Token *pos, Intern_String name, Typespec *type){
|
||||||
Decl *result = decl_new(p, DECL_Typedef, pos, name);
|
Decl *result = decl_new(p, DECL_Typedef, pos, name);
|
||||||
result->typedef_decl.type = type;
|
result->typedef_decl.typespec = type;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,57 +227,6 @@ typespec_require_name_string(Typespec *type){
|
|||||||
return string_empty;
|
return string_empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Statements
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
function Stmt *
|
|
||||||
stmt_new(Parser *p, Stmt_Kind kind, Token *pos){
|
|
||||||
Stmt *result = arena_push_struct(&p->main_arena, Stmt);
|
|
||||||
result->kind = kind;
|
|
||||||
result->pos = pos;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Stmt *
|
|
||||||
stmt_decl(Parser *p, Token *pos, Decl *decl){
|
|
||||||
Stmt *result = stmt_new(p, STMT_Decl, pos);
|
|
||||||
result->decl = decl;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Stmt *
|
|
||||||
stmt_expr(Parser *p, Token *pos, Expr *expr){
|
|
||||||
Stmt *result = stmt_new(p, STMT_Expr, pos);
|
|
||||||
result->expr = expr;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Stmt *
|
|
||||||
stmt_list(Parser *p, Token *pos){
|
|
||||||
Stmt *result = stmt_new(p, STMT_List, pos);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Stmt *
|
|
||||||
stmt_return(Parser *p, Token *pos, Expr *expr){
|
|
||||||
Stmt *result = stmt_new(p, STMT_Return, pos);
|
|
||||||
result->ret.expr = expr;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Stmt *
|
|
||||||
stmt_if(Parser *p, Token *pos, Stmt *body, Expr *cond){
|
|
||||||
Stmt *result = stmt_new(p, STMT_If, pos);
|
|
||||||
result->stmt_if.cond = cond;
|
|
||||||
result->stmt_if.body = body;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function void
|
|
||||||
stmt_push(Stmt *stmt, Stmt *child){
|
|
||||||
SLLQueuePush(stmt->list.first, stmt->list.last, child);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Pointer Array
|
// Pointer Array
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -2,5 +2,6 @@
|
|||||||
|
|
||||||
rem clang generate.c -fdiagnostics-absolute-paths -std=c99 -g -o generate.exe -Wl,user32.lib
|
rem clang generate.c -fdiagnostics-absolute-paths -std=c99 -g -o generate.exe -Wl,user32.lib
|
||||||
rem generate.exe
|
rem generate.exe
|
||||||
|
|
||||||
clang main.c -Wall -Wno-unused-function -fdiagnostics-absolute-paths -std=c17 -g -o main.exe -Wl,user32.lib
|
clang main.c -Wall -Wno-unused-function -fdiagnostics-absolute-paths -std=c17 -g -o main.exe -Wl,user32.lib
|
||||||
rem cl main.c -std:c17
|
rem cl main.c -std:c17
|
||||||
|
|||||||
55
dllqueue.c
Normal file
55
dllqueue.c
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
function void
|
||||||
|
push(Type *l, Type *node){
|
||||||
|
if(l->first == 0){
|
||||||
|
l->first = l->last = node;
|
||||||
|
node->prev = 0;
|
||||||
|
node->next = 0;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
l->last->next = node;
|
||||||
|
node->prev = l->last;
|
||||||
|
node->next = 0;
|
||||||
|
l->last = node;
|
||||||
|
}
|
||||||
|
node->parent = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
push_front(Type *l, Type *node){
|
||||||
|
if(l->first == 0){
|
||||||
|
l->first = l->last = node;
|
||||||
|
node->prev = 0;
|
||||||
|
node->next = 0;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
node->next = l->first;
|
||||||
|
l->first->prev = node;
|
||||||
|
node->prev = 0;
|
||||||
|
l->first = node;
|
||||||
|
}
|
||||||
|
node->parent = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
remove(Type *l, Type *node){
|
||||||
|
if(l->first == l->last){
|
||||||
|
assert(node == l->last);
|
||||||
|
l->first = l->last = 0;
|
||||||
|
}
|
||||||
|
else if(l->last == node){
|
||||||
|
l->last = l->last->prev;
|
||||||
|
l->last->next = 0;
|
||||||
|
}
|
||||||
|
else if(l->first == node){
|
||||||
|
l->first = l->first->next;
|
||||||
|
l->first->prev = 0;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
node->prev->next = node->next;
|
||||||
|
node->next->prev = node->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->parent = 0;
|
||||||
|
node->prev = 0;
|
||||||
|
node->next = 0;
|
||||||
|
}
|
||||||
46
generate.c
46
generate.c
@@ -13,24 +13,54 @@
|
|||||||
|
|
||||||
#include "new_lex.c"
|
#include "new_lex.c"
|
||||||
|
|
||||||
int main(){
|
//-----------------------------------------------------------------------------
|
||||||
|
// String replacing util
|
||||||
FILE *f = fopen("generated.c", "w");
|
//-----------------------------------------------------------------------------
|
||||||
assert(f);
|
typedef struct String_Map String_Map;
|
||||||
|
struct String_Map{
|
||||||
|
String replace;
|
||||||
|
String with;
|
||||||
|
};
|
||||||
|
|
||||||
|
function void
|
||||||
|
output_template(FILE *f, String filename, String_Map *map, SizeU map_cap){
|
||||||
Arena *scratch = arena_begin_scratch();
|
Arena *scratch = arena_begin_scratch();
|
||||||
String file = os_read_file(scratch, lit("token_array.c"));
|
String file = os_read_file(scratch, filename);
|
||||||
Token_Array array = lex_stream(scratch, file, lit("token_array.c"));
|
Token_Array array = lex_stream(scratch, file, filename);
|
||||||
for(Token *t = token_array_iter_begin(&array); t; t = token_array_iter_next(&array)){
|
for(Token *t = token_array_iter_begin(&array); t->kind != TK_End; t = token_array_iter_next(&array)){
|
||||||
|
String string = t->string;
|
||||||
|
for(SizeU i = 0; i < map_cap; i++){
|
||||||
|
if(string_compare(string, map[i].replace)){
|
||||||
|
string = map[i].with;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(f, "%.*s", (int)t->len, t->str);
|
|
||||||
|
fprintf(f, "%.*s", (int)string.len, string.str);
|
||||||
if(t->kind == TK_OpenBrace) fprintf(f, "\n");
|
if(t->kind == TK_OpenBrace) fprintf(f, "\n");
|
||||||
if(t->kind == TK_CloseBrace && token_array_iter_peek(&array, 0)->kind != TK_Semicolon) fprintf(f, "\n");
|
if(t->kind == TK_CloseBrace && token_array_iter_peek(&array, 0)->kind != TK_Semicolon) fprintf(f, "\n");
|
||||||
if(t->kind == TK_Semicolon) fprintf(f, "\n");
|
if(t->kind == TK_Semicolon) fprintf(f, "\n");
|
||||||
|
if(t->kind == TK_Keyword) fprintf(f, " ");
|
||||||
if(t[0].kind == TK_Identifier && token_array_iter_peek(&array, 0)->kind == TK_Identifier) fprintf(f, " ");
|
if(t[0].kind == TK_Identifier && token_array_iter_peek(&array, 0)->kind == TK_Identifier) fprintf(f, " ");
|
||||||
token_array_iter_peek(&array, 1);
|
token_array_iter_peek(&array, 1);
|
||||||
}
|
}
|
||||||
arena_end_scratch();
|
arena_end_scratch();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
|
||||||
|
FILE *f = fopen("generated.c", "w");
|
||||||
|
assert(f);
|
||||||
|
String_Map map[] = {
|
||||||
|
{lit("Type"), lit("Decl")},
|
||||||
|
{lit("first"), lit("list_decl.first")},
|
||||||
|
{lit("last"), lit("list_decl.last")},
|
||||||
|
{lit("remove"), lit("decl_list_remove")},
|
||||||
|
{lit("push_front"), lit("decl_dll_list_push_front")},
|
||||||
|
{lit("push"), lit("decl_dll_list_push")},
|
||||||
|
};
|
||||||
|
output_template(f, lit("dllqueue.c"), map, buff_cap(map));
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
49
generated.c
Normal file
49
generated.c
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
function void decl_dll_list_push(Decl*l,Decl*node){
|
||||||
|
if (l->list_decl.first==0){
|
||||||
|
l->list_decl.first=l->list_decl.last=node;
|
||||||
|
node->prev=0;
|
||||||
|
node->next=0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
l->list_decl.last->next=node;
|
||||||
|
node->prev=l->list_decl.last;
|
||||||
|
node->next=0;
|
||||||
|
l->list_decl.last=node;
|
||||||
|
}
|
||||||
|
node->parent=l;
|
||||||
|
}
|
||||||
|
function void decl_dll_list_push_front(Decl*l,Decl*node){
|
||||||
|
if (l->list_decl.first==0){
|
||||||
|
l->list_decl.first=l->list_decl.last=node;
|
||||||
|
node->prev=0;
|
||||||
|
node->next=0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node->next=l->list_decl.first;
|
||||||
|
l->list_decl.first->prev=node;
|
||||||
|
node->prev=0;
|
||||||
|
l->list_decl.first=node;
|
||||||
|
}
|
||||||
|
node->parent=l;
|
||||||
|
}
|
||||||
|
function void decl_list_remove(Decl*l,Decl*node){
|
||||||
|
if (l->list_decl.first==l->list_decl.last){
|
||||||
|
assert(node==l->list_decl.last);
|
||||||
|
l->list_decl.first=l->list_decl.last=0;
|
||||||
|
}
|
||||||
|
else if (l->list_decl.last==node){
|
||||||
|
l->list_decl.last=l->list_decl.last->prev;
|
||||||
|
l->list_decl.last->next=0;
|
||||||
|
}
|
||||||
|
else if (l->list_decl.first==node){
|
||||||
|
l->list_decl.first=l->list_decl.first->next;
|
||||||
|
l->list_decl.first->prev=0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node->prev->next=node->next;
|
||||||
|
node->next->prev=node->prev;
|
||||||
|
}
|
||||||
|
node->parent=0;
|
||||||
|
node->prev=0;
|
||||||
|
node->next=0;
|
||||||
|
}
|
||||||
356
new_ast.c
356
new_ast.c
@@ -4,11 +4,86 @@ typedef struct Decl Decl;
|
|||||||
typedef struct Stmt Stmt;
|
typedef struct Stmt Stmt;
|
||||||
typedef struct Stmt_If Stmt_If;
|
typedef struct Stmt_If Stmt_If;
|
||||||
typedef struct Typespec Typespec;
|
typedef struct Typespec Typespec;
|
||||||
typedef struct Typespec_Function_Arg Typespec_Function_Arg;
|
|
||||||
typedef struct Decl_Enum_Child Decl_Enum_Child;
|
typedef struct Decl_Enum_Child Decl_Enum_Child;
|
||||||
typedef struct Decl_Function_Arg Decl_Function_Arg;
|
typedef struct Decl_Function_Arg Decl_Function_Arg;
|
||||||
typedef struct Expr_Compound_Field Expr_Compound_Field;
|
typedef struct Expr_Compound_Field Expr_Compound_Field;
|
||||||
|
|
||||||
|
typedef struct AST AST;
|
||||||
|
typedef struct AST_Parent AST_Parent;
|
||||||
|
|
||||||
|
typedef enum AST_Kind{
|
||||||
|
AST_None,
|
||||||
|
|
||||||
|
AST_Decl_Struct, //
|
||||||
|
AST_Decl_SubStruct,
|
||||||
|
AST_Decl_SubUnion,
|
||||||
|
AST_Decl_Union,
|
||||||
|
AST_Decl_Enum,
|
||||||
|
AST_Decl_Note,
|
||||||
|
AST_Decl_Func,
|
||||||
|
AST_List,
|
||||||
|
AST_Stmt_If,
|
||||||
|
AST_Stmt_Decl,
|
||||||
|
AST_Stmt_Expr,
|
||||||
|
AST_Stmt_Return,
|
||||||
|
AST_Stmt_For,
|
||||||
|
AST_FirstParent = AST_Decl_Struct,
|
||||||
|
AST_LastParent = AST_Stmt_For,
|
||||||
|
|
||||||
|
AST_Decl_Func_Arg,
|
||||||
|
|
||||||
|
AST_Decl_Variable,
|
||||||
|
}AST_Kind;
|
||||||
|
|
||||||
|
#define AST_FIELDS AST *next, *prev; AST *notes; AST_Parent *parent; Token *pos; AST_Kind kind
|
||||||
|
#define AST_PARENT_FIELDS AST *first, *last
|
||||||
|
#define AST_UNION union{ struct{ AST_FIELDS; }; AST ast; }
|
||||||
|
#define AST_PARENT_UNION union{ struct{ AST_PARENT_FIELDS; }; AST_Parent child; }
|
||||||
|
|
||||||
|
struct AST{
|
||||||
|
AST_FIELDS;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct AST_Parent{
|
||||||
|
AST_UNION;
|
||||||
|
AST_PARENT_FIELDS;
|
||||||
|
} AST_Parent;
|
||||||
|
|
||||||
|
typedef struct AST_Note{
|
||||||
|
AST_PARENT_UNION;
|
||||||
|
Intern_String name;
|
||||||
|
Expr *expr;
|
||||||
|
}AST_Note;
|
||||||
|
|
||||||
|
typedef struct Decl_Struct{
|
||||||
|
AST_PARENT_UNION;
|
||||||
|
Intern_String name;
|
||||||
|
}Decl_Struct;
|
||||||
|
|
||||||
|
typedef struct Decl_Func_Arg{
|
||||||
|
AST_UNION;
|
||||||
|
Intern_String name;
|
||||||
|
Typespec *typespec;
|
||||||
|
}Decl_Func_Arg;
|
||||||
|
|
||||||
|
typedef struct AST_Decl_Enum_Child{
|
||||||
|
AST_UNION;
|
||||||
|
Intern_String name;
|
||||||
|
Expr *expr;
|
||||||
|
}AST_Decl_Enum_Child;
|
||||||
|
|
||||||
|
typedef struct Decl_Enum{
|
||||||
|
AST_PARENT_UNION;
|
||||||
|
Typespec *typespec;
|
||||||
|
}Decl_Enum;
|
||||||
|
|
||||||
|
typedef struct Decl_Func{
|
||||||
|
AST_PARENT_UNION;
|
||||||
|
Typespec *ret;
|
||||||
|
AST *body;
|
||||||
|
}Decl_Func;
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Expressions
|
// Expressions
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -168,11 +243,13 @@ typedef enum Decl_Kind{
|
|||||||
DECL_SubUnion,
|
DECL_SubUnion,
|
||||||
DECL_Enum,
|
DECL_Enum,
|
||||||
DECL_Variable,
|
DECL_Variable,
|
||||||
|
DECL_Const,
|
||||||
DECL_Typedef,
|
DECL_Typedef,
|
||||||
DECL_Function,
|
DECL_Function,
|
||||||
DECL_List,
|
DECL_List,
|
||||||
}Decl_Kind;
|
}Decl_Kind;
|
||||||
|
|
||||||
|
|
||||||
struct Decl{
|
struct Decl{
|
||||||
Decl_Kind kind;
|
Decl_Kind kind;
|
||||||
Decl *next;
|
Decl *next;
|
||||||
@@ -197,11 +274,11 @@ struct Decl{
|
|||||||
Decl *last;
|
Decl *last;
|
||||||
}struct_decl;
|
}struct_decl;
|
||||||
struct{
|
struct{
|
||||||
Typespec *type;
|
Typespec *typespec;
|
||||||
Expr *expr;
|
Expr *expr;
|
||||||
}var_decl;
|
}var_decl;
|
||||||
struct{
|
struct{
|
||||||
Typespec *type;
|
Typespec *typespec;
|
||||||
}typedef_decl;
|
}typedef_decl;
|
||||||
struct{
|
struct{
|
||||||
Decl_Function_Arg *first;
|
Decl_Function_Arg *first;
|
||||||
@@ -570,7 +647,15 @@ decl_struct(Arena *p, Decl_Kind kind, Token *pos, Intern_String name){
|
|||||||
function Decl *
|
function Decl *
|
||||||
decl_typedef(Arena *p, Token *pos, Intern_String name, Typespec *type){
|
decl_typedef(Arena *p, Token *pos, Intern_String name, Typespec *type){
|
||||||
Decl *result = decl_new(p, DECL_Typedef, pos, name);
|
Decl *result = decl_new(p, DECL_Typedef, pos, name);
|
||||||
result->typedef_decl.type = type;
|
result->typedef_decl.typespec = type;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Decl *
|
||||||
|
decl_const(Arena *arena, Token *pos, Intern_String name, Expr *expr, Typespec *typespec){
|
||||||
|
Decl *result = decl_new(arena, DECL_Const, pos, name);
|
||||||
|
result->var_decl.expr = expr;
|
||||||
|
result->var_decl.typespec = typespec;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,7 +669,7 @@ decl_enum(Arena *p, Token *pos, Intern_String name, Typespec *typespec){
|
|||||||
function Decl *
|
function Decl *
|
||||||
decl_variable(Arena *p, Token *pos, Intern_String name, Typespec *typespec, Expr *expr){
|
decl_variable(Arena *p, Token *pos, Intern_String name, Typespec *typespec, Expr *expr){
|
||||||
Decl *result = decl_new(p, DECL_Variable, pos, name);
|
Decl *result = decl_new(p, DECL_Variable, pos, name);
|
||||||
result->var_decl.type = typespec;
|
result->var_decl.typespec = typespec;
|
||||||
result->var_decl.expr = expr;
|
result->var_decl.expr = expr;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -630,108 +715,203 @@ decl_list_push(Decl *parent, Decl *child){
|
|||||||
SLLQueuePush(parent->list_decl.first, parent->list_decl.last, child);
|
SLLQueuePush(parent->list_decl.first, parent->list_decl.last, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Statements
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
function Stmt *
|
||||||
|
stmt_new(Arena *p, Stmt_Kind kind, Token *pos){
|
||||||
|
Stmt *result = arena_push_struct(p, Stmt);
|
||||||
|
result->kind = kind;
|
||||||
|
result->pos = pos;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Stmt *
|
||||||
|
stmt_decl(Arena *p, Token *pos, Decl *decl){
|
||||||
|
Stmt *result = stmt_new(p, STMT_Decl, pos);
|
||||||
|
result->decl = decl;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Stmt *
|
||||||
|
stmt_expr(Arena *p, Token *pos, Expr *expr){
|
||||||
|
Stmt *result = stmt_new(p, STMT_Expr, pos);
|
||||||
|
result->expr = expr;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Stmt *
|
||||||
|
stmt_list(Arena *p, Token *pos){
|
||||||
|
Stmt *result = stmt_new(p, STMT_List, pos);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Stmt *
|
||||||
|
stmt_return(Arena *p, Token *pos, Expr *expr){
|
||||||
|
Stmt *result = stmt_new(p, STMT_Return, pos);
|
||||||
|
result->ret.expr = expr;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Stmt *
|
||||||
|
stmt_if(Arena *p, Token *pos, Stmt *body, Expr *cond){
|
||||||
|
Stmt *result = stmt_new(p, STMT_If, pos);
|
||||||
|
result->stmt_if.cond = cond;
|
||||||
|
result->stmt_if.body = body;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
stmt_push(Stmt *stmt, Stmt *child){
|
||||||
|
SLLQueuePush(stmt->list.first, stmt->list.last, child);
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Double linked list
|
// Double linked list
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
function void
|
function void
|
||||||
decl_dll_list_push(Decl *l, Decl *node){
|
list_print(AST_Parent *decls){
|
||||||
if(l->list_decl.first == 0){
|
printf("\n");
|
||||||
l->list_decl.first = l->list_decl.last = node;
|
|
||||||
node->prev = 0;
|
|
||||||
node->next = 0;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
l->list_decl.last->next = node;
|
|
||||||
node->prev = l->list_decl.last;
|
|
||||||
node->next = 0;
|
|
||||||
l->list_decl.last = node;
|
|
||||||
}
|
|
||||||
node->parent = l;
|
|
||||||
}
|
|
||||||
|
|
||||||
function void
|
|
||||||
decl_dll_list_push_front(Decl *l, Decl *node){
|
|
||||||
if(l->list_decl.first == 0){
|
|
||||||
l->list_decl.first = l->list_decl.last = node;
|
|
||||||
node->prev = 0;
|
|
||||||
node->next = 0;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
node->next = l->list_decl.first;
|
|
||||||
l->list_decl.first->prev = node;
|
|
||||||
node->prev = 0;
|
|
||||||
l->list_decl.first = node;
|
|
||||||
}
|
|
||||||
node->parent = l;
|
|
||||||
}
|
|
||||||
|
|
||||||
function void
|
|
||||||
decl_list_remove(Decl *l, Decl *node){
|
|
||||||
if(l->list_decl.first == l->list_decl.last){
|
|
||||||
assert(node == l->list_decl.last);
|
|
||||||
l->list_decl.first = l->list_decl.last = 0;
|
|
||||||
}
|
|
||||||
else if(l->list_decl.last == node){
|
|
||||||
l->list_decl.last = l->list_decl.last->prev;
|
|
||||||
l->list_decl.last->next = 0;
|
|
||||||
}
|
|
||||||
else if(l->list_decl.first == node){
|
|
||||||
l->list_decl.first = l->list_decl.first->next;
|
|
||||||
l->list_decl.first->prev = 0;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
node->prev->next = node->next;
|
|
||||||
node->next->prev = node->prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
node->parent = 0;
|
|
||||||
node->prev = 0;
|
|
||||||
node->next = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function void
|
|
||||||
list_print(Decl *decls){
|
|
||||||
|
|
||||||
printf("next:");
|
printf("next:");
|
||||||
for(Decl *n = decls[0].list_decl.first; n; n=n->next){
|
for(AST *n = decls->first; n; n=n->next){
|
||||||
printf("%d", n->kind);
|
printf("%d", n->kind);
|
||||||
}
|
}
|
||||||
printf("prev:");
|
printf("prev:");
|
||||||
for(Decl *n = decls[0].list_decl.last; n; n=n->prev){
|
for(AST *n = decls->last; n; n=n->prev){
|
||||||
printf("%d", n->kind);
|
printf("%d", n->kind);
|
||||||
}
|
}
|
||||||
printf("parent:");
|
printf("parent:");
|
||||||
for(Decl *n = decls[0].list_decl.first; n; n=n->next){
|
for(AST *n = decls->first; n; n=n->next){
|
||||||
printf("%d", n->parent->kind);
|
printf("%d", n->parent->kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
ast_test(){
|
ast_remove(AST *node){
|
||||||
Decl decls[16] = {0};
|
AST_Parent *l = node->parent;
|
||||||
decls[0].kind = 9;
|
assert(l);
|
||||||
decls[1].kind = 1;
|
if (l->first==l->last){
|
||||||
decls[2].kind = 2;
|
assert(node==l->last);
|
||||||
decls[3].kind = 3;
|
l->first=l->last=0;
|
||||||
decls[4].kind = 4;
|
}
|
||||||
decl_dll_list_push(decls, decls+1);
|
else if (l->last==node){
|
||||||
decl_dll_list_push(decls, decls+2);
|
l->last=l->last->prev;
|
||||||
decl_dll_list_push(decls, decls+3);
|
l->last->next=0;
|
||||||
decl_dll_list_push_front(decls, decls+4);
|
}
|
||||||
|
else if (l->first==node){
|
||||||
|
l->first=l->first->next;
|
||||||
|
l->first->prev=0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node->prev->next=node->next;
|
||||||
|
node->next->prev=node->prev;
|
||||||
|
}
|
||||||
|
node->parent=0;
|
||||||
|
node->prev=0;
|
||||||
|
node->next=0;
|
||||||
|
}
|
||||||
|
|
||||||
//list_print(decls);
|
function void
|
||||||
decl_list_remove(decls, decls+1);
|
ast_push_first(AST_Parent *l, AST *node){
|
||||||
//list_print(decls);
|
if (l->first==0){
|
||||||
decl_list_remove(decls, decls+2);
|
l->first=l->last=node;
|
||||||
//list_print(decls);
|
node->prev=0;
|
||||||
decl_list_remove(decls, decls+3);
|
node->next=0;
|
||||||
//list_print(decls);
|
}
|
||||||
decl_list_remove(decls, decls+4);
|
else {
|
||||||
//list_print(decls);
|
l->last->next=node;
|
||||||
assert(decls[0].list_decl.first == 0);
|
node->prev=l->last;
|
||||||
assert(decls[0].list_decl.last == 0);
|
node->next=0;
|
||||||
|
l->last=node;
|
||||||
|
}
|
||||||
|
node->parent=l;
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
ast_push_last(AST_Parent *l, AST *node){
|
||||||
|
if(l->first == 0){
|
||||||
|
l->first = l->last = node;
|
||||||
|
node->prev = 0;
|
||||||
|
node->next = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node->next = l->first;
|
||||||
|
l->first->prev = node;
|
||||||
|
node->prev = 0;
|
||||||
|
l->first = node;
|
||||||
|
}
|
||||||
|
node->parent = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
ast_push_after(AST *in_list, AST *node){
|
||||||
|
AST_Parent *parent = in_list->parent;
|
||||||
|
assert(parent);
|
||||||
|
assert(parent->first && parent->last);
|
||||||
|
|
||||||
|
node->prev = in_list;
|
||||||
|
if(in_list == parent->last){
|
||||||
|
in_list->next = node;
|
||||||
|
parent->last = node;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node->next = in_list->next;
|
||||||
|
in_list->next = node;
|
||||||
|
node->next->prev = node;
|
||||||
|
}
|
||||||
|
node->parent=parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
ast_push_before(AST *in_list, AST *node){
|
||||||
|
AST_Parent *parent = in_list->parent;
|
||||||
|
assert(parent);
|
||||||
|
assert(parent->first && parent->last);
|
||||||
|
|
||||||
|
node->next = in_list;
|
||||||
|
if(parent->first == in_list){
|
||||||
|
in_list->prev = node;
|
||||||
|
parent->first = node;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
node->prev = in_list->prev;
|
||||||
|
in_list->prev = node;
|
||||||
|
node->prev->next = node;
|
||||||
|
}
|
||||||
|
node->parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function void
|
||||||
|
ast_test(){
|
||||||
|
printf("\nAST_Size = %u", (U32)sizeof(AST));
|
||||||
|
printf("\nAST_Struct_Size = %u", (U32)sizeof(Decl_Struct));
|
||||||
|
|
||||||
|
AST_Parent parent = {0};
|
||||||
|
AST decls[16] = {0};
|
||||||
|
parent.kind = 0;
|
||||||
|
for(int i = 0; i < buff_cap(decls); i++){
|
||||||
|
decls[i].kind = i+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ast_push_first(&parent, decls);
|
||||||
|
ast_push_first(&parent, decls+1);
|
||||||
|
ast_push_first(&parent, decls+2);
|
||||||
|
ast_push_before(decls, decls+3);
|
||||||
|
ast_push_before(decls, decls+4);
|
||||||
|
ast_push_after(decls, decls+5);
|
||||||
|
ast_push_after(decls+5, decls+6);
|
||||||
|
|
||||||
|
//list_print(&parent);
|
||||||
|
ast_remove(decls);
|
||||||
|
ast_remove(decls+1);
|
||||||
|
ast_remove(decls+2);
|
||||||
|
ast_remove(decls+3);
|
||||||
|
ast_remove(decls+4);
|
||||||
|
ast_remove(decls+5);
|
||||||
|
ast_remove(decls+6);
|
||||||
|
assert(parent.first == 0);
|
||||||
|
assert(parent.last == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ global Intern_String keyword_else;
|
|||||||
global Intern_String keyword_size_type;
|
global Intern_String keyword_size_type;
|
||||||
global Intern_String keyword_size_expr;
|
global Intern_String keyword_size_expr;
|
||||||
global Intern_String keyword_const;
|
global Intern_String keyword_const;
|
||||||
|
global Intern_String keyword_typedef;
|
||||||
|
global Intern_String keyword_return;
|
||||||
global Intern_String keyword_typeof;
|
global Intern_String keyword_typeof;
|
||||||
global Intern_String keyword_while;
|
global Intern_String keyword_while;
|
||||||
global Intern_String keyword_switch;
|
global Intern_String keyword_switch;
|
||||||
@@ -31,7 +33,9 @@ init_default_keywords(Intern_Table *t){
|
|||||||
keyword_typeof = intern_string(t, lit("typeof"));
|
keyword_typeof = intern_string(t, lit("typeof"));
|
||||||
keyword_const = intern_string(t, lit("const"));
|
keyword_const = intern_string(t, lit("const"));
|
||||||
keyword_while = intern_string(t, lit("while"));
|
keyword_while = intern_string(t, lit("while"));
|
||||||
|
keyword_return = intern_string(t, lit("return"));
|
||||||
keyword_switch = intern_string(t, lit("switch"));
|
keyword_switch = intern_string(t, lit("switch"));
|
||||||
|
keyword_typedef = intern_string(t, lit("typedef"));
|
||||||
keyword_case = intern_string(t, lit("case"));
|
keyword_case = intern_string(t, lit("case"));
|
||||||
keyword_struct = intern_string(t, lit("struct"));
|
keyword_struct = intern_string(t, lit("struct"));
|
||||||
keyword_enum = intern_string(t, lit("enum"));
|
keyword_enum = intern_string(t, lit("enum"));
|
||||||
|
|||||||
171
new_parse.c
171
new_parse.c
@@ -31,7 +31,7 @@ parser_push_error(Parser *p, Token *token, char *str, ...){
|
|||||||
|
|
||||||
// @Note(Krzosa): Print nice error message
|
// @Note(Krzosa): Print nice error message
|
||||||
{
|
{
|
||||||
printf("Error: %s %s:%d\n", string.str, token->file.str, (S32)token->line);
|
printf("\nError: %s %s:%d\n", string.str, token->file.str, (S32)token->line);
|
||||||
|
|
||||||
// @Note(Krzosa): Print error line
|
// @Note(Krzosa): Print error line
|
||||||
{
|
{
|
||||||
@@ -171,7 +171,6 @@ Compound literals
|
|||||||
- { }
|
- { }
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Expr_Compound_Field *
|
function Expr_Compound_Field *
|
||||||
parse_expr_compound_field(Parser *p){
|
parse_expr_compound_field(Parser *p){
|
||||||
Token *token = token_get(p);
|
Token *token = token_get(p);
|
||||||
@@ -554,7 +553,6 @@ name::const = 4254;
|
|||||||
// data: [24]U32;
|
// data: [24]U32;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
*/
|
*/
|
||||||
function void
|
function void
|
||||||
parse_note_list(Parser *p, Note *parent) {
|
parse_note_list(Parser *p, Note *parent) {
|
||||||
@@ -602,34 +600,37 @@ parse_assign_expr(Parser *p){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Typespec *
|
function Typespec *
|
||||||
parse_optional_type(Parser *p){
|
parse_optional_type(Parser *p, Intern_String type){
|
||||||
Typespec *result = 0;
|
Typespec *result = 0;
|
||||||
if(token_match(p, TK_Colon)){
|
if(token_match(p, TK_Colon)){
|
||||||
result = parse_typespec(p);
|
result = parse_typespec(p);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
result = typespec_name(p->arena, token_get(p), intern_int);
|
result = typespec_name(p->arena, token_get(p), type);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Decl *
|
function Decl *
|
||||||
parse_enum(Parser *p, Token *name){
|
parse_enum(Parser *p, Token *name){
|
||||||
Typespec *typespec = parse_optional_type(p);
|
Typespec *typespec = parse_optional_type(p, intern_int);
|
||||||
Decl *result = decl_enum(p->arena, name, name->intern_val, typespec);
|
Decl *result = decl_enum(p->arena, name, name->intern_val, typespec);
|
||||||
token_expect(p, TK_OpenBrace);
|
token_expect(p, TK_OpenBrace);
|
||||||
do{
|
do {
|
||||||
Note notes = parse_notes(p);
|
Note notes = parse_notes(p);
|
||||||
Token *val = token_expect(p, TK_Identifier);
|
Token *val = token_expect(p, TK_Identifier);
|
||||||
Expr *expr = parse_assign_expr(p);
|
Expr *expr = parse_assign_expr(p);
|
||||||
decl_enum_push(p->arena, result, val, val->intern_val, expr, ¬es);
|
decl_enum_push(p->arena, result, val, val->intern_val, expr, ¬es);
|
||||||
} while(token_match(p, TK_Comma));
|
if(!token_match(p, TK_Comma)){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}while(!token_is(p, TK_CloseBrace));
|
||||||
token_expect(p, TK_CloseBrace);
|
token_expect(p, TK_CloseBrace);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
parse_var_decl(Parser *p, Decl *parent, Token *name){
|
parse_var_decl(Parser *p, Decl *parent, Token *name, Note *notes){
|
||||||
Token *name_stack[64];
|
Token *name_stack[64];
|
||||||
S64 name_stack_len = 0;
|
S64 name_stack_len = 0;
|
||||||
name_stack[name_stack_len++] = name;
|
name_stack[name_stack_len++] = name;
|
||||||
@@ -640,6 +641,7 @@ parse_var_decl(Parser *p, Decl *parent, Token *name){
|
|||||||
token_expect(p, TK_Semicolon);
|
token_expect(p, TK_Semicolon);
|
||||||
for(S64 i = 0; i < name_stack_len; i++){
|
for(S64 i = 0; i < name_stack_len; i++){
|
||||||
Decl *decl = decl_variable(p->arena, name_stack[i], name_stack[i]->intern_val, typespec, 0);
|
Decl *decl = decl_variable(p->arena, name_stack[i], name_stack[i]->intern_val, typespec, 0);
|
||||||
|
decl_pass_notes(decl, notes);
|
||||||
decl_struct_push(parent, decl);
|
decl_struct_push(parent, decl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -651,35 +653,38 @@ parse_struct(Parser *p, Token *name, Decl_Kind struct_kind){
|
|||||||
Decl *result = decl_struct(p->arena, struct_kind, token, intern_name);
|
Decl *result = decl_struct(p->arena, struct_kind, token, intern_name);
|
||||||
token_expect(p, TK_OpenBrace);
|
token_expect(p, TK_OpenBrace);
|
||||||
do {
|
do {
|
||||||
|
Note notes = parse_notes(p);
|
||||||
Token *token = token_get(p);
|
Token *token = token_get(p);
|
||||||
if(token_match_keyword(p, keyword_union)){
|
if(token_match_keyword(p, keyword_union)){
|
||||||
Decl *decl = parse_struct(p, 0, DECL_SubUnion);
|
Decl *decl = parse_struct(p, 0, DECL_SubUnion);
|
||||||
|
decl_pass_notes(decl, ¬es);
|
||||||
decl_struct_push(result, decl);
|
decl_struct_push(result, decl);
|
||||||
}
|
}
|
||||||
else if(token_match_keyword(p, keyword_struct)){
|
else if(token_match_keyword(p, keyword_struct)){
|
||||||
Decl *decl = parse_struct(p, 0, DECL_SubStruct);
|
Decl *decl = parse_struct(p, 0, DECL_SubStruct);
|
||||||
|
decl_pass_notes(decl, ¬es);
|
||||||
decl_struct_push(result, decl);
|
decl_struct_push(result, decl);
|
||||||
}
|
}
|
||||||
else if(token_match(p, TK_Identifier)){
|
else if(token_match(p, TK_Identifier)){
|
||||||
if(token_is(p, TK_Colon)){
|
if(token_is(p, TK_Colon)){
|
||||||
if(token_peek_is_keyword(p, keyword_union, 1)){
|
if(token_peek_is_keyword(p, keyword_union, 1)){
|
||||||
token_next(p);
|
token_next(p); token_next(p);
|
||||||
token_next(p);
|
|
||||||
Decl *decl = parse_struct(p, token, DECL_SubUnion);
|
Decl *decl = parse_struct(p, token, DECL_SubUnion);
|
||||||
|
decl_pass_notes(decl, ¬es);
|
||||||
decl_struct_push(result, decl);
|
decl_struct_push(result, decl);
|
||||||
}
|
}
|
||||||
else if(token_peek_is_keyword(p, keyword_struct, 1)){
|
else if(token_peek_is_keyword(p, keyword_struct, 1)){
|
||||||
token_next(p);
|
token_next(p); token_next(p);
|
||||||
token_next(p);
|
|
||||||
Decl *decl = parse_struct(p, token, DECL_SubStruct);
|
Decl *decl = parse_struct(p, token, DECL_SubStruct);
|
||||||
|
decl_pass_notes(decl, ¬es);
|
||||||
decl_struct_push(result, decl);
|
decl_struct_push(result, decl);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
parse_var_decl(p, result, token);
|
parse_var_decl(p, result, token, ¬es);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
parse_var_decl(p, result, token);
|
parse_var_decl(p, result, token, ¬es);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@@ -690,9 +695,47 @@ parse_struct(Parser *p, Token *name, Decl_Kind struct_kind){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Decl *
|
function Decl *
|
||||||
parse_decl(Parser *p){
|
parse_typedef(Parser *p, Token *name){
|
||||||
Decl *result = 0;
|
token_expect(p, TK_Assign);
|
||||||
|
Typespec *typespec = parse_typespec(p);
|
||||||
|
token_expect(p, TK_Semicolon);
|
||||||
|
Decl *result = decl_typedef(p->arena, name, name->intern_val, typespec);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Decl *
|
||||||
|
parse_const(Parser *p, Token *name){
|
||||||
|
Typespec *typespec = 0;
|
||||||
|
if(token_match(p, TK_Colon))
|
||||||
|
typespec = parse_typespec(p);
|
||||||
|
token_expect(p, TK_Assign);
|
||||||
|
Expr *expr = parse_expr(p);
|
||||||
|
token_expect(p, TK_Semicolon);
|
||||||
|
Decl *result = decl_const(p->arena, name, name->intern_val, expr, typespec);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Decl *
|
||||||
|
parse_function(Parser *p, Token *name){
|
||||||
|
Decl *result = decl_function(p->arena, name, name->intern_val, 0);
|
||||||
|
if(!token_is(p, TK_CloseParen)){
|
||||||
|
do{
|
||||||
|
name = token_expect(p, TK_Identifier);
|
||||||
|
token_expect(p, TK_Colon);
|
||||||
|
Typespec *typespec = parse_typespec(p);
|
||||||
|
decl_func_push(p->arena, result, name, name->intern_val, typespec);
|
||||||
|
} while(token_match(p, TK_Comma));
|
||||||
|
}
|
||||||
|
token_expect(p, TK_CloseParen);
|
||||||
|
result->func_decl.ret = parse_optional_type(p, intern_void);
|
||||||
|
token_expect(p, TK_Semicolon);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function B32
|
||||||
|
parse_decl(Parser *p, Decl *parent){
|
||||||
Token *name = 0;
|
Token *name = 0;
|
||||||
|
Decl *result = 0;
|
||||||
Note note = parse_notes(p);
|
Note note = parse_notes(p);
|
||||||
if((name = token_match(p, TK_Identifier))){
|
if((name = token_match(p, TK_Identifier))){
|
||||||
if(token_match(p, TK_DoubleColon)){
|
if(token_match(p, TK_DoubleColon)){
|
||||||
@@ -706,31 +749,91 @@ parse_decl(Parser *p){
|
|||||||
else if((token = token_match_keyword(p, keyword_struct))){
|
else if((token = token_match_keyword(p, keyword_struct))){
|
||||||
result = parse_struct(p, name, DECL_Struct);
|
result = parse_struct(p, name, DECL_Struct);
|
||||||
}
|
}
|
||||||
|
else if((token = token_match_keyword(p, keyword_typedef))){
|
||||||
|
result = parse_typedef(p, name);
|
||||||
|
}
|
||||||
else if((token = token_match_keyword(p, keyword_const))){
|
else if((token = token_match_keyword(p, keyword_const))){
|
||||||
// Const value
|
result = parse_const(p, name);
|
||||||
}
|
}
|
||||||
else if((token = token_match(p, TK_OpenParen))){
|
else if((token = token_match(p, TK_OpenParen))){
|
||||||
// Function
|
result = parse_function(p, name);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
parser_push_error(p, token_get(p), "Expected token of kind todo:decl_tokens");
|
token = token_get(p);
|
||||||
|
parser_push_error(p, token, "Expected a declaration keyword. Got instead: %s", token_kind_string[token->kind]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
parser_push_error(p, token_get(p), "Expected token of kind '::'");
|
Token *token = token_get(p);
|
||||||
|
parser_push_error(p, token, "Expected a declaration which starts with token '::' got instead"
|
||||||
|
"token '%s'", token_kind_string[token->kind]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(result){
|
|
||||||
decl_pass_notes(result, ¬e);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(result){
|
||||||
|
decl_pass_notes(result, ¬e);
|
||||||
|
decl_list_push(parent, result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Decl
|
||||||
|
parse_decls(Parser *p){
|
||||||
|
Decl decl_list = {.kind=DECL_List};
|
||||||
|
while(!token_is(p, TK_End)){
|
||||||
|
B32 success = parse_decl(p, &decl_list);
|
||||||
|
if(!success){
|
||||||
|
parser_push_error(p, token_get(p), "Failed to parse decls, unexpected token!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return decl_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Statement parsing
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
stmt_list = '{' stmt* '}'
|
||||||
|
stmt =
|
||||||
|
| stmt_list
|
||||||
|
| 'return' expr ';'
|
||||||
|
| 'if' expr stmt_list
|
||||||
|
| 'for' simple_stmt_list ';' expr ';' simple_stmt_list stmt_list
|
||||||
|
| 'for' expr stmt_list
|
||||||
|
| expr assign? ';'
|
||||||
|
//| 'while' expr stmt_or_stmt_list
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
function Stmt *
|
||||||
|
parse_stmt(Parser *p){
|
||||||
|
Note notes = parse_notes(p);
|
||||||
|
Stmt *result = 0;
|
||||||
|
if(token_match_keyword(p, keyword_if)){
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(token_match_keyword(p, keyword_for)){
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(token_match_keyword(p, keyword_while)){
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(token_match_keyword(p, keyword_return)){
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(token_match(p, TK_OpenBrace)){
|
||||||
|
// Scope
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// Expr
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Test code
|
// Test code
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
function S64
|
function S64
|
||||||
eval_expr(Expr *expr){
|
eval_expr(Expr *expr){
|
||||||
switch(expr->kind){
|
switch(expr->kind){
|
||||||
@@ -875,15 +978,27 @@ parse_test_decls(){
|
|||||||
};
|
};
|
||||||
for(SizeU i = 0; i < buff_cap(decls); i++){
|
for(SizeU i = 0; i < buff_cap(decls); i++){
|
||||||
parser_restream(&p, decls[i], lit("Decl_Test"));
|
parser_restream(&p, decls[i], lit("Decl_Test"));
|
||||||
Decl *decl = parse_decl(&p);
|
Decl decl = parse_decls(&p);
|
||||||
assert(decl);
|
assert(decl.list_decl.first);
|
||||||
decl_print(decl);
|
decl_print(decl.list_decl.first);
|
||||||
}
|
}
|
||||||
|
arena_end_scratch();
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
parse_test_from_file(){
|
||||||
|
const String FILENAME = lit("test.cc");
|
||||||
|
Arena *scratch = arena_begin_scratch();
|
||||||
|
String file = os_read_file(scratch, FILENAME);
|
||||||
|
Parser p = parser_make_stream(scratch, file, FILENAME);
|
||||||
|
Decl d = parse_decls(&p);
|
||||||
|
decl_print(&d);
|
||||||
|
arena_end_scratch();
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
parse_test(){
|
parse_test(){
|
||||||
parse_test_expr();
|
parse_test_expr();
|
||||||
parse_test_decls();
|
parse_test_decls();
|
||||||
|
parse_test_from_file();
|
||||||
}
|
}
|
||||||
19
new_print.c
19
new_print.c
@@ -202,19 +202,32 @@ decl_print(Decl *node){
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case DECL_Const:
|
||||||
case DECL_Variable:{
|
case DECL_Variable:{
|
||||||
println("%s: ", node->name.s.str);
|
println("%s: ", node->name.s.str);
|
||||||
B32 r = typespec_print(node->var_decl.type);
|
if(node->var_decl.typespec) typespec_print(node->var_decl.typespec);
|
||||||
print_assign_expr(node->var_decl.expr);
|
print_assign_expr(node->var_decl.expr);
|
||||||
if(r) printf(";");
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DECL_Typedef:{
|
case DECL_Typedef:{
|
||||||
println("typedef %s ", node->name.s.str);
|
println("typedef %s ", node->name.s.str);
|
||||||
typespec_print(node->typedef_decl.type);
|
typespec_print(node->typedef_decl.typespec);
|
||||||
printf(";");
|
printf(";");
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case DECL_Function:{
|
||||||
|
println("");
|
||||||
|
typespec_print(node->func_decl.ret);
|
||||||
|
printf(" %s", node->name.s.str);
|
||||||
|
printf("(");
|
||||||
|
for(Decl_Function_Arg *arg = node->func_decl.first; arg; arg=arg->next){
|
||||||
|
printf("%s: ", arg->name.s.str);
|
||||||
|
typespec_print(arg->typespec);
|
||||||
|
if(arg != node->func_decl.last)
|
||||||
|
printf(", ");
|
||||||
|
}
|
||||||
|
printf(");");
|
||||||
|
} break;
|
||||||
|
|
||||||
case DECL_Struct:
|
case DECL_Struct:
|
||||||
case DECL_Union :{
|
case DECL_Union :{
|
||||||
|
|||||||
139
test.cc
139
test.cc
@@ -1,57 +1,23 @@
|
|||||||
#if 0
|
Thing :: const: *U32 = 0;
|
||||||
|
CONST_VAL::const = 185210591;
|
||||||
|
|
||||||
|
new_function::(Thing:[32]U32): U32;
|
||||||
@register
|
|
||||||
@param_expr(size)
|
|
||||||
@param_type(Type)
|
|
||||||
test::struct{
|
|
||||||
Array_Block::struct{
|
|
||||||
next: Array_Block*;
|
|
||||||
data: Type[size];
|
|
||||||
}
|
|
||||||
|
|
||||||
@inline Array::struct{
|
|
||||||
first: Array_Block;
|
|
||||||
last : Array_Block*;
|
|
||||||
block: S64;
|
|
||||||
len : S64;
|
|
||||||
}
|
|
||||||
|
|
||||||
array_make::(arena: Arena*) Type {
|
|
||||||
thing: Test_Type;
|
|
||||||
result: Type;
|
|
||||||
result.arena = arena;
|
|
||||||
result.last = &result.first;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
array_push::(array: Array*, item: Type*){
|
|
||||||
if array->len+1 > size{
|
|
||||||
assert(array->len);
|
|
||||||
block: Array_Block* = cast(Thing)arena_push_struct(array->arena, sizeof(:Array_Block));
|
|
||||||
array->last = array->last.next = block;
|
|
||||||
array->len = 0;
|
|
||||||
array->block += 1;
|
|
||||||
}
|
|
||||||
array->last.data[array->len++] = *item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@test(size = 4096)
|
@test(size = 4096)
|
||||||
OpenGL :: struct{
|
OpenGL :: struct{
|
||||||
glVertexAttribPointer: (GLuint, GLint, GLenum, GLboolean, GLsizei, GLvoid*);
|
glVertexAttribPointer: (GLuint, GLint, GLenum, GLboolean, GLsizei, *GLvoid);
|
||||||
glBindTexture: (GLenum, GLuint);
|
glBindTexture: (GLenum, GLuint);
|
||||||
glDrawArrays: (GLenum, GLint, GLsizei);
|
glDrawArrays: (GLenum, GLint, GLsizei);
|
||||||
|
|
||||||
test_array: int*[10];
|
test_array: [10]*int;
|
||||||
|
|
||||||
thing : Things*;
|
thing : *Things;
|
||||||
thing_cap: S64;
|
thing_cap: S64;
|
||||||
thing_len: S64;
|
thing_len: S64;
|
||||||
}
|
}
|
||||||
|
|
||||||
OS_Memory::struct{
|
OS_Memory::struct{
|
||||||
data: void*;
|
data: *void;
|
||||||
commit: SizeU;
|
commit: SizeU;
|
||||||
reserve: SizeU;
|
reserve: SizeU;
|
||||||
}
|
}
|
||||||
@@ -63,10 +29,11 @@ Arena::struct{
|
|||||||
}
|
}
|
||||||
|
|
||||||
String::struct{
|
String::struct{
|
||||||
str: U8*;
|
str: *U8;
|
||||||
len: S64;
|
len: S64;
|
||||||
}
|
}
|
||||||
Intern_String::typedef String;
|
Intern_String::typedef = String;
|
||||||
|
//CONST_VALUE::const = 121591;
|
||||||
|
|
||||||
@stringify
|
@stringify
|
||||||
@prefix="TK_"
|
@prefix="TK_"
|
||||||
@@ -147,12 +114,12 @@ Token::struct{
|
|||||||
}
|
}
|
||||||
file:String;
|
file:String;
|
||||||
line:S64;
|
line:S64;
|
||||||
line_begin:U8*;
|
line_begin:*U8;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lex_Stream::struct{
|
Lex_Stream::struct{
|
||||||
stream: U8*;
|
stream: *U8;
|
||||||
line_begin: U8*;
|
line_begin: *U8;
|
||||||
filename: String;
|
filename: String;
|
||||||
line: S64;
|
line: S64;
|
||||||
}
|
}
|
||||||
@@ -172,36 +139,36 @@ Expr_Kind::enum{
|
|||||||
|
|
||||||
Expr:: struct{
|
Expr:: struct{
|
||||||
kind: Expr_Kind;
|
kind: Expr_Kind;
|
||||||
token: Token*;
|
token: *Token;
|
||||||
next : Expr*;
|
next : *Expr;
|
||||||
union{
|
union{
|
||||||
cast_val: struct{
|
cast_val: struct{
|
||||||
type: AST_Node*;
|
type: *AST_Node;
|
||||||
expr: Expr*;
|
expr: *Expr;
|
||||||
}
|
}
|
||||||
list: struct{
|
list: struct{
|
||||||
first: Expr *;
|
first: *Expr;
|
||||||
last: Expr *;
|
last: *Expr;
|
||||||
}
|
}
|
||||||
call: struct{
|
call: struct{
|
||||||
atom: Expr *;
|
atom: *Expr;
|
||||||
list: Expr *;
|
list: *Expr;
|
||||||
}
|
}
|
||||||
index: struct{
|
index: struct{
|
||||||
atom: Expr *;
|
atom: *Expr;
|
||||||
index: Expr *;
|
index: *Expr;
|
||||||
}
|
}
|
||||||
unary: struct{
|
unary: struct{
|
||||||
expr: Expr* ;
|
expr: *Expr ;
|
||||||
}
|
}
|
||||||
binary: struct{
|
binary: struct{
|
||||||
left: Expr* ;
|
left: *Expr ;
|
||||||
right: Expr* ;
|
right: *Expr ;
|
||||||
}
|
}
|
||||||
ternary: struct{
|
ternary: struct{
|
||||||
cond: Expr* ;
|
cond: *Expr ;
|
||||||
on_true: Expr*;
|
on_true: *Expr;
|
||||||
on_false: Expr*;
|
on_false: *Expr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,36 +192,36 @@ AST_Kind::enum{
|
|||||||
|
|
||||||
AST_Node::struct{
|
AST_Node::struct{
|
||||||
kind: AST_Kind;
|
kind: AST_Kind;
|
||||||
pos : Token*;
|
pos : *Token;
|
||||||
name: Intern_String;
|
name: Intern_String;
|
||||||
|
|
||||||
next: AST_Node*;
|
next: *AST_Node;
|
||||||
next_scope: AST_Node*;
|
next_scope: *AST_Node;
|
||||||
|
|
||||||
first_note: AST_Node*;
|
first_note: *AST_Node;
|
||||||
last_note: AST_Node*;
|
last_note: *AST_Node;
|
||||||
|
|
||||||
first_child: AST_Node*;
|
first_child: *AST_Node;
|
||||||
last_child: AST_Node*;
|
last_child: *AST_Node;
|
||||||
union{
|
union{
|
||||||
base_type_size: SizeU;
|
base_type_size: SizeU;
|
||||||
pointer: AST_Node*;
|
pointer: *AST_Node;
|
||||||
typedef_type: AST_Node*;
|
typedef_type: *AST_Node;
|
||||||
variable_type: AST_Node*;
|
variable_type: *AST_Node;
|
||||||
func_return_type: AST_Node*;
|
func_return_type: *AST_Node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser_Error :: struct{
|
Parser_Error :: struct{
|
||||||
next: Parser_Error*;
|
next: *Parser_Error;
|
||||||
message: String;
|
message: String;
|
||||||
token : Token *;
|
token : *Token;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scope :: struct{
|
Scope :: struct{
|
||||||
next : Scope*;
|
next : *Scope;
|
||||||
first: AST_Node*;
|
first: *AST_Node;
|
||||||
last : AST_Node*;
|
last : *AST_Node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -263,21 +230,21 @@ Parser :: struct{
|
|||||||
intern_table_arena: Arena;
|
intern_table_arena: Arena;
|
||||||
symbol_table_arena: Arena;
|
symbol_table_arena: Arena;
|
||||||
|
|
||||||
scope_free_list: Scope *;
|
scope_free_list: Scope;
|
||||||
scope_stack: Scope *;
|
scope_stack: Scope;
|
||||||
global_scope: Scope *;
|
global_scope: Scope;
|
||||||
|
|
||||||
symbols_inserted: S64;
|
symbols_inserted: S64;
|
||||||
symbols_count: S64;
|
symbols_count: S64;
|
||||||
symbols: AST_Node *;
|
symbols: AST_Node;
|
||||||
|
|
||||||
interns: Intern_String *;
|
interns: Intern_String;
|
||||||
interns_in_bytes: S64;
|
interns_in_bytes: S64;
|
||||||
interns_inserted: S64;
|
interns_inserted: S64;
|
||||||
interns_count: S64;
|
interns_count: S64;
|
||||||
|
|
||||||
first_keyword: U8 *;
|
first_keyword: U8;
|
||||||
last_keyword: U8 *;
|
last_keyword: U8;
|
||||||
|
|
||||||
//@map(type="sparse") symbols: AST_Node;
|
//@map(type="sparse") symbols: AST_Node;
|
||||||
|
|
||||||
@@ -305,5 +272,3 @@ struct_type_lower_var_name_lower_push(struct_type *parent, var_type *child){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ token_array_iter_next(Token_Array *array){
|
|||||||
|
|
||||||
function Token *
|
function Token *
|
||||||
token_array_iter_peek(Token_Array *array, S64 i){
|
token_array_iter_peek(Token_Array *array, S64 i){
|
||||||
|
// @Todo(Krzosa): Simplify, too many calculations here
|
||||||
|
// Why even change state?
|
||||||
S64 save_len = array->iter_len;
|
S64 save_len = array->iter_len;
|
||||||
S64 save_block = array->iter_block;
|
S64 save_block = array->iter_block;
|
||||||
Token_Bucket *save_bucket = array->iter_bucket;
|
Token_Bucket *save_bucket = array->iter_bucket;
|
||||||
|
|||||||
Reference in New Issue
Block a user