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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [software/] [AS64/] [source/] [Macro.cpp] - Blame information for rev 48

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 robfinch
#include "stdafx.h"
2
 
3
// Substitute the argument list into the macro body.
4
 
5
char *Macro::SubArgs()
6
{
7
        char *buf, *bdy;
8
        char *p, *q;
9
        int ndx;
10
        static char ibuf[16000];
11
 
12
        bdy = body;
13
        ZeroMemory(ibuf, 16000);
14
        for (p = ibuf; *bdy; bdy++) {
15
                // If macro instance indicator found, substitute the instance number.
16
                if (*bdy == '@')
17
                        p += sprintf_s(p, 16000 - (p-buf), "%d", inst);
18
                else if (*bdy == MACRO_PARM_MARKER) {
19
                        if (isdigit(*(bdy+1))) {
20
                                bdy++;
21
                                ndx = *bdy - '0';
22
                                if (ndx < args->count) {
23
                                        // Copy the argument from the arg list to the output buffer.
24
                                        for (q = args->arg[ndx]->text; *q; q++) {
25
                                                *p = *q;
26
                                                p++;
27
                                        }
28
                                }
29
                                printf("Not enough args for substitution. %d\r\n", lineno);
30
                        }
31
                        else {
32
                                *p = *bdy;
33
                                p++;
34
                        }
35
                }
36
                // Not a parameter marker, just copy text to output.
37
                else {
38
                        *p = *bdy;
39
                        p++;
40
                }
41
        }
42
        buf = new char[strlen(ibuf)+1];
43
        memcpy(buf, ibuf, strlen(ibuf)+1);
44
        return (buf);
45
}
46
 
47
 
48
// ---------------------------------------------------------------------------
49
//   Description :
50
//      Gets the body of a macro. All macro bodies must be < 2k in size. Macro
51
//   parameters are matched up with their positions in the macro. A $<number>
52
//   (as in $1, $2, etc) is substituted in the macro body in place of the
53
//   parameter name (we don't actually care what the parameter name is).
54
//      Macros continued on the next line with '\' are also processed. The
55
//   newline is removed from the macro.
56
// ----------------------------------------------------------------------------
57
 
58
char *Macro::GetBody(char *parmlist[])
59
{
60
   char *b, *id = NULL, *p1, *p2;
61
   static char buf[16000];
62
   int ii, found, c;
63
   int InQuote = 0;
64
   int count = sizeof(buf)-1;
65
 
66
   SkipSpaces();
67
   memset(buf, 0, sizeof(buf));
68
   for (b = buf; count >= 0; b++, --count)
69
   {
70
      // First search for an identifier to substitute with parameter
71
      if (parmlist) {
72
         while (*inptr == ' ' || *inptr == '\t') {
73
            *b++ = *inptr;
74
                        inptr++;
75
            count--;
76
            if (count < 0)
77
               goto jmp1;
78
         }
79
         p1 = inptr;
80
         id = getIdentifier();
81
         p2 = inptr;
82
         if (id) {
83
            for (found = ii = 0; parmlist[ii]; ii++)
84
               if (strcmp(parmlist[ii], id) == 0) {
85
                  *b = '';
86
                  b++;
87
                  count--;
88
                  if (count < 0)
89
                     goto jmp1;
90
                  *b = '0' + (char)ii;
91
                  found = 1;
92
                  break;
93
               }
94
            // if the identifier was not a parameter then just copy it to
95
            // the macro body
96
            if (!found) {
97
               strncpy(b, p1, p2-p1);
98
               count -= p2 -p1 - 1;
99
               if (count < 0)
100
                  goto jmp1;
101
               b += p2-p1-1;  // b will be incremented at end of loop
102
            }
103
         }
104
         else
105
            inptr = p1;    // reset inptr if no identifier found
106
      }
107
      if (id == NULL) {
108
         c = *inptr;
109
                 inptr++;
110
         if (c == '"')
111
            InQuote = !InQuote;
112
         if (!InQuote) {
113
            if (c == '/') {
114
                                c = *inptr;
115
                                inptr++;
116
               c = NextCh();
117
               // Block comment ?
118
               if (c == '*') {
119
                  while(c > 0) {
120
                                          c = *inptr;
121
                                          inptr++;
122
                     if (c == '*') {
123
                                                 c = *inptr;
124
                                                 inptr++;
125
                        if (c == '/')
126
                           break;
127
                                                --inptr;
128
                     }
129
                  }
130
                  if (c > 0) {
131
                     --b;
132
                     continue;
133
                  }
134
                  else
135
                                          printf("End of line in comment. %d\n", lineno);
136
               }
137
               // Comment to EOL ?
138
               else if (c == '/') {
139
                                   while(c != '\n' && c > 0) { c = *inptr; inptr++; }
140
                  if (c > 0) {
141
                     --b;
142
                     ++count;
143
                     goto jmp1;
144
                  }
145
               }
146
                           else {
147
                                   c = '/';
148
                  --inptr;
149
                           }
150
            }
151
            else if (c == '\\')  // check for continuation onto next line
152
            {
153
                                while (c != '\n' && c > 0) { c= *inptr; inptr++}
154
               if (c > 0) {
155
                  --b;           // b will be incremented but we haven't got a character
156
                  ++count;
157
                  SkipSpaces();  // Skip leading spaces on next line
158
                  continue;
159
               }
160
            }
161
         }
162
         if (c == '\n' || c < 1) {
163
            if (InQuote)
164
                                printf("End of file in comment. %d\n", lineno);
165
            break;
166
         }
167
         *b = c;
168
      }
169
   }
170
jmp1:
171
   if (count < 0)
172
           printf("Expanded macro is too large. %d\n", lineno);
173
   *b = 0;
174
   rtrim(buf);    // Trim off trailing spaces.
175
   return buf;
176
}
177
 
