- Casting bitstruct to wider base type should be single step #2616.

- Experimental accept of ~ and ^ for optionals.
This commit is contained in:
Christoffer Lerno
2025-12-05 20:18:32 +01:00
parent 034a048c8a
commit a61fd6d280
6 changed files with 53 additions and 21 deletions

View File

@@ -70,7 +70,7 @@ fn any? AnyList.last_any(&self) @inline => InterfaceList {any}.last(self);
*>
macro AnyList.pop(&self, $Type)
{
if (!self.size) return NO_MORE_ELEMENT?;
if (!self.size) return NO_MORE_ELEMENT~;
defer self.free_element(self.entries[self.size]);
return *anycast(self.entries[--self.size], $Type);
}
@@ -85,7 +85,7 @@ macro AnyList.pop(&self, $Type)
*>
macro AnyList.pop_first(&self, $Type)
{
if (!self.size) return NO_MORE_ELEMENT?;
if (!self.size) return NO_MORE_ELEMENT~;
defer self.remove_at(0);
return *anycast(self.entries[0], $Type);
}

View File

@@ -46,7 +46,7 @@ fn String ElasticArray.to_tstring(&self)
fn void? ElasticArray.push_try(&self, Type element) @inline
{
if (self.size == MAX_SIZE) return mem::OUT_OF_MEMORY?;
if (self.size == MAX_SIZE) return mem::OUT_OF_MEMORY~;
self.entries[self.size++] = element;
}
@@ -60,7 +60,7 @@ fn void ElasticArray.push(&self, Type element) @inline
fn Type? ElasticArray.pop(&self)
{
if (!self.size) return NO_MORE_ELEMENT?;
if (!self.size) return NO_MORE_ELEMENT~;
return self.entries[--self.size];
}
@@ -74,7 +74,7 @@ fn void ElasticArray.clear(&self)
*>
fn Type? ElasticArray.pop_first(&self)
{
if (!self.size) return NO_MORE_ELEMENT?;
if (!self.size) return NO_MORE_ELEMENT~;
defer self.remove_at(0);
return self.entries[0];
}
@@ -241,7 +241,7 @@ fn void? ElasticArray.push_front_try(&self, Type type) @inline
*>
fn void? ElasticArray.insert_at_try(&self, usz index, Type value)
{
if (self.size == MAX_SIZE) return mem::OUT_OF_MEMORY?;
if (self.size == MAX_SIZE) return mem::OUT_OF_MEMORY~;
self.insert_at(index, value);
}
@@ -269,25 +269,25 @@ fn void ElasticArray.set_at(&self, usz index, Type type)
fn void? ElasticArray.remove_last(&self) @maydiscard
{
if (!self.size) return NO_MORE_ELEMENT?;
if (!self.size) return NO_MORE_ELEMENT~;
self.size--;
}
fn void? ElasticArray.remove_first(&self) @maydiscard
{
if (!self.size) return NO_MORE_ELEMENT?;
if (!self.size) return NO_MORE_ELEMENT~;
self.remove_at(0);
}
fn Type? ElasticArray.first(&self)
{
if (!self.size) return NO_MORE_ELEMENT?;
if (!self.size) return NO_MORE_ELEMENT~;
return self.entries[0];
}
fn Type? ElasticArray.last(&self)
{
if (!self.size) return NO_MORE_ELEMENT?;
if (!self.size) return NO_MORE_ELEMENT~;
return self.entries[self.size - 1];
}

View File

