Init new repository
This commit is contained in:
167
src/compiler/ast.c
Normal file
167
src/compiler/ast.c
Normal file
@@ -0,0 +1,167 @@
|
||||
LC_FUNCTION LC_AST *LC_CreateAST(LC_Token *pos, LC_ASTKind kind) {
|
||||
LC_AST *n = LC_PushStruct(L->ast_arena, LC_AST);
|
||||
n->id = ++L->ast_count;
|
||||
n->kind = kind;
|
||||
n->pos = pos;
|
||||
if (L->parser == &L->quick_parser) n->pos = &L->BuiltinToken;
|
||||
return n;
|
||||
}
|
||||
|
||||
LC_FUNCTION LC_AST *LC_CreateUnary(LC_Token *pos, LC_TokenKind op, LC_AST *expr) {
|
||||
LC_AST *r = LC_CreateAST(pos, LC_ASTKind_ExprUnary);
|
||||
r->eunary.op = op;
|
||||
r->eunary.expr = expr;
|
||||
return r;
|
||||
}
|
||||
|
||||
LC_FUNCTION LC_AST *LC_CreateBinary(LC_Token *pos, LC_AST *left, LC_AST *right, LC_TokenKind op) {
|
||||
LC_AST *r = LC_CreateAST(pos, LC_ASTKind_ExprBinary);
|
||||
r->ebinary.op = op;
|
||||
r->ebinary.left = left;
|
||||
r->ebinary.right = right;
|
||||
return r;
|
||||
}
|
||||
|
||||
LC_FUNCTION LC_AST *LC_CreateIndex(LC_Token *pos, LC_AST *left, LC_AST *index) {
|
||||
LC_AST *r = LC_CreateAST(pos, LC_ASTKind_ExprIndex);
|
||||
r->eindex.index = index;
|
||||
r->eindex.base = left;
|
||||
return r;
|
||||
}
|
||||
|
||||
LC_FUNCTION void LC_SetPointerSizeAndAlign(int size, int align) {
|
||||
L->pointer_align = align;
|
||||
L->pointer_size = size;
|
||||
if (L->tpvoid) {
|
||||
L->tpvoid->size = size;
|
||||
L->tpvoid->align = align;
|
||||
}
|
||||
if (L->tpchar) {
|
||||
L->tpchar->size = size;
|
||||
L->tpchar->align = align;
|
||||
}
|
||||
}
|
||||
|
||||
LC_FUNCTION LC_Type *LC_CreateType(LC_TypeKind kind) {
|
||||
LC_Type *r = LC_PushStruct(L->type_arena, LC_Type);
|
||||
L->type_count += 1;
|
||||
r->kind = kind;
|
||||
r->id = ++L->typeids;
|
||||
if (r->kind == LC_TypeKind_Proc || r->kind == LC_TypeKind_Pointer) {
|
||||
r->size = L->pointer_size;
|
||||
r->align = L->pointer_align;
|
||||
r->is_unsigned = true;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
LC_FUNCTION LC_Type *LC_CreateTypedef(LC_Decl *decl, LC_Type *base) {
|
||||
LC_Type *n = LC_CreateType(base->kind);
|
||||
*n = *base;
|
||||
decl->typedef_renamed_type_decl = base->decl;
|
||||
n->decl = decl;
|
||||
return n;
|
||||
}
|
||||
|
||||
LC_FUNCTION LC_Type *LC_CreatePointerType(LC_Type *type) {
|
||||
uint64_t key = (uint64_t)type;
|
||||
LC_Type *entry = (LC_Type *)LC_MapGetU64(&L->type_map, key);
|
||||
if (entry) {
|
||||
return entry;
|
||||
}
|
||||
LC_Type *n = LC_CreateType(LC_TypeKind_Pointer);
|
||||
n->tbase = type;
|
||||
LC_MapInsertU64(&L->type_map, key, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
LC_FUNCTION LC_Type *LC_CreateArrayType(LC_Type *type, int size) {
|
||||
uint64_t size_key = LC_HashBytes(&size, sizeof(size));
|
||||
uint64_t type_key = LC_HashBytes(type, sizeof(*type));
|
||||
uint64_t key = LC_HashMix(size_key, type_key);
|
||||
LC_Type *entry = (LC_Type *)LC_MapGetU64(&L->type_map, key);
|
||||
if (entry) {
|
||||
return entry;
|
||||
}
|
||||
LC_Type *n = LC_CreateType(LC_TypeKind_Array);
|
||||
n->tbase = type;
|
||||
n->tarray.size = size;
|
||||
n->size = type->size * size;
|
||||
n->align = type->align;
|
||||
LC_MapInsertU64(&L->type_map, key, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
LC_FUNCTION LC_Type *LC_CreateProcType(LC_TypeMemberList args, LC_Type *ret, bool has_vargs, bool has_vargs_any_promotion) {
|
||||
LC_ASSERT(NULL, ret);
|
||||
uint64_t key = LC_HashBytes(ret, sizeof(*ret));
|
||||
key = LC_HashMix(key, LC_HashBytes(&has_vargs, sizeof(has_vargs)));
|
||||
key = LC_HashMix(key, LC_HashBytes(&has_vargs_any_promotion, sizeof(has_vargs_any_promotion)));
|
||||
int procarg_count = 0;
|
||||
LC_TypeFor(it, args.first) {
|
||||
key = LC_HashMix(LC_HashBytes(it->type, sizeof(it->type[0])), key);
|
||||
key = LC_HashMix(LC_HashBytes((char *)it->name, LC_StrLen((char *)it->name)), key);
|
||||
if (it->default_value_expr) {
|
||||
key = LC_HashMix(LC_HashBytes(&it->default_value_expr, sizeof(LC_AST *)), key);
|
||||
}
|
||||
procarg_count += 1;
|
||||
}
|
||||
LC_Type *n = (LC_Type *)LC_MapGetU64(&L->type_map, key);
|
||||
if (n) return n;
|
||||
|
||||
n = LC_CreateType(LC_TypeKind_Proc);
|
||||
n->tproc.args = args;
|
||||
n->tproc.vargs = has_vargs;
|
||||
n->tproc.vargs_any_promotion = has_vargs_any_promotion;
|
||||
n->tproc.ret = ret;
|
||||
LC_MapInsertU64(&L->type_map, key, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
LC_FUNCTION LC_Type *LC_CreateIncompleteType(LC_Decl *decl) {
|
||||
LC_Type *n = LC_CreateType(LC_TypeKind_Incomplete);
|
||||
n->decl = decl;
|
||||
return n;
|
||||
}
|
||||
|
||||
LC_FUNCTION LC_Type *LC_CreateUntypedIntEx(LC_Type *base, LC_Decl *decl) {
|
||||
uint64_t hash_base = LC_HashBytes(base, sizeof(*base));
|
||||
uint64_t untyped_int = LC_TypeKind_UntypedInt;
|
||||
uint64_t key = LC_HashMix(hash_base, untyped_int);
|
||||
LC_Type *n = (LC_Type *)LC_MapGetU64(&L->type_map, key);
|
||||
if (n) return n;
|
||||
|
||||
n = LC_CreateType(LC_TypeKind_UntypedInt);
|
||||
n->tbase = base;
|
||||
n->decl = decl;
|
||||
return n;
|
||||
}
|
||||
|
||||
LC_FUNCTION LC_Type *LC_CreateUntypedInt(LC_Type *base) {
|
||||
LC_Decl *decl = LC_CreateDecl(LC_DeclKind_Type, LC_ILit("UntypedInt"), &L->NullAST);
|
||||
LC_Type *n = LC_CreateUntypedIntEx(base, decl);
|
||||
return n;
|
||||
}
|
||||
|
||||
LC_FUNCTION LC_TypeMember *LC_AddTypeToList(LC_TypeMemberList *list, LC_Intern name, LC_Type *type, LC_AST *ast) {
|
||||
LC_TypeFor(it, list->first) {
|
||||
if (name == it->name) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
LC_TypeMember *r = LC_PushStruct(L->arena, LC_TypeMember);
|
||||
r->name = name;
|
||||
r->type = type;
|
||||
r->ast = ast;
|
||||
LC_DLLAdd(list->first, list->last, r);
|
||||
list->count += 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
LC_FUNCTION LC_Type *LC_StripPointer(LC_Type *type) {
|
||||
if (type->kind == LC_TypeKind_Pointer) {
|
||||
return type->tbase;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
Reference in New Issue
Block a user