mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-31 20:00:09 +00:00
type_info_of; enum_value_to_string and string_to_enum_value
This commit is contained in:
+9
-5
@@ -4835,7 +4835,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
case BuiltinProc_size_of:
|
||||
case BuiltinProc_align_of:
|
||||
case BuiltinProc_offset_of:
|
||||
case BuiltinProc_type_info:
|
||||
case BuiltinProc_type_info_of:
|
||||
case BuiltinProc_transmute:
|
||||
// NOTE(bill): The first arg may be a Type, this will be checked case by case
|
||||
break;
|
||||
@@ -5295,10 +5295,10 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
break;
|
||||
|
||||
|
||||
case BuiltinProc_type_info: {
|
||||
// proc type_info(Type) -> ^Type_Info
|
||||
case BuiltinProc_type_info_of: {
|
||||
// proc type_info_of(Type) -> ^Type_Info
|
||||
if (c->context.scope->is_global) {
|
||||
compiler_error("`type_info` Cannot be declared within a #shared_global_scope due to how the internals of the compiler works");
|
||||
compiler_error("`type_info_of` Cannot be declared within a #shared_global_scope due to how the internals of the compiler works");
|
||||
}
|
||||
|
||||
// NOTE(bill): The type information may not be setup yet
|
||||
@@ -5311,7 +5311,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
}
|
||||
Type *t = o.type;
|
||||
if (t == nullptr || t == t_invalid || is_type_polymorphic(operand->type)) {
|
||||
error(ce->args[0], "Invalid argument for `type_info`");
|
||||
error(ce->args[0], "Invalid argument for `type_info_of`");
|
||||
return false;
|
||||
}
|
||||
t = default_type(t);
|
||||
@@ -7110,6 +7110,10 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
|
||||
o->mode = Addressing_Builtin;
|
||||
o->builtin_id = BuiltinProc_type_of;
|
||||
break;
|
||||
case Token_type_info_of:
|
||||
o->mode = Addressing_Builtin;
|
||||
o->builtin_id = BuiltinProc_type_info_of;
|
||||
break;
|
||||
|
||||
default:
|
||||
error(node, "Illegal implicit name `%.*s`", LIT(i->string));
|
||||
|
||||
+11
-10
@@ -40,7 +40,7 @@ enum BuiltinProcId {
|
||||
BuiltinProc_align_of,
|
||||
BuiltinProc_offset_of,
|
||||
BuiltinProc_type_of,
|
||||
BuiltinProc_type_info,
|
||||
BuiltinProc_type_info_of,
|
||||
|
||||
BuiltinProc_compile_assert,
|
||||
|
||||
@@ -86,7 +86,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
||||
{STR_LIT("align_of"), 1, false, Expr_Expr},
|
||||
{STR_LIT("offset_of"), 2, false, Expr_Expr},
|
||||
{STR_LIT("type_of"), 1, false, Expr_Expr},
|
||||
{STR_LIT("type_info"), 1, false, Expr_Expr},
|
||||
{STR_LIT("type_info_of"), 1, false, Expr_Expr},
|
||||
|
||||
{STR_LIT("compile_assert"), 1, false, Expr_Expr},
|
||||
|
||||
@@ -521,14 +521,15 @@ void scope_lookup_parent_entity(Scope *scope, String name, Scope **scope_, Entit
|
||||
if (found) {
|
||||
Entity *e = *found;
|
||||
if (gone_thru_proc) {
|
||||
// if (e->kind == Entity_Label) {
|
||||
// continue;
|
||||
// }
|
||||
// if (e->kind == Entity_Variable &&
|
||||
// !e->scope->is_file &&
|
||||
// !e->scope->is_global) {
|
||||
// continue;
|
||||
// }
|
||||
// IMPORTANT TODO(bill): Is this correct?!
|
||||
if (e->kind == Entity_Label) {
|
||||
continue;
|
||||
}
|
||||
if (e->kind == Entity_Variable &&
|
||||
!e->scope->is_file &&
|
||||
!e->scope->is_global) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (entity_) *entity_ = e;
|
||||
|
||||
+18
-13
@@ -3866,7 +3866,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
||||
return ir_emit_source_code_location(proc, procedure, pos);
|
||||
} break;
|
||||
|
||||
case BuiltinProc_type_info: {
|
||||
case BuiltinProc_type_info_of: {
|
||||
Type *t = default_type(type_of_expr(proc->module->info, ce->args[0]));
|
||||
return ir_type_info(proc, t);
|
||||
} break;
|
||||
@@ -4793,7 +4793,17 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
AstNode *p = unparen_expr(ce->proc);
|
||||
if (proc_mode == Addressing_Builtin) {
|
||||
Entity *e = entity_of_ident(proc->module->info, p);
|
||||
BuiltinProcId id = cast(BuiltinProcId)(e != nullptr ? e->Builtin.id : BuiltinProc_DIRECTIVE);
|
||||
BuiltinProcId id = BuiltinProc_Invalid;
|
||||
if (e != nullptr) {
|
||||
id = cast(BuiltinProcId)e->Builtin.id;
|
||||
} else {
|
||||
id = BuiltinProc_DIRECTIVE;
|
||||
if (ce->proc->kind == AstNode_Implicit) {
|
||||
ast_node(i, Implicit, ce->proc);
|
||||
GB_ASSERT(i->kind == Token_type_info_of);
|
||||
id = BuiltinProc_type_info_of;
|
||||
}
|
||||
}
|
||||
return ir_build_builtin_proc(proc, expr, tv, id);
|
||||
}
|
||||
|
||||
@@ -8106,24 +8116,19 @@ void ir_gen_tree(irGen *s) {
|
||||
str_lit("__$enum_values"), cast(i64)entry_index);
|
||||
|
||||
bool is_value_int = is_type_integer(t->Enum.base_type);
|
||||
if (!is_value_int) {
|
||||
GB_ASSERT(is_type_float(t->Enum.base_type));
|
||||
}
|
||||
|
||||
for (isize i = 0; i < count; i++) {
|
||||
irValue *name_ep = ir_emit_array_epi(proc, name_array, i);
|
||||
irValue *value_ep = ir_emit_array_epi(proc, value_array, i);
|
||||
|
||||
ExactValue value = fields[i]->Constant.value;
|
||||
irValue *v = ir_value_constant(a, t->Enum.base_type, value);
|
||||
|
||||
if (is_value_int) {
|
||||
value_ep = ir_emit_conv(proc, value_ep, t_i128_ptr);
|
||||
ir_emit_store(proc, value_ep, ir_value_constant(a, t_i128, value));
|
||||
} else {
|
||||
GB_ASSERT(is_type_float(t->Enum.base_type));
|
||||
f64 f = value.value_float;
|
||||
value_ep = ir_emit_conv(proc, value_ep, t_f64_ptr);
|
||||
ir_emit_store(proc, value_ep, ir_const_f64(a, f));
|
||||
}
|
||||
|
||||
ir_emit_store(proc, name_ep, ir_const_string(a, fields[i]->token.string));
|
||||
ir_emit_store(proc, value_ep, ir_emit_conv(proc, v, t_type_info_enum_value));
|
||||
ir_emit_store(proc, name_ep, ir_const_string(a, fields[i]->token.string));
|
||||
}
|
||||
|
||||
irValue *v_count = ir_const_int(a, count);
|
||||
|
||||
@@ -2217,6 +2217,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
||||
case Token_size_of:
|
||||
case Token_align_of:
|
||||
case Token_offset_of:
|
||||
case Token_type_info_of:
|
||||
return parse_call_expr(f, ast_implicit(f, advance_token(f)));
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -107,7 +107,6 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
|
||||
TOKEN_KIND(Token_macro, "macro"), \
|
||||
TOKEN_KIND(Token_struct, "struct"), \
|
||||
TOKEN_KIND(Token_union, "union"), \
|
||||
/* TOKEN_KIND(Token_raw_union, "raw_union"), */ \
|
||||
TOKEN_KIND(Token_enum, "enum"), \
|
||||
TOKEN_KIND(Token_bit_field, "bit_field"), \
|
||||
TOKEN_KIND(Token_vector, "vector"), \
|
||||
@@ -123,6 +122,7 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
|
||||
TOKEN_KIND(Token_align_of, "align_of"), \
|
||||
TOKEN_KIND(Token_offset_of, "offset_of"), \
|
||||
TOKEN_KIND(Token_type_of, "type_of"), \
|
||||
TOKEN_KIND(Token_type_info_of, "type_info_of"), \
|
||||
TOKEN_KIND(Token_asm, "asm"), \
|
||||
TOKEN_KIND(Token_yield, "yield"), \
|
||||
TOKEN_KIND(Token_await, "await"), \
|
||||
|
||||
Reference in New Issue
Block a user