[Commit] nickle ChangeLog,1.47,1.48 compile.c,1.150,1.151

Keith Packard commit at keithp.com
Thu May 20 23:10:37 PDT 2004


Committed by: keithp

Update of /local/src/CVS/nickle
In directory home.keithp.com:/tmp/cvs-serv2836

Modified Files:
	ChangeLog compile.c 
Log Message:
2004-05-20  Keith Packard  <keithp at keithp.com>

	* compile.c: (CompileLvalue), (_CompileExpr):
	Ok, so the previous change was incomplete.
	
	Restructure CompileLvalue so that the processing of ampersands is
	unified.  The unified rules were changed so that the value of a
	reference to a reference type is converted to a pointer instead of a
	reference.  That seems confusing enough.  Basically, it allows:

		&int r;
		*&int pr = & & r;


Index: ChangeLog
===================================================================
RCS file: /local/src/CVS/nickle/ChangeLog,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -d -r1.47 -r1.48
--- a/ChangeLog	21 May 2004 05:21:13 -0000	1.47
+++ b/ChangeLog	21 May 2004 06:10:34 -0000	1.48
@@ -1,5 +1,18 @@
 2004-05-20  Keith Packard  <keithp at keithp.com>
 
+	* compile.c: (CompileLvalue), (_CompileExpr):
+	Ok, so the previous change was incomplete.
+	
+	Restructure CompileLvalue so that the processing of ampersands is
+	unified.  The unified rules were changed so that the value of a
+	reference to a reference type is converted to a pointer instead of a
+	reference.  That seems confusing enough.  Basically, it allows:
+
+		&int r;
+		*&int pr = & & r;
+
+2004-05-20  Keith Packard  <keithp at keithp.com>
+
 	* compile.c: (_CompileExpr):
 	When compiling '&' expressions, if the operand is of ref type,
 	the result type is the referenced type, not NULL.

Index: compile.c
===================================================================
RCS file: /local/src/CVS/nickle/compile.c,v
retrieving revision 1.150
retrieving revision 1.151
diff -u -d -r1.150 -r1.151
--- a/compile.c	21 May 2004 05:21:13 -0000	1.150
+++ b/compile.c	21 May 2004 06:10:34 -0000	1.151
@@ -462,8 +462,8 @@
     SymbolPtr	s;
     int		depth;
     int		ndim;
-    OpCode	opCode = OpNoop;
     TypePtr	t;
+    Bool	flipTypes = False;
     
     switch (expr->base.tag) {
     case VAR:
@@ -520,16 +520,7 @@
 	if (!inst)
 	    break;
 	expr->base.type = s->symbol.type;
-	t = CompileRefType (expr->base.type);
-	if (amper && !t)
-	    CompileError (obj, stat, "Object right of '&' is not of ref type");
-	if (t && !amper)
-	{
-	    inst->base.opCode--;
-	    expr->base.type = t;
-	}
-	else if (assign)
-	    inst->base.opCode++;
+	flipTypes = True;
 	break;
     case AMPER:
 	obj = CompileLvalue (obj, expr->tree.left, stat, code,
@@ -552,19 +543,9 @@
 	    expr->base.type = typePoly;
 	    break;
 	}
-	opCode = OpDotRef;
-	t = CompileRefType (expr->base.type);
-	if (amper && !t)
-	    CompileError (obj, stat, "Object right of '&' is not of ref type");
-	if (t && !amper)
-	{
-	    opCode--;
-	    expr->base.type = t;
-	}
-	else if (assign)
-	    opCode++;
-        BuildInst (obj, opCode, inst, stat);
+        BuildInst (obj, OpDotRef, inst, stat);
 	inst->atom.atom = expr->tree.right->atom.atom;
+	flipTypes = True;
 	break;
     case ARROW:
 	obj = _CompileExpr (obj, expr->tree.left, True, stat, code);
@@ -578,18 +559,7 @@
 	    expr->base.type = typePoly;
 	    break;
 	}