@@ -242,8 +242,7 @@ macro Object* Object.push(&self, value)
<*
@require self.is_keyable()
*>
fn Object*? Object.get(&self, String key) => self.is_empty() ? NOT_FOUND? : self.map.get(key);
fn Object*? Object.get(&self, String key) => self.is_empty() ? NOT_FOUND~ : self.map.get(key);
fn bool Object.has_key(&self, String key) => self.is_map() && self.map.has_key(key);
@@ -308,7 +307,7 @@ macro get_integer_value(Object* value, $Type)
return ($Type)value.s.to_uint128();
$endif
}
if (!value.is_int()) return string::MALFORMED_INTEGER?;
if (!value.is_int()) return string::MALFORMED_INTEGER~;
return ($Type)value.i;
}
@@ -361,7 +360,7 @@ fn uint128? Object.get_uint128_at(&self, usz index) => self.get_integer_at(uint1
fn String? Object.get_string(&self, String key)
{
Object* value = self.get(key)!;
if (!value.is_string()) return TYPE_MISMATCH?;
if (!value.is_string()) return TYPE_MISMATCH~;
return value.s;
}
@@ -371,7 +370,7 @@ fn String? Object.get_string(&self, String key)
fn String? Object.get_string_at(&self, usz index)
{
Object* value = self.get_at(index);
if (!value.is_string()) return TYPE_MISMATCH?;
if (!value.is_string()) return TYPE_MISMATCH~;
return value.s;
}
@@ -381,7 +380,7 @@ fn String? Object.get_string_at(&self, usz index)
macro String? Object.get_enum(&self, $EnumType, String key)
{
Object value = self.get(key)!;
if ($EnumType.typeid != value.type) return TYPE_MISMATCH?;
if ($EnumType.typeid != value.type) return TYPE_MISMATCH~;
return ($EnumType)value.i;
}
@@ -391,7 +390,7 @@ macro String? Object.get_enum(&self, $EnumType, String key)
macro String? Object.get_enum_at(&self, $EnumType, usz index)
{
Object value = self.get_at(index);
if ($EnumType.typeid != value.type) return TYPE_MISMATCH?;
if ($EnumType.typeid != value.type) return TYPE_MISMATCH~;
return ($EnumType)value.i;
}

View File

@@ -7,6 +7,7 @@
### Fixes
- Regression with npot vector in struct triggering an assert #2219.
- Casting bitstruct to wider base type should be single step #2616.
### Stdlib changes

View File

@@ -716,6 +716,29 @@ static Expr *parse_unary_expr(ParseContext *c, Expr *left, SourceSpan lhs_start
return unary;
}
static Expr *parse_raise_expr_suffix(ParseContext *c, Expr *left_side, SourceSpan lhs_start)
{
ASSERT(expr_ok(left_side));
advance_and_verify(c, TOKEN_BIT_NOT);
Expr *expr = expr_new(EXPR_OPTIONAL, lhs_start);
expr->inner_expr = left_side;
RANGE_EXTEND_PREV(expr);
return expr;
}
static Expr *parse_raise_expr(ParseContext *c, Expr *left, SourceSpan lhs_start UNUSED)
{
ASSERT(!left && "Did not expect a left hand side!");
Expr *opt = EXPR_NEW_TOKEN(EXPR_OPTIONAL);
advance(c);
Expr *right_side = parse_precedence(c, PREC_UNARY);
CHECK_EXPR_OR_RET(right_side);
opt->inner_expr = right_side;
RANGE_EXTEND_PREV(opt);
return opt;
}
/**
* post_unary_expr ::= <expr> unary_op
*/
@@ -2196,8 +2219,8 @@ ParseRule rules[TOKEN_EOF + 1] = {
[TOKEN_DOT] = { NULL, parse_access_expr, PREC_CALL },
[TOKEN_BANG] = { parse_unary_expr, parse_rethrow_expr, PREC_CALL },
[TOKEN_BYTES] = { parse_bytes_expr, NULL, PREC_NONE },
[TOKEN_BIT_NOT] = { parse_unary_expr, NULL, PREC_UNARY },
[TOKEN_BIT_XOR] = { NULL, parse_binary, PREC_BIT },
[TOKEN_BIT_NOT] = { parse_unary_expr, parse_raise_expr_suffix, PREC_CALL },
[TOKEN_BIT_XOR] = { parse_raise_expr, parse_binary, PREC_BIT },
[TOKEN_BIT_OR] = { NULL, parse_binary, PREC_BIT },
[TOKEN_AMP] = { parse_unary_expr, parse_binary, PREC_BIT },
[TOKEN_EQEQ] = { NULL, parse_binary, PREC_RELATIONAL },

View File

@@ -1683,7 +1683,7 @@ RETRY:
base_type = base_type->decl->distinct->type->canonical;
goto RETRY;
}
if (!type_is_integer(base_type) || type_size(to) != type_size(base_type))
if (!type_is_integer(base_type) || type_size(to) < type_size(base_type))
{
return sema_cast_error(cc, false, is_silent);
}
@@ -1891,7 +1891,16 @@ static void cast_expand_to_vec(Expr *expr, Type *type)
expr->resolve_status = RESOLVE_DONE;
}
static void cast_bitstruct_to_int_arr(Expr *expr, Type *type) { expr_rewrite_recast(expr, type); }
static void cast_bitstruct_to_int_arr(Expr *expr, Type *type)
{
if (type_size(expr->type) < type_size(type))
{
expr_rewrite_recast(expr, type_flatten(expr->type)->decl->strukt.container_type->type);
cast_int_to_int(expr, type);
return;
}
expr_rewrite_recast(expr, type);
}
static void cast_int_arr_to_bitstruct(Expr *expr, Type *type)
{
if (expr_is_const_int(expr))