Removed resolved pointer from Ast_Typespec, it's accessed using a map now
This commit is contained in:
886
ast.c
886
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);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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(")");
|
||||
|
||||
3
main.cpp
3
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();
|
||||
|
||||
50
new_ast.cpp
50
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<Ast_Compound_Item *> 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<Ast_Compound_Item *>
|
||||
|
||||
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<Ast_Lambda_Arg *> 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<Ast_Lambda_Arg *> 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<Ast *> 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<Ast_If_Node *> 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<Ast_Named *> decls){
|
||||
AST_NEW(Package, AST_PACKAGE, pos);
|
||||
AST_NEW(Package, PACKAGE, pos);
|
||||
result->decls = decls.tight_copy(pctx->perm);
|
||||
result->ordered = array_make<Ast_Named *>(pctx->perm, decls.len);
|
||||
result->name = intern_string(&pctx->interns, name);
|
||||
|
||||
@@ -326,7 +326,6 @@ lex__stream(Intern_Table *table, Array<Token> *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<Token> *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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<Ast_Resolved_Type *> 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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user