]> git.sur5r.net Git - cc65/blobdiff - src/cc65/expr.c
Fixed _textcolor definition.
[cc65] / src / cc65 / expr.c
index e5c1a17b91b5b0cef39448c040eb98cbf58e295e..e6522f94900a89d3212d496e70d2e06c12b11fd7 100644 (file)
@@ -1,7 +1,7 @@
 /* expr.c
 **
 ** 1998-06-21, Ullrich von Bassewitz
-** 2015-06-26, Greg King
+** 2017-12-05, Greg King
 */
 
 
@@ -536,6 +536,10 @@ static void FunctionCall (ExprDesc* Expr)
     /* Special handling for function pointers */
     if (IsFuncPtr) {
 
+        if (Func->WrappedCall) {
+            Warning ("Calling a wrapped function via a pointer, wrapped-call will not be used");
+        }
+
         /* If the function is not a fastcall function, load the pointer to
         ** the function into the primary.
         */
@@ -584,7 +588,47 @@ static void FunctionCall (ExprDesc* Expr)
     } else {
 
         /* Normal function */
-        g_call (TypeOf (Expr->Type), (const char*) Expr->Name, ParamSize);
+        if (Func->WrappedCall) {
+            char tmp[64];
+            StrBuf S = AUTO_STRBUF_INITIALIZER;
+
+            /* Store the WrappedCall data in tmp4 */
+            sprintf(tmp, "ldy #%u", Func->WrappedCallData);
+            SB_AppendStr (&S, tmp);
+            g_asmcode (&S);
+            SB_Clear(&S);
+
+            SB_AppendStr (&S, "sty tmp4");
+            g_asmcode (&S);
+            SB_Clear(&S);
+
+            /* Store the original function address in ptr4 */
+            SB_AppendStr (&S, "ldy #<(_");
+            SB_AppendStr (&S, (const char*) Expr->Name);
+            SB_AppendChar (&S, ')');
+            g_asmcode (&S);
+            SB_Clear(&S);
+
+            SB_AppendStr (&S, "sty ptr4");
+            g_asmcode (&S);
+            SB_Clear(&S);
+
+            SB_AppendStr (&S, "ldy #>(_");
+            SB_AppendStr (&S, (const char*) Expr->Name);
+            SB_AppendChar (&S, ')');
+            g_asmcode (&S);
+            SB_Clear(&S);
+
+            SB_AppendStr (&S, "sty ptr4+1");
+            g_asmcode (&S);
+            SB_Clear(&S);
+
+            SB_Done (&S);
+
+            g_call (TypeOf (Expr->Type), Func->WrappedCall->Name, ParamSize);
+        } else {
+            g_call (TypeOf (Expr->Type), (const char*) Expr->Name, ParamSize);
+        }
 
     }
 
