Fix bug on runtime "nameof" with optional values. Fixed issues with integer to enum casts. 0.2.25. Added enum_by_name.

This commit is contained in:
Christoffer Lerno
2022-07-27 00:46:02 +02:00
parent 1adc8b8264
commit 64d883cb99
7 changed files with 50 additions and 15 deletions

View File

@@ -9,6 +9,11 @@ fault IteratorResult
NO_MORE_ELEMENT
}
fault SearchResult
{
MISSING
}
fault VarCastResult
{
TYPE_MISMATCH
@@ -92,7 +97,19 @@ macro bitcast(expr, $Type) @builtin
var $size = (usize)($sizeof(expr));
$assert($size == $Type.sizeof, "Cannot bitcast between types of different size.");
$Type x = void;
memcpy(&x, &expr, $size, false, $alignof($Type), $alignof(expr));
mem::memcpy(&x, &expr, $size, false, $alignof($Type), $alignof(expr));
return x;
}
/**
* @require $Type.kind == TypeKind.ENUM `Only enums may be used`
**/
macro enum_by_name($Type, char[] enum_name) @builtin
{
typeid x = $Type.typeid;
foreach (i, name : x.names)
{
if (str::compare(name, enum_name)) return ($Type)i;
}
return SearchResult.MISSING!;
}

View File

@@ -51,8 +51,6 @@ macro void memset(void* dst, char val, usize bytes, bool $is_volatile = false, u
}
enum AllocationKind
{
ALLOC,

View File

@@ -48,6 +48,15 @@ fn ZString tcopy_zstring(char[] s)
return (ZString)str;
}
fn bool compare(char[] a, char[] b)
{
if (a.len != b.len) return false;
foreach (i, c : a)
{
if (c != b[i]) return false;
}
return true;
}
fault UnicodeResult
{
INVALID_UTF8,

View File

@@ -5576,7 +5576,8 @@ static inline void llvm_emit_builtin_access(GenContext *c, BEValue *be_value, Ex
return;
case ACCESS_FAULTNAME:
{
assert(inner->type->canonical->type_kind == TYPE_FAULTTYPE || inner->type->canonical->type_kind == TYPE_ANYERR);
Type *inner_type = type_no_fail(inner->type)->canonical;
assert(inner_type->type_kind == TYPE_FAULTTYPE || inner_type->type_kind == TYPE_ANYERR);
llvm_value_rvalue(c, be_value);
LLVMValueRef val = llvm_emit_alloca_aligned(c, type_chars, "faultname_zero");
BEValue zero;
@@ -5606,12 +5607,13 @@ static inline void llvm_emit_builtin_access(GenContext *c, BEValue *be_value, Ex
}
case ACCESS_ENUMNAME:
{
assert(inner->type->canonical->type_kind == TYPE_ENUM);
Type *inner_type = type_no_fail(inner->type)->canonical;
assert(inner_type->canonical->type_kind == TYPE_ENUM);
llvm_value_rvalue(c, be_value);
LLVMTypeRef subarray = llvm_get_type(c, type_chars);
LLVMTypeRef backend = LLVMTypeOf(inner->type->canonical->backend_typeid);
LLVMValueRef to_introspect = LLVMBuildIntToPtr(c->builder, inner->type->canonical->backend_typeid,
LLVMTypeRef backend = LLVMTypeOf(inner_type->backend_typeid);
LLVMValueRef to_introspect = LLVMBuildIntToPtr(c->builder, inner_type->backend_typeid,
LLVMPointerType(c->introspect_type, 0), "");
LLVMValueRef ptr = LLVMBuildStructGEP2(c->builder, c->introspect_type, to_introspect, INTROSPECT_INDEX_ADDITIONAL, "");
LLVMValueRef ptr_to_first = llvm_emit_bitcast(c, ptr, type_get_ptr(type_chars));

View File

@@ -229,10 +229,19 @@ static bool int_literal_to_int(Expr *expr, Type *canonical, Type *type)
/**
* Convert from compile time int to any enum
*/
bool lit_integer_to_enum(Expr *expr, Type *canonical, Type *type)
bool integer_to_enum(Expr *expr, Type *canonical, Type *type)
{
assert(canonical->type_kind == TYPE_ENUM);
unsigned max_enums = vec_size(canonical->decl->enums.values);
Decl *enum_decl = canonical->decl;
if (expr->expr_kind != EXPR_CONST)
{
REMINDER("Add check for runtime enum conversions");
Type *underlying_type = enum_decl->enums.type_info->type->canonical;
if (!cast(expr, underlying_type)) return false;
expr->type = type;
return true;
}
unsigned max_enums = vec_size(enum_decl->enums.values);
Int to_convert = expr->const_expr.ixx;
if (int_is_neg(to_convert))
{
@@ -245,7 +254,7 @@ bool lit_integer_to_enum(Expr *expr, Type *canonical, Type *type)
SEMA_ERROR(expr, "This value exceeds the number of enums in %s.", canonical->decl->name);
return false;
}
Decl *decl = canonical->decl->enums.values[to_convert.i.low];
Decl *decl = enum_decl->enums.values[to_convert.i.low];
expr->const_expr = (ExprConst) {
.enum_val = decl,
.const_kind = CONST_ENUM
@@ -1288,7 +1297,7 @@ static bool cast_inner(Expr *expr, Type *from_type, Type *to, Type *to_type)
if (type_is_float(to)) return int_to_float(expr, CAST_SIFP, to, to_type);
if (to == type_bool) return integer_to_bool(expr, to_type);
if (to->type_kind == TYPE_POINTER) return int_to_pointer(expr, to_type);
if (to->type_kind == TYPE_ENUM) return lit_integer_to_enum(expr, to, to_type);
if (to->type_kind == TYPE_ENUM) return integer_to_enum(expr, to, to_type);
break;
case ALL_UNSIGNED_INTS:
if (type_is_integer_unsigned(to)) return int_conversion(expr, CAST_UIUI, to, to_type);
@@ -1296,7 +1305,7 @@ static bool cast_inner(Expr *expr, Type *from_type, Type *to, Type *to_type)
if (type_is_float(to)) return int_to_float(expr, CAST_UIFP, to, to_type);
if (to == type_bool) return integer_to_bool(expr, to_type);
if (to->type_kind == TYPE_POINTER) return int_to_pointer(expr, to_type);
if (to->type_kind == TYPE_ENUM) return lit_integer_to_enum(expr, to, to_type);
if (to->type_kind == TYPE_ENUM) return integer_to_enum(expr, to, to_type);
break;
case ALL_FLOATS:
if (type_is_integer(to)) return float_to_integer(expr, to, to_type);

View File

@@ -65,7 +65,7 @@ void expr_rewrite_to_builtin_access(SemaContext *context, Expr *expr, Expr *pare
expr->expr_kind = EXPR_BUILTIN_ACCESS;
expr->builtin_access_expr.kind = kind;
expr->builtin_access_expr.inner = exprid(parent);
expr->type = type;
expr->type = type_get_opt_fail(type, IS_FAILABLE(parent));
expr->resolve_status = RESOLVE_DONE;
}
@@ -3683,7 +3683,7 @@ CHECK_DEEPER:
if (flat_type->type_kind == TYPE_TYPEID)
{
if (sema_expr_apply_typeid_property(context, expr, parent, kw)) return true;
SEMA_ERROR(identifier, "'%s' is not a valid proprty for typeid.", kw);
SEMA_ERROR(identifier, "'%s' is not a valid property for typeid.", kw);
return false;
}

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.2.24"
#define COMPILER_VERSION "0.2.25"