2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
7 static char rcs_lex[] = "$Id: basic.lex,v 1.3 1994/06/24 11:30:28 ceriel Exp $" ;
10 /* This file contains the new lexical analizer */
13 int token, classvalue,length;
17 "abs", FUNCTION, ABSSYM, 0,
18 "and", ANDSYM, ANDSYM, 0,
19 "asc", FUNCTION, ASCSYM, 0,
21 "atn", FUNCTION, ATNSYM, 0,
22 "auto", ILLEGAL, 0, 0,
23 "base", BASESYM, 0, 0,
24 "call", CALLSYM, 0, 0,
25 "cdbl", FUNCTION, CDBLSYM, 0,
26 "chain", ILLEGAL, 0, 0,
27 "chr", FUNCTION, CHRSYM, 0,
28 "cint", FUNCTION, CINTSYM, 0,
29 "clear", CLEARSYM, 0, 0,
30 "cload", ILLEGAL, 0, 0,
31 "close", CLOSESYM, 0, 0,
32 "common", ILLEGAL, 0, 0,
33 "cont", ILLEGAL, 0, 0,
34 "cos", FUNCTION, COSSYM, 0,
35 "csng", FUNCTION, CSNGSYM, 0,
36 "csave", ILLEGAL, 0, 0,
37 "cvi", FUNCTION, CVISYM, 0,
38 "cvs", FUNCTION, CVSSYM, 0,
39 "cvd", FUNCTION, CVDSYM, 0,
40 "data", DATASYM, 0, 0,
41 "defint", DEFINTSYM, 0, 0,
42 "defsng", DEFSNGSYM, 0, 0,
43 "defdbl", DEFDBLSYM, 0, 0,
44 "defstr", DEFSTRSYM, 0, 0,
46 "delete", ILLEGAL, 0, 0,
48 "edit", ILLEGAL, 0, 0,
49 "else", ELSESYM, 0, 0,
51 "eof", FUNCTION, EOFSYM, 0,
52 "eqv", EQVSYM, EQVSYM, 0,
53 "erase", ILLEGAL, 0, 0,
54 "error", ERRORSYM, 0, 0,
57 "exp", FUNCTION, EXPSYM, 0,
58 "field", FIELDSYM, 0, 0,
59 "fix", FUNCTION, FIXSYM, 0,
61 "fre", FUNCTION, FRESYM, 0,
63 "gosub", GOSUBSYM, 0, 0,
64 "goto", GOTOSYM, 0, 0,
65 "hex", FUNCTION, HEXSYM, 0,
67 "imp", IMPSYM, IMPSYM, 0,
68 "inkey", INKEYSYM, 0, 0,
69 "input", INPUTSYM, 0, 0,
70 "inp", FUNCTION, INPSYM, 0,
71 "instr", FUNCTION, INSTRSYM, 0,
72 "int", FUNCTION, INTSYM, 0,
73 "kill", ILLEGAL, 0, 0,
74 "left", FUNCTION, LEFTSYM, 0,
75 "len", FUNCTION, LENSYM, 0,
77 "line", LINESYM, 0, 0,
78 "list", LISTSYM, 0, 0,
79 "llist", ILLEGAL, 0, 0,
80 "load", LOADSYM, 0, 0,
81 "loc", FUNCTION, LOCSYM, 0,
82 "log", FUNCTION, LOGSYM, 0,
83 "lpos", FUNCTION, LPOSSYM, 0,
84 "lprint", ILLEGAL, 0, 0,
85 "lset", LSETSYM, 0, 0,
86 "merge", MERGESYM, 0, 0,
88 "mki", FUNCTION, MKISYM, 0,
89 "mks", FUNCTION, MKSSYM, 0,
90 "mkd", FUNCTION, MKDSYM, 0,
92 "name", ILLEGAL, 0, 0,
94 "next", NEXTSYM, 0, 0,
96 "null", ILLEGAL, 0, 0,
98 "oct", FUNCTION, OCTSYM, 0,
99 "open", OPENSYM, 0, 0,
100 "option", OPTIONSYM, 0, 0,
101 "or", ORSYM, ORSYM, 0,
102 "out", FUNCTION, OUTSYM, 0,
103 "peek", PEEKSYM, 0, 0,
104 "poke", POKESYM, 0, 0,
105 "print", PRINTSYM, 0, 0,
106 "pos", FUNCTION, POSSYM, 0,
108 "randomize", RANDOMIZESYM, 0, 0,
109 "read", READSYM, 0, 0,
111 "renum", ILLEGAL, 0, 0,
112 "ren", ILLEGAL, 0, 0,
113 "restore", RESTORESYM, 0, 0,
114 "resume", ILLEGAL, 0, 0,
115 "return", RETURNSYM, 0, 0,
116 "right", FUNCTION, RIGHTSYM, 0,
117 "rnd", FUNCTION, RNDSYM, 0,
118 "run", ILLEGAL, 0, 0,
119 "save", ILLEGAL, 0, 0,
120 "step", STEPSYM, 0, 0,
121 "sgn", FUNCTION, SGNSYM, 0,
122 "sin", FUNCTION, SINSYM, 0,
123 "space", FUNCTION, SPACESYM, 0,
124 "spc", FUNCTION, SPCSYM, 0,
125 "sqr", FUNCTION, SQRSYM, 0,
126 "stop", STOPSYM, 0, 0,
127 "string", FUNCTION, STRINGSYM, 0,
128 "str", FUNCTION, STRSYM, 0,
129 "swap", SWAPSYM, 0, 0,
130 "tab", FUNCTION, TABSYM, 0,
131 "tan", FUNCTION, TANSYM, 0,
132 "then", THENSYM, 0, 0,
134 "tron", TRONOFFSYM, TRONSYM, 0,
135 "troff", TRONOFFSYM, TROFFSYM, 0,
136 "using", USINGSYM, 0, 0,
137 "usr", FUNCTION, USRSYM, 0,
138 "val", FUNCTION, VALSYM, 0,
139 "varptr", FUNCTION, VARPTRSYM, 0,
140 "wait", ILLEGAL, 0, 0,
141 "while", WHILESYM, 0, 0,
142 "wend", WENDSYM, 0, 0,
143 "width", ILLEGAL, 0, 0,
144 "write", WRITESYM, 0, 0,
145 "xor", XORSYM, XORSYM, 0,
149 /* Keyword index table */
153 /* Initialize the keyword table */
158 for(k=keywords;k->name;k++)
159 k->length= strlen(k->name);
161 for(i=0;k->name && i<='z'-'a';i++)
163 for(;k->name && *k->name<i+'a';k++);
164 if ( *k->name!=i+'a') continue;
165 kex[*k->name-'a']=k-keywords;
166 for(;k->name && *k->name==i+'a';k++);
167 kex[*(k-1)->name-'a'+1]=k-keywords;
172 print("%c:%d\n",'a'+i,kex[i]);
178 /* Get each line separately into the buffer */
179 /* Lines too long are terminated and flagged illegal */
181 #define MAXLINELENGTH 1024
183 char inputline[MAXLINELENGTH]; /* current source line */
184 char *cptr; /* next character to decode */
185 int yylineno=0; /* source line counter */
187 #define GETSBUFSIZE 1024
189 char fgets_buf[GETSBUFSIZE];
193 char *our_fgets(buffer,n_char,stream)
198 /* Read one line or n_char */
199 static int characters_left = 0;
200 static char *internal_bufp = fgets_buf;
203 external_bufp = buffer; /* Moves through the external buffer */
205 if ( characters_left ) { /* There is still something buffered */
206 if ( n_char > 1 ) { /* More characters have to be copied */
207 if ( *internal_bufp == '\n' ) {
208 *external_bufp++ = *internal_bufp++;
210 *external_bufp = '\0';
211 return(buffer); /* One line is read */
213 *external_bufp++ = *internal_bufp++;
215 n_char--; /* One character is copied */
217 } else { /* Enough characters read */
218 *external_bufp = '\0';
221 } else { /* Read new block */
222 sys_read(stream,fgets_buf,GETSBUFSIZE,&characters_left);
223 internal_bufp = fgets_buf;
224 /* Move pointer back to the beginning */
225 if ( characters_left == 0 ) { /* Nothing read */
226 if ( external_bufp == buffer ) {
227 *external_bufp = '\0';
229 } else { /* Something was already copied */
230 *external_bufp = '\0';
238 extern char *strindex();
242 /* get next input line */
244 if ( our_fgets(inputline,MAXLINELENGTH,yyin) == 0)
247 if ( strindex(inputline,'\n') == 0)
248 error("source line too long");
249 inputline[MAXLINELENGTH-1]=0;
251 fprint(STDERR, inputline);
265 cptr++; return( STRINGTYPE);
267 cptr++; return( INTTYPE);
269 cptr++; return( FLOATTYPE);
271 cptr++; return( DOUBLETYPE);
277 /* symbols in Microsoft are significant for the first 40 characters */
278 #define SIGNIFICANT 40
279 char name[SIGNIFICANT+1];
290 for(c=cptr; *c && isalnum(*c);c++)
293 for (k= keywords+kex[*cptr-'a']; k->name != 0 && *(k->name)== *cptr;k++)
294 if ( strncmp(cptr,k->name,k->length)==0)
296 /* if ( isalnum( *(cptr+k->length) )) *//* EHB */
297 if ( isalnum( *(cptr+k->length) ) && /* EHB */
298 k->token == FUNCTION) /* EHB */
300 /* keywords door delimiters gescheiden */
302 yylval.integer= k->classvalue;
303 if (debug) print("lookup:%d %d\n",
304 k->classvalue,k->token);
305 if ( k->token == FUNCTION)
307 /* stripp type character */
311 if ( k->token == REMSYM || k->token==ILLEGAL)
312 while ( *cptr && *cptr!=':' &&
317 /* Is it a function name ? */
319 /* Identifier found, update the symbol table */
321 while (( isalnum(*c) || *c == '.') && i < SIGNIFICANT)
323 while (isalnum(*c) || *c == '.') c++; /* skip rest */
326 Sym= srchsymbol(name);
329 if (Sym->symtype!=DEFAULTTYPE)
331 if (typech && typech!=Sym->symtype && wflag)
332 warning("type re-declared,ignored");
336 if (debug) print("lookup:%d Identifier\n",Sym);
337 if ( (name[0]=='f' || name[0]=='F') &&
338 (name[1]=='n' || name[1]=='N') )
345 /* Parsing unsigned numbers */
348 /* read HEX and OCTAL numbers */
351 if ( *cptr == 'H' || *cptr=='h')
356 while ( isdigit(*cptr) ||
357 (*cptr>='a' && *cptr<='f' ) ||
358 (*cptr>='A' && *cptr<='F' ) ) cptr++;
359 (void) sscanf(c,"%x",&ival);
361 if ( *cptr == 'O' || *cptr == 'o')
366 while ( isdigit(*cptr) ) cptr++;
367 (void) sscanf(c,"%o",&ival);
368 } else error("H or O expected");
375 /* Computes base to the power exponent. This was not done in the old
377 double powr(base,exp)
391 for ( i = 1; i <= abs_exp; i++ ) {
392 result = result * base;
396 return ( 1.0 / result );
408 static char numbuf[256];
409 register char *d = numbuf;
414 while (*c == '0') c++;
417 if (i1 < 0) overflow = 1;
418 if (d < &numbuf[255]) *d++ = *c;
421 if (d == numbuf) *d++ = '0';
423 if ( *c != '.' && *c != 'e' && *c != 'E'
424 && *c != 'd' && *c != 'D' ){
425 if ( i1> MAXINT || i1<MININT || overflow) {
429 /*NOSTRICT*/ ival= i1;
431 if (yydebug) print("number:INTVALUE %d",i1);
437 if (d < &numbuf[255]) *d++ = *c;
439 while ( isdigit(*c)){
440 if (d < &numbuf[255]) *d++ = *c;
444 /* handle exponential part */
445 if ( *c == 'e' || *c == 'E' || *c == 'd' || *c == 'D' ){
446 if (d < &numbuf[254]) *d++ = 'e';
448 if ( *c=='-' || *c=='+') {
449 if (d < &numbuf[255]) *d++ = *c;
453 if (d < &numbuf[255]) *d++ = *c;
456 if (*(d-1) == 'e') *d++ = '0';
461 if (yydebug) print("number:FLTVALUE %s",dval);
468 /* Maximale grootte van een chunk; >= 4 */
469 #define CHUNKSIZE 123
476 char firstchar = *cptr;
477 char buffer[CHUNKSIZE],*bufp = buffer;
479 /* generate label here */
480 if (! in_data) yylval.integer= genemlabel();
481 if ( *cptr== '"') cptr++;
490 if (yydebug) print("STRVALUE\n");
492 if ( firstchar == '"')
493 error("non-terminated string");
500 if ( bufp >= buffer + CHUNKSIZE - 4 ) {
502 C_con_scon(buffer,(arith)(bufp-buffer));
509 if ( bufp >= buffer + CHUNKSIZE - 4 ) {
511 C_con_scon(buffer,(arith)(bufp-buffer));
522 C_con_scon(buffer,(arith)(bufp-buffer));
524 yylval.integer= genemlabel();
525 C_rom_dlb((label)i,(arith)0);
526 C_rom_icon("9999",(arith)BEMINTSIZE);
527 C_rom_icon(itoa(length),(arith)BEMINTSIZE);
530 if (yydebug) print("STRVALUE found\n");
541 /* Here is the big switch */
544 case 'a': case 'b': case 'c': case 'd': case 'e':
545 case 'f': case 'g': case 'h': case 'i': case 'j':
546 case 'k': case 'l': case 'm': case 'n': case 'o':
547 case 'p': case 'q': case 'r': case 's': case 't':
548 case 'u': case 'v': case 'w': case 'x': case 'y':
549 case 'z': case 'A': case 'B': case 'C': case 'D':
550 case 'E': case 'F': case 'G': case 'H': case 'I':
551 case 'J': case 'K': case 'L': case 'M': case 'N':
552 case 'O': case 'P': case 'Q': case 'R': case 'S':
553 case 'T': case 'U': case 'V': case 'W': case 'X':
554 case 'Y': case 'Z': case '_':
557 case '0': case '1': case '2': case '3': case '4':
558 case '5': case '6': case '7': case '8': case '9':
563 /* comment at end of line */
564 while ( *cptr != '\n' && *cptr) cptr++;
570 if ( yydebug) print("end of buffer");
574 return(scanstring());
575 /* handle double operators */
581 return(readconstant());
589 yylval.integer= GESYM;
599 yylval.integer=LESYM;
605 yylval.integer=NESYM;