@@ -652,6 +696,23 @@ static void Primary (ExprDesc* E)
 
     switch (CurTok.Tok) {
 
+        case TOK_BOOL_AND:
+            /* A computed goto label address */
+            if (IS_Get (&Standard) >= STD_CC65) {
+                SymEntry* Entry;
+                NextToken ();
+                Entry = AddLabelSym (CurTok.Ident, SC_REF | SC_GOTO_IND);
+                /* output its label */
+                E->Flags = E_RTYPE_RVAL | E_LOC_STATIC;
+                E->Name = Entry->V.L.Label;
+                E->Type = PointerTo (type_void);
+                NextToken ();
+            } else {
+                Error ("Computed gotos are a C extension, not supported with this --standard");
+                ED_MakeConstAbsInt (E, 1);
+            }
+            break;
+
         case TOK_IDENT:
             /* Identifier. Get a pointer to the symbol table entry */
             Sym = E->Sym = FindSym (CurTok.Ident);
@@ -687,7 +748,7 @@ static void Primary (ExprDesc* E)
                 } else if ((Sym->Flags & SC_FUNC) == SC_FUNC) {
                     /* Function */
                     E->Flags = E_LOC_GLOBAL | E_RTYPE_LVAL;
-                    E->Name = (unsigned long) Sym->Name;
+                    E->Name = (uintptr_t) Sym->Name;
                 } else if ((Sym->Flags & SC_AUTO) == SC_AUTO) {
                     /* Local variable. If this is a parameter for a variadic
                     ** function, we have to add some address calculations, and the
@@ -710,10 +771,10 @@ static void Primary (ExprDesc* E)
                     /* Static variable */
                     if (Sym->Flags & (SC_EXTERN | SC_STORAGE)) {
                         E->Flags = E_LOC_GLOBAL | E_RTYPE_LVAL;
-                        E->Name = (unsigned long) Sym->Name;
+                        E->Name = (uintptr_t) Sym->Name;
                     } else {
                         E->Flags = E_LOC_STATIC | E_RTYPE_LVAL;
-                        E->Name = Sym->V.Label;
+                        E->Name = Sym->V.L.Label;
                     }
                 } else {
                     /* Local static variable */
@@ -747,20 +808,20 @@ static void Primary (ExprDesc* E)
                     ** list and returning int.
                     */
                     if (IS_Get (&Standard) >= STD_C99) {
-                        Error ("Call to undefined function `%s'", Ident);
+                        Error ("Call to undefined function '%s'", Ident);
                     } else {
-                        Warning ("Call to undefined function `%s'", Ident);
+                        Warning ("Call to undefined function '%s'", Ident);
                     }
                     Sym = AddGlobalSym (Ident, GetImplicitFuncType(), SC_EXTERN | SC_REF | SC_FUNC);
                     E->Type  = Sym->Type;
                     E->Flags = E_LOC_GLOBAL | E_RTYPE_RVAL;
-                    E->Name  = (unsigned long) Sym->Name;
+                    E->Name  = (uintptr_t) Sym->Name;
                 } else {
                     /* Undeclared Variable */
                     Sym = AddLocalSym (Ident, type_int, SC_AUTO | SC_REF, 0);
                     E->Flags = E_LOC_STACK | E_RTYPE_LVAL;
                     E->Type = type_int;
-                    Error ("Undefined symbol: `%s'", Ident);
+                    Error ("Undefined symbol: '%s'", Ident);
                 }
 
             }
@@ -1130,7 +1191,7 @@ static void StructRef (ExprDesc* Expr)
     NextToken ();
     Field = FindStructField (Expr->Type, Ident);
     if (Field == 0) {
-        Error ("Struct/union has no field named `%s'", Ident);
+        Error ("Struct/union has no field named '%s'", Ident);
         /* Make the expression an integer at address zero */
         ED_MakeConstAbs (Expr, 0, type_int);
         return;
@@ -1264,7 +1325,7 @@ static void hie11 (ExprDesc *Expr)
                     ** Since we don't have a name, invent one.
                     */
                     ED_MakeConstAbs (Expr, 0, GetImplicitFuncType ());
-                    Expr->Name = (long) IllegalFunc;
+                    Expr->Name = (uintptr_t) IllegalFunc;
                 }
                 /* Call the function */
                 FunctionCall (Expr);
@@ -1534,8 +1595,8 @@ static void PostInc (ExprDesc* Expr)
     /* Get the data type */
     Flags = TypeOf (Expr->Type);
 
-    /* Fast path: char */
-    if ((Flags & CF_CHAR) == CF_CHAR && ED_GetLoc(Expr) & (E_LOC_GLOBAL | E_LOC_STATIC)) {
+    /* Emit smaller code if a char variable is at a constant location */
+    if ((Flags & CF_CHAR) == CF_CHAR && ED_IsLocConst(Expr)) {
 
         LoadExpr (CF_NONE, Expr);
         AddCodeLine ("inc %s", ED_GetLabelName(Expr, 0));
@@ -1590,8 +1651,8 @@ static void PostDec (ExprDesc* Expr)
     /* Get the data type */
     Flags = TypeOf (Expr->Type);
 
-    /* Fast path: char */
-    if ((Flags & CF_CHAR) == CF_CHAR && ED_GetLoc(Expr) & (E_LOC_GLOBAL | E_LOC_STATIC)) {
+    /* Emit smaller code if a char variable is at a constant location */
+    if ((Flags & CF_CHAR) == CF_CHAR && ED_IsLocConst(Expr)) {
 
         LoadExpr (CF_NONE, Expr);
         AddCodeLine ("dec %s", ED_GetLabelName(Expr, 0));
@@ -2441,7 +2502,7 @@ static void parseadd (ExprDesc* Expr)
                 typeadjust (Expr, &Expr2, 1);
             } else {
                 /* OOPS */
-                Error ("Invalid operands for binary operator `+'");
+                Error ("Invalid operands for binary operator '+'");
             }
 
         } else {
@@ -2523,7 +2584,7 @@ static void parseadd (ExprDesc* Expr)
                 }
             } else {
                 /* OOPS */
-                Error ("Invalid operands for binary operator `+'");
+                Error ("Invalid operands for binary operator '+'");
                 flags = CF_INT;
             }
 
@@ -2567,7 +2628,7 @@ static void parseadd (ExprDesc* Expr)
                 flags = typeadjust (Expr, &Expr2, 1);
             } else {
                 /* OOPS */
-                Error ("Invalid operands for binary operator `+'");
+                Error ("Invalid operands for binary operator '+'");
                 flags = CF_INT;
             }
 
