168 lines
5.4 KiB
C
168 lines
5.4 KiB
C
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;
|
|
}
|