From 8b7383a008c8875637d37c0df18e8773cc0bd06c Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 30 Apr 2019 14:00:03 +1000 Subject: [PATCH] oceani: delay constant assignment test to type analysis. When we get more complex types, it will be easier to guard against assigning to a constant during type analysis. Signed-off-by: NeilBrown --- csrc/oceani.mdc | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/csrc/oceani.mdc b/csrc/oceani.mdc index edc3b12..0760674 100644 --- a/csrc/oceani.mdc +++ b/csrc/oceani.mdc @@ -1415,7 +1415,7 @@ propagation is needed. ###### ast - enum val_rules {Rnolabel = 1<<0, Rboolok = 1<<1}; + enum val_rules {Rnolabel = 1<<0, Rboolok = 1<<1, Rnoconstant = 2<<1}; ###### format cases case 'r': @@ -1765,6 +1765,14 @@ link to find the primary instance. } if (v->merged) v = v->merged; + if (v->constant && (rules & Rnoconstant)) { + type_err(c, "error: Cannot assign to a constant: %v", + prog, NULL, 0, NULL); + type_err(c, "info: name was defined as a constant here", + v->where_decl, NULL, 0, NULL); + *ok = 0; + return v->val.type; + } if (v->val.type == NULL) { if (type && *ok != 0) { v->val = val_prepare(type); @@ -2488,20 +2496,12 @@ it is declared, and error will be raised as the name is created as Declare, ###### SimpleStatement Grammar - | Variable = Expression ${ { - struct var *v = cast(var, $1); - + | Variable = Expression ${ $0 = new(binode); $0->op = Assign; $0->left = $<1; $0->right = $<3; - if (v->var && v->var->constant) { - type_err(config2context(config), "Cannot assign to a constant: %v", - $0->left, NULL, 0, NULL); - type_err(config2context(config), "name was defined as a constant here", - v->var->where_decl, NULL, 0, NULL); - } - } }$ + }$ | VariableDecl = Expression ${ $0 = new(binode); $0->op = Declare; @@ -2567,8 +2567,11 @@ it is declared, and error will be raised as the name is created as case Declare: /* Both must match and not be labels, * Type must support 'dup', - * result is Tnone */ - t = propagate_types(b->left, c, ok, NULL, Rnolabel); + * For Assign, left must not be constant. + * result is Tnone + */ + t = propagate_types(b->left, c, ok, NULL, + Rnolabel | (b->op == Assign ? Rnoconstant : 0)); if (!b->right) return Tnone; @@ -2580,7 +2583,8 @@ it is declared, and error will be raised as the name is created as } else { t = propagate_types(b->right, c, ok, NULL, Rnolabel); if (t) - propagate_types(b->left, c, ok, t, 0); + propagate_types(b->left, c, ok, t, + (b->op == Assign ? Rnoconstant : 0)); } if (t && t->dup == NULL) { type_err(c, "error: cannot assign value of type %1", b, t, 0, NULL); -- 2.43.0