@@ -2609,7 +2670,7 @@ static void parseadd (ExprDesc* Expr)
                 flags = typeadjust (Expr, &Expr2, 0) & ~CF_CONST;
             } else {
                 /* OOPS */
-                Error ("Invalid operands for binary operator `+'");
+                Error ("Invalid operands for binary operator '+'");
                 flags = CF_INT;
             }
 
@@ -2645,7 +2706,7 @@ static void parsesub (ExprDesc* Expr)
 
     /* lhs cannot be function or pointer to function */
     if (IsTypeFunc (Expr->Type) || IsTypeFuncPtr (Expr->Type)) {
-        Error ("Invalid left operand for binary operator `-'");
+        Error ("Invalid left operand for binary operator '-'");
         /* Make it pointer to char to avoid further errors */
         Expr->Type = type_uchar;
     }
@@ -2668,7 +2729,7 @@ static void parsesub (ExprDesc* Expr)
 
     /* rhs cannot be function or pointer to function */
     if (IsTypeFunc (Expr2.Type) || IsTypeFuncPtr (Expr2.Type)) {
-        Error ("Invalid right operand for binary operator `-'");
+        Error ("Invalid right operand for binary operator '-'");
         /* Make it pointer to char to avoid further errors */
         Expr2.Type = type_uchar;
     }
@@ -2706,7 +2767,7 @@ static void parsesub (ExprDesc* Expr)
                 Expr->IVal -= Expr2.IVal;
             } else {
                 /* OOPS */
-                Error ("Invalid operands for binary operator `-'");
+                Error ("Invalid operands for binary operator '-'");
             }
 
             /* Result is constant, condition codes not set */
@@ -2739,7 +2800,7 @@ static void parsesub (ExprDesc* Expr)
                 flags = typeadjust (Expr, &Expr2, 1);
             } else {
                 /* OOPS */
-                Error ("Invalid operands for binary operator `-'");
+                Error ("Invalid operands for binary operator '-'");
                 flags = CF_INT;
             }
 
@@ -2793,7 +2854,7 @@ static void parsesub (ExprDesc* Expr)
             flags = typeadjust (Expr, &Expr2, 0);
         } else {
             /* OOPS */
-            Error ("Invalid operands for binary operator `-'");
+            Error ("Invalid operands for binary operator '-'");
             flags = CF_INT;
         }
 
@@ -3260,7 +3321,7 @@ static void opeq (const GenDesc* Gen, ExprDesc* Expr, const char* Op)
 
     /* The rhs must be an integer (or a float, but we don't support that yet */
     if (!IsClassInt (Expr2.Type)) {
-        Error ("Invalid right operand for binary operator `%s'", Op);
+        Error ("Invalid right operand for binary operator '%s'", Op);
         /* Continue. Wrong code will be generated, but the compiler won't
         ** break, so this is the best error recovery.
         */
@@ -3377,7 +3438,7 @@ static void addsubeq (const GenDesc* Gen, ExprDesc *Expr, const char* Op)
     */
     hie1 (&Expr2);
     if (!IsClassInt (Expr2.Type)) {
-        Error ("Invalid right operand for binary operator `%s'", Op);
+        Error ("Invalid right operand for binary operator '%s'", Op);
         /* Continue. Wrong code will be generated, but the compiler won't
         ** break, so this is the best error recovery.
         */