about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compile.c27
1 files changed, 10 insertions, 17 deletions
diff --git a/compile.c b/compile.c
index dc070ca..61aab05 100644
--- a/compile.c
+++ b/compile.c
@@ -51,7 +51,7 @@ rvar(struct node *node, struct scope *scope) {
 static struct val
 roper(struct node *node, struct scope *scope)
 {
-	struct val l, m, r, ref, val;
+	struct val l, m, r, ref, refl, refr, val;
 	struct scope *lscope;
 	vlong i, j;
 
@@ -99,23 +99,19 @@ roper(struct node *node, struct scope *scope)
 	UN(OINV, ~)
 #undef UN
 	break; case OASSIGN:
-	{
-		struct val shouldfree = nil;
-		struct var *var;
-
-		val = getval(VVAR, eval(node->noper.l, scope), scope, 0);
+		refl = getval(VVAR, eval(node->noper.l, scope), scope, 0);
 		lscope = scope;
-		i = findvar(val.name, &lscope);
-		if (i >= 0)
-			shouldfree = deref(val, scope);
+		i = findvar(refl.name, &lscope);
+		l = i >= 0 ? deref(refl, scope) : nil;
 
-		r = deref(eval(node->noper.r, scope), scope);
+		refr = eval(node->noper.r, scope);
+		r = deref(refr, scope);
 
 		/* it's fine to use scope here as it won't be used after */
-		assignvar(val.name, copyval(r), &scope);
-		freeval(shouldfree);
-		freeval(r);
-	}
+		assignvar(refl.name, copyval(r), &scope);
+		freeval(l);
+		if (refr.type == VVAR)
+			freeval(r);
 #define ASS(NAME, OPER) break; case NAME: \
 { \
 	ref = getval(VVAR, eval(node->noper.l, scope), scope, 0); \
@@ -217,8 +213,6 @@ roper(struct node *node, struct scope *scope)
 		if (ref.type == VARR)
 			freeval(ref);
 	break; case OCONCAT:
-	{
-		struct val refl, refr;
 		refl = eval(node->noper.l, scope);
 		l = getval(VARR, refl, scope, 1);
 		refr = eval(node->noper.r, scope);
@@ -239,7 +233,6 @@ roper(struct node *node, struct scope *scope)
 			freeval(refl);
 		if (refr.type == VARR)
 			freeval(refr);
-	}
 	break; case OLEN:
 		m = getval(VARR, eval(node->noper.m, scope), scope, 1);
 		val.num = m.len;