]> git.sur5r.net Git - cc65/blobdiff - src/ca65/expr.c
Finished implemenation of commands to delete macros. Added the new commands to
[cc65] / src / ca65 / expr.c
index cb747c754b7e0befda6ce415f7ae77ae5b56514b..b8efe42b1448ca6ff3fc394ad18ac7f07ebc6a08 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2008 Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2011, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -319,7 +319,7 @@ static ExprNode* Symbol (SymEntry* S)
 
 
 
-static ExprNode* FuncBankByte (void)
+ExprNode* FuncBankByte (void)
 /* Handle the .BANKBYTE builtin function */
 {
     return BankByte (Expression ());
@@ -333,15 +333,15 @@ static ExprNode* FuncBlank (void)
     /* We have a list of tokens that ends with the closing paren. Skip
      * the tokens, and count them. Allow optionally curly braces.
      */
-    Token Term = GetTokListTerm (TOK_RPAREN);
+    token_t Term = GetTokListTerm (TOK_RPAREN);
     unsigned Count = 0;
-    while (Tok != Term) {
+    while (CurTok.Tok != Term) {
 
        /* Check for end of line or end of input. Since the calling function
         * will check for the closing paren, we don't need to print an error
         * here, just bail out.
         */
-       if (TokIsSep (Tok)) {
+       if (TokIsSep (CurTok.Tok)) {
            break;
        }
 
@@ -353,7 +353,7 @@ static ExprNode* FuncBlank (void)
     }
 
     /* If the list was enclosed in curly braces, skip the closing brace */
-    if (Term == TOK_RCURLY && Tok == TOK_RCURLY) {
+    if (Term == TOK_RCURLY && CurTok.Tok == TOK_RCURLY) {
         NextTok ();
     }
 
@@ -385,7 +385,7 @@ static ExprNode* FuncDefined (void)
 /* Handle the .DEFINED builtin function */
 {
     /* Parse the symbol name and search for the symbol */
-    SymEntry* Sym = ParseScopedSymName (SYM_FIND_EXISTING);
+    SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
 
     /* Check if the symbol is defined */
     return GenLiteralExpr (Sym != 0 && SymIsDef (Sym));
@@ -393,7 +393,7 @@ static ExprNode* FuncDefined (void)
 
 
 
-static ExprNode* FuncHiByte (void)
+ExprNode* FuncHiByte (void)
 /* Handle the .HIBYTE builtin function */
 {
     return HiByte (Expression ());
@@ -409,7 +409,7 @@ static ExprNode* FuncHiWord (void)
 
 
 
-static ExprNode* FuncLoByte (void)
+ExprNode* FuncLoByte (void)
 /* Handle the .LOBYTE builtin function */
 {
     return LoByte (Expression ());
@@ -437,11 +437,11 @@ static ExprNode* DoMatch (enum TC EqualityLevel)
      * single linked list of tokens including attributes. The list is
      * either enclosed in curly braces, or terminated by a comma.
      */
-    Token Term = GetTokListTerm (TOK_COMMA);
-    while (Tok != Term) {
+    token_t Term = GetTokListTerm (TOK_COMMA);
+    while (CurTok.Tok != Term) {
 
        /* We may not end-of-line of end-of-file here */
-       if (TokIsSep (Tok)) {
+       if (TokIsSep (CurTok.Tok)) {
            Error ("Unexpected end of line");
            return GenLiteral0 ();
        }
@@ -476,10 +476,10 @@ static ExprNode* DoMatch (enum TC EqualityLevel)
     Term = GetTokListTerm (TOK_RPAREN);
     Result = 1;
     Node = Root;
-    while (Tok != Term) {
+    while (CurTok.Tok != Term) {
 
        /* We may not end-of-line of end-of-file here */
-       if (TokIsSep (Tok)) {
+       if (TokIsSep (CurTok.Tok)) {
            Error ("Unexpected end of line");
            return GenLiteral0 ();
        }
@@ -535,11 +535,69 @@ static ExprNode* FuncMatch (void)
 
 
 
+static ExprNode* FuncMax (void)
+/* Handle the .MAX function */
+{
+    ExprNode* Left;
+    ExprNode* Right;
+    ExprNode* Expr;
+    long LeftVal, RightVal;
+
+    /* Two arguments to the pseudo function */
+    Left = Expression ();
+    ConsumeComma ();
+    Right = Expression ();
+
+    /* Check if we can evaluate the value immediately */
+    if (IsEasyConst (Left, &LeftVal) && IsEasyConst (Right, &RightVal)) {
+        FreeExpr (Left);
+        FreeExpr (Right);
+        Expr = GenLiteralExpr ((LeftVal > RightVal)? LeftVal : RightVal);
+    } else {
+        /* Make an expression node */
+        Expr = NewExprNode (EXPR_MAX);
+        Expr->Left = Left;
+        Expr->Right = Right;
+    }
+    return Expr;
+}
+
+
+
+static ExprNode* FuncMin (void)
+/* Handle the .MIN function */
+{
+    ExprNode* Left;
+    ExprNode* Right;
+    ExprNode* Expr;
+    long LeftVal, RightVal;
+
+    /* Two arguments to the pseudo function */
+    Left = Expression ();
+    ConsumeComma ();
+    Right = Expression ();
+
+    /* Check if we can evaluate the value immediately */
+    if (IsEasyConst (Left, &LeftVal) && IsEasyConst (Right, &RightVal)) {
+        FreeExpr (Left);
+        FreeExpr (Right);
+        Expr = GenLiteralExpr ((LeftVal < RightVal)? LeftVal : RightVal);
+    } else {
+        /* Make an expression node */
+        Expr = NewExprNode (EXPR_MIN);
+        Expr->Left = Left;
+        Expr->Right = Right;
+    }
+    return Expr;
+}
+
+
+
 static ExprNode* FuncReferenced (void)
 /* Handle the .REFERENCED builtin function */
 {
     /* Parse the symbol name and search for the symbol */
-    SymEntry* Sym = ParseScopedSymName (SYM_FIND_EXISTING);
+    SymEntry* Sym = ParseAnySymName (SYM_FIND_EXISTING);
 
     /* Check if the symbol is referenced */
     return GenLiteralExpr (Sym != 0 && SymIsRef (Sym));
@@ -563,18 +621,18 @@ static ExprNode* FuncSizeOf (void)
     SizeSym = 0;
 
     /* Check for a cheap local which needs special handling */
-    if (Tok == TOK_LOCAL_IDENT) {
+    if (CurTok.Tok == TOK_LOCAL_IDENT) {
 
         /* Cheap local symbol */
-        Sym = SymFindLocal (SymLast, &SVal, SYM_FIND_EXISTING);
+        Sym = SymFindLocal (SymLast, &CurTok.SVal, SYM_FIND_EXISTING);
         if (Sym == 0) {
-            Error ("Unknown symbol or scope: `%m%p'", &SVal);
+            Error ("Unknown symbol or scope: `%m%p'", &CurTok.SVal);
         } else {
             SizeSym = GetSizeOfSymbol (Sym);
         }
 
         /* Remember and skip SVal, terminate ScopeName so it is empty */
-        SB_Copy (&Name, &SVal);
+        SB_Copy (&Name, &CurTok.SVal);
         NextTok ();
         SB_Terminate (&ScopeName);
 
@@ -650,14 +708,14 @@ static ExprNode* FuncStrAt (void)
     unsigned char C = 0;
 
     /* String constant expected */
-    if (Tok != TOK_STRCON) {
+    if (CurTok.Tok != TOK_STRCON) {
        Error ("String constant expected");
        NextTok ();
                goto ExitPoint;
     }
 
     /* Remember the string and skip it */
-    SB_Copy (&Str, &SVal);
+    SB_Copy (&Str, &CurTok.SVal);
     NextTok ();
 
     /* Comma must follow */
@@ -693,11 +751,11 @@ static ExprNode* FuncStrLen (void)
     int Len;
 
     /* String constant expected */
-    if (Tok != TOK_STRCON) {
+    if (CurTok.Tok != TOK_STRCON) {
 
        Error ("String constant expected");
        /* Smart error recovery */
-       if (Tok != TOK_RPAREN) {
+       if (CurTok.Tok != TOK_RPAREN) {
            NextTok ();
        }
                Len = 0;
@@ -705,7 +763,7 @@ static ExprNode* FuncStrLen (void)
     } else {
 
         /* Get the length of the string */
-               Len = SB_GetLen (&SVal);
+               Len = SB_GetLen (&CurTok.SVal);
 
        /* Skip the string */
        NextTok ();
@@ -723,15 +781,15 @@ static ExprNode* FuncTCount (void)
     /* We have a list of tokens that ends with the closing paren. Skip
      * the tokens, and count them. Allow optionally curly braces.
      */
-    Token Term = GetTokListTerm (TOK_RPAREN);
+    token_t Term = GetTokListTerm (TOK_RPAREN);
     int Count = 0;
-    while (Tok != Term) {
+    while (CurTok.Tok != Term) {
 
        /* Check for end of line or end of input. Since the calling function
         * will check for the closing paren, we don't need to print an error
         * here, just bail out.
         */
-       if (TokIsSep (Tok)) {
+       if (TokIsSep (CurTok.Tok)) {
            break;
        }
 
@@ -743,7 +801,7 @@ static ExprNode* FuncTCount (void)
     }
 
     /* If the list was enclosed in curly braces, skip the closing brace */
-    if (Term == TOK_RCURLY && Tok == TOK_RCURLY) {
+    if (Term == TOK_RCURLY && CurTok.Tok == TOK_RCURLY) {
         NextTok ();
     }
 
@@ -770,7 +828,7 @@ static ExprNode* Function (ExprNode* (*F) (void))
     NextTok ();
 
     /* Expression must be enclosed in braces */
-    if (Tok != TOK_LPAREN) {
+    if (CurTok.Tok != TOK_LPAREN) {
        Error ("'(' expected");
        SkipUntilSep ();
        return GenLiteral0 ();
@@ -795,30 +853,26 @@ static ExprNode* Factor (void)
     ExprNode* N;
     long      Val;
 
-    switch (Tok) {
+    switch (CurTok.Tok) {
 
        case TOK_INTCON:
-           N = GenLiteralExpr (IVal);
+           N = GenLiteralExpr (CurTok.IVal);
                    NextTok ();
            break;
 
        case TOK_CHARCON:
-           N = GenLiteralExpr (TgtTranslateChar (IVal));
+           N = GenLiteralExpr (TgtTranslateChar (CurTok.IVal));
                    NextTok ();
            break;
 
        case TOK_NAMESPACE:
        case TOK_IDENT:
-            N = Symbol (ParseScopedSymName (SYM_ALLOC_NEW));
-           break;
-
         case TOK_LOCAL_IDENT:
-            N = Symbol (SymFindLocal (SymLast, &SVal, SYM_ALLOC_NEW));
-            NextTok ();
-            break;
+            N = Symbol (ParseAnySymName (SYM_ALLOC_NEW));
+           break;
 
        case TOK_ULABEL:
-           N = ULabRef (IVal);
+           N = ULabRef (CurTok.IVal);
            NextTok ();
            break;
 
@@ -919,6 +973,14 @@ static ExprNode* Factor (void)
            N = Function (FuncMatch);
            break;
 
+        case TOK_MAX:
+            N = Function (FuncMax);
+            break;
+
+        case TOK_MIN:
+            N = Function (FuncMin);
+            break;
+
         case TOK_REFERENCED:
            N = Function (FuncReferenced);
            break;
@@ -945,7 +1007,7 @@ static ExprNode* Factor (void)
            break;
 
         case TOK_VERSION:
-            N = GenLiteralExpr (VERSION);
+            N = GenLiteralExpr (GetVersionAsNumber ());
             NextTok ();
             break;
 
@@ -954,9 +1016,10 @@ static ExprNode* Factor (void)
            break;
 
        default:
-           if (LooseCharTerm && Tok == TOK_STRCON && SB_GetLen (&SVal) == 1) {
+           if (LooseCharTerm && CurTok.Tok == TOK_STRCON && 
+                SB_GetLen (&CurTok.SVal) == 1) {
                /* A character constant */
-               N = GenLiteralExpr (TgtTranslateChar (SB_At (&SVal, 0)));
+               N = GenLiteralExpr (TgtTranslateChar (SB_At (&CurTok.SVal, 0)));
            } else {
                N = GenLiteral0 ();     /* Dummy */
                Error ("Syntax error");
@@ -975,16 +1038,17 @@ static ExprNode* Term (void)
     ExprNode* Root = Factor ();
 
     /* Handle multiplicative operations */
-    while (Tok == TOK_MUL || Tok == TOK_DIV || Tok == TOK_MOD ||
-          Tok == TOK_AND || Tok == TOK_XOR || Tok == TOK_SHL ||
-          Tok == TOK_SHR) {
+    while (CurTok.Tok == TOK_MUL || CurTok.Tok == TOK_DIV ||
+           CurTok.Tok == TOK_MOD || CurTok.Tok == TOK_AND ||
+           CurTok.Tok == TOK_XOR || CurTok.Tok == TOK_SHL ||
+          CurTok.Tok == TOK_SHR) {
 
         long LVal, RVal, Val;
         ExprNode* Left;
         ExprNode* Right;
 
         /* Remember the token and skip it */
-        Token T = Tok;
+        token_t T = CurTok.Tok;
         NextTok ();
 
         /* Move root to left side and read the right side */
@@ -1078,14 +1142,16 @@ static ExprNode* SimpleExpr (void)
     ExprNode* Root = Term ();
 
     /* Handle additive operations */
-    while (Tok == TOK_PLUS || Tok == TOK_MINUS || Tok == TOK_OR) {
+    while (CurTok.Tok == TOK_PLUS  ||
+           CurTok.Tok == TOK_MINUS ||
+           CurTok.Tok == TOK_OR) {
 
         long LVal, RVal, Val;
         ExprNode* Left;
         ExprNode* Right;
 
         /* Remember the token and skip it */
-        Token T = Tok;
+        token_t T = CurTok.Tok;
         NextTok ();
 
         /* Move root to left side and read the right side */
@@ -1139,15 +1205,16 @@ static ExprNode* BoolExpr (void)
     ExprNode* Root = SimpleExpr ();
 
     /* Handle booleans */
-    while (Tok == TOK_EQ || Tok == TOK_NE || Tok == TOK_LT ||
-          Tok == TOK_GT || Tok == TOK_LE || Tok == TOK_GE) {
+    while (CurTok.Tok == TOK_EQ || CurTok.Tok == TOK_NE ||
+           CurTok.Tok == TOK_LT || CurTok.Tok == TOK_GT ||
+           CurTok.Tok == TOK_LE || CurTok.Tok == TOK_GE) {
 
         long LVal, RVal, Val;
         ExprNode* Left;
         ExprNode* Right;
 
         /* Remember the token and skip it */
-        Token T = Tok;
+        token_t T = CurTok.Tok;
         NextTok ();
 
         /* Move root to left side and read the right side */
@@ -1207,14 +1274,14 @@ static ExprNode* Expr2 (void)
     ExprNode* Root = BoolExpr ();
 
     /* Handle booleans */
-    while (Tok == TOK_BOOLAND || Tok == TOK_BOOLXOR) {
+    while (CurTok.Tok == TOK_BOOLAND || CurTok.Tok == TOK_BOOLXOR) {
 
         long LVal, RVal, Val;
         ExprNode* Left;
         ExprNode* Right;
 
         /* Remember the token and skip it */
-        Token T = Tok;
+        token_t T = CurTok.Tok;
         NextTok ();
 
         /* Move root to left side and read the right side */
@@ -1266,14 +1333,14 @@ static ExprNode* Expr1 (void)
     ExprNode* Root = Expr2 ();
 
     /* Handle booleans */
-    while (Tok == TOK_BOOLOR) {
+    while (CurTok.Tok == TOK_BOOLOR) {
 
         long LVal, RVal, Val;
         ExprNode* Left;
         ExprNode* Right;
 
         /* Remember the token and skip it */
-        Token T = Tok;
+        token_t T = CurTok.Tok;
         NextTok ();
 
         /* Move root to left side and read the right side */
@@ -1322,7 +1389,7 @@ static ExprNode* Expr0 (void)
     ExprNode* Root;
 
     /* Handle booleans */
-    if (Tok == TOK_BOOLNOT) {
+    if (CurTok.Tok == TOK_BOOLNOT) {
 
         long Val;
         ExprNode* Left;
@@ -1453,11 +1520,11 @@ ExprNode* GenSymExpr (SymEntry* Sym)
 
 
 
-static ExprNode* GenSectionExpr (unsigned SegNum)
+static ExprNode* GenSectionExpr (unsigned SecNum)
 /* Return an expression node for the given section */
 {
     ExprNode* Expr = NewExprNode (EXPR_SECTION);
-    Expr->V.SegNum = SegNum;
+    Expr->V.SecNum = SecNum;
     return Expr;
 }
 
@@ -1667,7 +1734,7 @@ ExprNode* CloneExpr (ExprNode* Expr)
            break;
 
        case EXPR_SECTION:
-           Clone = GenSectionExpr (Expr->V.SegNum);
+           Clone = GenSectionExpr (Expr->V.SecNum);
            break;
 
         default:
@@ -1707,7 +1774,7 @@ void WriteExpr (ExprNode* Expr)
         case EXPR_SYMBOL:
            if (SymIsImport (Expr->V.Sym)) {
                 ObjWrite8 (EXPR_SYMBOL);
-                ObjWriteVar (GetSymIndex (Expr->V.Sym));
+                ObjWriteVar (GetSymImportId (Expr->V.Sym));
             } else {
                 WriteExpr (GetSymExpr (Expr->V.Sym));
             }
@@ -1715,7 +1782,7 @@ void WriteExpr (ExprNode* Expr)
 
         case EXPR_SECTION:
             ObjWrite8 (EXPR_SECTION);
-           ObjWrite8 (Expr->V.SegNum);
+           ObjWrite8 (Expr->V.SecNum);
            break;
 
        case EXPR_ULABEL: