mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Allow an expression list be an lvalue if the last value is an lvalue. Fix indexing from back for [] overloads.
This commit is contained in:
@@ -36,7 +36,7 @@ fn void List.tinit(List* list, usz initial_capacity = 16)
|
||||
list.init(initial_capacity, mem::temp_allocator()) @inline;
|
||||
}
|
||||
|
||||
fn void List.push(List *list, Type element) @inline
|
||||
fn void List.push(List* list, Type element) @inline
|
||||
{
|
||||
list.append(element);
|
||||
}
|
||||
@@ -58,14 +58,14 @@ fn Type List.pop(List* list)
|
||||
/**
|
||||
* @require list.size > 0
|
||||
*/
|
||||
fn Type List.pop_first(List *list)
|
||||
fn Type List.pop_first(List* list)
|
||||
{
|
||||
Type value = list.entries[0];
|
||||
list.remove_at(0);
|
||||
return value;
|
||||
}
|
||||
|
||||
fn void List.remove_at(List *list, usz index)
|
||||
fn void List.remove_at(List* list, usz index)
|
||||
{
|
||||
for (usz i = index + 1; i < list.size; i++)
|
||||
{
|
||||
@@ -74,7 +74,7 @@ fn void List.remove_at(List *list, usz index)
|
||||
list.size--;
|
||||
}
|
||||
|
||||
fn void List.push_front(List *list, Type type) @inline
|
||||
fn void List.push_front(List* list, Type type) @inline
|
||||
{
|
||||
list.insert_at(0, type);
|
||||
}
|
||||
@@ -95,37 +95,37 @@ fn void List.remove_last(List* list)
|
||||
list.size--;
|
||||
}
|
||||
|
||||
fn void List.remove_first(List *list)
|
||||
fn void List.remove_first(List* list)
|
||||
{
|
||||
list.remove_at(0);
|
||||
}
|
||||
|
||||
fn Type* List.first(List *list)
|
||||
fn Type* List.first(List* list)
|
||||
{
|
||||
return list.size ? &list.entries[0] : null;
|
||||
}
|
||||
|
||||
fn Type* List.last(List *list)
|
||||
fn Type* List.last(List* list)
|
||||
{
|
||||
return list.size ? &list.entries[list.size - 1] : null;
|
||||
}
|
||||
|
||||
fn bool List.is_empty(List *list)
|
||||
fn bool List.is_empty(List* list)
|
||||
{
|
||||
return !list.size;
|
||||
}
|
||||
|
||||
fn usz List.len(List *list) @operator(len)
|
||||
fn usz List.len(List* list) @operator(len)
|
||||
{
|
||||
return list.size;
|
||||
}
|
||||
|
||||
fn Type List.get(List *list, usz index)
|
||||
fn Type List.get(List* list, usz index)
|
||||
{
|
||||
return list.entries[index];
|
||||
}
|
||||
|
||||
fn void List.free(List *list)
|
||||
fn void List.free(List* list)
|
||||
{
|
||||
if (!list.allocator) return;
|
||||
list.allocator.free_aligned(list.entries)!!;
|
||||
@@ -134,7 +134,7 @@ fn void List.free(List *list)
|
||||
list.entries = null;
|
||||
}
|
||||
|
||||
fn void List.swap(List *list, usz i, usz j)
|
||||
fn void List.swap(List* list, usz i, usz j)
|
||||
{
|
||||
@swap(list.entries[i], list.entries[j]);
|
||||
}
|
||||
@@ -142,7 +142,7 @@ fn void List.swap(List *list, usz i, usz j)
|
||||
/**
|
||||
* Reserve at least min_capacity
|
||||
**/
|
||||
fn void List.reserve(List *list, usz min_capacity)
|
||||
fn void List.reserve(List* list, usz min_capacity)
|
||||
{
|
||||
if (!min_capacity) return;
|
||||
if (list.capacity >= min_capacity) return;
|
||||
@@ -163,7 +163,7 @@ macro Type* List.@item_ref(List &list, usz index) @operator(&[])
|
||||
}
|
||||
|
||||
|
||||
private fn void List.ensure_capacity(List *list) @inline
|
||||
private fn void List.ensure_capacity(List* list) @inline
|
||||
{
|
||||
if (list.capacity == list.size)
|
||||
{
|
||||
|
||||
@@ -2137,6 +2137,8 @@ void expr_rewrite_to_builtin_access(Expr *expr, Expr *parent, BuiltinAccessKind
|
||||
void expr_rewrite_to_string(Expr *expr_to_rewrite, const char *string);
|
||||
void expr_rewrite_to_const_zero(Expr *expr, Type *type);
|
||||
bool expr_rewrite_to_const_initializer_index(Type *list_type, ConstInitializer *list, Expr *result, unsigned index);
|
||||
void expr_rewrite_to_variable(Expr *expr, Decl *decl);
|
||||
void expr_rewrite_to_binary(Expr *expr_to_rewrite, Expr *left, Expr *right, BinaryOp op);
|
||||
|
||||
bool expr_const_in_range(const ExprConst *left, const ExprConst *right, const ExprConst *right_to);
|
||||
bool expr_const_compare(const ExprConst *left, const ExprConst *right, BinaryOp op);
|
||||
@@ -3050,7 +3052,6 @@ INLINE void expr_rewrite_const_typeid(Expr *expr, Type *type)
|
||||
expr->resolve_status = RESOLVE_DONE;
|
||||
}
|
||||
|
||||
|
||||
INLINE void expr_rewrite_const_int(Expr *expr, Type *type, uint64_t v, bool narrowable)
|
||||
{
|
||||
expr->expr_kind = EXPR_CONST;
|
||||
|
||||
@@ -883,6 +883,20 @@ Expr *expr_variable(Decl *decl)
|
||||
return expr;
|
||||
}
|
||||
|
||||
void expr_rewrite_to_variable(Expr *expr, Decl *decl)
|
||||
{
|
||||
expr->expr_kind = EXPR_IDENTIFIER;
|
||||
if (decl->resolve_status == RESOLVE_DONE)
|
||||
{
|
||||
expr->identifier_expr.decl = decl;
|
||||
expr->resolve_status = RESOLVE_DONE;
|
||||
expr->type = decl->type;
|
||||
return;
|
||||
}
|
||||
expr->identifier_expr.ident = decl->name;
|
||||
expr->resolve_status = RESOLVE_NOT_DONE;
|
||||
}
|
||||
|
||||
void expr_rewrite_insert_deref(Expr *original)
|
||||
{
|
||||
// Assume *(&x) => x
|
||||
@@ -921,3 +935,9 @@ void expr_rewrite_to_string(Expr *expr_to_rewrite, const char *string)
|
||||
expr_to_rewrite->resolve_status = RESOLVE_DONE;
|
||||
expr_to_rewrite->type = type_get_ptr(type_get_array(type_char, len));
|
||||
}
|
||||
|
||||
void expr_rewrite_to_binary(Expr *expr_to_rewrite, Expr *left, Expr *right, BinaryOp op)
|
||||
{
|
||||
expr_to_rewrite->binary_expr = (ExprBinary) { .operator = op, .left = exprid(left), .right = exprid(right) };
|
||||
expr_to_rewrite->expr_kind = EXPR_BINARY;
|
||||
}
|
||||
|
||||
@@ -426,6 +426,9 @@ static bool sema_binary_is_expr_lvalue(Expr *top_expr, Expr *expr)
|
||||
case EXPR_HASH_IDENT:
|
||||
SEMA_ERROR(top_expr, "You cannot assign to an unevaluated expression.");
|
||||
return false;
|
||||
case EXPR_EXPRESSION_LIST:
|
||||
if (!vec_size(expr->expression_list)) return false;
|
||||
return sema_binary_is_expr_lvalue(top_expr, VECLAST(expr->expression_list));
|
||||
case EXPR_POISONED:
|
||||
case EXPR_ARGV_TO_SUBARRAY:
|
||||
case EXPR_ASM:
|
||||
@@ -448,7 +451,6 @@ static bool sema_binary_is_expr_lvalue(Expr *top_expr, Expr *expr)
|
||||
case EXPR_DECL:
|
||||
case EXPR_DESIGNATED_INITIALIZER_LIST:
|
||||
case EXPR_DESIGNATOR:
|
||||
case EXPR_EXPRESSION_LIST:
|
||||
case EXPR_EXPR_BLOCK:
|
||||
case EXPR_FAILABLE:
|
||||
case EXPR_FLATPATH:
|
||||
@@ -2386,6 +2388,33 @@ static inline bool sema_expr_analyse_subscript(SemaContext *context, Expr *expr,
|
||||
}
|
||||
if (overload)
|
||||
{
|
||||
if (start_from_end)
|
||||
{
|
||||
Decl *len = sema_find_operator(context, current_expr, OVERLOAD_LEN);
|
||||
if (!len)
|
||||
{
|
||||
SEMA_ERROR(subscripted, "Cannot index '%s' from the end, since there is no 'len' overload.", type_to_error_string(subscripted->type));
|
||||
return false;
|
||||
}
|
||||
if (!sema_analyse_expr(context, current_expr)) return false;
|
||||
Decl *temp = decl_new_generated_var(current_expr->type, VARDECL_PARAM, current_expr->span);
|
||||
Expr *decl = expr_generate_decl(temp, expr_copy(current_expr));
|
||||
current_expr->expr_kind = EXPR_EXPRESSION_LIST;
|
||||
current_expr->expression_list = NULL;
|
||||
vec_add(current_expr->expression_list, decl);
|
||||
vec_add(current_expr->expression_list, expr_variable(temp));
|
||||
if (!sema_analyse_expr(context, current_expr)) return false;
|
||||
Expr *var_for_len = expr_variable(temp);
|
||||
Expr *len_expr = expr_new(EXPR_CALL, expr->span);
|
||||
if (!sema_insert_method_call(context, len_expr, len, var_for_len, NULL)) return false;
|
||||
if (!sema_analyse_expr(context, len_expr)) return false;
|
||||
Expr *index_copy = expr_copy(index);
|
||||
if (!sema_analyse_expr(context, index_copy)) return false;
|
||||
if (!cast(index_copy, len_expr->type)) return false;
|
||||
expr_rewrite_to_binary(index, len_expr, index_copy, BINARYOP_SUB);
|
||||
index->resolve_status = RESOLVE_NOT_DONE;
|
||||
if (!sema_analyse_expr(context, index)) return false;
|
||||
}
|
||||
if (eval_type == SUBSCRIPT_EVAL_ASSIGN)
|
||||
{
|
||||
expr->expr_kind = EXPR_SUBSCRIPT_ASSIGN;
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.3.104"
|
||||
#define COMPILER_VERSION "0.3.105"
|
||||
Reference in New Issue
Block a user