acc/src/vtype.c
2023-06-26 08:13:31 +08:00

88 lines
1.7 KiB
C

#include "vtype.h"
#include "ast.h"
#include "fatals.h"
// Find out the type after appling the give ast operator(unary arithmetic variant).
// Writes into parameter _res_
void VType_unary(const struct VType *self, int op, struct VType *res, int line) {
if (op == A_RETURN) {
VType_init(res);
return;
}
*res = *self;
if (self->bt == VT_VOID) {
fail_type(line);
}
switch (op) {
case A_BNOT:
case A_NEG: {
} break;
case A_LNOT: {
res->bt = VT_BOOL;
} break;
default: {
fail_ast_op(op, __FUNCTION__);
}
}
}
// Initialize a VType into void.
void VType_init(struct VType *self) {
self->bt = VT_VOID;
}
// Returns the number of bits in a int type.
// Returns 0 if the given value type is not a variant of int type.
int VType_int_size(const struct VType *self) {
static const int map[][2] = {
{VT_BOOL, 1},
{VT_I32, 32},
{VT_I64, 64},
{VT_EXCEED},
};
for (int i = 0; map[i][0] != VT_EXCEED; ++i) {
if (map[i][0] == self->bt) {
return (map[i][1]);
}
}
return (0);
}
// Returns whether the first given value type can be extended to be equal second.
bool VType_ext_eq(const struct VType *x, const struct VType *y) {
if (VType_eq(x, y)) {
return (true);
}
int xsz = VType_int_size(x);
if (xsz == 0) {
return (false);
}
int ysz = VType_int_size(y);
if (ysz == 0) {
return (false);
}
return (xsz <= ysz);
}
// Returns whether the given value types are the same.
bool VType_eq(const struct VType *x, const struct VType *y) {
return (x->bt == y->bt);
}
// Returns whether the given VType is a variant of integer(including bool)
bool VType_is_int(const struct VType *self) {
switch (self->bt) {
case VT_BOOL: case VT_I32: case VT_I64:
return (true);
default:
return (false);
}
}