diff --git a/ast.c b/ast.c index a63ccb9..0bd6115 100644 --- a/ast.c +++ b/ast.c @@ -1,571 +1,5 @@ -typedef struct Expr Expr; -typedef struct Note Note; -typedef struct Stmt_If Stmt_If; -typedef struct Typespec Typespec; -typedef struct Decl_Enum_Child Decl_Enum_Child; -typedef struct Expr_Compound_Field Expr_Compound_Field; - -typedef struct AST AST; -typedef struct AST_Parent AST_Parent; - -//----------------------------------------------------------------------------- -// Expressions -//----------------------------------------------------------------------------- -typedef enum Expr_Sizeof_Kind{ - SIZEOF_Expr, - SIZEOF_Type, -}Expr_Sizeof_Kind; - -typedef enum Expr_Kind{ - EK_None, - EK_Int, - EK_String, - EK_Identifier, - EK_Compound, - EK_Paren, - EK_PostfixUnary, - EK_Unary, - EK_Binary, - EK_Ternary, - EK_Cast, - EK_Field, - EK_Call, - EK_Index, - EK_SizeType, - EK_SizeExpr, -} Expr_Kind; - -typedef enum Expr_Compound_Kind{ - COMPOUND_None, - COMPOUND_Default, - COMPOUND_Named, - COMPOUND_Index, -}Expr_Compound_Kind; - -struct Expr_Compound_Field{ - Expr_Compound_Field *next; - Expr_Compound_Kind kind; - Token *pos; - Expr *init; - union{ - Expr *index; - Intern_String name; - }; -}; - -struct Expr { - Expr_Kind kind; - Token *token; - Expr *next; - union { - U64 int_val; - Intern_String intern_val; - double float_val; - struct { - Expr *expr; - } paren; - struct { - Typespec *typespec; - Expr* expr; - } cast; - struct{ - Intern_String name; - Expr *expr; - }field; - - struct{ - Typespec *typespec; - Expr_Compound_Field *first; - Expr_Compound_Field *last; - }compound; - - struct { - Expr *atom; - Expr_Compound_Field *first; - Expr_Compound_Field *last; - } call; - struct{ - - }arg; - struct { - Expr *atom; - Expr *index; - } index; - - struct { - Token_Kind op; - Expr* expr; - } unary; - struct { - Token_Kind op; - Expr *expr; - } postfix_unary; - struct { - Token_Kind op; - Expr* left; - Expr* right; - } binary; - struct { - Expr* cond; - Expr* on_true; - Expr* on_false; - } ternary; - - struct{ - Typespec *typespec; - } size_type; - - struct{ - Expr *expr; - } size_expr; - }; -}; - -//----------------------------------------------------------------------------- -// Type specifiers -//----------------------------------------------------------------------------- -typedef enum Typespec_Kind{ - TS_None, - TS_Name, - TS_Pointer, - TS_Array, - TS_Function, - TS_NamedArgument, -}Typespec_Kind; - -struct Typespec{ - Typespec *next; - Typespec_Kind kind; - Token *pos; - union{ - Typespec *base; - Intern_String name; - struct{ - Intern_String name; - Typespec *base; - }named; - struct{ - Typespec *first; - Typespec *last; - Typespec *ret; - }func; - struct{ - Typespec *base; - Expr *size; - }arr; - }; -}; - -//----------------------------------------------------------------------------- -// Abstract Syntax Tree, declarations, statements all in one -//----------------------------------------------------------------------------- -typedef enum AST_Kind:U32{ - AST_None, - AST_Decl_Enum_Child, - AST_Decl_Var, - AST_Decl_Const, - AST_Decl_Typedef, - AST_Decl_Func_Arg, - AST_Decl_Variable, - AST_Stmt_ElseIf, - AST_Stmt_Else, - AST_Stmt_Init, - AST_Stmt_Expr, - AST_Stmt_Assign, - AST_Stmt_Return, - AST_Stmt_For, - AST_Stmt_Defer, - - AST_Decl_Struct, // First Parent, First Struct - AST_Decl_SubStruct, - AST_Decl_SubUnion, - AST_Decl_Union, // Last Struct - AST_Decl_Enum, - AST_Decl_Func, - AST_Note, - AST_Note_List, - AST_Stmt_Block, - AST_Stmt_If, - AST_Stmt_Decl, - AST_Program,// Last Parent - AST_FirstParent = AST_Decl_Struct, - AST_LastParent = AST_Program, - AST_FirstStruct = AST_Decl_Struct, - AST_LastStruct = AST_Decl_Union, -}AST_Kind; - -typedef enum AST_Flags{ - AST_Flags_None, - AST_Flags_Ordered = 1 -}AST_Flags; - -//----------------------------------------------------------------------------- -// Inheritence like macro helpers -//----------------------------------------------------------------------------- -// AST - 48 Bytes -// AST_Parent - 64 Bytes -#define AST_FIELDS AST_Kind kind; AST_Flags flags; AST *next, *prev; AST_Parent *notes; AST_Parent *parent; Token *pos -#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; } - -//----------------------------------------------------------------------------- -// Base classes -//----------------------------------------------------------------------------- -struct AST{AST_FIELDS;}; -typedef struct AST_Parent{ - AST_UNION; - AST_PARENT_FIELDS; -} AST_Parent; - -//----------------------------------------------------------------------------- -// Declarations -//----------------------------------------------------------------------------- -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 AST_Parent Stmt_Block; -typedef struct Decl_Func{ - AST_PARENT_UNION; - Intern_String name; - Typespec *ret; - Stmt_Block *body; - B32 is_incomplete; -}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; - -//----------------------------------------------------------------------------- -// Statements -//----------------------------------------------------------------------------- -typedef Stmt_If Stmt_If; -struct Stmt_If{ - AST_PARENT_UNION; - Expr *condition; - Stmt_Block *body; -}; - -typedef struct Stmt_ElseIf{ - AST_UNION; - Expr *condition; - Stmt_Block *body; -}Stmt_ElseIf; - -typedef struct Stmt_Else{ - AST_UNION; - Stmt_Block *body; -}Stmt_Else; - -typedef struct Stmt_Return{ - AST_UNION; - Expr *expr; -} Stmt_Return; - -typedef struct Stmt_Init{ - AST_UNION; - Intern_String name; - Typespec *typespec; - Expr *expr; -}Stmt_Init; - -typedef struct Stmt_Assign{ - AST_UNION; - Token_Kind op; - Expr *left; - Expr *right; -}Stmt_Assign; - -typedef struct Stmt_Expr{ - AST_UNION; - Expr *expr; -}Stmt_Expr; - -typedef struct Stmt_Defer{ - AST_UNION; - Stmt_Block *body; -}Stmt_Defer; - -typedef struct Stmt_For{ - AST_UNION; - AST *on_begin; - Expr*condition; - AST *on_iter; - Stmt_Block *body; -}Stmt_For; - -//----------------------------------------------------------------------------- -// Expression constructors -//----------------------------------------------------------------------------- -function Expr * -expr_new(Arena *p, Expr_Kind kind, Token *token){ - Expr *expr = arena_push_struct(p, Expr); - expr->kind = kind; - expr->token = token; - return expr; -} - -function Expr * -expr_int(Arena *p, Token *token){ - assert(token->kind == TK_Integer); - Expr *expr = expr_new(p, EK_Int, token); - expr->int_val = token->int_val; - return expr; -} - -function Expr * -expr_str(Arena *p, Token *token){ - assert(token->kind == TK_StringLit); - Expr *expr = expr_new(p, EK_String, token); - expr->intern_val = token->intern_val; - return expr; -} - -function Expr * -expr_identifier(Arena *p, Token *token){ - assert(token->kind == TK_Identifier); - Expr *expr = expr_new(p, EK_Identifier, token); - expr->intern_val = token->intern_val; - return expr; -} - -function Expr * -expr_field(Arena *p, Token *token, Expr *inexpr){ - assert(token->kind == TK_Identifier); - Expr *expr = expr_new(p, EK_Field, token); - expr->field.expr = inexpr; - expr->field.name = token->intern_val; - return expr; -} - -function Expr * -expr_paren(Arena *p, Token *token, Expr *inexpr){ - Expr *expr = expr_new(p, EK_Paren, token); - expr->paren.expr = inexpr; - return expr; -} - -function Expr * -expr_postfix_unary(Arena *p, Token *op, Expr *exp){ - Expr *expr = expr_new(p, EK_PostfixUnary, op); - expr->unary.op = op->kind; - expr->unary.expr = exp; - return expr; -} - -function Expr * -expr_unary(Arena *p, Token *op, Expr *exp){ - Expr *expr = expr_new(p, EK_Unary, op); - expr->unary.op = op->kind; - expr->unary.expr = exp; - return expr; -} - -function Expr * -expr_binary(Arena *p, Token *op, Expr *left, Expr *right){ - Expr *expr = expr_new(p, EK_Binary, op); - expr->binary.op = op->kind; - expr->binary.left = left; - expr->binary.right = right; - return expr; -} - -function Expr * -expr_ternary(Arena *p, Token *op, Expr *cond, Expr *on_true, Expr *on_false){ - Expr *expr = expr_new(p, EK_Ternary, op); - expr->ternary.cond = cond; - expr->ternary.on_true = on_true; - expr->ternary.on_false = on_false; - return expr; -} - -function Expr * -expr_call(Arena *p, Token *token, Expr *atom){ - Expr *expr = expr_new(p, EK_Call, token); - expr->call.atom = atom; - return expr; -} - -function Expr * -expr_index(Arena *p, Token *token, Expr *atom, Expr *index){ - Expr *expr = expr_new(p, EK_Index, token); - expr->index.atom = atom; - expr->index.index = index; - return expr; -} - -function Expr * -expr_cast(Arena *p, Token *token, Typespec *type, Expr *exp){ - Expr *expr = expr_new(p, EK_Cast, token); - expr->cast.typespec = type; - expr->cast.expr = exp; - return expr; -} - -function Expr * -expr_size_type(Arena *p, Token *token, Typespec *type){ - Expr *expr = expr_new(p, EK_SizeType, token); - expr->size_type.typespec = type; - return expr; -} - -function Expr * -expr_sizeof_expr(Arena *p, Token *token, Expr *in_expr){ - Expr *expr = expr_new(p, EK_SizeExpr, token); - expr->size_expr.expr = in_expr; - return expr; -} - -function Expr * -expr_compound(Arena *arena, Token *pos, Typespec *typespec){ - Expr *result = expr_new(arena, EK_Compound, pos); - result->compound.typespec = typespec; - return result; -} - -function Expr_Compound_Field * -expr_compound_new(Arena *arena, Expr_Compound_Kind kind, Token *pos, Expr *init){ - Expr_Compound_Field *result = arena_push_struct(arena, Expr_Compound_Field); - result->kind = kind; - result->pos = pos; - result->init = init; - return result; -} - -function Expr_Compound_Field * -expr_compound_default(Arena *arena, Token *pos, Expr *init){ - Expr_Compound_Field *result = expr_compound_new(arena, COMPOUND_Default, pos, init); - return result; -} - -function Expr_Compound_Field * -expr_compound_named(Arena *arena, Token *pos, Intern_String name, Expr *init){ - Expr_Compound_Field *result = expr_compound_new(arena, COMPOUND_Named, pos, init); - result->name = name; - return result; -} - -function Expr_Compound_Field * -expr_compound_index(Arena *arena, Token *pos, Expr *index, Expr *init){ - Expr_Compound_Field *result = expr_compound_new(arena, COMPOUND_Index, pos, init); - result->index = index; - return result; -} function void -expr_call_push(Expr *list, Expr_Compound_Field *field){ - SLLQueuePush(list->call.first, list->call.last, field); -} - -function void -expr_compound_push(Expr *list, Expr_Compound_Field *field){ - SLLQueuePush(list->compound.first, list->compound.last, field); -} - -//----------------------------------------------------------------------------- -// Type specifier constructors -//----------------------------------------------------------------------------- -function Typespec * -typespec_new(Arena *p, Typespec_Kind kind, Token *pos){ - Typespec *result = arena_push_struct(p, Typespec); - result->kind = kind; - result->pos = pos; - return result; -} - -function Typespec * -typespec_name(Arena *p, Token *pos, Intern_String name){ - Typespec *result = typespec_new(p, TS_Name, pos); - result->name = name; - return result; -} - -function Typespec * -typespec_pointer(Arena *p, Token *pos, Typespec *base){ - Typespec *result = typespec_new(p, TS_Pointer, pos); - result->base = base; - return result; -} - -function Typespec * -typespec_array(Arena *p, Token *pos, Typespec *base, Expr *size){ - Typespec *result = typespec_new(p, TS_Array, pos); - result->arr.base = base; - result->arr.size = size; - return result; -} - -function Typespec * -typespec_function(Arena *p, Token *pos, Typespec *ret){ - Typespec *result = typespec_new(p, TS_Function, pos); - result->func.ret = ret; - return result; -} - -function Typespec * -typespec_named_argument(Arena *arena, Token *pos, Typespec *typespec, Intern_String name){ - Typespec *result = typespec_new(arena, TS_NamedArgument, pos); - result->named.base = typespec; - result->named.name = name; - return result; -} - -function void -typespec_function_push(Typespec *func, Typespec *arg){ - SLLQueuePush(func->func.first, func->func.last, arg); -} - -//----------------------------------------------------------------------------- -// Double linked list -//----------------------------------------------------------------------------- - -function void ast_remove(AST *node){ AST_Parent *l = node->parent; assert(l); @@ -590,7 +24,7 @@ ast_remove(AST *node){ node->next=0; } -function void +function void ast_push_last(AST_Parent *l, AST *node){ if (l->first==0){ l->first=l->last=node; @@ -606,7 +40,7 @@ ast_push_last(AST_Parent *l, AST *node){ node->parent=l; } -function void +function void ast_push_first(AST_Parent *l, AST *node){ if(l->first == 0){ l->first = l->last = node; @@ -627,7 +61,7 @@ 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; @@ -646,7 +80,7 @@ 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; @@ -659,315 +93,3 @@ ast_push_before(AST *in_list, AST *node){ } node->parent = parent; } - -//----------------------------------------------------------------------------- -// AST Constructors -//----------------------------------------------------------------------------- -#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; -} - -//----------------------------------------------------------------------------- -// Notes -//----------------------------------------------------------------------------- - -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; -} - -#define ast_push_copy(a,p,T) arena_push_copy(a, p, sizeof(T)) -function AST * -ast_shallow_copy(Arena *a, AST *ast){ - AST *result = 0; - switch(ast->kind){ - case AST_Note_List: { - result = ast_push_copy(a, ast, Note_List); - } break; - default: invalid_codepath; - } - return result; -} - -//----------------------------------------------------------------------------- -// Declarations -//----------------------------------------------------------------------------- -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->name = name; - 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; - result->name = name; - 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_Block * -stmt_block(Arena *arena, Token *pos){ - Stmt_Block *result = ast_parent_new(arena, Stmt_Block, pos); - return result; -} - -function Stmt_If * -stmt_if(Arena *arena, Token *pos, Expr *condition){ - Stmt_If *result = ast_parent_new(arena, Stmt_If, pos); - result->condition = condition; - result->body = stmt_block(arena, pos); - return result; -} - -function Stmt_ElseIf * -stmt_else_if_push(Arena *arena, Stmt_If *parent, Token *pos, Expr *condition){ - Stmt_ElseIf *result = ast_new(arena, Stmt_ElseIf, pos); - result->condition = condition; - result->body = stmt_block(arena, pos); - ast_push_last((AST_Parent *)parent, (AST *)result); - return result; -} - -function Stmt_Else * -stmt_else_push(Arena *arena, Stmt_If *parent, Token *pos){ - Stmt_Else *result = ast_new(arena, Stmt_Else, pos); - result->body = stmt_block(arena, pos); - ast_push_last((AST_Parent *)parent, (AST *)result); - return result; -} - -function Stmt_Init * -stmt_init(Arena *arena, Token *pos, Intern_String name, Typespec *typespec, Expr *expr){ - Stmt_Init *result = ast_new(arena, Stmt_Init, pos); - result->typespec = typespec; - result->expr = expr; - result->name = name; - return result; -} - -function Stmt_Assign * -stmt_assign(Arena *arena, Token *pos, Token_Kind op, Expr *left, Expr *right){ - Stmt_Assign *result = ast_new(arena, Stmt_Assign, pos); - result->op = op; - result->left = left; - result->right = right; - return result; -} - -function Stmt_Expr * -stmt_expr(Arena *arena, Token *pos, Expr *expr){ - Stmt_Expr *result = ast_new(arena, Stmt_Expr, pos); - result->expr = expr; - return result; -} - -function Stmt_Return * -stmt_return(Arena *arena, Token *pos, Expr *expr){ - Stmt_Return *result = ast_new(arena, Stmt_Return, pos); - result->expr = expr; - return result; -} - -function Stmt_For * -stmt_for(Arena *arena, Token *pos, Token *pos_block, AST *on_begin, Expr *condition, AST *on_iter){ - Stmt_For *result = ast_new(arena, Stmt_For, pos); - result->on_iter = on_iter; - result->on_begin = on_begin; - result->condition = condition; - result->body = stmt_block(arena, pos_block); - return result; -} - -function Stmt_Defer * -stmt_defer(Arena *arena, Token *pos){ - Stmt_Defer *result = ast_new(arena, Stmt_Defer, pos); - result->body = stmt_block(arena, pos); - return result; -} - -//----------------------------------------------------------------------------- -// Test stuff -//----------------------------------------------------------------------------- -function void -list_print(AST_Parent *decls){ - printf("\n"); - printf("next:"); - for(AST *n = decls->first; n; n=n->next){ - printf("%d", n->kind); - } - printf("prev:"); - for(AST *n = decls->last; n; n=n->prev){ - printf("%d", n->kind); - } - printf("parent:"); - for(AST *n = decls->first; n; n=n->next){ - printf("%d", n->parent->kind); - } -} - -function void -ast_test(){ - printf("\nAST_Size = %u", (U32)sizeof(AST)); - printf("\nAST_Parent_Size = %u", (U32)sizeof(AST_Parent)); - printf("\nAST_Struct_Size = %u", (U32)sizeof(Decl_Struct)); - printf("\nAST_Func_Size = %u", (U32)sizeof(Decl_Func)); - - 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_last(&parent, decls); - ast_push_last(&parent, decls+1); - ast_push_last(&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); - */ -} - - diff --git a/cgenerate.cpp b/cgenerate.cpp index f8d5faf..acf0449 100644 --- a/cgenerate.cpp +++ b/cgenerate.cpp @@ -122,7 +122,7 @@ gen_expr(Ast_Expr *ast){ Ast_Begin(AST_CAST, Ast_Cast){ gen("("); gen("("); - gen_simple_decl(node->typespec->resolved_type, {}); + gen_simple_decl(resolved_typespec_get(node->typespec), {}); gen(")"); gen_expr(node->expr); gen(")"); @@ -248,11 +248,13 @@ gen_ast(Ast *ast){ if(node->expr->kind == AST_LAMBDA){ Ast_Lambda *lambda = (Ast_Lambda *)node->expr; gen("static "); - gen_simple_decl(lambda->ret->resolved_type, node->name); + Ast_Resolved_Type *ret = resolved_typespec_get(lambda->ret); + gen_simple_decl(ret, node->name); gen("("); For(lambda->args){ assert(it[0]->kind == AST_LAMBDA_ARG); - gen_simple_decl(it[0]->typespec->resolved_type, it[0]->name); + Ast_Resolved_Type *type = resolved_typespec_get(it[0]->typespec); + gen_simple_decl(type, it[0]->name); if(it != (lambda->args.end() - 1)) gen(", "); } gen(")"); diff --git a/main.cpp b/main.cpp index e3e2003..36ddf99 100644 --- a/main.cpp +++ b/main.cpp @@ -7,6 +7,9 @@ #include "new_resolve.cpp" #include "cgenerate.cpp" +/// @todo +/// [ ] - Typespecs should probably be expressions so stuff like would be possible :: *[32]int + int main(){ test_os_memory(); thread_ctx_init(); diff --git a/new_ast.cpp b/new_ast.cpp index 55410bb..b19fd05 100644 --- a/new_ast.cpp +++ b/new_ast.cpp @@ -113,6 +113,7 @@ struct Ast{ Ast_Kind kind; // @todo? + // bool is_atom: 1; // bool is_stmt: 1; // bool is_expr: 1; // bool is_decl: 1; @@ -200,7 +201,6 @@ struct Ast_Lambda : Ast_Expr { struct Ast_Resolved_Type; struct Ast_Typespec:Ast{ - Ast_Resolved_Type *resolved_type; union{ Ast_Typespec *base; Intern_String name; @@ -237,34 +237,34 @@ function Ast_Typespec *ast_typespec_name(Token *pos, Intern_String name); //----------------------------------------------------------------------------- #define AST_NEW(T,ikind,ipos) \ Ast_##T *result = exp_alloc_type(pctx->perm, Ast_##T, AF_ZeroMemory);\ - result->kind = ikind; \ + result->kind = AST_##ikind; \ result->pos = ipos; \ result->id = ++pctx->unique_ids function Ast_Atom * ast_expr_string(Token *pos, Intern_String string){ - AST_NEW(Atom, AST_STR, pos); + AST_NEW(Atom, STR, pos); result->intern_val = string; return result; } function Ast_Atom * ast_expr_identifier(Token *pos, Intern_String string){ - AST_NEW(Atom, AST_IDENT, pos); + AST_NEW(Atom, IDENT, pos); result->intern_val = string; return result; } function Ast_Atom * ast_expr_integer(Token *pos, S64 integer){ - AST_NEW(Atom, AST_INT, pos); + AST_NEW(Atom, INT, pos); result->int_val = integer; return result; } function Ast_Expr * ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){ - AST_NEW(Binary, AST_BINARY, op); + AST_NEW(Binary, BINARY, op); result->op = op->kind; result->left = left; result->right = right; @@ -273,7 +273,7 @@ ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){ function Ast_Compound * ast_expr_compound(Token *pos, Ast_Typespec *typespec, Array exprs){ - AST_NEW(Compound, AST_COMPOUND, pos); + AST_NEW(Compound, COMPOUND, pos); result->typespec = typespec; result->exprs = exprs.tight_copy(pctx->perm); return result; @@ -281,7 +281,7 @@ ast_expr_compound(Token *pos, Ast_Typespec *typespec, Array function Ast_Compound_Item * ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Atom *name, Ast_Expr *item){ - AST_NEW(Compound_Item, AST_COMPOUND_ITEM, pos); + AST_NEW(Compound_Item, COMPOUND_ITEM, pos); result->name = name; result->index = index; result->item = item; @@ -290,7 +290,7 @@ ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Atom *name, Ast_Expr *it function Ast_Expr * ast_expr_cast(Token *pos, Ast_Expr *expr, Ast_Typespec *typespec){ - AST_NEW(Cast, AST_CAST, pos); + AST_NEW(Cast, CAST, pos); result->expr = expr; result->typespec = typespec; return result; @@ -298,7 +298,7 @@ ast_expr_cast(Token *pos, Ast_Expr *expr, Ast_Typespec *typespec){ function Ast_Expr * ast_expr_unary(Token *pos, Token_Kind op, Ast_Expr *expr){ - AST_NEW(Unary, AST_UNARY, pos); + AST_NEW(Unary, UNARY, pos); result->expr = expr; result->op = op; return result; @@ -306,7 +306,7 @@ ast_expr_unary(Token *pos, Token_Kind op, Ast_Expr *expr){ function Ast_Expr * ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){ - AST_NEW(Index, AST_INDEX, pos); + AST_NEW(Index, INDEX, pos); result->expr = expr; result->index = index; return result; @@ -314,7 +314,7 @@ ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){ function Ast_Lambda * ast_lambda(Token *pos, Array params, Ast_Typespec *ret, Ast_Block *block){ - AST_NEW(Lambda, AST_LAMBDA, pos); + AST_NEW(Lambda, LAMBDA, pos); result->args = params.tight_copy(pctx->perm); result->ret = ret; result->block = block; @@ -326,13 +326,13 @@ ast_lambda(Token *pos, Array params, Ast_Typespec *ret, Ast_Bl function Ast_Expr * ast_expr_lambda_empty(Token *pos){ - AST_NEW(Expr, AST_LAMBDA, pos); + AST_NEW(Expr, LAMBDA, pos); return result; } function Ast_Lambda_Arg * ast_expr_lambda_arg(Token *pos, Intern_String name, Ast_Typespec *typespec){ - AST_NEW(Lambda_Arg, AST_LAMBDA_ARG, pos); + AST_NEW(Lambda_Arg, LAMBDA_ARG, pos); result->name = name; result->typespec = typespec; return result; @@ -340,21 +340,21 @@ ast_expr_lambda_arg(Token *pos, Intern_String name, Ast_Typespec *typespec){ function Ast_Block * ast_block(Token *pos, Array stmts){ - AST_NEW(Block, AST_BLOCK, pos); + AST_NEW(Block, BLOCK, pos); result->stmts = stmts.tight_copy(pctx->perm); return result; } function Ast_If * ast_if(Token *pos, Array ifs){ - AST_NEW(If, AST_IF, pos); + AST_NEW(If, IF, pos); result->ifs = ifs.tight_copy(pctx->perm); return result; } function Ast_If_Node * ast_if_node(Token *pos, Ast_Init *init, Ast_Expr *expr, Ast_Block *block){ - AST_NEW(If_Node, AST_IF_NODE, pos); + AST_NEW(If_Node, IF_NODE, pos); result->block = block; result->expr = expr; result->init = init; @@ -363,7 +363,7 @@ ast_if_node(Token *pos, Ast_Init *init, Ast_Expr *expr, Ast_Block *block){ function Ast_Init * ast_init(Token *pos, Token_Kind op, Ast_Atom *ident, Ast_Expr *expr){ - AST_NEW(Init, AST_INIT, pos); + AST_NEW(Init, INIT, pos); result->op = op; result->ident = ident; result->expr = expr; @@ -375,21 +375,21 @@ ast_init(Token *pos, Token_Kind op, Ast_Atom *ident, Ast_Expr *expr){ //----------------------------------------------------------------------------- function Ast_Typespec * ast_typespec_name(Token *pos, Intern_String name){ - AST_NEW(Typespec, AST_TYPESPEC_IDENT, pos); + AST_NEW(Typespec, TYPESPEC_IDENT, pos); result->name = name; return result; } function Ast_Typespec * ast_typespec_pointer(Token *pos, Ast_Typespec *base){ - AST_NEW(Typespec, AST_TYPESPEC_POINTER, pos); + AST_NEW(Typespec, TYPESPEC_POINTER, pos); result->base = base; return result; } function Ast_Typespec * ast_typespec_array(Token *pos, Ast_Typespec *base, Ast_Expr *expr){ - AST_NEW(Typespec, AST_TYPESPEC_ARRAY, pos); + AST_NEW(Typespec, TYPESPEC_ARRAY, pos); result->arr.base = base; result->arr.expr = expr; return result; @@ -397,7 +397,7 @@ ast_typespec_array(Token *pos, Ast_Typespec *base, Ast_Expr *expr){ function Ast_Typespec * ast_typespec_lambda(Token *pos, Ast_Lambda *lambda){ - AST_NEW(Typespec, AST_TYPESPEC_LAMBDA, pos); + AST_NEW(Typespec, TYPESPEC_LAMBDA, pos); result->lambda = lambda; return result; } @@ -408,7 +408,7 @@ ast_typespec_lambda(Token *pos, Ast_Lambda *lambda){ function Ast_Var * ast_var(Token *pos, Ast_Typespec *typespec, Intern_String name, Ast_Expr *expr){ - AST_NEW(Var, AST_VAR, pos); + AST_NEW(Var, VAR, pos); result->expr = expr; result->typespec = typespec; result->name = name; @@ -417,7 +417,7 @@ ast_var(Token *pos, Ast_Typespec *typespec, Intern_String name, Ast_Expr *expr){ function Ast_Const * ast_const(Token *pos, Intern_String name, Ast_Expr *expr){ - AST_NEW(Const, AST_CONST, pos); + AST_NEW(Const, CONST, pos); result->expr = expr; result->name = name; return result; @@ -425,7 +425,7 @@ ast_const(Token *pos, Intern_String name, Ast_Expr *expr){ function Ast_Package * ast_package(Token *pos, String name, Array decls){ - AST_NEW(Package, AST_PACKAGE, pos); + AST_NEW(Package, PACKAGE, pos); result->decls = decls.tight_copy(pctx->perm); result->ordered = array_make(pctx->perm, decls.len); result->name = intern_string(&pctx->interns, name); diff --git a/new_lex.cpp b/new_lex.cpp index 1e47466..cd8dfeb 100644 --- a/new_lex.cpp +++ b/new_lex.cpp @@ -326,7 +326,6 @@ lex__stream(Intern_Table *table, Array *array, Lex_Stream *s){ switch(lexc(s)){ case '\t': case ' ': lex_advance(s); t.indent++; break; case '\r': lex_advance(s); break; - case '/': { if(lexci(s,1) == '/'){ lex_advance(s); lex_advance(s); @@ -353,6 +352,11 @@ lex__stream(Intern_Table *table, Array *array, Lex_Stream *s){ } } break; + // @todo: add [;;] operator which adds new scope + // @todo: also need some way to detect indentation so that + // first of all we can check for consistency and second of + // all because we would know by how much to indent + // @todo: after detecting indentation 2 spaces would become 1 indent value case ';' : { Token semi = token_make(lexcp(s), s->file, s->line, s->line_begin); Token *last = lex_last_indent_token(s); diff --git a/new_parse.cpp b/new_parse.cpp index b150ae0..f8886ff 100644 --- a/new_parse.cpp +++ b/new_parse.cpp @@ -204,7 +204,7 @@ parse_block(){ do{ Token *token = token_get(); if(token_match_keyword(keyword_return)){ - AST_NEW(Return, AST_RETURN, token); + AST_NEW(Return, RETURN, token); if(!token_is_scope()) result->expr = parse_expr(); stmts.add(result); } diff --git a/new_resolve.cpp b/new_resolve.cpp index c1d2059..b5603eb 100644 --- a/new_resolve.cpp +++ b/new_resolve.cpp @@ -3,6 +3,7 @@ enum Sym_Kind{ SYM_NONE, + SYM_TYPESPEC, SYM_TYPE, SYM_CONST, SYM_VAR, @@ -103,6 +104,14 @@ resolved_get(Ast *ast){ return result; } +function Ast_Resolved_Type * +resolved_typespec_get(Ast_Typespec *ast){ + Sym *result = resolved_get(ast); + assert(result->kind == SYM_TYPESPEC); + assert(result->type); + return result->type; +} + function void sym_insert_builtin_type(String name, Ast_Resolved_Type *type){ Intern_String string = intern_string(&pctx->interns, name); @@ -152,8 +161,8 @@ eval_typespec(Ast_Typespec *ast){ parsing_error(node->pos, "This identifier is not a type"); } - node->resolved_type = type_sym->type; - return node->resolved_type; + sym_new_resolved(SYM_TYPESPEC, {}, type_sym->type, node); + return type_sym->type; Ast_End(); } @@ -162,15 +171,19 @@ eval_typespec(Ast_Typespec *ast){ Ast_Resolved_Type *ret = eval_typespec(node->lambda->ret); Array args = {scratch}; For(node->lambda->args) args.add(eval_typespec(it[0]->typespec)); - node->resolved_type = type_lambda(ret, args); - return node->resolved_type; + + Ast_Resolved_Type *resolved_type = type_lambda(ret, args); + sym_new_resolved(SYM_TYPESPEC, {}, resolved_type, node); + return resolved_type; Ast_End(); } Ast_Begin(AST_TYPESPEC_POINTER, Ast_Typespec){ Ast_Resolved_Type *type = eval_typespec(node->base); - node->resolved_type = type_pointer(type); - return node->resolved_type; + Ast_Resolved_Type *resolved_type = type_pointer(type); + + sym_new_resolved(SYM_TYPESPEC, {}, resolved_type, node); + return resolved_type; Ast_End(); } @@ -179,8 +192,10 @@ eval_typespec(Ast_Typespec *ast){ Operand expr = eval_expr(node->arr.expr); if(!expr.is_const) parsing_error(node->pos, "Array size is not a constant"); if(expr.type != type_int) parsing_error(node->pos, "Array size is expected to be of type [Int] is instead of type %s", type_names[expr.type->kind]); - node->resolved_type = type_array(type, expr.int_val); - return node->resolved_type; + + Ast_Resolved_Type *resolved_type = type_array(type, expr.int_val); + sym_new_resolved(SYM_TYPESPEC, {}, resolved_type, node); + return resolved_type; Ast_End(); } invalid_default_case; @@ -336,8 +351,11 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple Sym *arg_sym = sym_new_resolved(SYM_VAR, it[0]->name, type, it[0]); sym_insert(arg_sym); } + + Sym *resolved_ret = resolved_get(node->ret); + assert(resolved_ret->kind == SYM_TYPESPEC); For(node->block->stmts){ - eval_stmt(it[0], node->ret->resolved_type); + eval_stmt(it[0], resolved_ret->type); } scope_close(scope_index); }