Implement general casts and pointer dereferencing.

Prior to this casts and pointer dereferencing were special-cased.
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index 219a436..fb7ec80 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -1019,6 +1019,7 @@
             LOG_API("storeR0(%d);\n", ea);
             TypeTag tag = pType->tag;
             switch (tag) {
+                case TY_POINTER:
                 case TY_INT:
                 case TY_FLOAT:
                     if (ea > -LOCAL && ea < LOCAL) {
@@ -2027,6 +2028,7 @@
             TypeTag tag = pType->tag;
             switch (tag) {
                 case TY_INT:
+                case TY_POINTER:
                     gmov(6, ea); /* mov %eax, EA */
                     break;
                 case TY_FLOAT:
@@ -3663,41 +3665,34 @@
                     pGen->genUnaryOp(a);
                 }
             } else if (t == '(') {
-                expr();
-                skip(')');
-            } else if (t == '*') {
-                /* This is a pointer dereference, but we currently only
-                 * support a pointer dereference if it's immediately
-                 * in front of a cast. So parse the cast right here.
-                 */
-                skip('(');
-                Type* pCast = expectCastTypeDeclaration(mLocalArena);
-                // We currently only handle 3 types of cast:
-                // (int*), (char*) , (int (*)())
-                if(typeEqual(pCast, mkpIntPtr)) {
-                    t = TOK_INT;
-                } else if (typeEqual(pCast, mkpCharPtr)) {
-                    t = TOK_CHAR;
-                } else if (typeEqual(pCast, mkpFloatPtr)) {
-                    t = TOK_FLOAT;
-                } else if (typeEqual(pCast, mkpDoublePtr)) {
-                    t = TOK_DOUBLE;
-                } else if (typeEqual(pCast, mkpPtrIntFn)){
-                    t = 0;
+                // It's either a cast or an expression
+                Type* pCast = acceptCastTypeDeclaration(mLocalArena);
+                if (pCast) {
+                    skip(')');
+                    unary(false);
+                    pGen->convertR0(pCast);
                 } else {
-                    String buffer;
-                    decodeType(buffer, pCast);
-                    error("Unsupported cast type %s", buffer.getUnwrapped());
-                    decodeType(buffer, mkpPtrIntFn);
-                }
-                skip(')');
-                unary(false);
-                if (accept('=')) {
-                    pGen->pushR0();
                     expr();
-                    pGen->storeR0ToTOS(pCast);
-                } else if (t) {
-                    pGen->loadR0FromR0(pCast);
+                    skip(')');
+                }
+            } else if (t == '*') {
+                /* This is a pointer dereference.
+                 */
+                unary(false);
+                Type* pR0Type = pGen->getR0Type();
+                if (pR0Type->tag != TY_POINTER) {
+                    error("Expected a pointer type.");
+                } else {
+                    if (pR0Type->pHead->tag == TY_FUNC) {
+                        t = 0;
+                    }
+                    if (accept('=')) {
+                        pGen->pushR0();
+                        expr();
+                        pGen->storeR0ToTOS(pR0Type);
+                    } else if (t) {
+                        pGen->loadR0FromR0(pR0Type);
+                    }
                 }
                 // Else we fall through to the function call below, with
                 // t == 0 to trigger an indirect function call. Hack!