178
 
179
void Arg::Clear()
180
{
181
        ZeroMemory(text,sizeof(text));
182
}
183
 
184
// ---------------------------------------------------------------------------
185
//   Description :
186
//      Gets an argument to be substituted into a macro body. Note that the
187
//   round bracket nesting level is kept track of so that a comma in the
188
//   middle of an argument isn't inadvertently picked up as an argument
189
//   separator.
190
// ---------------------------------------------------------------------------
191
 
192
void Arg::Get()
193
{
194
   int Depth = 0;
195
   int c;
196
   char *argstr = text;
197
 
198
   SkipSpaces();
199
   ZeroMemory(text,sizeof(text));
200
   while(1)
201
   {
202
           if (argstr-text > sizeof(text)-2) {
203
                   printf("Macro argument too large %d. Is a ')' missing ?\n",lineno);
204
                   break;
205
           }
206
      c = *inptr;
207
          inptr++;
208
      if (c < 1) {
209
         if (Depth > 0)
210
                        printf("err16\r\n");
211
         break;
212
      }
213
      if (c == '(')
214
         Depth++;
215
      else if (c == ')') {
216
         if (Depth < 1) {  // check if we hit the end of the arg list
217
            --inptr;
218
            break;
219
         }
220
         Depth--;
221
      }
222
      else if (Depth == 0 && c == ',') {   // comma at outermost level means
223
         --inptr;
224
         break;                           // end of argument has been found
225
      }
226
          else if (Depth == 0 && (c=='\r' || c=='\n')) {
227
                  --inptr;
228
                  break;
229
          }
230
      *argstr++ = c;       // copy input argument to argstr.
231
   }
232
//   if (argbuf[0])
233
//         if (fdbg) fprintf(fdbg,"    macro arg<%s>\r\n",argbuf);
234
   return;
235
}
236
 
237
void Arglist::Get()
238
{
239
        int nn;
240
        char lastch;
241
 
242
        for (nn = 0; nn < 10; nn++)
243
                args[nn]->Clear();
244
        for (nn = 0; nn < 10; nn++) {
245
                args[nn]->Get();
246
                if (*inptr != ',') {
247
                        SkipSpaces();
248
                        break;
249
                }
250
                inptr++;        // skip over ,
251
        }
252
        args->count = nn;
253
        while (*inptr) {
254
                if (*inptr==0)
255
                        break;
256
                if (*inptr=='\n') {
257
                        lineno++;
258
                        inptr++;
259
                        break;
260
                }
261
                inptr++;
262
        }
263
}
264
 
265
// ---------------------------------------------------------------------------
266
//   Description :
267
//      Used during the definition of a macro to get the associated parameter
268
//   list.
269
//
270
//   Returns
271
//      pointer to first parameter in list.
272
// ----------------------------------------------------------------------------
273
 
274
int Macro::GetParmList(char *parmlist[])
275
{
276
   int id;
277
   int Depth = 0, c, count;
278
 
279
   count = 0;
280
   while(1)
281
   {
282
      id = getIdentifier();
283
      if (id!=0) {
284
         if (count >= 20) {
285
                         printf("Too many macro parameters %d.\n", lineno);
286
             goto errxit;
287
         }
288
         parmlist[count] = _strdup(lastid);
289
         if (parmlist[count] == NULL)
290
                         printf("Insufficient memory %d\n", lineno);
291
         count++;
292
      }
293
          do {
294
                        SkipSpaces();
295
                        c = *inptr;
296
                        inptr++;
297
                        if (c=='\\') {
298
                                ScanToEOL();
299
                                inptr++;
300
                        }
301
                }
302
                while (c=='\\');
303
      if (c == ')') {   // we've gotten our last parameter
304
         inptr--;
305
         break;
306
      }
307
      if (c != ',') {
308
                  printf("Expecting ',' in macro parameter list %d.\n", lineno);
309
         goto errxit;
310
      }
311
   }
312
//   if (count < 1)
313
//      err(17);
314
   if (count < 20)
315
      parmlist[count] = NULL;
316
errxit:;
317
   return count;
318
}
319
 
320
 
321
// -----------------------------------------------------------------------------
322
//   Description :
323
//      Copies a macro into the input buffer. Resets the input buffer pointer
324
//   to the start of the macro.
325
//
326
//   slen; - the number of characters being substituted
327
// -----------------------------------------------------------------------------
328
 
329
void Macro::Substitute(char *body, int slen)
330
{
331
   int mlen, dif, nchars;
332
   int nn;
333
   char *p;
334
 
335
   mlen = strlen(body);          // macro length
336
   dif = mlen - slen;
337
   nchars = inptr-masterFile;         // calculate number of characters that could be remaining
338
   memmove(inptr+dif, inptr, sizeof(masterFile)-500-nchars-dif);  // shift open space in input buffer
339
   inptr -= slen;                // reset input pointer to start of replaced text
340
   memcpy(inptr, body, mlen);    // copy macro body in place over identifier
341
}
342
 

powered by: WebSVN 2.1.0

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