home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / assembler / as / src / c / symbol < prev    next >
Encoding:
Text File  |  1992-08-02  |  6.2 KB  |  222 lines

  1.  
  2. /*
  3.  *   symbol.c
  4.  * Copyright © 1992 Niklas Röjemo
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "symbol.h"
  11. #include "global.h"
  12. #include "error.h"
  13. #include "AofFile.h"
  14. #include "code.h"
  15. #include "help_lex.h"
  16.  
  17. static Symbol *symbolTabel[SYMBOL_TABELSIZE];
  18.  
  19. static Symbol *symbolNew(int len,char *str)
  20. {
  21.   Symbol *result;
  22.   char *dst;
  23.   if((result = (Symbol *)malloc(sizeof(Symbol)+len))!=0) {
  24.     result->next = 0;
  25.     result->type = result->offset = 0;
  26.     result->value.Tag = ValueIllegal;
  27.     result->used = -1;
  28.     result->len = len;
  29.     dst = &(result->str[0]);
  30.     while(len--)
  31.       *dst++ = *str++;
  32.     *dst = 0;
  33.   } else
  34.     error(ErrorSerious,FALSE,"Inrenal symbolNew: Out of memory!");
  35.   return result;
  36. }
  37.  
  38. static BOOL EqSymLex(Symbol *str, Lex *lx)
  39. {
  40.   char *s,*l;
  41.   int i;
  42.   if(str->len != lx->LexId.len)
  43.     return FALSE;
  44.   for(i = str->len, s = str->str, l = lx->LexId.str; i>0; i--)
  45.     if(*s++ != *l++)
  46.       return FALSE;
  47.   return TRUE;
  48. }
  49.  
  50. static char er[1024];
  51.  
  52.  
  53. Symbol *symbolAdd(Lex l)
  54. {
  55.   Symbol **isearch = &symbolTabel[l.LexId.hash];
  56.   if(l.tag != LexId)
  57.     error(ErrorSerious,FALSE,"Internal symbolAdd: Non-Id.");
  58.   while(*isearch) {
  59.     if(EqSymLex(*isearch,&l)) {
  60.       if((*isearch)->type & SYMBOL_DEFINED) {
  61.         strncpy(er,l.LexId.str,l.LexId.len);
  62.         er[l.LexId.len] = 0;
  63.         error(ErrorError,TRUE,"Reddefinition of %s",er);
  64.       } else {
  65.         if((*isearch)->type & SYMBOL_AREA) {
  66.           strncpy(er,l.LexId.str,l.LexId.len);
  67.           er[l.LexId.len] = 0;
  68.           error(ErrorError,TRUE,"Area %s is already defined",er);
  69.         } else {
  70.           (*isearch)->type |= SYMBOL_DEFINED;
  71.           return *isearch;
  72.         }
  73.       } 
  74.     }
  75.     isearch = &((*isearch)->next);
  76.   }
  77.   *isearch = symbolNew(l.LexId.len,l.LexId.str);
  78.   (*isearch)->type |= SYMBOL_DEFINED;
  79.   return *isearch;
  80. }
  81.  
  82. Symbol *symbolGet(Lex l)
  83. {
  84.   Symbol **isearch;
  85.   if(l.tag != LexId) {
  86.     if(l.tag == LexNone) {
  87.       isearch = &symbolTabel[0];
  88.       while(*isearch)
  89.         isearch = &((*isearch)->next);
  90.       *isearch = symbolNew(7,"|Dummy|");
  91.   } else
  92.       error(ErrorSerious,FALSE,"Internal symbolGet: Non-Id.");
  93.   } else {
  94.     isearch = &symbolTabel[l.LexId.hash];
  95.     while(*isearch) {
  96.       if(EqSymLex(*isearch,&l))
  97.         return *isearch;
  98.       else
  99.         isearch = &((*isearch)->next);
  100.     }       
  101.   }
  102.   *isearch = symbolNew(l.LexId.len,l.LexId.str);
  103.   return *isearch;
  104. }
  105.  
  106. static int stringtabelsize = -1;
  107.  
  108. int symbolFix(void)        /* Returns number of symbols */
  109. {
  110.   int nosym = 0;
  111.   int strsize = 4; /* Always contains its length */
  112.   int i;
  113.   Symbol *sym;
  114.  
  115.   for(i=0; i<SYMBOL_TABELSIZE; i++) {
  116.     for(sym = symbolTabel[i]; sym; sym = sym->next){
  117.       if(sym->type == SYMBOL_AREA) {
  118.         sym->offset = strsize;
  119.         strsize += sym->len+1;
  120.       } else if(sym->used >= 0 || sym->type & SYMBOL_REFERENCE) {
  121.         sym->offset = strsize;
  122.         strsize += sym->len+1;
  123.         sym->used = nosym++;
  124.       }
  125.     }
  126.   }
  127.   stringtabelsize = strsize;
  128.   return nosym;
  129. }
  130.  
  131. int symbolStringSize(void)
  132. {
  133.   if(stringtabelsize<0)
  134.     error(ErrorSerious,FALSE,"Internal error stringtabelsize < 0.\n");
  135.   return stringtabelsize;
  136. }
  137.  
  138. void symbolStringOutput(FILE *outfile)  /* Count already output */
  139. {
  140.   int i;
  141.   Symbol *sym;
  142.  
  143.   for(i=0; i<SYMBOL_TABELSIZE; i++)
  144.     for(sym = symbolTabel[i]; sym; sym = sym->next)
  145.       if(sym->used >= 0 || sym->type == SYMBOL_AREA)
  146.         fwrite((void *)sym->str,1,sym->len+1,outfile);
  147.  
  148. }
  149.  
  150. void symbolSymbolOutput(FILE *outfile)
  151. {
  152.   int i;
  153.   Symbol *sym;
  154.   Value value;
  155.   int v;
  156.   AofSymbol asym;
  157.  
  158.   for(i=0; i<SYMBOL_TABELSIZE; i++)
  159.     for(sym = symbolTabel[i]; sym; sym = sym->next)
  160.       if(sym->type != SYMBOL_AREA && sym->used >= 0) {
  161.         asym.Name = sym->offset;
  162.         if(sym->type & SYMBOL_DEFINED) {
  163.           if(sym->value.Tag == ValueCode) {
  164.             codeInit();
  165.             value = codeEvalLow(ValueAll,sym->value.ValueCode.len,sym->value.ValueCode.c);
  166.           } else {           
  167.             value = sym->value;
  168.           }
  169.           switch(value.Tag) {
  170.             case ValueIllegal:
  171.               errorLine(0,ErrorError,TRUE,"Symbol %s can not be evaluated.",sym->str);
  172.               v = 0;
  173.               break;
  174.             case ValueInt:
  175.               v = value.ValueInt.i;
  176.               break;
  177.             case ValueFloat:
  178.               errorLine(0,ErrorError,TRUE,"Linker does not understand float constants (%s).",sym->str);
  179.               v = (int) value.ValueFloat.f;
  180.               break;
  181.             case ValueString:
  182.               v = lexChar2Int(FALSE,value.ValueString.len,value.ValueString.s);
  183.               break;
  184.             case ValueBool:
  185.               v = value.ValueBool.b;
  186.               break;
  187.             case ValueCode:
  188.               errorLine(0,ErrorError,TRUE,"Linker does not understand code constants (%s).",sym->str);
  189.               v = 0;
  190.               break;
  191.             case ValueLateLabel:
  192.               if(!value.ValueLate.late->next &&                  /* Only one late label */
  193.                   value.ValueLate.late->factor == 1 &&           /* ... occuring one time */
  194.                   value.ValueLate.late->symbol->type & SYMBOL_AREA) { /* ... and it is an area */
  195.                 if(sym->type & SYMBOL_ABSOLUTE) { /* Change absolute to relative */
  196.                   sym->type &= ~SYMBOL_ABSOLUTE;
  197.                   v = value.ValueLate.i;
  198.                   sym->area.ptr = value.ValueLate.late->symbol;
  199.                 } else
  200.                   if(sym->area.ptr != value.ValueLate.late->symbol) 
  201.                     errorLine(0,ErrorError,TRUE,"Linker can not have 2 areas for the same symbol (%s).",sym->str);
  202.               } else {
  203.                 errorLine(0,ErrorError,TRUE,"Linker can not have many late labels for the same symbol (%s).",sym->str);
  204.               }
  205.               break;
  206.             default:
  207.               errorLine(0,ErrorSerious,FALSE,"Huh? This should not be possible.(%s)",sym->str);
  208.           }
  209.           asym.Value = v;
  210.           if((asym.Type = sym->type) & SYMBOL_ABSOLUTE)
  211.             asym.AreaName = 0;
  212.           else
  213.             asym.AreaName = sym->area.ptr->offset;
  214.         } else {
  215.           asym.Type = sym->type | TYPE_REFERENCE;
  216.           asym.Value = 0;
  217.           asym.AreaName = 0;
  218.         } 
  219.         fwrite((void *)&asym,sizeof(AofSymbol),1,outfile);
  220.       }
  221. }
  222.