]> git.sur5r.net Git - cc65/blobdiff - src/ca65/expr.c
The longbranch macros did not work with numeric addresses
[cc65] / src / ca65 / expr.c
index fc43cdcb8e0f89306fca6a80d88920f88576ad58..497a6143abbece80766303dd70af328eb520dd0f 100644 (file)
 
 
 
-#include "../common/exprdefs.h"
-#include "../common/xmalloc.h"
+#include <string.h>
 
+/* common */
+#include "check.h"
+#include "exprdefs.h"
+#include "print.h"
+#include "tgttrans.h"
+#include "xmalloc.h"
+
+/* ca65 */
 #include "error.h"
 #include "global.h"
 #include "instr.h"
@@ -113,145 +120,6 @@ static void FreeExprNode (ExprNode* E)
 
 
 
-/*****************************************************************************/
-/*             Dump an expression tree on stdout for debugging              */
-/*****************************************************************************/
-
-
-
-static void InternalDumpExpr (ExprNode* Expr)
-/* Dump an expression in UPN */
-{
-    if (Expr == 0) {
-       return;
-    }
-    InternalDumpExpr (Expr->Left);
-    InternalDumpExpr (Expr->Right);
-
-    switch (Expr->Op) {
-
-       case EXPR_LITERAL:
-       case EXPR_ULABEL:
-           printf (" $%04lX", Expr->V.Val & 0xFFFF);
-           break;
-
-       case EXPR_SYMBOL:
-                   printf (" %s", GetSymName (Expr->V.Sym));
-           break;
-
-       case EXPR_SEGMENT:
-           printf (" SEG");
-           break;
-
-               case EXPR_PLUS:
-           printf (" +");
-           break;
-
-               case EXPR_MINUS:
-           printf (" -");
-           break;
-
-               case EXPR_MUL:
-           printf (" *");
-           break;
-
-               case EXPR_DIV:
-           printf (" /");
-           break;
-
-               case EXPR_MOD:
-           printf (" %%");
-           break;
-
-       case EXPR_OR:
-           printf (" OR");
-           break;
-
-       case EXPR_XOR:
-           printf (" XOR");
-           break;
-
-       case EXPR_AND:
-           printf (" AND");
-           break;
-
-       case EXPR_SHL:
-           printf (" SHL");
-           break;
-
-       case EXPR_SHR:
-           printf (" SHR");
-           break;
-
-               case EXPR_EQ:
-           printf (" =");
-           break;
-
-               case EXPR_NE:
-           printf ("<>");
-           break;
-
-               case EXPR_LT:
-           printf (" <");
-           break;
-
-               case EXPR_GT:
-           printf (" >");
-           break;
-
-               case EXPR_UNARY_MINUS:
-           printf (" NEG");
-           break;
-
-               case EXPR_NOT:
-           printf (" ~");
-           break;
-
-               case EXPR_LOBYTE:
-           printf (" LO");
-           break;
-
-               case EXPR_HIBYTE:
-           printf (" HI");
-           break;
-
-               case EXPR_SWAP:
-           printf (" SWAP");
-           break;
-
-       case EXPR_BAND:
-           printf (" BOOL_AND");
-           break;
-
-       case EXPR_BOR:
-           printf (" BOOL_OR");
-           break;
-
-       case EXPR_BXOR:
-           printf (" BOOL_XOR");
-           break;
-
-       case EXPR_BNOT:
-           printf (" BOOL_NOT");
-           break;
-
-        default:
-                   Internal ("Unknown Op type: %u", Expr->Op);
-
-    }
-}
-
-
-
-void DumpExpr (ExprNode* Expr)
-/* Dump an expression tree to stdout */
-{
-    InternalDumpExpr (Expr);
-    printf ("\n");
-}
-
-
-
 /*****************************************************************************/
 /*                                          Code                                    */
 /*****************************************************************************/
@@ -492,13 +360,15 @@ static int FuncStrAt (void)
     Index = ConstExpression ();
 
     /* Must be a valid index */
-    if (Index >= strlen (Str)) {
+    if (Index >= (long) strlen (Str)) {
        Error (ERR_RANGE);
        return 0;
     }
 
-    /* Return the char, handle as unsigned */
-    return (unsigned char) Str[(size_t)Index];
+    /* Return the char, handle as unsigned. Be sure to translate it into
+     * the target character set.
+     */
+    return (unsigned char) TgtTranslateChar (Str [(size_t)Index]);
 }
 
 
