mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-07 08:08:50 +00:00
Reimplement immutable with different rules.
This commit is contained in:
+3
-7
@@ -1,16 +1,12 @@
|
|||||||
#import "fmt.odin";
|
#import "fmt.odin";
|
||||||
|
|
||||||
x := [...]int{1, 2, 3, 4};
|
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
{
|
{
|
||||||
|
|
||||||
|
x := [...]int{1, 2, 3, 4};
|
||||||
foo :: proc() -> [...]int {
|
immutable y := ^x;
|
||||||
return x;
|
fmt.println(y^[0]);
|
||||||
}
|
|
||||||
|
|
||||||
// foo()[0] = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+21
-22
@@ -1030,7 +1030,7 @@ void check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *typ
|
|||||||
}
|
}
|
||||||
o->mode = Addressing_Variable;
|
o->mode = Addressing_Variable;
|
||||||
if (e->Variable.is_immutable) {
|
if (e->Variable.is_immutable) {
|
||||||
o->mode = Addressing_Value;
|
o->mode = Addressing_Immutable;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2714,7 +2714,9 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
|
|||||||
break;
|
break;
|
||||||
case Entity_Variable:
|
case Entity_Variable:
|
||||||
// TODO(bill): This is the rule I need?
|
// TODO(bill): This is the rule I need?
|
||||||
if (sel.indirect || operand->mode != Addressing_Value) {
|
if (operand->mode == Addressing_Immutable) {
|
||||||
|
// Okay
|
||||||
|
} else if (sel.indirect || operand->mode != Addressing_Value) {
|
||||||
operand->mode = Addressing_Variable;
|
operand->mode = Addressing_Variable;
|
||||||
} else {
|
} else {
|
||||||
operand->mode = Addressing_Value;
|
operand->mode = Addressing_Value;
|
||||||
@@ -4097,6 +4099,16 @@ void check_expr_with_type_hint(Checker *c, Operand *o, AstNode *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_Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool check_set_index_data(Operand *o, Type *type, bool indirection, i64 *max_count) {
|
bool check_set_index_data(Operand *o, Type *type, bool indirection, i64 *max_count) {
|
||||||
Type *t = base_type(type_deref(type));
|
Type *t = base_type(type_deref(type));
|
||||||
|
|
||||||
@@ -4106,9 +4118,7 @@ bool check_set_index_data(Operand *o, Type *type, bool indirection, i64 *max_cou
|
|||||||
if (o->mode == Addressing_Constant) {
|
if (o->mode == Addressing_Constant) {
|
||||||
*max_count = o->value.value_string.len;
|
*max_count = o->value.value_string.len;
|
||||||
}
|
}
|
||||||
if (o->mode != Addressing_Variable) {
|
check_set_mode_with_indirection(o, indirection);
|
||||||
o->mode = Addressing_Value;
|
|
||||||
}
|
|
||||||
o->type = t_u8;
|
o->type = t_u8;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -4116,22 +4126,13 @@ bool check_set_index_data(Operand *o, Type *type, bool indirection, i64 *max_cou
|
|||||||
|
|
||||||
case Type_Array:
|
case Type_Array:
|
||||||
*max_count = t->Array.count;
|
*max_count = t->Array.count;
|
||||||
if (indirection) {
|
check_set_mode_with_indirection(o, indirection);
|
||||||
o->mode = Addressing_Variable;
|
|
||||||
} else if (o->mode != Addressing_Variable) {
|
|
||||||
o->mode = Addressing_Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
o->type = t->Array.elem;
|
o->type = t->Array.elem;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Type_Vector:
|
case Type_Vector:
|
||||||
*max_count = t->Vector.count;
|
*max_count = t->Vector.count;
|
||||||
if (indirection) {
|
check_set_mode_with_indirection(o, indirection);
|
||||||
o->mode = Addressing_Variable;
|
|
||||||
} else if (o->mode != Addressing_Variable) {
|
|
||||||
o->mode = Addressing_Value;
|
|
||||||
}
|
|
||||||
o->type = t->Vector.elem;
|
o->type = t->Vector.elem;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -4143,11 +4144,7 @@ bool check_set_index_data(Operand *o, Type *type, bool indirection, i64 *max_cou
|
|||||||
|
|
||||||
case Type_DynamicArray:
|
case Type_DynamicArray:
|
||||||
o->type = t->DynamicArray.elem;
|
o->type = t->DynamicArray.elem;
|
||||||
if (indirection) {
|
check_set_mode_with_indirection(o, indirection);
|
||||||
o->mode = Addressing_Variable;
|
|
||||||
} else if (o->mode != Addressing_Variable) {
|
|
||||||
o->mode = Addressing_Value;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5183,7 +5180,9 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
|||||||
} else {
|
} else {
|
||||||
Type *t = base_type(o->type);
|
Type *t = base_type(o->type);
|
||||||
if (t->kind == Type_Pointer) {
|
if (t->kind == Type_Pointer) {
|
||||||
o->mode = Addressing_Variable;
|
if (o->mode != Addressing_Immutable) {
|
||||||
|
o->mode = Addressing_Variable;
|
||||||
|
}
|
||||||
o->type = t->Pointer.elem;
|
o->type = t->Pointer.elem;
|
||||||
} else {
|
} else {
|
||||||
gbString str = expr_to_string(o->expr);
|
gbString str = expr_to_string(o->expr);
|
||||||
|
|||||||
+2
-6
@@ -268,17 +268,13 @@ Type *check_assignment_variable(Checker *c, Operand *rhs, AstNode *lhs_node) {
|
|||||||
AstNode *x = ln->IndexExpr.expr;
|
AstNode *x = ln->IndexExpr.expr;
|
||||||
TypeAndValue *tav = type_and_value_of_expression(&c->info, x);
|
TypeAndValue *tav = type_and_value_of_expression(&c->info, x);
|
||||||
GB_ASSERT(tav != NULL);
|
GB_ASSERT(tav != NULL);
|
||||||
switch (tav->mode) {
|
if (tav->mode != Addressing_Variable) {
|
||||||
case Addressing_Variable:
|
|
||||||
break;
|
|
||||||
case Addressing_Value:
|
|
||||||
if (!is_type_pointer(tav->type)) {
|
if (!is_type_pointer(tav->type)) {
|
||||||
gbString str = expr_to_string(lhs.expr);
|
gbString str = expr_to_string(lhs.expr);
|
||||||
error_node(lhs.expr, "Cannot assign to the value of a map `%s`", str);
|
error_node(lhs.expr, "Cannot assign to the value of a map `%s`", str);
|
||||||
gb_string_free(str);
|
gb_string_free(str);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@@ -297,7 +293,7 @@ Type *check_assignment_variable(Checker *c, Operand *rhs, AstNode *lhs_node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gbString str = expr_to_string(lhs.expr);
|
gbString str = expr_to_string(lhs.expr);
|
||||||
if (e != NULL && e->kind == Entity_Variable && e->Variable.is_immutable) {
|
if (lhs.mode == Addressing_Immutable) {
|
||||||
error_node(lhs.expr, "Cannot assign to an immutable: `%s`", str);
|
error_node(lhs.expr, "Cannot assign to an immutable: `%s`", str);
|
||||||
} else {
|
} else {
|
||||||
error_node(lhs.expr, "Cannot assign to `%s`", str);
|
error_node(lhs.expr, "Cannot assign to `%s`", str);
|
||||||
|
|||||||
+18
-16
@@ -6,6 +6,22 @@ typedef enum ExprKind {
|
|||||||
Expr_Stmt,
|
Expr_Stmt,
|
||||||
} ExprKind;
|
} ExprKind;
|
||||||
|
|
||||||
|
typedef enum AddressingMode {
|
||||||
|
Addressing_Invalid,
|
||||||
|
|
||||||
|
Addressing_NoValue,
|
||||||
|
Addressing_Value,
|
||||||
|
Addressing_Variable,
|
||||||
|
Addressing_Immutable,
|
||||||
|
Addressing_Constant,
|
||||||
|
Addressing_Type,
|
||||||
|
Addressing_Builtin,
|
||||||
|
Addressing_Overload,
|
||||||
|
Addressing_MapIndex,
|
||||||
|
|
||||||
|
Addressing_Count,
|
||||||
|
} AddressingMode;
|
||||||
|
|
||||||
// Statements and Declarations
|
// Statements and Declarations
|
||||||
typedef enum StmtFlag {
|
typedef enum StmtFlag {
|
||||||
Stmt_BreakAllowed = 1<<0,
|
Stmt_BreakAllowed = 1<<0,
|
||||||
@@ -106,22 +122,6 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum AddressingMode {
|
|
||||||
Addressing_Invalid,
|
|
||||||
|
|
||||||
Addressing_NoValue,
|
|
||||||
Addressing_Value,
|
|
||||||
Addressing_Variable,
|
|
||||||
Addressing_Constant,
|
|
||||||
Addressing_Type,
|
|
||||||
Addressing_Builtin,
|
|
||||||
Addressing_Overload,
|
|
||||||
Addressing_MapIndex,
|
|
||||||
|
|
||||||
Addressing_Count,
|
|
||||||
} AddressingMode;
|
|
||||||
|
|
||||||
#include "types.c"
|
#include "types.c"
|
||||||
|
|
||||||
#define MAP_TYPE Entity *
|
#define MAP_TYPE Entity *
|
||||||
@@ -149,7 +149,9 @@ bool is_operand_value(Operand o) {
|
|||||||
switch (o.mode) {
|
switch (o.mode) {
|
||||||
case Addressing_Value:
|
case Addressing_Value:
|
||||||
case Addressing_Variable:
|
case Addressing_Variable:
|
||||||
|
case Addressing_Immutable:
|
||||||
case Addressing_Constant:
|
case Addressing_Constant:
|
||||||
|
case Addressing_MapIndex:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
+3
-3
@@ -2358,7 +2358,7 @@ bool is_token_field_prefix(TokenKind kind) {
|
|||||||
switch (kind) {
|
switch (kind) {
|
||||||
case Token_using:
|
case Token_using:
|
||||||
case Token_no_alias:
|
case Token_no_alias:
|
||||||
// case Token_immutable:
|
case Token_immutable:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -2374,7 +2374,7 @@ u32 parse_field_prefixes(AstFile *f) {
|
|||||||
switch (f->curr_token.kind) {
|
switch (f->curr_token.kind) {
|
||||||
case Token_using: using_count += 1; next_token(f); break;
|
case Token_using: using_count += 1; next_token(f); break;
|
||||||
case Token_no_alias: no_alias_count += 1; next_token(f); break;
|
case Token_no_alias: no_alias_count += 1; next_token(f); break;
|
||||||
// case Token_immutable: immutable_count += 1; next_token(f); break;
|
case Token_immutable: immutable_count += 1; next_token(f); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (using_count > 1) syntax_error(f->curr_token, "Multiple `using` in this field list");
|
if (using_count > 1) syntax_error(f->curr_token, "Multiple `using` in this field list");
|
||||||
@@ -3272,7 +3272,7 @@ AstNode *parse_stmt(AstFile *f) {
|
|||||||
return ast_bad_stmt(f, token, f->curr_token);
|
return ast_bad_stmt(f, token, f->curr_token);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
case Token_immutable: {
|
case Token_immutable: {
|
||||||
Token token = expect_token(f, Token_immutable);
|
Token token = expect_token(f, Token_immutable);
|
||||||
AstNode *node = parse_stmt(f);
|
AstNode *node = parse_stmt(f);
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \
|
|||||||
TOKEN_KIND(Token_map, "map"), \
|
TOKEN_KIND(Token_map, "map"), \
|
||||||
TOKEN_KIND(Token_using, "using"), \
|
TOKEN_KIND(Token_using, "using"), \
|
||||||
TOKEN_KIND(Token_no_alias, "no_alias"), \
|
TOKEN_KIND(Token_no_alias, "no_alias"), \
|
||||||
|
TOKEN_KIND(Token_immutable, "immutable"), \
|
||||||
TOKEN_KIND(Token_cast, "cast"), \
|
TOKEN_KIND(Token_cast, "cast"), \
|
||||||
TOKEN_KIND(Token_transmute, "transmute"), \
|
TOKEN_KIND(Token_transmute, "transmute"), \
|
||||||
TOKEN_KIND(Token_down_cast, "down_cast"), \
|
TOKEN_KIND(Token_down_cast, "down_cast"), \
|
||||||
|
|||||||
Reference in New Issue
Block a user