MinGW fixes (development)
[sverilog.git] / lexor.lex
blobd0dfa798075d001d6fff3956287b41222b35690d
2 %option never-interactive
3 %option nounput
5 %{
6 /*
7  * Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
8  *
9  *    This source code is free software; you can redistribute it
10  *    and/or modify it in source code form under the terms of the GNU
11  *    General Public License as published by the Free Software
12  *    Foundation; either version 2 of the License, or (at your option)
13  *    any later version.
14  *
15  *    This program is distributed in the hope that it will be useful,
16  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *    GNU General Public License for more details.
19  *
20  *    You should have received a copy of the GNU General Public License
21  *    along with this program; if not, write to the Free Software
22  *    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
23  */
25 # include "config.h"
27       //# define YYSTYPE lexval
29 # include  <iostream>
30 # include  "compiler.h"
31 # include  "parse_misc.h"
32 # include  "parse_api.h"
33 # include  "parse.h"
34 # include  <ctype.h>
35 # include  <string.h>
36 # include  "lexor_keyword.h"
37 # include  "discipline.h"
38 # include  <list>
40 # define YY_USER_INIT reset_lexor();
41 # define yylval VLlval
44  * Lexical location information is passed in the yylloc variable to th
45  * parser. The file names, strings, are kept in a list so that I can
46  * re-use them. The set_file_name function will return a pointer to
47  * the name as it exists in the list (and delete the passed string.)
48  * If the name is new, it will be added to the list.
49  */
50 extern YYLTYPE yylloc;
52 static char* strdupnew(char const *str)
54        return str ? strcpy(new char [strlen(str)+1], str) : 0;
57 static const char* set_file_name(char*text)
59       perm_string path = filename_strings.make(text);
60       delete[]text;
62         /* Check this file name with the list of library file
63            names. If there is a match, then turn on the
64            pform_library_flag. This is how the parser knows that
65            modules declared in this file are library modules. */
66       pform_library_flag = library_file_map[path];
67       return path;
71 extern void pform_set_timescale(int, int, const char*file, unsigned line);
73 void reset_lexor();
74 static void line_directive();
75 static void line_directive2();
77 static verinum*make_unsized_binary(const char*txt);
78 static verinum*make_undef_highz_dec(const char*txt);
79 static verinum*make_unsized_dec(const char*txt);
80 static verinum*make_unsized_octal(const char*txt);
81 static verinum*make_unsized_hex(const char*txt);
83 static int dec_buf_div2(char *buf);
85 static void process_timescale(const char*txt);
87 static list<int> keyword_mask_stack;
89 static int comment_enter;
92 %x CCOMMENT
93 %x PCOMMENT
94 %x LCOMMENT
95 %x CSTRING
96 %s UDPTABLE
97 %x PPTIMESCALE
98 %x PPDEFAULT_NETTYPE
99 %x PPBEGIN_KEYWORDS
100 %s EDGES
101 %x REAL_SCALE
103 W [ \t\b\f\r]+
105 S [afpnumkKMGT]
109 ^"#line"[ ]+\"[^\"]*\"[ ]+[0-9]+.* { line_directive(); }
110 ^"`line"[ ]+[0-9]+[ ]+\"[^\"]*\".* { line_directive2(); }
112 [ \t\b\f\r] { ; }
113 \n { yylloc.first_line += 1; }
115   /* C++ style comments start with / / and run to the end of the
116      current line. These are very easy to handle. */
118 "//".* { comment_enter = YY_START; BEGIN(LCOMMENT); }
119 <LCOMMENT>.    { yymore(); }
120 <LCOMMENT>\n   { yylloc.first_line += 1; BEGIN(comment_enter); }
123   /* The contents of C-style comments are ignored, like white space. */
125 "/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
126 <CCOMMENT>.    { yymore(); }
127 <CCOMMENT>\n   { yylloc.first_line += 1; yymore(); }
128 <CCOMMENT>"*/" { BEGIN(comment_enter); }
131 "(*" { return K_PSTAR; }
132 "*)" { return K_STARP; }
133 "<<" { return K_LS; }
134 "<<<" { return K_LS; /* Note: Functionally, <<< is the same as <<. */}
135 ">>"  { return K_RS; }
136 ">>>" { return K_RSS; }
137 "**" { return K_POW; }
138 "<=" { return K_LE; }
139 ">=" { return K_GE; }
140 "=>" { return K_EG; }
141 "*>" { return K_SG; }
142 "==" { return K_EQ; }
143 "!=" { return K_NE; }
144 "===" { return K_CEQ; }
145 "!==" { return K_CNE; }
146 "||" { return K_LOR; }
147 "&&" { return K_LAND; }
148 "&&&" { return K_TAND; }
149 "~|" { return K_NOR; }
150 "~^" { return K_NXOR; }
151 "^~" { return K_NXOR; }
152 "~&" { return K_NAND; }
153 "->" { return K_TRIGGER; }
154 "+:" { return K_PO_POS; }
155 "-:" { return K_PO_NEG; }
156 "<+" { return K_CONTRIBUTE; }
158   /* Watch out for the tricky case of (*). Cannot parse this as "(*"
159      and ")", but since I know that this is really ( * ), replace it
160      with "*" and return that. */
161 "("{W}*"*"{W}*")" { return '*'; }
163 <EDGES>"]" { BEGIN(0); return yytext[0]; }
164 [}{;:\[\],()#=.@&!?<>%|^~+*/-] { return yytext[0]; }
166 \"            { BEGIN(CSTRING); }
167 <CSTRING>\\\\ { yymore(); /* Catch \\, which is a \ escaping itself */ }
168 <CSTRING>\\\" { yymore(); /* Catch \", which is an escaped quote */ }
169 <CSTRING>\n   { BEGIN(0);
170                 yylval.text = strdup(yytext);
171                 VLerror(yylloc, "Missing close quote of string.");
172                 yylloc.first_line += 1;
173                 return STRING; }
174 <CSTRING>\"   { BEGIN(0);
175                 yylval.text = strdup(yytext);
176                 yylval.text[strlen(yytext)-1] = 0;
177                 return STRING; }
178 <CSTRING>.    { yymore(); }
180 <UDPTABLE>\(\?0\)    { return '_'; }
181 <UDPTABLE>\(\?1\)    { return '+'; }
182 <UDPTABLE>\(\?[xX]\) { return '%'; }
183 <UDPTABLE>\(\?\?\)  { return '*'; }
184 <UDPTABLE>\(01\)    { return 'r'; }
185 <UDPTABLE>\(0[xX]\) { return 'Q'; }
186 <UDPTABLE>\(b[xX]\) { return 'q'; }
187 <UDPTABLE>\(b0\)    { return 'f'; /* b0 is 10|00, but only 10 is meaningful */}
188 <UDPTABLE>\(b1\)    { return 'r'; /* b1 is 11|01, but only 01 is meaningful */}
189 <UDPTABLE>\(0\?\)   { return 'P'; }
190 <UDPTABLE>\(10\)    { return 'f'; }
191 <UDPTABLE>\(1[xX]\) { return 'M'; }
192 <UDPTABLE>\(1\?\)   { return 'N'; }
193 <UDPTABLE>\([xX]0\) { return 'F'; }
194 <UDPTABLE>\([xX]1\) { return 'R'; }
195 <UDPTABLE>\([xX]\?\) { return 'B'; }
196 <UDPTABLE>[bB]     { return 'b'; }
197 <UDPTABLE>[lL]     { return 'l'; /* IVL extension */ }
198 <UDPTABLE>[hH]     { return 'h'; /* IVL extension */ }
199 <UDPTABLE>[fF]     { return 'f'; }
200 <UDPTABLE>[rR]     { return 'r'; }
201 <UDPTABLE>[xX]     { return 'x'; }
202 <UDPTABLE>[nN]     { return 'n'; }
203 <UDPTABLE>[pP]     { return 'p'; }
204 <UDPTABLE>[01\?\*\-] { return yytext[0]; }
206 <EDGES>"01" { return K_edge_descriptor; }
207 <EDGES>"0x" { return K_edge_descriptor; }
208 <EDGES>"0z" { return K_edge_descriptor; }
209 <EDGES>"10" { return K_edge_descriptor; }
210 <EDGES>"1x" { return K_edge_descriptor; }
211 <EDGES>"1z" { return K_edge_descriptor; }
212 <EDGES>"x0" { return K_edge_descriptor; }
213 <EDGES>"x1" { return K_edge_descriptor; }
214 <EDGES>"z0" { return K_edge_descriptor; }
215 <EDGES>"z1" { return K_edge_descriptor; }
217 [a-zA-Z_][a-zA-Z0-9$_]* {
218       int rc = lexor_keyword_code(yytext, yyleng);
219       switch (rc) {
220           case IDENTIFIER:
221             yylval.text = strdupnew(yytext);
222             if (strncmp(yylval.text,"PATHPULSE$", 10) == 0)
223                   rc = PATHPULSE_IDENTIFIER;
224             break;
226           case K_edge:
227             BEGIN(EDGES);
228             break;
230           default:
231             yylval.text = 0;
232             break;
233       }
235         /* If this identifier names a discipline, then return this as
236            a DISCIPLINE_IDENTIFIER and return the discipline as the
237            value instead. */
238       if (rc == IDENTIFIER && gn_verilog_ams_flag) {
239             perm_string tmp = lex_strings.make(yylval.text);
240             map<perm_string,discipline_t*>::iterator cur = disciplines.find(tmp);
241             if (cur != disciplines.end()) {
242                   yylval.discipline = (*cur).second;
243                   rc = DISCIPLINE_IDENTIFIER;
244             }
245       }
247       return rc;
248   }
251 \\[^ \t\b\f\r\n]+         {
252       yylval.text = strdupnew(yytext+1);
253       return IDENTIFIER; }
255 \$([a-zA-Z0-9$_]+)        {
256       if (strcmp(yytext,"$setuphold") == 0)
257             return K_Ssetuphold;
258       if (strcmp(yytext,"$attribute") == 0)
259             return KK_attribute;
260       if (strcmp(yytext,"$hold") == 0)
261             return K_Shold;
262       if (strcmp(yytext,"$period") == 0)
263             return K_Speriod;
264       if (strcmp(yytext,"$recovery") == 0)
265             return K_Srecovery;
266       if (strcmp(yytext,"$recrem") == 0)
267             return K_Srecrem;
268       if (strcmp(yytext,"$setup") == 0)
269             return K_Ssetup;
270       if (strcmp(yytext,"$width") == 0)
271             return K_Swidth;
272       yylval.text = strdupnew(yytext);
273       return SYSTEM_IDENTIFIER; }
276 \'[sS]?[dD][ \t]*[0-9][0-9_]*  { yylval.number = make_unsized_dec(yytext);
277                             return BASED_NUMBER; }
278 \'[sS]?[dD][ \t]*[xzXZ?]_* { yylval.number = make_undef_highz_dec(yytext);
279                              return BASED_NUMBER; }
280 \'[sS]?[bB][ \t]*[0-1xzXZ_\?]+ { yylval.number = make_unsized_binary(yytext);
281                         return BASED_NUMBER; }
282 \'[sS]?[oO][ \t]*[0-7xzXZ_\?]+ { yylval.number = make_unsized_octal(yytext);
283                         return BASED_NUMBER; }
284 \'[sS]?[hH][ \t]*[0-9a-fA-FxzXZ_\?]+ { yylval.number = make_unsized_hex(yytext);
285                               return BASED_NUMBER; }
287 [0-9][0-9_]* {
288       yylval.number = make_unsized_dec(yytext);
289       based_size = yylval.number->as_ulong();
290       return DEC_NUMBER; }
292   /* These rules handle the scaled real literals from Verilog-AMS. The
293      value is a number with a single letter scale factor. If
294      verilog-ams is not enabled, then reject this rule. If it is
295      enabled, then collect the scale and use it to scale the value. */
296 [0-9][0-9_]*\.[0-9][0-9_]*/{S} {
297       if (!gn_verilog_ams_flag) REJECT;
298       BEGIN(REAL_SCALE);
299       yymore();  }
301 [0-9][0-9_]*/{S} {
302       if (!gn_verilog_ams_flag) REJECT;
303       BEGIN(REAL_SCALE);
304       yymore();  }
306 <REAL_SCALE>{S} {
307       size_t token_len = strlen(yytext);
308       char*tmp = new char[token_len + 5];
309       int scale = 0;
310       strcpy(tmp, yytext);
311       switch (tmp[token_len-1]) {
312           case 'a': scale = -18; break; /* atto- */
313           case 'f': scale = -15; break; /* femto- */
314           case 'p': scale = -12; break; /* pico- */
315           case 'n': scale = -9;  break; /* nano- */
316           case 'u': scale = -6;  break; /* micro- */
317           case 'm': scale = -3;  break; /* milli- */
318           case 'k': scale = 3;  break; /* kilo- */
319           case 'K': scale = 3;  break; /* kilo- */
320           case 'M': scale = 6;  break; /* mega- */
321           case 'G': scale = 9;  break; /* giga- */
322           case 'T': scale = 12; break; /* tera- */
323           default: assert(0); break;
324       }
325       snprintf(tmp+token_len-1, 5, "e%d", scale);
326       yylval.realtime = new verireal(tmp);
327       delete[]tmp;
329       BEGIN(0);
330       return REALTIME;  }
332 [0-9][0-9_]*\.[0-9][0-9_]*([Ee][+-]?[0-9][0-9_]*)? {
333       yylval.realtime = new verireal(yytext);
334       return REALTIME; }
336 [0-9][0-9_]*[Ee][+-]?[0-9][0-9_]* {
337       yylval.realtime = new verireal(yytext);
338       return REALTIME; }
341   /* Notice and handle the timescale directive. */
343 ^{W}?`timescale { BEGIN(PPTIMESCALE); }
344 <PPTIMESCALE>.* { process_timescale(yytext); }
345 <PPTIMESCALE>\n {
346       yylloc.first_line += 1;
347       BEGIN(0); }
350   /* These are directives that I do not yet support. I think that IVL
351      should handle these, not an external preprocessor. */
353 ^{W}?`celldefine{W}?.*              {  }
354 ^{W}?`default_decay_time{W}?.*      {  }
355 ^{W}?`default_trireg_strength{W}?.* {  }
356 ^{W}?`delay_mode_distributed{W}?.*  {  }
357 ^{W}?`delay_mode_unit{W}?.*         {  }
358 ^{W}?`delay_mode_path{W}?.*         {  }
359 ^{W}?`delay_mode_zero{W}?.*         {  }
360 ^{W}?`disable_portfaults{W}?.*      {  }
361 ^{W}?`enable_portfaults{W}?.*       {  }
362 ^{W}?`endcelldefine{W}?.*           {  }
363 `endprotect                         {  }
364 ^{W}?`line{W}?.*                    {  }
365 ^{W}?`nosuppress_faults{W}?.*       {  }
366 ^{W}?`nounconnected_drive{W}?.*     {  }
367 `protect                            {  }
368 ^{W}?`resetall{W}?.*                {  }
369 ^{W}?`suppress_faults{W}?.*         {  }
370 ^{W}?`unconnected_drive{W}?.*       {  }
371 ^{W}?`uselib{W}?.*                  {  }
373 ^{W}?`begin_keywords{W}? { BEGIN(PPBEGIN_KEYWORDS); }
375 <PPBEGIN_KEYWORDS>\"[a-zA-Z0-9 -]*\".* {
376       keyword_mask_stack.push_front(lexor_keyword_mask);
378       char*word = yytext+1;
379       char*tail = strchr(word, '"');
380       tail[0] = 0;
381       if (strcmp(word,"1364-1995") == 0) {
382             lexor_keyword_mask = GN_KEYWORDS_1364_1995;
383       } else if (strcmp(word,"1364-2001") == 0) {
384             lexor_keyword_mask = GN_KEYWORDS_1364_1995
385                                 |GN_KEYWORDS_1364_2001
386                                 |GN_KEYWORDS_1364_2001_CONFIG;
387       } else if (strcmp(word,"1364-2001-noconfig") == 0) {
388             lexor_keyword_mask = GN_KEYWORDS_1364_1995
389                                 |GN_KEYWORDS_1364_2001;
390       } else if (strcmp(word,"1364-2005") == 0) {
391             lexor_keyword_mask = GN_KEYWORDS_1364_1995
392                                 |GN_KEYWORDS_1364_2001
393                                 |GN_KEYWORDS_1364_2001_CONFIG
394                                 |GN_KEYWORDS_1364_2005;
395       } else if (strcmp(word,"VAMS-2.3") == 0) {
396             lexor_keyword_mask = GN_KEYWORDS_1364_1995
397                                 |GN_KEYWORDS_1364_2001
398                                 |GN_KEYWORDS_1364_2001_CONFIG
399                                 |GN_KEYWORDS_1364_2005
400                                 |GN_KEYWORDS_VAMS_2_3;
401       } else {
402             fprintf(stderr, "%s:%d: Ignoring unknown keywords string: %s\n",
403                     yylloc.text, yylloc.first_line, word);
404       }
405       BEGIN(0);
408 <PPBEGIN_KEYWORDS>.* {
409       fprintf(stderr, "%s:%d: Malformed keywords specification: %s\n",
410               yylloc.text, yylloc.first_line, yytext);
411       BEGIN(0);
414 ^{W}?`end_keywords{W}?.* {
415       if (!keyword_mask_stack.empty()) {
416             lexor_keyword_mask = keyword_mask_stack.front();
417             keyword_mask_stack.pop_front();
418       } else {
419             fprintf(stderr, "%s:%d: Mismatched end_keywords directive\n",
420                     yylloc.text, yylloc.first_line);
421       }
424   /* Notice and handle the default_nettype directive. The lexor
425      detects the default_nettype keyword, and the second part of the
426      rule collects the rest of the line and processes it. We only need
427      to look for the first work, and interpret it. */
429 `default_nettype{W}? { BEGIN(PPDEFAULT_NETTYPE); }
430 <PPDEFAULT_NETTYPE>.* {
431       NetNet::Type net_type;
432       size_t wordlen = strcspn(yytext, " \t\f\r\n");
433       yytext[wordlen] = 0;
434       if (strcmp(yytext,"wire") == 0) {
435             net_type = NetNet::WIRE;
437       } else if (strcmp(yytext,"none") == 0) {
438             net_type = NetNet::NONE;
440       } else {
441             cerr << yylloc.text << ":" << yylloc.first_line
442                  << " error: Net type " << yytext
443                  << " is not a valid (and supported)"
444                  << " default net type." << endl;
445             net_type = NetNet::WIRE;
446             error_count += 1;
447       }
448       pform_set_default_nettype(net_type, yylloc.text, yylloc.first_line);
449   }
450 <PPDEFAULT_NETTYPE>\n {
451       yylloc.first_line += 1;
452       BEGIN(0); }
455   /* These are directives that are not supported by me and should have
456      been handled by an external preprocessor such as ivlpp. */
458 ^{W}?`define{W}?.* {
459       cerr << yylloc.text << ":" << yylloc.first_line <<
460             ": `define not supported. Use an external preprocessor."
461            << endl;
462   }
464 ^{W}?`else{W}?.* {
465       cerr << yylloc.text << ":" << yylloc.first_line <<
466             ": `else not supported. Use an external preprocessor."
467            << endl;
468   }
470 ^{W}?`endif{W}?.* {
471       cerr << yylloc.text << ":" << yylloc.first_line <<
472             ": `endif not supported. Use an external preprocessor."
473            << endl;
474   }
476 ^{W}?`ifdef{W}?.* {
477       cerr << yylloc.text << ":" << yylloc.first_line <<
478             ": `ifdef not supported. Use an external preprocessor."
479            << endl;
480   }
482 ^`include{W}?.* {
483       cerr << yylloc.text << ":" << yylloc.first_line <<
484             ": `include not supported. Use an external preprocessor."
485            << endl;
486   }
488 ^`undef{W}?.* {
489       cerr << yylloc.text << ":" << yylloc.first_line <<
490             ": `undef not supported. Use an external preprocessor."
491            << endl;
492   }
495 `{W} { cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
496             << "Stray tic (`) here. Perhaps you put white space" << endl;
497        cerr << yylloc.text << ":" << yylloc.first_line << ":      : "
498             << "between the tic and preprocessor directive?"
499             << endl;
500        error_count += 1; }
502   /* Final catchall. something got lost or mishandled. */
503   /* XXX Should we tell the luser something about the lexical state? */
505 <*>.|\n {   cerr << yylloc.text << ":" << yylloc.first_line
506            << ": error: unmatched character (";
507       if (isgraph(yytext[0]))
508             cerr << yytext[0];
509       else
510             cerr << "hex " << hex << (0xffU & ((unsigned) (yytext[0])));
512       cerr << ")" << endl;
513       error_count += 1; }
518  * The UDP state table needs some slightly different treatment by the
519  * lexor. The level characters are normally accepted as other things,
520  * so the parser needs to switch my mode when it believes in needs to.
521  */
522 void lex_start_table()
524       BEGIN(UDPTABLE);
527 void lex_end_table()
529       BEGIN(INITIAL);
532 static verinum*make_unsized_binary(const char*txt)
534       bool sign_flag = false;
535       const char*ptr = txt;
536       assert(*ptr == '\'');
537       ptr += 1;
539       if (tolower(*ptr) == 's') {
540             sign_flag = true;
541             ptr += 1;
542       }
544       assert(tolower(*ptr) == 'b');
545       ptr += 1;
547       while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
548             ptr += 1;
550       unsigned size = 0;
551       for (const char*idx = ptr ;  *idx ;  idx += 1)
552             if (*idx != '_') size += 1;
554       if ((based_size > 0) && (size > based_size)) yywarn(yylloc,
555           "extra digits given for sized binary constant.");
557       verinum::V*bits = new verinum::V[size];
559       unsigned idx = size;
560       while (*ptr) {
561             switch (ptr[0]) {
562                 case '0':
563                   bits[--idx] = verinum::V0;
564                   break;
565                 case '1':
566                   bits[--idx] = verinum::V1;
567                   break;
568                 case 'z': case 'Z': case '?':
569                   bits[--idx] = verinum::Vz;
570                   break;
571                 case 'x': case 'X':
572                   bits[--idx] = verinum::Vx;
573                   break;
574                   case '_':
575                   break;
576                 default:
577                   fprintf(stderr, "%c\n", ptr[0]);
578                   assert(0);
579             }
580             ptr += 1;
581       }
583       verinum*out = new verinum(bits, size, false);
584       out->has_sign(sign_flag);
585       delete[]bits;
586       return out;
590 static verinum*make_unsized_octal(const char*txt)
592       bool sign_flag = false;
593       const char*ptr = txt;
594       assert(*ptr == '\'');
595       ptr += 1;
597       if (tolower(*ptr) == 's') {
598             sign_flag = true;
599             ptr += 1;
600       }
602       assert(tolower(*ptr) == 'o');
603       ptr += 1;
605       while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
606             ptr += 1;
608       unsigned size = 0;
609       for (const char*idx = ptr ;  *idx ;  idx += 1)
610             if (*idx != '_') size += 3;
612       if (based_size > 0) {
613             int rem = based_size % 3;
614             if (rem != 0) based_size += 3 - rem;
615             if (size > based_size) yywarn(yylloc,
616                 "extra digits given for sized octal constant.");
617       }
619       verinum::V*bits = new verinum::V[size];
621       unsigned idx = size;
622       while (*ptr) {
623             unsigned val;
624             switch (ptr[0]) {
625                 case '0': case '1': case '2': case '3':
626                 case '4': case '5': case '6': case '7':
627                   val = *ptr - '0';
628                   bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
629                   bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
630                   bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
631                   break;
632                 case 'x': case 'X':
633                   bits[--idx] = verinum::Vx;
634                   bits[--idx] = verinum::Vx;
635                   bits[--idx] = verinum::Vx;
636                   break;
637                 case 'z': case 'Z': case '?':
638                   bits[--idx] = verinum::Vz;
639                   bits[--idx] = verinum::Vz;
640                   bits[--idx] = verinum::Vz;
641                   break;
642                 case '_':
643                   break;
644                 default:
645                   assert(0);
646             }
647             ptr += 1;
648       }
650       verinum*out = new verinum(bits, size, false);
651       out->has_sign(sign_flag);
652       delete[]bits;
653       return out;
657 static verinum*make_unsized_hex(const char*txt)
659       bool sign_flag = false;
660       const char*ptr = txt;
661       assert(*ptr == '\'');
662       ptr += 1;
664       if (tolower(*ptr) == 's') {
665             sign_flag = true;
666             ptr += 1;
667       }
668       assert(tolower(*ptr) == 'h');
670       ptr += 1;
671       while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
672             ptr += 1;
674       unsigned size = 0;
675       for (const char*idx = ptr ;  *idx ;  idx += 1)
676             if (*idx != '_') size += 4;
678       if (based_size > 0) {
679             int rem = based_size % 4;
680             if (rem != 0) based_size += 4 - rem;
681             if (size > based_size) yywarn(yylloc,
682                 "extra digits given for sized hex constant.");
683       }
685       verinum::V*bits = new verinum::V[size];
687       unsigned idx = size;
688       while (*ptr) {
689             unsigned val;
690             switch (ptr[0]) {
691                 case '0': case '1': case '2': case '3': case '4':
692                 case '5': case '6': case '7': case '8': case '9':
693                   val = *ptr - '0';
694                   bits[--idx] = (val&8) ? verinum::V1 : verinum::V0;
695                   bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
696                   bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
697                   bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
698                   break;
699                 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
700                 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
701                   val = tolower(*ptr) - 'a' + 10;
702                   bits[--idx] = (val&8) ? verinum::V1 : verinum::V0;
703                   bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
704                   bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
705                   bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
706                   break;
707                 case 'x': case 'X':
708                   bits[--idx] = verinum::Vx;
709                   bits[--idx] = verinum::Vx;
710                   bits[--idx] = verinum::Vx;
711                   bits[--idx] = verinum::Vx;
712                   break;
713                 case 'z': case 'Z': case '?':
714                   bits[--idx] = verinum::Vz;
715                   bits[--idx] = verinum::Vz;
716                   bits[--idx] = verinum::Vz;
717                   bits[--idx] = verinum::Vz;
718                   break;
719                 case '_':
720                   break;
721                 default:
722                   assert(0);
723             }
724             ptr += 1;
725       }
727       verinum*out = new verinum(bits, size, false);
728       out->has_sign(sign_flag);
729       delete[]bits;
730       return out;
734 /* Divide the integer given by the string by 2. Return the remainder bit. */
735 static int dec_buf_div2(char *buf)
737     int partial;
738     int len = strlen(buf);
739     char *dst_ptr;
740     int pos;
742     partial = 0;
743     pos = 0;
745     /* dst_ptr overwrites buf, but all characters that are overwritten
746        were already used by the reader. */
747     dst_ptr = buf;
749     while(buf[pos] == '0')
750         ++pos;
752     for(; pos<len; ++pos){
753         if (buf[pos]=='_')
754             continue;
756         assert(isdigit(buf[pos]));
758         partial= partial*10 + (buf[pos]-'0');
760         if (partial >= 2){
761             *dst_ptr = partial/2 + '0';
762             partial = partial & 1;
764             ++dst_ptr;
765         }
766         else{
767             *dst_ptr = '0';
768             ++dst_ptr;
769         }
770     }
772     // If result of division was zero string, it should remain that way.
773     // Don't eat the last zero...
774     if (dst_ptr == buf){
775         *dst_ptr = '0';
776         ++dst_ptr;
777     }
778     *dst_ptr = 0;
780     return partial;
783 /* Support a single x, z or ? as a decimal constant (from 1364-2005). */
784 static verinum* make_undef_highz_dec(const char* ptr)
786       bool signed_flag = false;
788       assert(*ptr == '\'');
789       /* The number may have decorations of the form 'sd<code>,
790          possibly with space between the d and the <code>.
791          Also, the 's' is optional, and marks the number as signed. */
792       ptr += 1;
794       if (tolower(*ptr) == 's') {
795           signed_flag = true;
796           ptr += 1;
797       }
799       assert(tolower(*ptr) == 'd');
800       ptr += 1;
802       while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
803           ptr += 1;
805         /* Process the code. */
806       verinum::V* bits = new verinum::V[1];
807       switch (*ptr) {
808           case 'x':
809           case 'X':
810             bits[0] = verinum::Vx;
811             break;
812           case 'z':
813           case 'Z':
814           case '?':
815             bits[0] = verinum::Vz;
816             break;
817           default:
818             assert(0);
819       }
820       ptr += 1;
821       while (*ptr == '_') ptr += 1;
822       assert(*ptr == 0);
824       verinum*out = new verinum(bits, 1, false);
825       out->has_sign(signed_flag);
826       delete[]bits;
827       return out;
831  * Making a decimal number is much easier then the other base numbers
832  * because there are no z or x values to worry about. It is much
833  * harder then other base numbers because the width needed in bits is
834  * hard to calculate.
835  */
837 static verinum*make_unsized_dec(const char*ptr)
839       char buf[4096];
840       bool signed_flag = false;
841       unsigned idx;
843       if (ptr[0] == '\'') {
844               /* The number has decorations of the form 'sd<digits>,
845                  possibly with space between the d and the <digits>.
846                  Also, the 's' is optional, and markes the number as
847                  signed. */
848             ptr += 1;
850             if (tolower(*ptr) == 's') {
851                   signed_flag = true;
852                   ptr += 1;
853             }
855             assert(tolower(*ptr) == 'd');
856             ptr += 1;
858             while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
859                   ptr += 1;
861       } else {
862               /* ... or an undecorated decimal number is passed
863                  it. These numbers are treated as signed decimal. */
864             assert(isdigit(*ptr));
865             signed_flag = true;
866       }
869         /* Copy the digits into a buffer that I can use to do in-place
870            decimal divides. */
871       idx = 0;
872       while ((idx < sizeof buf) && (*ptr != 0)) {
873             if (*ptr == '_') {
874                   ptr += 1;
875                   continue;
876             }
878             buf[idx++] = *ptr++;
879       }
881       if (idx == sizeof buf) {
882             fprintf(stderr, "Ridiculously long"
883                     " decimal constant will be truncated!\n");
884             idx -= 1;
885       }
887       buf[idx] = 0;
888       unsigned tmp_size = idx * 4 + 1;
889       verinum::V *bits = new verinum::V[tmp_size];
891       idx = 0;
892       while (idx < tmp_size) {
893             int rem = dec_buf_div2(buf);
894             bits[idx++] = (rem == 1) ? verinum::V1 : verinum::V0;
895       }
897       assert(strcmp(buf, "0") == 0);
899         /* Now calculate the minimum number of bits needed to
900            represent this unsigned number. */
901       unsigned size = tmp_size;
902       while ((size > 1) && (bits[size-1] == verinum::V0))
903             size -= 1;
905         /* Now account for the signedness. Don't leave a 1 in the high
906            bit if this is a signed number. */
907       if (signed_flag && (bits[size-1] == verinum::V1)) {
908             size += 1;
909             assert(size <= tmp_size);
910       }
912         /* Since we never have the real number of bits that a decimal
913            number represents we do not check for extra bits. */
914 //      if (based_size > 0) { }
916       verinum*res = new verinum(bits, size, false);
917       res->has_sign(signed_flag);
919       delete[]bits;
920       return res;
925  * The timescale parameter has the form:
926  *      " <num> xs / <num> xs"
927  */
928 static void process_timescale(const char*txt)
930       unsigned num;
931       const char*cp = txt + strspn(txt, " \t");
932       char*tmp;
933       const char*ctmp;
935       int unit = 0;
936       int prec = 0;
938       num = strtoul(cp, &tmp, 10);
939       if (num == 0) {
940             VLerror(yylloc, "Invalid timescale string.");
941             return;
942       }
944       while (num >= 10) {
945             unit += 1;
946             num  /= 10;
947       }
948       if (num != 1) {
949             VLerror(yylloc, "Invalid timescale unit number.");
950             return;
951       }
953       cp = tmp;
954       cp += strspn(cp, " \t");
955       ctmp = cp + strcspn(cp, " \t/");
957       if (strncmp("s", cp, ctmp-cp) == 0) {
958             unit -= 0;
960       } else if (strncmp("ms", cp, ctmp-cp) == 0) {
961             unit -= 3;
963       } else if (strncmp("us", cp, ctmp-cp) == 0) {
964             unit -= 6;
966       } else if (strncmp("ns", cp, ctmp-cp) == 0) {
967             unit -= 9;
969       } else if (strncmp("ps", cp, ctmp-cp) == 0) {
970             unit -= 12;
972       } else if (strncmp("fs", cp, ctmp-cp) == 0) {
973             unit -= 15;
975       } else {
976             VLerror(yylloc, "Invalid timescale unit of measurement");
977             return;
978       }
980       cp = ctmp;
981       cp += strspn(cp, " \t/");
983       num = strtoul(cp, &tmp, 10);
984       if (num == 0) {
985             VLerror(yylloc, "Invalid timescale string.");
986             return;
987       }
988       assert(num);
989       while (num >= 10) {
990             prec += 1;
991             num  /= 10;
992       }
993       if (num != 1) {
994             VLerror(yylloc, "Invalid timescale precision number.");
995             return;
996       }
998       cp = tmp;
999       cp += strspn(cp, " \t");
1000       ctmp = cp + strcspn(cp, " \t\r");
1002       if (strncmp("s", cp, ctmp-cp) == 0) {
1003             prec -= 0;
1005       } else if (strncmp("ms", cp, ctmp-cp) == 0) {
1006             prec -= 3;
1008       } else if (strncmp("us", cp, ctmp-cp) == 0) {
1009             prec -= 6;
1011       } else if (strncmp("ns", cp, ctmp-cp) == 0) {
1012             prec -= 9;
1014       } else if (strncmp("ps", cp, ctmp-cp) == 0) {
1015             prec -= 12;
1017       } else if (strncmp("fs", cp, ctmp-cp) == 0) {
1018             prec -= 15;
1020       } else {
1021             VLerror(yylloc, "Invalid timescale precision units of measurement");
1022             return;
1023       }
1025       pform_set_timescale(unit, prec, yylloc.text, yylloc.first_line);
1028 int yywrap()
1030       return 1;
1034  * The line directive matches lines of the form #line "foo" N and
1035  * calls this function. Here I parse out the file name and line
1036  * number, and change the yylloc to suite.
1037  */
1038 static void line_directive()
1040       char*qt1 = strchr(yytext, '"');
1041       assert(qt1);
1042       qt1 += 1;
1044       char*qt2 = strchr(qt1, '"');
1045       assert(qt2);
1047       char*buf = new char[qt2-qt1+1];
1048       strncpy(buf, qt1, qt2-qt1);
1049       buf[qt2-qt1] = 0;
1051       yylloc.text = set_file_name(buf);
1053       qt2 += 1;
1054       yylloc.first_line = strtoul(qt2,0,0);
1057 static void line_directive2()
1059       assert(strncmp(yytext,"`line",5) == 0);
1060       char*cp = yytext + strlen("`line");
1061       cp += strspn(cp, " ");
1062       yylloc.first_line = strtoul(cp,&cp,10);
1064       yylloc.first_line -= 1;
1066       cp += strspn(cp, " ");
1067       if (*cp == 0) return;
1069       char*qt1 = strchr(yytext, '"');
1070       assert(qt1);
1071       qt1 += 1;
1073       char*qt2 = strchr(qt1, '"');
1074       assert(qt2);
1076       char*buf = new char[qt2-qt1+1];
1077       strncpy(buf, qt1, qt2-qt1);
1078       buf[qt2-qt1] = 0;
1080       yylloc.text = set_file_name(buf);
1083 extern FILE*vl_input;
1084 void reset_lexor()
1086       yyrestart(vl_input);
1087       yylloc.first_line = 1;
1089         /* Announce the first file name. */
1090       yylloc.text = set_file_name(strdupnew(vl_file.c_str()));