@@ -614,11 +484,15 @@ static ExprNode* Factor (void)
     switch (Tok) {
 
        case TOK_INTCON:
-       case TOK_CHARCON:
            N = LiteralExpr (IVal);
                    NextTok ();
            break;
 
+       case TOK_CHARCON:
+           N = LiteralExpr (TgtTranslateChar (IVal));
+                   NextTok ();
+           break;
+
         case TOK_NAMESPACE:
            NextTok ();
            if (Tok != TOK_IDENT) {
@@ -682,14 +556,14 @@ static ExprNode* Factor (void)
            NextTok ();
            N = NewExprNode ();
            N->Left = Factor ();
-           N->Op   = EXPR_LOBYTE;
+           N->Op   = EXPR_BYTE0;
            break;
 
        case TOK_GT:
            NextTok ();
            N = NewExprNode ();
            N->Left = Factor ();
-           N->Op   = EXPR_HIBYTE;
+           N->Op   = EXPR_BYTE1;
            break;
 
        case TOK_LPAREN:
@@ -740,8 +614,13 @@ static ExprNode* Factor (void)
            break;
 
        default:
-           N = LiteralExpr (0);        /* Dummy */
-           Error (ERR_SYNTAX);
+           if (LooseCharTerm && Tok == TOK_STRCON && strlen(SVal) == 1) {
+               /* A character constant */
+               N = LiteralExpr (TgtTranslateChar (SVal[0]));
+           } else {
+               N = LiteralExpr (0);    /* Dummy */
+               Error (ERR_SYNTAX);
+           }
            NextTok ();
            break;
     }
@@ -1158,7 +1037,7 @@ int IsConstExpr (ExprNode* Root)
            case EXPR_SYMBOL:
                Sym = Root->V.Sym;
                if (SymHasUserMark (Sym)) {
-                   if (Verbose) {
+                   if (Verbosity > 0) {
                        DumpExpr (Root);
                    }
                    PError (GetSymPos (Sym), ERR_CIRCULAR_REFERENCE);
@@ -1231,10 +1110,13 @@ static void CheckByteExpr (const ExprNode* N, int* IsByte)
            case EXPR_LEAFNODE:
                switch (N->Op) {
 
-                   case EXPR_SYMBOL:
-                       if (SymIsZP (N->V.Sym)) {
-                           *IsByte = 1;
-                       }
+                   case EXPR_SYMBOL:
+                       if (SymIsZP (N->V.Sym)) {
+                           *IsByte = 1;
+                       } else if (SymHasExpr (N->V.Sym)) {
+                           /* Check if this expression is a byte expression */
+                           *IsByte = IsByteExpr (GetSymExpr (N->V.Sym));
+                       }
                        break;
 
                    case EXPR_SEGMENT:
@@ -1273,7 +1155,8 @@ int IsByteExpr (ExprNode* Root)
            SimplifyExpr (Root);
        }
                return IsByteRange (GetExprVal (Root));
-    } else if (Root->Op == EXPR_LOBYTE || Root->Op == EXPR_HIBYTE) {
+    } else if (Root->Op == EXPR_BYTE0 || Root->Op == EXPR_BYTE1 ||
+              Root->Op == EXPR_BYTE2 || Root->Op == EXPR_BYTE3) {
        /* Symbol forced to have byte range */
                IsByte = 1;
     } else {
@@ -1370,12 +1253,18 @@ long GetExprVal (ExprNode* Expr)
                case EXPR_NOT:
            return ~GetExprVal (Expr->Left);
 
-               case EXPR_LOBYTE:
+               case EXPR_BYTE0:
            return GetExprVal (Expr->Left) & 0xFF;
 
-               case EXPR_HIBYTE:
+               case EXPR_BYTE1:
            return (GetExprVal (Expr->Left) >> 8) & 0xFF;
 
+               case EXPR_BYTE2:
+           return (GetExprVal (Expr->Left) >> 16) & 0xFF;
+
+               case EXPR_BYTE3:
+           return (GetExprVal (Expr->Left) >> 24) & 0xFF;
+
         case EXPR_SWAP:
            Left = GetExprVal (Expr->Left);
            return ((Left >> 8) & 0x00FF) | ((Left << 8) & 0xFF00);
@@ -1423,7 +1312,7 @@ static ExprNode* RemoveSyms (ExprNode* Expr, int MustClone)
                SymEntry* Sym = Expr->V.Sym;
                if (SymHasUserMark (Sym)) {
                    /* Circular definition */
-                   if (Verbose) {
+                   if (Verbosity) {
                        DumpExpr (Expr);
                    }
                    PError (GetSymPos (Sym), ERR_CIRCULAR_REFERENCE);