Files

117 lines
5.6 KiB
C

#include "spl_intrin.h"
static const spl_intrin_info_t g_intrin_table[] = {
[SPL_INTRIN_NONE] = {0},
[SPL_INTRIN_BITSIZEOF] = {"@bitsizeof", SPL_INTRIN_BITSIZEOF, SPL_INTRIN_FORM_CALL, 1, 1,
SPL_INTRIN_RESULT_USIZE},
[SPL_INTRIN_SIZEOF] = {"@sizeof", SPL_INTRIN_SIZEOF, SPL_INTRIN_FORM_CALL, 1, 1,
SPL_INTRIN_RESULT_USIZE},
[SPL_INTRIN_ALIGNOF] = {"@alignof", SPL_INTRIN_ALIGNOF, SPL_INTRIN_FORM_CALL, 1, 1,
SPL_INTRIN_RESULT_USIZE},
[SPL_INTRIN_ASSERT] = {"@assert", SPL_INTRIN_ASSERT, SPL_INTRIN_FORM_CALL, 1, 2,
SPL_INTRIN_RESULT_UNIT},
[SPL_INTRIN_BREAKPOINT] = {"@breakpoint", SPL_INTRIN_BREAKPOINT, SPL_INTRIN_FORM_CALL, 0, 0,
SPL_INTRIN_RESULT_UNIT},
[SPL_INTRIN_LEN] = {"len", SPL_INTRIN_LEN, SPL_INTRIN_FORM_FIELD, 0, 0,
SPL_INTRIN_RESULT_USIZE},
[SPL_INTRIN_INT_CAST] = {"@int_cast", SPL_INTRIN_INT_CAST, SPL_INTRIN_FORM_CALL, 2, 2,
SPL_INTRIN_RESULT_UNIT},
[SPL_INTRIN_TRUNCATE] = {"@truncate", SPL_INTRIN_TRUNCATE, SPL_INTRIN_FORM_CALL, 2, 2,
SPL_INTRIN_RESULT_UNIT},
[SPL_INTRIN_BIT_CAST] = {"@bit_cast", SPL_INTRIN_BIT_CAST, SPL_INTRIN_FORM_CALL, 2, 2,
SPL_INTRIN_RESULT_UNIT},
[SPL_INTRIN_FLOAT_CAST] = {"@float_cast", SPL_INTRIN_FLOAT_CAST, SPL_INTRIN_FORM_CALL, 2, 2,
SPL_INTRIN_RESULT_UNIT},
[SPL_INTRIN_FLOAT2INT] = {"@float2int", SPL_INTRIN_FLOAT2INT, SPL_INTRIN_FORM_CALL, 2, 2,
SPL_INTRIN_RESULT_UNIT},
[SPL_INTRIN_INT2FLOAT] = {"@int2float", SPL_INTRIN_INT2FLOAT, SPL_INTRIN_FORM_CALL, 2, 2,
SPL_INTRIN_RESULT_UNIT},
[SPL_INTRIN_BOOL2INT] = {"@bool2int", SPL_INTRIN_BOOL2INT, SPL_INTRIN_FORM_CALL, 1, 2,
SPL_INTRIN_RESULT_UNIT},
[SPL_INTRIN_PTR2INT] = {"@ptr2int", SPL_INTRIN_PTR2INT, SPL_INTRIN_FORM_CALL, 1, 2,
SPL_INTRIN_RESULT_UNIT},
[SPL_INTRIN_INT2PTR] = {"@int2ptr", SPL_INTRIN_INT2PTR, SPL_INTRIN_FORM_CALL, 2, 2,
SPL_INTRIN_RESULT_UNIT},
[SPL_INTRIN_PTR_CAST] = {"@ptr_cast", SPL_INTRIN_PTR_CAST, SPL_INTRIN_FORM_CALL, 2, 2,
SPL_INTRIN_RESULT_UNIT},
[SPL_INTRIN_ENUM2INT] = {"@enum2int", SPL_INTRIN_ENUM2INT, SPL_INTRIN_FORM_CALL, 1, 1,
SPL_INTRIN_RESULT_USIZE},
[SPL_INTRIN_OFFSETOF] = {"@offsetof", SPL_INTRIN_OFFSETOF, SPL_INTRIN_FORM_CALL, 2, 2,
SPL_INTRIN_RESULT_USIZE},
[SPL_INTRIN_FIELD_COUNT] = {"@field_count", SPL_INTRIN_FIELD_COUNT, SPL_INTRIN_FORM_CALL, 1, 1,
SPL_INTRIN_RESULT_USIZE},
[SPL_INTRIN_FILE_NAME] = {"@file_name", SPL_INTRIN_FILE_NAME, SPL_INTRIN_FORM_CALL, 0, 0,
SPL_INTRIN_RESULT_USIZE},
[SPL_INTRIN_LINE] = {"@line", SPL_INTRIN_LINE, SPL_INTRIN_FORM_CALL, 0, 0,
SPL_INTRIN_RESULT_USIZE},
[SPL_INTRIN_COL] = {"@col", SPL_INTRIN_COL, SPL_INTRIN_FORM_CALL, 0, 0,
SPL_INTRIN_RESULT_USIZE},
[SPL_INTRIN_FN_NAME] = {"@fn_name", SPL_INTRIN_FN_NAME, SPL_INTRIN_FORM_CALL, 0, 0,
SPL_INTRIN_RESULT_USIZE},
};
static const usize g_intrin_count = sizeof(g_intrin_table) / sizeof(g_intrin_table[0]);
const spl_intrin_info_t *spl_intrin_info(spl_intrin_t kind) {
if ((usize)kind >= g_intrin_count)
return NULL;
return &g_intrin_table[kind];
}
spl_intrin_t spl_intrin_lookup_call(const char *name) {
if (!name)
return SPL_INTRIN_NONE;
const char *n = name[0] == '@' ? name + 1 : name;
for (usize i = 1; i < g_intrin_count; ++i) {
const spl_intrin_info_t *d = &g_intrin_table[i];
if (d->form != SPL_INTRIN_FORM_CALL)
continue;
const char *dn = d->name[0] == '@' ? d->name + 1 : d->name;
if (strcmp(dn, n) == 0)
return d->kind;
}
return SPL_INTRIN_NONE;
}
spl_intrin_t spl_intrin_lookup_field(spl_lang_type_kind_t recv_kind, const char *field) {
if (!field)
return SPL_INTRIN_NONE;
if (strcmp(field, "len") == 0) {
if (recv_kind == SPL_LANG_TYPE_ARRAY || recv_kind == SPL_LANG_TYPE_SLICE)
return SPL_INTRIN_LEN;
}
return SPL_INTRIN_NONE;
}
spl_intrin_t spl_intrin_lookup_cast(spl_type_t *type, spl_type_id_t ft, spl_type_id_t tt) {
/* 这是 `as` 的展开规则表。要调整 as 的语义,改这里。 */
spl_type_node_t *f = spl_type_node(type, ft);
spl_type_node_t *t = spl_type_node(type, tt);
if (!f || !t)
return SPL_INTRIN_NONE;
if (f->kind == SPL_TYPE_INT && t->kind == SPL_TYPE_INT) {
usize fb = f->int_type.bits;
usize tb = t->int_type.bits;
if (fb == tb)
return SPL_INTRIN_BIT_CAST;
if (fb > tb)
return SPL_INTRIN_TRUNCATE;
return SPL_INTRIN_INT_CAST;
}
if (f->kind == SPL_TYPE_FLOAT && t->kind == SPL_TYPE_FLOAT)
return SPL_INTRIN_FLOAT_CAST;
if (f->kind == SPL_TYPE_BOOL && t->kind == SPL_TYPE_INT)
return SPL_INTRIN_BOOL2INT;
if (f->kind == SPL_TYPE_PTR && t->kind == SPL_TYPE_INT)
return SPL_INTRIN_PTR2INT;
if (f->kind == SPL_TYPE_INT && t->kind == SPL_TYPE_PTR)
return SPL_INTRIN_INT2PTR;
if (f->kind == SPL_TYPE_PTR && t->kind == SPL_TYPE_PTR)
return SPL_INTRIN_PTR_CAST;
/* int float 刻意不在这里:只能通过显式 builtin 调用。
enum<->int 也刻意禁止(用 @enum2int 取 tag)。 */
return SPL_INTRIN_NONE;
}