diff options
| author | gingerBill <bill@gingerbill.org> | 2019-07-15 21:18:37 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2019-07-15 21:18:37 +0100 |
| commit | f25818e9230b77bbe3a3422c75d1544c9b417fcf (patch) | |
| tree | 41af5cb07e0a83d8385d456f8cbeca4fb08e01fd /src | |
| parent | 3d531be71176cd0b9191119bf373e3a52c3dde91 (diff) | |
Make procedure parameters just named values rather than copied variables
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_expr.cpp | 40 | ||||
| -rw-r--r-- | src/check_stmt.cpp | 4 | ||||
| -rw-r--r-- | src/check_type.cpp | 14 | ||||
| -rw-r--r-- | src/parser.cpp | 8 | ||||
| -rw-r--r-- | src/parser.hpp | 2 |
5 files changed, 28 insertions, 40 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 4c2133f4c..6845c167d 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1533,8 +1533,14 @@ void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *node) { if (ast_node_expect(node, Ast_UnaryExpr)) { ast_node(ue, UnaryExpr, node); gbString str = expr_to_string(ue->expr); - error(op, "Cannot take the pointer address of '%s'", str); - gb_string_free(str); + defer (gb_string_free(str)); + + Entity *e = entity_of_ident(o->expr); + if (e != nullptr && (e->flags & EntityFlag_Param) != 0) { + error(op, "Cannot take the pointer address of '%s' which is a procedure parameter", str); + } else { + error(op, "Cannot take the pointer address of '%s'", str); + } } o->mode = Addressing_Invalid; return; @@ -5909,17 +5915,6 @@ void check_expr_with_type_hint(CheckerContext *c, Operand *o, Ast *e, Type *t) { } } -void check_set_mode_with_indirection(Operand *o, bool indirection) { - if (o->mode != Addressing_Immutable) { - if (indirection) { - o->mode = Addressing_Variable; - } else if (o->mode != Addressing_Variable && - o->mode != Addressing_Constant) { - o->mode = Addressing_Value; - } - } -} - bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 *max_count) { switch (t->kind) { case Type_Basic: @@ -5927,7 +5922,9 @@ bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 *max_count) if (o->mode == Addressing_Constant) { *max_count = o->value.value_string.len; } - check_set_mode_with_indirection(o, indirection); + if (o->mode != Addressing_Immutable && o->mode != Addressing_Constant) { + o->mode = Addressing_Variable; + } o->type = t_u8; return true; } @@ -5935,20 +5932,29 @@ bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 *max_count) case Type_Array: *max_count = t->Array.count; - check_set_mode_with_indirection(o, indirection); + if (o->mode != Addressing_Immutable) { + if (indirection) { + o->mode = Addressing_Variable; + } else if (o->mode != Addressing_Variable && + o->mode != Addressing_Constant) { + o->mode = Addressing_Value; + } + } o->type = t->Array.elem; return true; case Type_Slice: o->type = t->Slice.elem; - if (o->mode != Addressing_Immutable) { + if (o->mode != Addressing_Immutable && o->mode != Addressing_Constant) { o->mode = Addressing_Variable; } return true; case Type_DynamicArray: o->type = t->DynamicArray.elem; - check_set_mode_with_indirection(o, indirection); + if (o->mode != Addressing_Immutable && o->mode != Addressing_Constant) { + o->mode = Addressing_Variable; + } return true; } diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 24f540930..e2090688f 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -303,9 +303,13 @@ Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs) } } + Entity *e = entity_of_ident(lhs->expr); + gbString str = expr_to_string(lhs->expr); if (lhs->mode == Addressing_Immutable) { error(lhs->expr, "Cannot assign to an immutable: '%s'", str); + } else if (e != nullptr && e->flags & EntityFlag_Param) { + error(lhs->expr, "Cannot assign to '%s' which is a procedure parameter", str); } else { error(lhs->expr, "Cannot assign to '%s'", str); } diff --git a/src/check_type.cpp b/src/check_type.cpp index df3c554dd..f4e5b49d0 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1519,18 +1519,6 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is } } - if (p->flags&FieldFlag_in) { - if (is_type_param) { - error(param, "'in' cannot be applied to a type parameter"); - p->flags &= ~FieldFlag_in; - } else if (is_variadic) { - error(param, "'in' cannot be applied to a variadic parameter"); - p->flags &= ~FieldFlag_in; - } - } - - bool is_in = (p->flags&FieldFlag_in) != 0; - for_array(j, p->names) { Ast *name = p->names[j]; @@ -1670,7 +1658,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is param = alloc_entity_const_param(scope, name->Ident.token, type, poly_const, is_type_polymorphic(type)); } else { - param = alloc_entity_param(scope, name->Ident.token, type, is_using, is_in); + param = alloc_entity_param(scope, name->Ident.token, type, is_using, true); param->Variable.param_value = param_value; } } diff --git a/src/parser.cpp b/src/parser.cpp index d2e64f23c..a377b773c 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2854,7 +2854,6 @@ enum FieldPrefixKind { FieldPrefix_no_alias, FieldPrefix_c_var_arg, FieldPrefix_auto_cast, - FieldPrefix_in, }; FieldPrefixKind is_token_field_prefix(AstFile *f) { @@ -2865,9 +2864,6 @@ FieldPrefixKind is_token_field_prefix(AstFile *f) { case Token_using: return FieldPrefix_using; - case Token_in: - return FieldPrefix_in; - case Token_auto_cast: return FieldPrefix_auto_cast; @@ -2892,7 +2888,6 @@ u32 parse_field_prefixes(AstFile *f) { i32 using_count = 0; i32 no_alias_count = 0; i32 c_vararg_count = 0; - i32 in_count = 0; i32 auto_cast_count = 0; for (;;) { @@ -2910,14 +2905,12 @@ u32 parse_field_prefixes(AstFile *f) { case FieldPrefix_using: using_count += 1; advance_token(f); break; case FieldPrefix_no_alias: no_alias_count += 1; advance_token(f); break; case FieldPrefix_c_var_arg: c_vararg_count += 1; advance_token(f); break; - case FieldPrefix_in: in_count += 1; advance_token(f); break; case FieldPrefix_auto_cast: auto_cast_count += 1; advance_token(f); break; } } if (using_count > 1) syntax_error(f->curr_token, "Multiple 'using' in this field list"); if (no_alias_count > 1) syntax_error(f->curr_token, "Multiple '#no_alias' in this field list"); if (c_vararg_count > 1) syntax_error(f->curr_token, "Multiple '#c_vararg' in this field list"); - if (in_count > 1) syntax_error(f->curr_token, "Multiple 'in' in this field list"); if (auto_cast_count > 1) syntax_error(f->curr_token, "Multiple 'auto_cast' in this field list"); @@ -2925,7 +2918,6 @@ u32 parse_field_prefixes(AstFile *f) { if (using_count > 0) field_flags |= FieldFlag_using; if (no_alias_count > 0) field_flags |= FieldFlag_no_alias; if (c_vararg_count > 0) field_flags |= FieldFlag_c_vararg; - if (in_count > 0) field_flags |= FieldFlag_in; if (auto_cast_count > 0) field_flags |= FieldFlag_auto_cast; return field_flags; } diff --git a/src/parser.hpp b/src/parser.hpp index a6c9d190b..9f4f68a7b 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -186,8 +186,6 @@ enum FieldFlag { FieldFlag_c_vararg = 1<<3, FieldFlag_auto_cast = 1<<4, - FieldFlag_in = 1<<5, - FieldFlag_Results = 1<<16, |