]> git.sur5r.net Git - cc65/commitdiff
Allow token lists to be optionally enclosed in curly braces. Using such
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 9 May 2004 19:45:07 +0000 (19:45 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 9 May 2004 19:45:07 +0000 (19:45 +0000)
enclosement, tokens that would otherwise terminate the list can be part
of the list.

git-svn-id: svn://svn.cc65.org/cc65/trunk@3013 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ca65/expr.c
src/ca65/macro.c
src/ca65/nexttok.c
src/ca65/scanner.c
src/ca65/scanner.h

index 75e1aee264144452ab58883dd6ae946e51e4e59c..e3a1f6c0ad927599e685e48d94462e4599ae3cec 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/* (C) 1998-2004 Ullrich von Bassewitz                                       */
 /*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
@@ -418,15 +418,22 @@ static ExprNode* DoMatch (enum TC EqualityLevel)
 /* Handle the .MATCH and .XMATCH builtin functions */
 {
     int Result;
+    enum Token Term;
     TokNode* Root = 0;
     TokNode* Last = 0;
     TokNode* Node;
 
     /* A list of tokens follows. Read this list and remember it building a
      * single linked list of tokens including attributes. The list is
-     * terminated by a comma.
+     * either enclosed in curly braces, or terminated by a comma.
      */
-    while (Tok != TOK_COMMA) {
+    if (Tok == TOK_LCURLY) {
+        NextTok ();
+        Term = TOK_RCURLY;
+    } else {
+        Term = TOK_COMMA;
+    }
+    while (Tok != Term) {
 
        /* We may not end-of-line of end-of-file here */
        if (TokIsSep (Tok)) {
@@ -449,15 +456,27 @@ static ExprNode* DoMatch (enum TC EqualityLevel)
        NextTok ();
     }
 
-    /* Skip the comma */
+    /* Skip the terminator token*/
     NextTok ();
 
-    /* Read the second list which is terminated by the right parenthesis and
-     * compare each token against the one in the first list.
+    /* If the token list was enclosed in curly braces, we expect a comma */
+    if (Term == TOK_RCURLY) {
+        ConsumeComma ();
+    }
+
+    /* Read the second list which is optionally enclosed in curly braces and
+     * terminated by the right parenthesis. Compare each token against the 
+     * one in the first list.
      */
+    if (Tok == TOK_LCURLY) {
+        NextTok ();
+        Term = TOK_RCURLY;
+    } else {
+        Term = TOK_RPAREN;
+    }
     Result = 1;
     Node = Root;
-    while (Tok != TOK_RPAREN) {
+    while (Tok != Term) {
 
        /* We may not end-of-line of end-of-file here */
        if (TokIsSep (Tok)) {
@@ -485,6 +504,11 @@ static ExprNode* DoMatch (enum TC EqualityLevel)
        NextTok ();
     }
 
+    /* If the token list was enclosed in curly braces, eat the closing brace */
+    if (Term == TOK_RCURLY) {
+        NextTok ();
+    }
+
     /* Check if there are remaining tokens in the first list */
     if (Node != 0) {
        Result = 0;
index 282bbe6871356fa7b40bf3fbaf117f4cea251d6e..aea87253cfd6e901c9662f8feac0ac71fd6ce3de 100644 (file)
@@ -655,7 +655,9 @@ MacEnd:
 static void StartExpClassic (Macro* M)
 /* Start expanding the classic macro M */
 {
-    MacExp* E;
+    MacExp*     E;
+    enum Token  Term;
+
 
     /* Skip the macro name */
     NextTok ();
@@ -670,21 +672,29 @@ static void StartExpClassic (Macro* M)
 
                /* Check for maximum parameter count */
        if (E->ParamCount >= M->ParamCount) {
-           Error ("Too many macro parameters");
-           SkipUntilSep ();
+                   ErrorSkip ("Too many macro parameters");
            break;
        }
 
-       /* Read tokens for one parameter, accept empty params */
+        /* The macro may optionally be enclosed in curly braces */
+        if (Tok == TOK_LCURLY) {
+            NextTok ();
+            Term = TOK_RCURLY;
+        } else {
+            Term = TOK_COMMA;
+        }
+
+               /* Read tokens for one parameter, accept empty params */
        Last = 0;
-       while (Tok != TOK_COMMA && Tok != TOK_SEP) {
+       while (Tok != Term && Tok != TOK_SEP) {
 
            TokNode* T;
 
            /* Check for end of file */
            if (Tok == TOK_EOF) {
-               Error ("Unexpected end of file");
-               return;
+               Error ("Unexpected end of file");
+                FreeMacExp (E);
+               return;
            }
 
            /* Get the next token in a node */
@@ -694,7 +704,7 @@ static void StartExpClassic (Macro* M)
            if (Last == 0) {
                E->Params [E->ParamCount] = T;
            } else {
-               Last->Next = T;
+               Last->Next = T;
            }
            Last = T;
 
@@ -705,14 +715,28 @@ static void StartExpClassic (Macro* M)
        /* One parameter more */
        ++E->ParamCount;
 
+        /* If the macro argument was enclosed in curly braces, end-of-line
+         * is an error. Skip the closing curly brace.
+         */
+        if (Term == TOK_RCURLY) {
+            if (Tok == TOK_SEP) {
+                Error ("End of line encountered within macro argument");
+                break;
+            }
+            NextTok ();
+        }
+
        /* Check for a comma */
        if (Tok == TOK_COMMA) {
-           NextTok ();
-       } else {
-           break;
-       }
+           NextTok ();
+       } else {
+           break;
+       }
     }
 
+    /* We must be at end of line now, otherwise something is wrong */
+    ExpectSep ();
+
     /* Insert a new token input function */
     PushInput (MacExpand, E, ".MACRO");
 }
@@ -736,14 +760,23 @@ static void StartExpDefine (Macro* M)
     /* Read the actual parameters */
     while (Count--) {
 
-               TokNode* Last;
+        enum Token Term;
+               TokNode*   Last;
+
+        /* The macro may optionally be enclosed in curly braces */
+        if (Tok == TOK_LCURLY) {
+            NextTok ();
+            Term = TOK_RCURLY;
+        } else {
+            Term = TOK_COMMA;
+        }
 
                /* Check if there is really a parameter */
-               if (TokIsSep (Tok) || Tok == TOK_COMMA) {
-                   Error ("Macro parameter expected");
-                   SkipUntilSep ();
-                   return;
-               }
+               if (TokIsSep (Tok) || Tok == Term) {
+            ErrorSkip ("Macro parameter #%u is empty", E->ParamCount+1);
+            FreeMacExp (E);
+            return;
+        }
 
                /* Read tokens for one parameter */
                Last = 0;
@@ -765,11 +798,22 @@ static void StartExpDefine (Macro* M)
            /* And skip it... */
            NextTok ();
 
-       } while (Tok != TOK_COMMA && !TokIsSep (Tok));
+               } while (Tok != Term && !TokIsSep (Tok));
 
        /* One parameter more */
        ++E->ParamCount;
 
+        /* If the macro argument was enclosed in curly braces, end-of-line
+         * is an error. Skip the closing curly brace.
+         */
+        if (Term == TOK_RCURLY) {
+            if (TokIsSep (Tok)) {
+                Error ("End of line encountered within macro argument");
+                break;
+            }
+            NextTok ();
+        }
+
                /* Check for a comma */
                if (Count > 0) {
                    if (Tok == TOK_COMMA) {
@@ -782,7 +826,7 @@ static void StartExpDefine (Macro* M)
 
     /* Macro expansion will overwrite the current token. This is a problem
      * for define style macros since these are called from the scanner level.
-     * To avoid it, remember the current token and re-insert it if macro
+     * To avoid it, remember the current token and re-insert it, once macro
      * expansion is done.
      */
     E->Final = NewTokNode ();
index 4d6e8968300399ddc1258697702191a0f4d9a5a5..4c89bc1a70bda576a93d72d33cadae7e8a19fd86 100644 (file)
@@ -65,18 +65,29 @@ static unsigned RawMode = 0;                /* Raw token mode flag/counter */
 
 
 static TokList* CollectTokens (unsigned Start, unsigned Count)
-/* Read a list of tokens that is terminated by a right paren. For all tokens
- * starting at the one with index Start, and ending at (Start+Count-1), place
- * them into a token list, and return this token list.
+/* Read a list of tokens that is optionally enclosed in curly braces and
+ * terminated by a right paren. For all tokens starting at the one with index
+ * Start, and ending at (Start+Count-1), place them into a token list, and
+ * return this token list.
  */
 {
+    enum Token Term;
+    unsigned   Current;
+
     /* Create the token list */
     TokList* List = NewTokList ();
 
+    /* Determine if the list is enclosed in curly braces. */
+    if (Tok == TOK_LCURLY) {
+        NextTok ();
+        Term = TOK_RCURLY;
+    } else {
+        Term = TOK_LCURLY;
+    }
+
     /* Read the token list */
-    unsigned Current = 0;
-    unsigned Parens  = 0;
-    while (Parens != 0 || Tok != TOK_RPAREN) {
+    Current = 0;
+    while (Tok != Term) {
 
        /* Check for end of line or end of input */
        if (TokIsSep (Tok)) {
@@ -90,20 +101,18 @@ static TokList* CollectTokens (unsigned Start, unsigned Count)
            AddCurTok (List);
        }
 
-       /* Check for and count parenthesii */
-       if (Tok == TOK_LPAREN) {
-           ++Parens;
-       } else if (Tok == TOK_RPAREN) {
-           --Parens;
-       }
-
        /* Get the next token */
        ++Current;
        NextTok ();
     }
 
-    /* Eat the closing paren */
-    ConsumeRParen ();
+    /* Eat the terminator token */
+    NextTok ();
+
+    /* If the list was enclosed in curly braces, we do expect now a right paren */
+    if (Term == TOK_RCURLY) {
+        ConsumeRParen ();
+    }
 
     /* Return the list of collected tokens */
     return List;
@@ -422,7 +431,7 @@ void ConsumeSep (void)
     /* We expect a separator token */
     ExpectSep ();
 
-    /* If we have one, skip it */
+    /* If we are at end of line, skip it */
     if (Tok == TOK_SEP) {
        NextTok ();
     }
index 62f7277b2d52e8fa05232278e8f12b6ebd0cb655..981b43a6895501a9f84a81973c47d32b9481804c 100644 (file)
@@ -980,6 +980,16 @@ CharAgain:
            Tok = TOK_RBRACK;
            return;
 
+       case '{':
+           NextChar ();
+           Tok = TOK_LCURLY;
+           return;
+
+       case '}':
+           NextChar ();
+           Tok = TOK_RCURLY;
+           return;
+
        case '<':
            NextChar ();
            if (C == '=') {
index b9d38895fa5e5345dcda5acf5e5daeae6d0e3da1..aa5cf6c7f867a05e061ba2ea9f611f0c30dfe07c 100644 (file)
@@ -106,6 +106,8 @@ enum Token {
     TOK_RPAREN,                /* ) */
     TOK_LBRACK,                /* [ */
     TOK_RBRACK,                /* ] */
+    TOK_LCURLY,         /* { */
+    TOK_RCURLY,         /* } */
 
     TOK_OVERRIDE_ZP,    /* z: */
     TOK_OVERRIDE_ABS,   /* a: */