home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / assembler / as / src / c / area next >
Encoding:
Text File  |  1993-03-07  |  4.2 KB  |  183 lines

  1. /*
  2.  * area.c
  3.  * Copyright © 1992 Niklas Röjemo
  4.  */
  5.  
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <ctype.h>
  9. #include <string.h>
  10. #include "lex.h"
  11. #include "hash.h"
  12. #include "symbol.h"
  13. #include "commands.h"
  14. #include "error.h"
  15. #include "input.h"
  16. #include "expr.h"
  17. #include "area.h"
  18.  
  19. #define DOUBLE_UP_TO 128*1024
  20. #define GROWSIZE      16*1024
  21.  
  22. Symbol *areaCurrent = 0;
  23. Symbol *areaEntry = 0;
  24. int     areaEntryOffset;
  25.  
  26. Symbol *areaHead = 0;
  27.  
  28. static Area *areaNew(int type)
  29. {
  30.   Area *res = malloc(sizeof(Area));
  31.   if(res) {
  32.     res->next = areaHead;
  33.     res->type = type | AREA_INIT;
  34.     res->imagesize = 0;
  35.     res->image = 0;
  36.     res->norelocs = 0;
  37.     res->relocs = 0;
  38.     res->lits = 0;
  39.   } else
  40.     error(ErrorSerious,FALSE,"Internal areaNew: Out of memory!.");
  41.   return res;
  42. }
  43.  
  44. static BOOL areaImage(Area *area,int newsize)
  45. {
  46.   char *new;
  47.   if(area->imagesize)
  48.     new = realloc(area->image,newsize);
  49.   else
  50.     new =  malloc(newsize);
  51.   if(new) {
  52.     area->imagesize = newsize;
  53.     area->image = new;
  54.     return TRUE;
  55.   } else
  56.     return FALSE;
  57.  
  58.  
  59. void areaGrow(Area *area,int mingrow)
  60. {
  61.  int inc;
  62.  if(area->imagesize && area->imagesize < DOUBLE_UP_TO)
  63.    inc = area->imagesize;
  64.  else
  65.    inc = GROWSIZE;
  66.  if(inc<mingrow)
  67.    inc = mingrow;
  68.  while(inc > mingrow && !areaImage(area,area->imagesize+inc)) {
  69.    inc = inc/2;
  70.  }
  71.  if(inc<=mingrow)
  72.    if(!areaImage(area,area->imagesize+mingrow))
  73.      error(ErrorSerious,FALSE,"Internal areaGrow: Out of memory, minsize = %d.",mingrow);
  74. }
  75.  
  76. void areaInit(void)
  77. {
  78.   areaCurrent = 0;
  79. }
  80.  
  81. void areaFinish(void)   /* insert ltorg at end of all areas */
  82. {
  83.   Symbol *ap;
  84.   for(ap = areaHead; ap; ap = ap->area.info->next) {
  85.     areaCurrent = ap;
  86.     litOrg(ap->area.info->lits);
  87.   }
  88. }
  89.  
  90. void c_entry(void)
  91. {
  92.   if(areaCurrent) {
  93.     if(areaEntry)
  94.       error(ErrorError,FALSE,"More than one entry.");
  95.     else {
  96.       areaEntry = areaCurrent;
  97.       areaEntryOffset = areaCurrent->value.ValueInt.i;
  98.     }
  99.   } else {
  100.     error(ErrorError,FALSE,"No area selected before entry.");
  101.   }
  102. }
  103.  
  104.  
  105. void c_align(void)         /* !!! Ought to do zero fill */
  106. {
  107.   Value value;
  108.   skipblanks();
  109.   if(!inputLook() || inputLook() == ';') { /* No expression follows */
  110.     areaCurrent->value.ValueInt.i = (areaCurrent->value.ValueInt.i+3) & ~3;
  111.   } else {    /* An expression follows */
  112.     exprBuild();
  113.     value = exprEval(ValueInt);
  114.     switch(value.Tag) {
  115.     case ValueInt:
  116.       areaCurrent->value.ValueInt.i = (areaCurrent->value.ValueInt.i+value.ValueInt.i-1)/value.ValueInt.i;
  117.       areaCurrent->value.ValueInt.i *= value.ValueInt.i;
  118.       break;
  119.     default:
  120.       error(ErrorError,TRUE,"Unresolved align not possible.");
  121.     }
  122.   }
  123. }
  124.  
  125. void c_reserve(void)         /* !!! Ought to do zero fill */
  126. {
  127.   Value value;
  128.   exprBuild();
  129.   value = exprEval(ValueInt);
  130.   switch(value.Tag) {
  131.   case ValueInt:
  132.     if(!areaCurrent)
  133.       error(ErrorSerious,TRUE,"No area defined.");
  134.     else 
  135.       areaCurrent->value.ValueInt.i += value.ValueInt.i;
  136.     break;
  137.   default:
  138.     error(ErrorError,TRUE,"Unresolved reserve not possible.");
  139.   }
  140. }
  141.  
  142. void c_area(void)
  143. {
  144.   Symbol *sym;
  145.   int oldtype = 0;
  146.   int newtype = 0;
  147.   int c;
  148.  
  149.   sym = symbolGet(lexGetId());
  150.   if(sym->type & SYMBOL_DEFINED) {
  151.     error(ErrorError,TRUE,"Redifinition of label to area %s.",sym->str);
  152.   } else if(sym->type == SYMBOL_AREA) {
  153.     oldtype = sym->area.info->type;
  154.   } else {
  155.     sym->type = SYMBOL_AREA;
  156.     sym->value.Tag = ValueInt;
  157.     sym->value.ValueInt.i = 0;
  158.     sym->area.info = areaNew(0);
  159.     areaHead = sym;
  160.   }
  161.   skipblanks();
  162.   while ((c=inputGet()) == ',') {
  163.     Lex attribute = lexGetId();
  164.     if(!strncmp("CODE",attribute.LexId.str,attribute.LexId.len))
  165.       newtype |= AREA_CODE | AREA_INIT;
  166.     else if(!strncmp("DATA",attribute.LexId.str,attribute.LexId.len))
  167.       newtype |= AREA_DATA | AREA_INIT;
  168.     else if(!strncmp("NOINIT",attribute.LexId.str,attribute.LexId.len))
  169.       newtype |= AREA_UDATA | AREA_INIT;
  170.     else if(!strncmp("READONLY",attribute.LexId.str,attribute.LexId.len))
  171.       newtype |= AREA_READONLY | AREA_INIT;
  172.     else
  173.       error(ErrorError,TRUE,"Illegal area attribute %s.",attribute.LexId.str);
  174.     skipblanks();
  175.   }
  176.   inputUnGet(c);
  177.   if(newtype && oldtype && newtype != oldtype)
  178.     error(ErrorError,TRUE,"Changing attribute of area %s.",sym->str);
  179.   sym->area.info->type |= newtype; 
  180.   areaCurrent = sym;
  181. }
  182.