home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 2 / RISC_DISC_2.iso / pd_share / program / language / as / source / c / lex < prev    next >
Encoding:
Text File  |  1994-09-13  |  7.5 KB  |  292 lines

  1. /*
  2.  *   lex.c
  3.  * Copyright © 1992 Niklas Röjemo
  4.  */
  5.  
  6. #include <ctype.h>
  7. #include <math.h>
  8. #include "error.h"
  9. #include "lex.h"
  10. #include "help_lex.h"
  11. #include "input.h"
  12. #include "hash.h"
  13. #include "symbol.h"
  14.  
  15. extern int gcc_backend;
  16. extern int lexAcornBinop(Lex *lex);
  17. extern int lexAcornUnop(Lex *lex);
  18.  
  19.  
  20. static Lex nextbinop;
  21. static BOOL nextbinopvalid = FALSE;
  22.  
  23.  
  24. static int lexint(int base)
  25. {
  26.   int res = 0;
  27.   char c;
  28.  
  29.   if(base != 16) {
  30.     if((c=inputLook()) == '0') {
  31.       base = 8;
  32.       if((c=inputSkipLook()) == 'x' || c == 'X') {
  33.         base = 16;
  34.         inputSkip();
  35.       }
  36.     } else {
  37.       if(inputLookN(1) == '_') {
  38.         inputSkipN(2);
  39.         if((base = c-'0')<2 || base > 9)
  40.           error(ErrorError,TRUE,"Illegal base %d.",base);
  41.       }
  42.     }
  43.   }
  44.  
  45.   for(;isxdigit(c = inputLook()); inputSkip()) {
  46.     if(c > '9') {
  47.       if(c >= 'a')
  48.         c -= 'a' - 10;
  49.       else
  50.         c -= 'A' - 10;
  51.     } else
  52.       c -= '0';
  53.     if(c < base)
  54.       res = res*base + c;
  55.     else {
  56.       return res;
  57.     }
  58.   }
  59.   return res;
  60. }
  61.  
  62. static FLOAT lexfloat(int r)
  63. {
  64.   FLOAT res = r;
  65.   FLOAT frac = 0.1;
  66.   FLOAT exp = 0.0;
  67.   int    signexp = 1;
  68.   char c;
  69.  
  70.   if(inputGet()=='.') {  /* Fraction part */
  71.     while(isdigit(c=inputGet())) {
  72.       res = res + frac*((FLOAT)c-(FLOAT)'0');
  73.       frac /= 10.0;
  74.     }
  75.     if(c=='e' || c == 'E') {  /* Exponent part */
  76.       if(inputLook() == '-') {
  77.         inputSkip();
  78.         signexp = -1;
  79.       } else if (inputLook() == '+') {
  80.         inputSkip();
  81.       }
  82.       while(isdigit(c=inputGet()))
  83.         exp = exp*10.0+((FLOAT)c-(FLOAT)'0');
  84.     }
  85.   } else
  86.     error(ErrorError,TRUE,"Parse error in lexfloat.");
  87.   inputUnGet(c);
  88.   return res*pow(10.0,signexp*exp);
  89. }
  90.  
  91. Lex lexGetId(void)
  92. {
  93.   char c;
  94.   Lex result;
  95.   nextbinopvalid = FALSE;
  96.   skipblanks();
  97.   if((c=inputGet()) == '|') {
  98.     result.tag = LexId;
  99.     result.LexId.str = inputSymbol(&result.LexId.len,'|');
  100.     if(inputGet() != '|') error(ErrorError,TRUE,"Identifier continues over newline");
  101.     result.LexId.hash = hashstr(result.LexId.str,result.LexId.len,SYMBOL_TABELSIZE);
  102.   } else {
  103.     inputUnGet(c);
  104.     if(isalpha(c) || c == '.' || c == '_' || c == '$') {
  105.       result.tag = LexId;
  106.       result.LexId.str = inputSymbol(&result.LexId.len,0);
  107.       result.LexId.hash = hashstr(result.LexId.str,result.LexId.len,SYMBOL_TABELSIZE);
  108.     } else {
  109.       error(ErrorError,TRUE,"Missing identifier.");
  110.       result.tag = LexNone;
  111.     }
  112.   }
  113.   return result;
  114. }
  115.  
  116. Lex lexGetPrim(void)
  117. {
  118.   char c;
  119.   char *str;
  120.   int   len;
  121.   Lex result;
  122.   nextbinopvalid = FALSE;
  123.   skipblanks();
  124.   switch(c=inputGet()) {
  125.   case '+':
  126.     result.tag = LexOperator; result.LexOperator.op = Op_none; result.LexOperator.pri =10; break;
  127.   case '-':
  128.     result.tag = LexOperator; result.LexOperator.op = Op_neg; result.LexOperator.pri = 10; break;
  129.   case '!':
  130.     result.tag = LexOperator; result.LexOperator.op = Op_lnot; result.LexOperator.pri =10; break;
  131.   case '~':
  132.     result.tag = LexOperator; result.LexOperator.op = Op_not; result.LexOperator.pri = 10; break;
  133.   case '(':  case ')':
  134.     result.tag = LexDelim; result.LexDelim.delim = c; break;
  135.   case ':':
  136.     lexAcornUnop(&result); break;
  137.   case '&':
  138.     result.tag = LexInt; result.LexInt.value = lexint(16); break;
  139.   case '0':  case '1':  case '2':  case '3':  case '4':
  140.   case '5':  case '6':  case '7':  case '8':  case '9':
  141.     inputUnGet(c);
  142.     result.tag = LexInt; result.LexInt.value = lexint(10);
  143.     if(inputLook() == '.') {
  144.       result.tag = LexFloat; result.LexFloat.value = lexfloat(result.LexInt.value);
  145.     } break;
  146.   case '\'':
  147.     result.tag = LexInt;
  148.     str = inputSymbol(&len,'\'');
  149.     if(inputGet() != '\'') error(ErrorError,TRUE,"Character continues over newline");
  150.     result.LexInt.value = lexChar2Int(TRUE,len,str);
  151.     break;
  152.   case '"':
  153.     result.tag = LexString;
  154.     result.LexString.str = inputSymbol(&result.LexString.len,'"');
  155.     if(inputGet() != '"') error(ErrorError,TRUE,"String continues over newline");
  156.     break;
  157.   case '|':
  158.     result.tag = LexId;
  159.     result.LexId.str = inputSymbol(&result.LexId.len,'|');
  160.     if(inputGet() != '|') error(ErrorError,TRUE,"Identifier continues over newline");
  161.     result.LexId.hash = hashstr(result.LexId.str,result.LexId.len,SYMBOL_TABELSIZE);
  162.     break;
  163.   case '.':
  164.     result.tag = LexPosition;
  165.     break;
  166.   case '@':
  167.     if(gcc_backend)
  168.       result.tag = LexNone;
  169.     else
  170.       result.tag = LexStorage;
  171.     break;
  172.   default:
  173.     inputUnGet(c);
  174.     if(isalpha(c) || c == '_' || c == '$') {
  175.       result.tag = LexId;
  176.       result.LexId.str = inputSymbol(&result.LexId.len,0);
  177.       result.LexId.hash = hashstr(result.LexId.str,result.LexId.len,SYMBOL_TABELSIZE);
  178.       break;
  179.     } else {
  180.       result.tag = LexNone;
  181.     }
  182.   }
  183.   return result;
  184. }
  185.  
  186. Lex lexGetBinop(void)
  187. {
  188.   Lex result;
  189.   int c;
  190.   if(nextbinopvalid) {
  191.     nextbinopvalid = FALSE;
  192.     return nextbinop;
  193.   }
  194.   skipblanks();
  195.   switch(c=inputGet()) {
  196.   case '*':
  197.     result.tag = LexOperator; result.LexOperator.op = Op_mul; result.LexOperator.pri = 10; break;
  198.   case '/':
  199.     result.tag = LexOperator; result.LexOperator.op = Op_div; result.LexOperator.pri = 10; break;
  200.   case '%':
  201.     result.tag = LexOperator; result.LexOperator.op = Op_mod; result.LexOperator.pri = 10; break;
  202.   case '+':
  203.     result.tag = LexOperator; result.LexOperator.op = Op_add; result.LexOperator.pri = 9; break;
  204.   case '-':
  205.     result.tag = LexOperator; result.LexOperator.op = Op_sub; result.LexOperator.pri = 9; break;
  206.   case '^':
  207.     result.tag = LexOperator; result.LexOperator.op = Op_xor; result.LexOperator.pri = 6; break;
  208.   case '>':
  209.     result.tag = LexOperator;
  210.     switch(inputLook()){
  211.     case '>' :
  212.       result.LexOperator.pri = 5;
  213.       if(inputSkipLook() == '>') {
  214.         inputSkip();
  215.         result.LexOperator.op = Op_asr;
  216.       } else {
  217.         result.LexOperator.op = Op_sr;
  218.       }
  219.       break;
  220.     case '=' :
  221.       inputSkip();
  222.       result.LexOperator.op = Op_ge; result.LexOperator.pri = 4; break;
  223.     default:
  224.       result.LexOperator.op = Op_gt; result.LexOperator.pri = 4;
  225.     }
  226.     break;
  227.   case '<':
  228.     result.tag = LexOperator;
  229.     switch(inputLook()){
  230.     case '<' :
  231.       inputSkip();
  232.       result.LexOperator.pri = 5; result.LexOperator.op = Op_sl; break;
  233.     case '=' :
  234.       inputSkip();
  235.       result.LexOperator.op = Op_le; result.LexOperator.pri = 4; break;
  236.     default:
  237.       result.LexOperator.op = Op_lt; result.LexOperator.pri = 4;
  238.     }
  239.     break;
  240.   case '=':
  241.     if(inputLook() == '=') {
  242.       inputSkip();
  243.       result.tag = LexOperator; result.LexOperator.pri = 3; result.LexOperator.op = Op_eq;
  244.     } else
  245.       result.tag = LexNone;
  246.     break;
  247.   case '!':
  248.     if(inputLook() == '=') {
  249.       inputSkip();
  250.       result.tag = LexOperator; result.LexOperator.pri = 3; result.LexOperator.op = Op_ne;
  251.     } else
  252.       result.tag = LexNone;
  253.     break;
  254.   case '|':
  255.     result.tag = LexOperator;
  256.     if(inputLook() == '|') {
  257.       inputSkip();
  258.       result.LexOperator.pri = 1; result.LexOperator.op = Op_lor;
  259.     } else {
  260.       result.LexOperator.pri = 7; result.LexOperator.op = Op_or;
  261.     }
  262.     break;
  263.   case '&':
  264.     result.tag = LexOperator;
  265.     if(inputLook() == '&') {
  266.       inputSkip();
  267.       result.LexOperator.pri = 2; result.LexOperator.op = Op_land;
  268.     } else {
  269.       result.LexOperator.pri = 8; result.LexOperator.op = Op_and;
  270.     }
  271.     break;
  272.   case ':':
  273.     lexAcornBinop(&result); break;
  274.   default:
  275.     inputUnGet(c);
  276.     result.tag = LexNone;
  277.   }
  278.   return result;
  279. }
  280.  
  281. int lexNextPri()
  282. {
  283.   if(!nextbinopvalid) {
  284.     nextbinop = lexGetBinop();
  285.     nextbinopvalid = TRUE;
  286.   }
  287.   if(nextbinop.tag == LexOperator)
  288.     return nextbinop.LexOperator.pri;
  289.   else
  290.     return -1;
  291. }
  292.