-	opCode = OpArrowRef;
-	t = CompileRefType (expr->base.type);
-	if (amper && !t)
-	    CompileError (obj, stat, "Object right of '&' is not of ref type");
-	if (t && !amper)
-	{
-	    opCode--;
-	    expr->base.type = t;
-	}
-	else if (assign)
-	    opCode++;
-        BuildInst (obj, opCode, inst, stat);
+	BuildInst (obj, OpArrowRef, inst, stat);
 	inst->atom.atom = expr->tree.right->atom.atom;
 	break;
     case OS:
@@ -615,19 +585,9 @@
 	    expr->base.type = typePoly;
 	    break;
 	}
-	opCode = OpArrayRef;
-	t = CompileRefType (expr->base.type);
-	if (amper && !t)
-	    CompileError (obj, stat, "Object right of '&' is not of ref type");
-	if (t && !amper)
-	{
-	    opCode--;
-	    expr->base.type = t;
-	}
-	else if (assign)
-	    opCode++;
-        BuildInst (obj, opCode, inst, stat);
+	BuildInst (obj, OpArrayRef, inst, stat);
 	inst->ints.value = ndim;
+	flipTypes = True;
 	break;
     case STAR:
 	obj = _CompileExpr (obj, expr->tree.left, True, stat, code);
@@ -645,6 +605,55 @@
         expr->base.type = typePoly;
 	break;
     }
+    if (flipTypes)
+    {
+	t = CompileRefType (expr->base.type);
+	if (amper)
+	{
+	    if (t)
+	    {
+		/* 
+		 * reference to a reference type; that
+		 * means just reference the variable itself, but
+		 * switch the expression type to '*foo' instead of
+		 * '&foo'
+		 */
+		expr->base.type = NewTypeRef (t, True);
+		if (assign)
+		    inst->base.opCode++;
+	    }
+	    else
+	    {
+		/*
+		 * reference to a non-reference type.  Error
+		 */
+		CompileError (obj, stat, "Object right of '&' is not of ref type");
+		expr->base.type = typePoly;
+	    }
+	}
+	else
+	{
+	    if (t)
+	    {
+		/*
+		 * access to a reference type; that means
+		 * fetch the value of the reference
+		 */
+		inst->base.opCode--;
+		expr->base.type = t;
+	    }
+	    else
+	    {
+		/*
+		 * access to a non-reference type; that
+		 * means just reference the variable itself and
+		 * leave the type alone
+		 */
+		if (assign)
+		    inst->base.opCode++;
+	    }
+	}
+    }
     assert (expr->base.type);
     RETURN (obj);
 }
@@ -2393,17 +2402,16 @@
     case STAR:	    obj = CompileUnFunc (obj, expr, Dereference, stat, code,"*"); break;
     case AMPER:	    
 	obj = CompileLvalue (obj, expr->tree.left, stat, code, False, False, False, False);
-	expr->base.type = CompileRefType (expr->tree.left->base.type);
+	t = CompileRefType (expr->tree.left->base.type);
+	if (!t)
+	    t = expr->tree.left->base.type;
+	expr->base.type = NewTypeRef (t, True);
 	if (!expr->base.type)
 	{
-	    expr->base.type = NewTypeRef (expr->tree.left->base.type, False);
-	    if (!expr->base.type)
-	    {
-		CompileError (obj, stat, "Type '%T' cannot be an l-value",
-			      expr->tree.left->base.type);
-		expr->base.type = typePoly;
-		break;
-	    }
+	    CompileError (obj, stat, "Type '%T' cannot be an l-value",
+			  expr->tree.left->base.type);
+	    expr->base.type = typePoly;
+	    break;
 	}
 	break;
     case UMINUS:    obj = CompileUnOp (obj, expr, NegateOp, stat, code); break;




More information about the Commit mailing list