basic.lex 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. /*
  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".
  4. */
  5. #ifndef NORSCID
  6. static char rcs_lex[] = "$Id$" ;
  7. #endif
  8. /* This file contains the new lexical analizer */
  9. typedef struct {
  10. char *name;
  11. int token, classvalue,length;
  12. } Key;
  13. Key keywords [] ={
  14. "abs", FUNCTION, ABSSYM, 0,
  15. "and", ANDSYM, ANDSYM, 0,
  16. "asc", FUNCTION, ASCSYM, 0,
  17. "as", ASSYM, 0, 0,
  18. "atn", FUNCTION, ATNSYM, 0,
  19. "auto", ILLEGAL, 0, 0,
  20. "base", BASESYM, 0, 0,
  21. "call", CALLSYM, 0, 0,
  22. "cdbl", FUNCTION, CDBLSYM, 0,
  23. "chain", ILLEGAL, 0, 0,
  24. "chr", FUNCTION, CHRSYM, 0,
  25. "cint", FUNCTION, CINTSYM, 0,
  26. "clear", CLEARSYM, 0, 0,
  27. "cload", ILLEGAL, 0, 0,
  28. "close", CLOSESYM, 0, 0,
  29. "common", ILLEGAL, 0, 0,
  30. "cont", ILLEGAL, 0, 0,
  31. "cos", FUNCTION, COSSYM, 0,
  32. "csng", FUNCTION, CSNGSYM, 0,
  33. "csave", ILLEGAL, 0, 0,
  34. "cvi", FUNCTION, CVISYM, 0,
  35. "cvs", FUNCTION, CVSSYM, 0,
  36. "cvd", FUNCTION, CVDSYM, 0,
  37. "data", DATASYM, 0, 0,
  38. "defint", DEFINTSYM, 0, 0,
  39. "defsng", DEFSNGSYM, 0, 0,
  40. "defdbl", DEFDBLSYM, 0, 0,
  41. "defstr", DEFSTRSYM, 0, 0,
  42. "def", DEFSYM, 0, 0,
  43. "delete", ILLEGAL, 0, 0,
  44. "dim", DIMSYM, 0, 0,
  45. "edit", ILLEGAL, 0, 0,
  46. "else", ELSESYM, 0, 0,
  47. "end", ENDSYM, 0, 0,
  48. "eof", FUNCTION, EOFSYM, 0,
  49. "eqv", EQVSYM, EQVSYM, 0,
  50. "erase", ILLEGAL, 0, 0,
  51. "error", ERRORSYM, 0, 0,
  52. "err", ERRSYM, 0, 0,
  53. "erl", ERLSYM, 0, 0,
  54. "exp", FUNCTION, EXPSYM, 0,
  55. "field", FIELDSYM, 0, 0,
  56. "fix", FUNCTION, FIXSYM, 0,
  57. "for", FORSYM, 0, 0,
  58. "fre", FUNCTION, FRESYM, 0,
  59. "get", GETSYM, 0, 0,
  60. "gosub", GOSUBSYM, 0, 0,
  61. "goto", GOTOSYM, 0, 0,
  62. "hex", FUNCTION, HEXSYM, 0,
  63. "if", IFSYM, 0, 0,
  64. "imp", IMPSYM, IMPSYM, 0,
  65. "inkey", INKEYSYM, 0, 0,
  66. "input", INPUTSYM, 0, 0,
  67. "inp", FUNCTION, INPSYM, 0,
  68. "instr", FUNCTION, INSTRSYM, 0,
  69. "int", FUNCTION, INTSYM, 0,
  70. "kill", ILLEGAL, 0, 0,
  71. "left", FUNCTION, LEFTSYM, 0,
  72. "len", FUNCTION, LENSYM, 0,
  73. "let", LETSYM, 0, 0,
  74. "line", LINESYM, 0, 0,
  75. "list", LISTSYM, 0, 0,
  76. "llist", ILLEGAL, 0, 0,
  77. "load", LOADSYM, 0, 0,
  78. "loc", FUNCTION, LOCSYM, 0,
  79. "log", FUNCTION, LOGSYM, 0,
  80. "lpos", FUNCTION, LPOSSYM, 0,
  81. "lprint", ILLEGAL, 0, 0,
  82. "lset", LSETSYM, 0, 0,
  83. "merge", MERGESYM, 0, 0,
  84. "mid", MIDSYM, 0, 0,
  85. "mki", FUNCTION, MKISYM, 0,
  86. "mks", FUNCTION, MKSSYM, 0,
  87. "mkd", FUNCTION, MKDSYM, 0,
  88. "mod", MODSYM, 0, 0,
  89. "name", ILLEGAL, 0, 0,
  90. "new", ILLEGAL, 0, 0,
  91. "next", NEXTSYM, 0, 0,
  92. "not", NOTSYM, 0, 0,
  93. "null", ILLEGAL, 0, 0,
  94. "on", ONSYM, 0, 0,
  95. "oct", FUNCTION, OCTSYM, 0,
  96. "open", OPENSYM, 0, 0,
  97. "option", OPTIONSYM, 0, 0,
  98. "or", ORSYM, ORSYM, 0,
  99. "out", FUNCTION, OUTSYM, 0,
  100. "peek", PEEKSYM, 0, 0,
  101. "poke", POKESYM, 0, 0,
  102. "print", PRINTSYM, 0, 0,
  103. "pos", FUNCTION, POSSYM, 0,
  104. "put", PUTSYM, 0, 0,
  105. "randomize", RANDOMIZESYM, 0, 0,
  106. "read", READSYM, 0, 0,
  107. "rem", REMSYM, 0, 0,
  108. "renum", ILLEGAL, 0, 0,
  109. "ren", ILLEGAL, 0, 0,
  110. "restore", RESTORESYM, 0, 0,
  111. "resume", ILLEGAL, 0, 0,
  112. "return", RETURNSYM, 0, 0,
  113. "right", FUNCTION, RIGHTSYM, 0,
  114. "rnd", FUNCTION, RNDSYM, 0,
  115. "run", ILLEGAL, 0, 0,
  116. "save", ILLEGAL, 0, 0,
  117. "step", STEPSYM, 0, 0,
  118. "sgn", FUNCTION, SGNSYM, 0,
  119. "sin", FUNCTION, SINSYM, 0,
  120. "space", FUNCTION, SPACESYM, 0,
  121. "spc", FUNCTION, SPCSYM, 0,
  122. "sqr", FUNCTION, SQRSYM, 0,
  123. "stop", STOPSYM, 0, 0,
  124. "string", FUNCTION, STRINGSYM, 0,
  125. "str", FUNCTION, STRSYM, 0,
  126. "swap", SWAPSYM, 0, 0,
  127. "tab", FUNCTION, TABSYM, 0,
  128. "tan", FUNCTION, TANSYM, 0,
  129. "then", THENSYM, 0, 0,
  130. "to", TOSYM, 0, 0,
  131. "tron", TRONOFFSYM, TRONSYM, 0,
  132. "troff", TRONOFFSYM, TROFFSYM, 0,
  133. "using", USINGSYM, 0, 0,
  134. "usr", FUNCTION, USRSYM, 0,
  135. "val", FUNCTION, VALSYM, 0,
  136. "varptr", FUNCTION, VARPTRSYM, 0,
  137. "wait", ILLEGAL, 0, 0,
  138. "while", WHILESYM, 0, 0,
  139. "wend", WENDSYM, 0, 0,
  140. "width", ILLEGAL, 0, 0,
  141. "write", WRITESYM, 0, 0,
  142. "xor", XORSYM, XORSYM, 0,
  143. 0, 0, 0, 0
  144. };
  145. /* Keyword index table */
  146. int kex[27];
  147. /* Initialize the keyword table */
  148. fillkex()
  149. {
  150. Key *k;
  151. int i;
  152. for(k=keywords;k->name;k++)
  153. k->length= strlen(k->name);
  154. k=keywords;
  155. for(i=0;k->name && i<='z'-'a';i++)
  156. {
  157. for(;k->name && *k->name<i+'a';k++);
  158. if ( *k->name!=i+'a') continue;
  159. kex[*k->name-'a']=k-keywords;
  160. for(;k->name && *k->name==i+'a';k++);
  161. kex[*(k-1)->name-'a'+1]=k-keywords;
  162. }
  163. if (debug)
  164. {
  165. for(i=0;i<27;i++)
  166. print("%c:%d\n",'a'+i,kex[i]);
  167. }
  168. }
  169. #include <ctype.h>
  170. /* Get each line separately into the buffer */
  171. /* Lines too long are terminated and flagged illegal */
  172. #define MAXLINELENGTH 1024
  173. char inputline[MAXLINELENGTH]; /* current source line */
  174. char *cptr; /* next character to decode */
  175. int yylineno=0; /* source line counter */
  176. #define GETSBUFSIZE 1024
  177. char fgets_buf[GETSBUFSIZE];
  178. char *our_fgets(buffer,n_char,stream)
  179. char *buffer;
  180. int n_char;
  181. File *stream;
  182. {
  183. /* Read one line or n_char */
  184. static int characters_left = 0;
  185. static char *internal_bufp = fgets_buf;
  186. char *external_bufp;
  187. external_bufp = buffer; /* Moves through the external buffer */
  188. while ( 1 ) {
  189. if ( characters_left ) { /* There is still something buffered */
  190. if ( n_char > 1 ) { /* More characters have to be copied */
  191. if ( *internal_bufp == '\n' ) {
  192. *external_bufp++ = *internal_bufp++;
  193. characters_left--;
  194. *external_bufp = '\0';
  195. return(buffer); /* One line is read */
  196. } else {
  197. *external_bufp++ = *internal_bufp++;
  198. characters_left--;
  199. n_char--; /* One character is copied */
  200. }
  201. } else { /* Enough characters read */
  202. *external_bufp = '\0';
  203. return(buffer);
  204. }
  205. } else { /* Read new block */
  206. sys_read(stream,fgets_buf,GETSBUFSIZE,&characters_left);
  207. internal_bufp = fgets_buf;
  208. /* Move pointer back to the beginning */
  209. if ( characters_left == 0 ) { /* Nothing read */
  210. if ( external_bufp == buffer ) {
  211. *external_bufp = '\0';
  212. return(0); /* EOF */
  213. } else { /* Something was already copied */
  214. *external_bufp = '\0';
  215. return(buffer);
  216. }
  217. }
  218. }
  219. }
  220. }
  221. extern char *strchr();
  222. getline()
  223. {
  224. /* get next input line */
  225. if ( our_fgets(inputline,MAXLINELENGTH,yyin) == 0)
  226. return(FALSE);
  227. yylineno ++;
  228. if ( strchr(inputline,'\n') == 0)
  229. error("source line too long");
  230. inputline[MAXLINELENGTH-1]=0;
  231. if ( listing)
  232. fprint(STDERR, inputline);
  233. cptr= inputline;
  234. return(TRUE);
  235. }
  236. typechar()
  237. {
  238. switch(*cptr)
  239. {
  240. case '$':
  241. cptr++; return( STRINGTYPE);
  242. case '%':
  243. cptr++; return( INTTYPE);
  244. case '!':
  245. cptr++; return( FLOATTYPE);
  246. case '#':
  247. cptr++; return( DOUBLETYPE);
  248. }
  249. return(0);
  250. }
  251. /* symbols in Microsoft are significant for the first 40 characters */
  252. #define SIGNIFICANT 40
  253. char name[SIGNIFICANT+1];
  254. lookup()
  255. {
  256. Key *k;
  257. Symbol *Sym;
  258. char *c;
  259. int i, typech;
  260. sval= name;
  261. for(c=cptr; *c && isalnum(*c);c++)
  262. if ( isupper(*c) )
  263. *c= tolower(*c);
  264. for (k= keywords+kex[*cptr-'a']; k->name != 0 && *(k->name)== *cptr;k++)
  265. if ( strncmp(cptr,k->name,k->length)==0)
  266. {
  267. /* if ( isalnum( *(cptr+k->length) )) *//* EHB */
  268. if ( isalnum( *(cptr+k->length) ) && /* EHB */
  269. k->token == FUNCTION) /* EHB */
  270. continue;
  271. /* keywords door delimiters gescheiden */
  272. cptr += k->length;
  273. yylval.integer= k->classvalue;
  274. if (debug) print("lookup:%d %d\n",
  275. k->classvalue,k->token);
  276. if ( k->token == FUNCTION)
  277. {
  278. /* stripp type character */
  279. typech=typechar();
  280. }
  281. /* illegals + rem */
  282. if ( k->token == REMSYM || k->token==ILLEGAL)
  283. while ( *cptr && *cptr!=':' &&
  284. *cptr!='\n')
  285. cptr++;
  286. return( k->token);
  287. }
  288. /* Is it a function name ? */
  289. c=cptr;
  290. /* Identifier found, update the symbol table */
  291. i=0;
  292. while (( isalnum(*c) || *c == '.') && i < SIGNIFICANT)
  293. name[i++]= *c++;
  294. while (isalnum(*c) || *c == '.') c++; /* skip rest */
  295. name[i]=0;
  296. cptr=c;
  297. Sym= srchsymbol(name);
  298. yylval.Sptr = Sym;
  299. typech= typechar();
  300. if (Sym->symtype!=DEFAULTTYPE)
  301. {
  302. if (typech && typech!=Sym->symtype && wflag)
  303. warning("type re-declared,ignored");
  304. }
  305. if ( typech)
  306. Sym->symtype=typech;
  307. if (debug) print("lookup:%d Identifier\n",Sym);
  308. if ( (name[0]=='f' || name[0]=='F') &&
  309. (name[1]=='n' || name[1]=='N') )
  310. return(FUNCTID);
  311. return(IDENTIFIER);
  312. }
  313. /* Parsing unsigned numbers */
  314. readconstant()
  315. {
  316. /* read HEX and OCTAL numbers */
  317. char *c;
  318. cptr++;
  319. if ( *cptr == 'H' || *cptr=='h')
  320. {
  321. /* HEX */
  322. cptr++;
  323. c=cptr;
  324. while ( isdigit(*cptr) ||
  325. (*cptr>='a' && *cptr<='f' ) ||
  326. (*cptr>='A' && *cptr<='F' ) ) cptr++;
  327. (void) sscanf(c,"%x",&ival);
  328. } else
  329. if ( *cptr == 'O' || *cptr == 'o')
  330. {
  331. /* OCTAL */
  332. cptr++;
  333. c=cptr;
  334. while ( isdigit(*cptr) ) cptr++;
  335. (void) sscanf(c,"%o",&ival);
  336. } else error("H or O expected");
  337. return(INTVALUE);
  338. }
  339. #ifdef ____
  340. /* Computes base to the power exponent. This was not done in the old
  341. compiler */
  342. double powr(base,exp)
  343. double base;
  344. int exp;
  345. {
  346. int i;
  347. double result;
  348. int abs_exp;
  349. if ( exp < 0 )
  350. abs_exp = -exp;
  351. else
  352. abs_exp = exp;
  353. result = 1.0;
  354. for ( i = 1; i <= abs_exp; i++ ) {
  355. result = result * base;
  356. }
  357. if ( exp < 0 )
  358. return ( 1.0 / result );
  359. else
  360. return ( result );
  361. }
  362. #endif
  363. number()
  364. {
  365. long i1;
  366. int overflow = 0;
  367. register char *c;
  368. static char numbuf[256];
  369. register char *d = numbuf;
  370. dval = numbuf;
  371. i1=0;
  372. c=cptr;
  373. while (*c == '0') c++;
  374. while (isdigit(*c)){
  375. i1= i1*10 + *c-'0';
  376. if (i1 < 0) overflow = 1;
  377. if (d < &numbuf[255]) *d++ = *c;
  378. c++;
  379. }
  380. if (d == numbuf) *d++ = '0';
  381. cptr=c;
  382. if ( *c != '.' && *c != 'e' && *c != 'E'
  383. && *c != 'd' && *c != 'D' ){
  384. if ( i1> MAXINT || i1<MININT || overflow) {
  385. *d = 0;
  386. return(FLTVALUE);
  387. }
  388. /*NOSTRICT*/ ival= i1;
  389. #ifdef YYDEBUG
  390. if (yydebug) print("number:INTVALUE %d",i1);
  391. #endif
  392. return(INTVALUE);
  393. }
  394. /* handle floats */
  395. if (*c == '.') {
  396. if (d < &numbuf[255]) *d++ = *c;
  397. c++;
  398. while ( isdigit(*c)){
  399. if (d < &numbuf[255]) *d++ = *c;
  400. c++;
  401. }
  402. }
  403. /* handle exponential part */
  404. if ( *c == 'e' || *c == 'E' || *c == 'd' || *c == 'D' ){
  405. if (d < &numbuf[254]) *d++ = 'e';
  406. c++;
  407. if ( *c=='-' || *c=='+') {
  408. if (d < &numbuf[255]) *d++ = *c;
  409. c++;
  410. }
  411. while (isdigit(*c)){
  412. if (d < &numbuf[255]) *d++ = *c;
  413. c++;
  414. }
  415. if (*(d-1) == 'e') *d++ = '0';
  416. }
  417. *d = 0;
  418. cptr=c;
  419. #ifdef YYDEBUG
  420. if (yydebug) print("number:FLTVALUE %s",dval);
  421. #endif
  422. return(FLTVALUE);
  423. }
  424. /* Maximale grootte van een chunk; >= 4 */
  425. #define CHUNKSIZE 123
  426. scanstring()
  427. {
  428. int i,length=0;
  429. char firstchar = *cptr;
  430. char buffer[CHUNKSIZE],*bufp = buffer;
  431. /* generate label here */
  432. if (! in_data) yylval.integer= genemlabel();
  433. if ( *cptr== '"') cptr++;
  434. sval= cptr;
  435. while ( *cptr !='"')
  436. {
  437. switch(*cptr)
  438. {
  439. case 0:
  440. case '\n':
  441. #ifdef YYDEBUG
  442. if (yydebug) print("STRVALUE\n");
  443. #endif
  444. if ( firstchar == '"')
  445. error("non-terminated string");
  446. return(STRVALUE);
  447. /*
  448. case '\'':
  449. case '\\':
  450. *bufp++ = '\\';
  451. *bufp++ = *cptr;
  452. if ( bufp >= buffer + CHUNKSIZE - 4 ) {
  453. if (! in_data)
  454. C_con_scon(buffer,(arith)(bufp-buffer));
  455. bufp = buffer;
  456. }
  457. break;
  458. */
  459. default:
  460. *bufp++ = *cptr;
  461. if ( bufp >= buffer + CHUNKSIZE - 4 ) {
  462. if (! in_data)
  463. C_con_scon(buffer,(arith)(bufp-buffer));
  464. bufp = buffer;
  465. }
  466. }
  467. cptr++;
  468. length++;
  469. }
  470. *cptr = 0;
  471. *bufp++ = 0;
  472. cptr++;
  473. if (! in_data) {
  474. C_con_scon(buffer,(arith)(bufp-buffer));
  475. i=yylval.integer;
  476. yylval.integer= genemlabel();
  477. C_rom_dlb((label)i,(arith)0);
  478. C_rom_icon("9999",(arith)BEMINTSIZE);
  479. C_rom_icon(itoa(length),(arith)BEMINTSIZE);
  480. }
  481. #ifdef YYDEBUG
  482. if (yydebug) print("STRVALUE found\n");
  483. #endif
  484. return(STRVALUE);
  485. }
  486. yylex()
  487. {
  488. char *c;
  489. /* Here is the big switch */
  490. c= cptr;
  491. switch(*c){
  492. case 'a': case 'b': case 'c': case 'd': case 'e':
  493. case 'f': case 'g': case 'h': case 'i': case 'j':
  494. case 'k': case 'l': case 'm': case 'n': case 'o':
  495. case 'p': case 'q': case 'r': case 's': case 't':
  496. case 'u': case 'v': case 'w': case 'x': case 'y':
  497. case 'z': case 'A': case 'B': case 'C': case 'D':
  498. case 'E': case 'F': case 'G': case 'H': case 'I':
  499. case 'J': case 'K': case 'L': case 'M': case 'N':
  500. case 'O': case 'P': case 'Q': case 'R': case 'S':
  501. case 'T': case 'U': case 'V': case 'W': case 'X':
  502. case 'Y': case 'Z': case '_':
  503. return(lookup());
  504. case '0': case '1': case '2': case '3': case '4':
  505. case '5': case '6': case '7': case '8': case '9':
  506. case '.':
  507. return(number());
  508. case '\'':
  509. /* comment at end of line */
  510. while ( *cptr != '\n' && *cptr) cptr++;
  511. case '\n':
  512. cptr++;
  513. return(EOLN);
  514. case 0:
  515. #ifdef YYDEBUG
  516. if ( yydebug) print("end of buffer");
  517. #endif
  518. return(0);
  519. case '"':
  520. return(scanstring());
  521. /* handle double operators */
  522. case ' ':
  523. case '\t':
  524. cptr++;
  525. return(yylex());
  526. case '&':
  527. return(readconstant());
  528. case '?':
  529. cptr++;
  530. return(PRINTSYM);
  531. case '>':
  532. if ( *(c+1)=='='){
  533. c++; c++;
  534. cptr=c;
  535. yylval.integer= GESYM;
  536. return(RELOP);
  537. }
  538. yylval.integer= '>';
  539. cptr++;
  540. return(RELOP);
  541. case '<':
  542. if ( *(c+1)=='='){
  543. c++; c++;
  544. cptr=c;
  545. yylval.integer=LESYM;
  546. return(RELOP);
  547. } else
  548. if ( *(c+1)=='>'){
  549. c++; c++;
  550. cptr=c;
  551. yylval.integer=NESYM;
  552. return(RELOP);
  553. }
  554. yylval.integer= '<';
  555. cptr++;
  556. return(RELOP);
  557. }
  558. return(*cptr++);
  559. }