[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