OpenCores
URL https://opencores.org/ocsvn/thor/thor/trunk

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [software/] [AS64/] [source/] [Macro.cpp] - Diff between revs 48 and 54

Show entire file | Details | Blame | View Log

Rev 48 Rev 54
Line 1... Line 1...
#include "stdafx.h"
#include "stdafx.h"
 
 
 
int Macro::inst = 0;
 
 
// Substitute the argument list into the macro body.
// Substitute the argument list into the macro body.
 
 
char *Macro::SubArgs()
char *Macro::SubArgs(Arglist *al)
{
{
        char *buf, *bdy;
        char *buf, *bdy;
        char *p, *q;
        char *p, *q;
        int ndx;
        int ndx;
        static char ibuf[16000];
        int bufsz;
 
 
        bdy = body;
        bdy = body;
        ZeroMemory(ibuf, 16000);
        buf = new char[16000];
        for (p = ibuf; *bdy; bdy++) {
        ZeroMemory(buf, 16000);
 
        bufsz = 16000;
 
        for (p = buf; *bdy; bdy++) {
                // If macro instance indicator found, substitute the instance number.
                // If macro instance indicator found, substitute the instance number.
                if (*bdy == '@')
                if (*bdy == '@') {
                        p += sprintf_s(p, 16000 - (p-buf), "%d", inst);
                        p += sprintf_s(p, bufsz - (p - buf), "%d", inst);
 
                        *p = '\0';
 
                }
                else if (*bdy == MACRO_PARM_MARKER) {
                else if (*bdy == MACRO_PARM_MARKER) {
                        if (isdigit(*(bdy+1))) {
                        if (isdigit(*(bdy+1))) {
                                bdy++;
                                bdy++;
                                ndx = *bdy - '0';
                                ndx = *bdy - '0';
                                if (ndx < args->count) {
                                if (ndx < parms.count && ndx < al->count) {
                                        // Copy the argument from the arg list to the output buffer.
                                        // Copy the parameter from the arg list to the output buffer.
                                        for (q = args->arg[ndx]->text; *q; q++) {
                                        if (&buf[bufsz] - p > al->args[ndx].text.length()) {
                                                *p = *q;
                                                strcpy(p, (char *)al->args[ndx].text.c_str());
                                                p++;
                                                while (*p) p++;
                                        }
                                        }
                                }
                                }
                                printf("Not enough args for substitution. %d\r\n", lineno);
 
                        }
                        }
                        else {
                        else {
                                *p = *bdy;
                                *p = *bdy;
                                p++;
                                p++;
                        }
                        }
Line 36... Line 41...
                // Not a parameter marker, just copy text to output.
                // Not a parameter marker, just copy text to output.
                else {
                else {
                        *p = *bdy;
                        *p = *bdy;
                        p++;
                        p++;
                }
                }
 
                if (&buf[bufsz] - p < 20) {
 
                        ndx = p - buf;
 
                        q = new char[bufsz + 10000];
 
                        memcpy(q, buf, bufsz);
 
                        bufsz += 10000;
 
                        delete[] buf;
 
                        buf = q;
 
                        p = &buf[ndx];
        }
        }
        buf = new char[strlen(ibuf)+1];
        }
        memcpy(buf, ibuf, strlen(ibuf)+1);
        *p = '\0';
        return (buf);
        return (buf);
}
}
 
 
 
 
 
void SkipBlockComment()
 
{
 
        char c;
 
 
 
        do {
 
                c = *inptr;
 
                inptr++;
 
                if (c == '*') {
 
                        c = *inptr;
 
                        inptr++;
 
                        if (c == '/')
 
                                break;
 
                        --inptr;
 
                }
 
        } while (c > 0);
 
}
 
 
 
int ProcessUnquoted()
 
{
 
        char c;
 
 
 
        c = *inptr;
 
        if (c == '/') {
 
                c = *inptr;
 
                inptr++;
 
                c = *inptr;
 
                inptr++;
 
                // Block comment ?
 
                if (c == '*') {
 
                        SkipBlockComment();
 
                        c = *inptr;
 
                        if (c > 0)
 
                                return (1);
 
                        else {
 
                                printf("End of file in block comment. %d\n", lineno);
 
                                return (0);
 
                        }
 
                }
 
                // Comment to EOL ?
 
                else if (c == '/') {
 
                        ScanToEOL();
 
                        c = *inptr;
 
                        if (c > 0)
 
                                return (0);
 
                }
 
                else {
 
                        c = '/';
 
                        --inptr;
 
                }
 
        }
 
        return (1);
 
}
 
 
 
int CountLeadingSpaces()
 
{
 
        int count;
 
 
 
        count = 0;
 
        while (*inptr == ' ' || *inptr == '\t') {
 
                inptr++;
 
                count++;
 
        }
 
        return (count);
 
}
 
 
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//   Description :
//   Description :
//      Gets the body of a macro. All macro bodies must be < 2k in size. Macro
//      Gets the body of a macro. All macro bodies must be < 2k in size. Macro
//   parameters are matched up with their positions in the macro. A $<number>
//   parameters are matched up with their positions in the macro. A $<number>
//   (as in $1, $2, etc) is substituted in the macro body in place of the
//   (as in $1, $2, etc) is substituted in the macro body in place of the
//   parameter name (we don't actually care what the parameter name is).
//   parameter name (we don't actually care what the parameter name is).
//      Macros continued on the next line with '\' are also processed. The
//      Macros continued on the next line with '\' are also processed. The
//   newline is removed from the macro.
//   newline is removed from the macro.
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
char *Macro::GetBody(char *parmlist[])
char *Macro::GetBody()
{
{
   char *b, *id = NULL, *p1, *p2;
   char *b, *id = NULL, *p1, *p2;
   static char buf[16000];
        char *buf;
   int ii, found, c;
   int ii, found, c;
   int InQuote = 0;
   int InQuote = 0;
   int count = sizeof(buf)-1;
        int count = 16000;
 
        bool abort = false;
 
 
 
        try {
 
                buf = new char[count];
 
                ZeroMemory(buf, count);
   SkipSpaces();
   SkipSpaces();
   memset(buf, 0, sizeof(buf));
                for (b = buf; count >= 0; )
   for (b = buf; count >= 0; b++, --count)
 
   {
   {
      // First search for an identifier to substitute with parameter
      // First search for an identifier to substitute with parameter
      if (parmlist) {
                        if (parms.count > 0) {
         while (*inptr == ' ' || *inptr == '\t') {
                                ii = CountLeadingSpaces();
            *b++ = *inptr;
                                count -= ii;
                        inptr++;
 
            count--;
 
            if (count < 0)
            if (count < 0)
               goto jmp1;
                                        break;
         }
                                memcpy(b, inptr - ii, ii);
 
                                b += ii;
         p1 = inptr;
         p1 = inptr;
         id = getIdentifier();
                                NextToken();
         p2 = inptr;
         p2 = inptr;
         if (id) {
                                if (token == tk_endm)
            for (found = ii = 0; parmlist[ii]; ii++)
                                        break;
               if (strcmp(parmlist[ii], id) == 0) {
                                if (token == tk_id) {
                  *b = '';
                                        for (found = ii = 0; ii < parms.count && !abort; ii++) {
 
                                                if (parms.args[ii].text.compare(lastid) == 0) {
 
                                                        *b = '\x14';
                  b++;
                  b++;
                  count--;
                  count--;
                  if (count < 0)
                                                        if (count < 0) {
                     goto jmp1;
                                                                abort = true;
 
                                                        }
 
                                                        else {
                  *b = '0' + (char)ii;
                  *b = '0' + (char)ii;
 
                                                                b++;
                  found = 1;
                  found = 1;
                  break;
                  break;
               }
               }
 
                                                }
 
                                        }
 
                                        if (abort)
 
                                                break;
            // if the identifier was not a parameter then just copy it to
            // if the identifier was not a parameter then just copy it to
            // the macro body
            // the macro body
            if (!found) {
            if (!found) {
               strncpy(b, p1, p2-p1);
                                                count -= p2 - p1;
               count -= p2 -p1 - 1;
 
               if (count < 0)
               if (count < 0)
                  goto jmp1;
                                                        break;
               b += p2-p1-1;  // b will be incremented at end of loop
                                                memcpy(b, p1, p2 - p1);
 
                                                b += p2 - p1;
            }
            }
         }
         }
         else
         else
            inptr = p1;    // reset inptr if no identifier found
            inptr = p1;    // reset inptr if no identifier found
      }
      }
      if (id == NULL) {
                        if (token == tk_endm)
 
                                break;
 
                        if (token != tk_id) {
 
                                memcpy(b, p1, p2 - p1);
 
                                b += p2 - p1;
 
                                inptr = p2;
         c = *inptr;
         c = *inptr;
 
                                //inptr++;
 
                                if (c == '"') {
                 inptr++;
                 inptr++;
         if (c == '"')
 
            InQuote = !InQuote;
            InQuote = !InQuote;
 
                                }
         if (!InQuote) {
         if (!InQuote) {
            if (c == '/') {
                                        p1 = inptr;
                                c = *inptr;
                                        c = ProcessUnquoted();
                                inptr++;
                                        if (count - (inptr - p1) < 0) {
               c = NextCh();
                                                count = -1;
               // Block comment ?
 
               if (c == '*') {
 
                  while(c > 0) {
 
                                          c = *inptr;
 
                                          inptr++;
 
                     if (c == '*') {
 
                                                 c = *inptr;
 
                                                 inptr++;
 
                        if (c == '/')
 
                           break;
                           break;
                                                --inptr;
 
                     }
                     }
 
                                        memcpy(b, p1, (inptr - p1));
 
                                        b += (inptr - p1);
 
                                        if (c == 0)
 
                                                break;
 
                                        c = inptr[-1];
                  }
                  }
                  if (c > 0) {
                                if (c < 1) {
                     --b;
                                        if (InQuote)
                     continue;
                                                printf("End of file in quote. %d\n", lineno);
 
                                        break;
                  }
                  }
                  else
 
                                          printf("End of line in comment. %d\n", lineno);
 
               }
               }
               // Comment to EOL ?
 
               else if (c == '/') {
 
                                   while(c != '\n' && c > 0) { c = *inptr; inptr++; }
 
                  if (c > 0) {
 
                     --b;
 
                     ++count;
 
                     goto jmp1;
 
                  }
                  }
 
 
 
                if (count < 0) {
 
                        delete[] buf;
 
                        printf("Expanded macro is too large. %d\n", lineno);
 
                        body = new char[20];
 
                        strcpy(body, "<too large>");
 
                        return (body);
               }
               }
                           else {
                           else {
                                   c = '/';
                        *b = '\0';
                  --inptr;
                        --b;
                           }
                        // Trim off trailing spaces.
            }
                        while ((*b == ' ' || *b == '\t') && b > buf) {
            else if (c == '\\')  // check for continuation onto next line
                                b--;
            {
 
                                while (c != '\n' && c > 0) { c= *inptr; inptr++}
 
               if (c > 0) {
 
                  --b;           // b will be incremented but we haven't got a character
 
                  ++count;
 
                  SkipSpaces();  // Skip leading spaces on next line
 
                  continue;
 
               }
 
            }
 
         }
         }
         if (c == '\n' || c < 1) {
                        b++;
            if (InQuote)
                        *b = '\0';
                                printf("End of file in comment. %d\n", lineno);
                        body = new char[strlen(buf) + 10];
            break;
                        strcpy(body, buf);
 
                        delete[] buf;
 
                        return (body);
         }
         }
         *b = c;
 
      }
      }
 
        catch (...) {
 
                printf("Thrown error\n");
   }
   }
jmp1:
 
   if (count < 0)
 
           printf("Expanded macro is too large. %d\n", lineno);
 
   *b = 0;
 
   rtrim(buf);    // Trim off trailing spaces.
 
   return buf;
 
}
}
 
 
 
 
void Arg::Clear()
void Arg::Clear()
{
{
        ZeroMemory(text,sizeof(text));
        text = "";
}
}
 
 
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//   Description :
//   Description :
//      Gets an argument to be substituted into a macro body. Note that the
//      Gets an argument to be substituted into a macro body. Note that the
Line 191... Line 269...
 
 
void Arg::Get()
void Arg::Get()
{
{
   int Depth = 0;
   int Depth = 0;
   int c;
   int c;
   char *argstr = text;
        char ch;
 
        char *st;
 
 
   SkipSpaces();
   SkipSpaces();
   ZeroMemory(text,sizeof(text));
        st = inptr;
   while(1)
   while(1)
   {
   {
           if (argstr-text > sizeof(text)-2) {
 
                   printf("Macro argument too large %d. Is a ')' missing ?\n",lineno);
 
                   break;
 
           }
 
      c = *inptr;
      c = *inptr;
          inptr++;
          inptr++;
      if (c < 1) {
      if (c < 1) {
         if (Depth > 0)
         if (Depth > 0)
                        printf("err16\r\n");
                        printf("err16\r\n");
Line 225... Line 300...
      }
      }
          else if (Depth == 0 && (c=='\r' || c=='\n')) {
          else if (Depth == 0 && (c=='\r' || c=='\n')) {
                  --inptr;
                  --inptr;
                  break;
                  break;
          }
          }
      *argstr++ = c;       // copy input argument to argstr.
 
   }
   }
 
         ch = *inptr;
 
         *inptr = '\0';
 
         text = std::string(st);
 
         *inptr = ch;
//   if (argbuf[0])
//   if (argbuf[0])
//         if (fdbg) fprintf(fdbg,"    macro arg<%s>\r\n",argbuf);
//         if (fdbg) fprintf(fdbg,"    macro arg<%s>\r\n",argbuf);
   return;
   return;
}
}
 
 
void Arglist::Get()
void Arglist::Get()
{
{
        int nn;
        int nn;
        char lastch;
        char lastch;
 
        bool done = false;
 
 
        for (nn = 0; nn < 10; nn++)
        for (nn = 0; nn < 10; nn++)
                args[nn]->Clear();
                args[nn].Clear();
        for (nn = 0; nn < 10; nn++) {
        count = 0;
                args[nn]->Get();
j1:
                if (*inptr != ',') {
 
                        SkipSpaces();
                        SkipSpaces();
                        break;
        switch (*inptr) {
                }
        case '\n':
                inptr++;        // skip over ,
 
        }
 
        args->count = nn;
 
        while (*inptr) {
 
                if (*inptr==0)
 
                        break;
 
                if (*inptr=='\n') {
 
                        lineno++;
                        lineno++;
 
        case '\r':
 
                inptr++;
 
                goto j1;
 
        case '(':
 
                inptr++;
 
                SkipSpaces();
 
                for (; count < 10 && !done; count++) {
 
                        args[count].Get();
 
                        switch (*inptr) {
 
                                // Arg list can continue on next line
 
                        case '\n':
 
                                lineno++;
 
                        case '\r':
 
                                inptr++;
 
                                continue;
 
                        case ')':
 
                                done = true;
                        inptr++;
                        inptr++;
                        break;
                        break;
                }
                        case ',':
 
                                inptr++;
 
                                SkipSpaces();
 
                                continue;
 
                        case '\0':
 
                                break;
 
                        default:
                inptr++;
                inptr++;
        }
        }
}
}
 
                break;
 
        default:;
 
        }
 
}
 
 
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//   Description :
//   Description :
//      Used during the definition of a macro to get the associated parameter
//      Used during the definition of a macro to get the associated parameter
//   list.
//   list.
//
//
//   Returns
//   Returns
//      pointer to first parameter in list.
//      pointer to first parameter in list.
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
 
 
int Macro::GetParmList(char *parmlist[])
int Macro::GetParmList()
{
{
   int id;
   int id;
   int Depth = 0, c, count;
        int Depth = 0, c;
 
 
   count = 0;
        parms.count = 0;
   while(1)
   while(1)
   {
   {
      id = getIdentifier();
                NextToken();
      if (id!=0) {
                if (token==tk_id) {
         if (count >= 20) {
                        if (parms.count >= 20) {
                         printf("Too many macro parameters %d.\n", lineno);
                         printf("Too many macro parameters %d.\n", lineno);
             goto errxit;
             goto errxit;
         }
         }
         parmlist[count] = _strdup(lastid);
                        parms.args[parms.count].text = std::string(lastid);
         if (parmlist[count] == NULL)
                        parms.count++;
                         printf("Insufficient memory %d\n", lineno);
 
         count++;
 
      }
      }
          do {
          do {
                        SkipSpaces();
                        SkipSpaces();
                        c = *inptr;
                        c = *inptr;
                        inptr++;
                        inptr++;
Line 307... Line 403...
      if (c != ',') {
      if (c != ',') {
                  printf("Expecting ',' in macro parameter list %d.\n", lineno);
                  printf("Expecting ',' in macro parameter list %d.\n", lineno);
         goto errxit;
         goto errxit;
      }
      }
   }
   }
//   if (count < 1)
 
//      err(17);
 
   if (count < 20)
 
      parmlist[count] = NULL;
 
errxit:;
errxit:;
   return count;
   return (parms.count);
}
}
 
 
 
 
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//   Description :
//   Description :
Line 324... Line 416...
//   to the start of the macro.
//   to the start of the macro.
//
//
//   slen; - the number of characters being substituted
//   slen; - the number of characters being substituted
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
 
 
void Macro::Substitute(char *body, int slen)
void Macro::Substitute(char *what, int slen)
{
{
   int mlen, dif, nchars;
   int mlen, dif, nchars;
   int nn;
   int nn;
   char *p;
   char *p;
 
 
   mlen = strlen(body);          // macro length
        mlen = strlen(what);          // macro length
   dif = mlen - slen;
   dif = mlen - slen;
   nchars = inptr-masterFile;         // calculate number of characters that could be remaining
   nchars = inptr-masterFile;         // calculate number of characters that could be remaining
   memmove(inptr+dif, inptr, sizeof(masterFile)-500-nchars-dif);  // shift open space in input buffer
        if (dif > 10000) {
 
                p = new char[masterFileLength + dif + 10000];
 
                memcpy(p, masterFile, masterFileLength);
 
                masterFile = p;
 
                masterFileLength = masterFileLength + dif + 10000;
 
                inptr = &masterFile[nchars];
 
        }
 
        memmove(inptr+dif, inptr, masterFileLength-500-nchars-dif);  // shift open space in input buffer
   inptr -= slen;                // reset input pointer to start of replaced text
   inptr -= slen;                // reset input pointer to start of replaced text
   memcpy(inptr, body, mlen);    // copy macro body in place over identifier
        memcpy(inptr, what, mlen);    // copy macro body in place over identifier
 
        inst++;
}
}
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.