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