home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 2 / RISC_DISC_2.iso / pd_share / program / language / as / source / c / value < prev   
Encoding:
Text File  |  1993-03-07  |  5.0 KB  |  166 lines

  1.  
  2. /*
  3.  * value.c
  4.  * Copyright © 1992 Niklas Röjemo
  5.  */
  6.  
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "value.h"
  10. #include "code.h"
  11. #include "error.h"
  12.  
  13. /* Code demands at least one Lateinfo */
  14. Value valueLateToCode(int offset,LateInfo *late)
  15. {
  16.   LateInfo *l;
  17.   Value value;
  18.   int factor;
  19.   int size;
  20.  
  21.   for(size=1, l= late; l; l= l->next) {
  22.     if((factor = l->factor) == -1 || factor == 1)
  23.       size += 2;
  24.     else if(factor != 0)
  25.       size += 4;
  26.   }
  27.   if(offset == 0) {
  28.     size -= 2;                       /* No need to include offset ... */
  29.     if(late->factor == -1) size++;   /* ... but must insert an unary - */
  30.   }
  31.   value.ValueCode.c = malloc(size*sizeof(Code));
  32.   
  33.   if(value.ValueCode.c) {
  34.     value.Tag = ValueCode;
  35.     value.ValueCode.len = size;
  36.     size = 0;
  37.     if(offset != 0) {
  38.       value.ValueCode.c[size  ].Tag = CodeValue;
  39.       value.ValueCode.c[size  ].CodeValue.value.Tag = ValueInt;
  40.       value.ValueCode.c[size++].CodeValue.value.ValueInt.i = offset;
  41.     }
  42.     for(l=late; l; l=l->next) {
  43.       if((factor = l->factor) == -1 || factor == 1) {
  44.         value.ValueCode.c[size  ].Tag = CodeSymbol;
  45.         value.ValueCode.c[size++].CodeSymbol.symbol = l->symbol;
  46.         if(size != 1) { /* Add offset */
  47.           value.ValueCode.c[size  ].Tag = CodeOperator;
  48.           value.ValueCode.c[size++].CodeOperator.op = (factor>0?Op_add:Op_sub);
  49.         } else if(factor == -1) {
  50.           value.ValueCode.c[size  ].Tag = CodeOperator;
  51.           value.ValueCode.c[size++].CodeOperator.op = Op_neg;
  52.         }
  53.       } else if(factor != 0) {
  54.         value.ValueCode.c[size  ].Tag = CodeSymbol;
  55.         value.ValueCode.c[size++].CodeSymbol.symbol = l->symbol;
  56.         value.ValueCode.c[size  ].Tag = CodeValue;
  57.         value.ValueCode.c[size  ].CodeValue.value.Tag = ValueInt;
  58.         value.ValueCode.c[size++].CodeValue.value.ValueInt.i = factor;
  59.         value.ValueCode.c[size  ].Tag = CodeOperator;
  60.         value.ValueCode.c[size++].CodeOperator.op = Op_mul;
  61.         if(size != 3) { /* Add offset */
  62.           value.ValueCode.c[size  ].Tag = CodeOperator;
  63.           value.ValueCode.c[size++].CodeOperator.op = Op_add;
  64.         }
  65.       }
  66.     }
  67.   } else {
  68.     error(ErrorSerious,FALSE,"Out of memory in valueLateToCode.");
  69.     value.Tag = ValueIllegal;
  70.   }
  71.   return value;
  72. }
  73.  
  74.  
  75. Value valueCopy(Value value)
  76. {
  77.   switch(value.Tag) {
  78.     case ValueIllegal:
  79.     case ValueInt:
  80.     case ValueFloat:
  81.     case ValueBool:
  82.       break;;
  83.     case ValueString:
  84.       error(ErrorSerious,FALSE,"Internal valueCopy: Can not handle string.");
  85.       break;
  86.     case ValueCode:
  87.       value.ValueCode.c = codeCopy(value.ValueCode.len,value.ValueCode.c);
  88.       break;
  89.     case ValueLateLabel:
  90.       value = valueLateToCode(value.ValueLate.i,value.ValueLate.late);
  91.       break;
  92.     default:
  93.       error(ErrorSerious,FALSE,"Internal valueCopy: Illegal value.");
  94.       value.Tag = ValueIllegal;
  95.   }
  96.   return value;
  97. }
  98.  
  99. void valueFree(Value value)
  100. {
  101.   switch(value.Tag) {
  102.     case ValueIllegal:
  103.     case ValueInt:
  104.     case ValueFloat:
  105.     case ValueBool:
  106.       break;
  107.     case ValueString:
  108.       error(ErrorSerious,FALSE,"Internal valueFree: Can not handle string.");
  109.       break;
  110.     case ValueCode:
  111.       free(value.ValueCode.c);
  112.       break;
  113.     case ValueLateLabel:
  114.       error(ErrorSerious,FALSE,"Internal valueFree: Can not handle late label.");
  115.       break;
  116.     default:
  117.       error(ErrorSerious,FALSE,"Internal valueFree: Illegal value.");
  118.   }
  119. }
  120.  
  121. static int lateInfoEqual(LateInfo *a, LateInfo *b)
  122. {
  123.   for(; a || b; a = a->next, b = b->next) {
  124.     if(!a || !b)               return FALSE;
  125.     if(a->factor != b->factor) return FALSE;
  126.     if(a->symbol != b->symbol) return FALSE;
  127.   }
  128.   return TRUE;
  129. }
  130.  
  131. int valueEqual(Value *a, Value *b)
  132. {
  133.   if(a->Tag == ValueLateLabel) { /* Prevent valueEqual(ValueLateLabel,ValueCode) */
  134.     Value *t = a; a = b; b = t;
  135.   }
  136.   switch(a->Tag) {
  137.     case ValueIllegal: return b->Tag == ValueIllegal;
  138.     case ValueInt:     return b->Tag == ValueInt    && a->ValueInt.i   == b->ValueInt.i;
  139.     case ValueFloat:   return b->Tag == ValueFloat  && a->ValueFloat.f == b->ValueFloat.f;
  140.     case ValueBool:    return b->Tag == ValueBool   && a->ValueBool.b  == b->ValueBool.b;
  141.     case ValueString:
  142.       return b->Tag == ValueString && 
  143.         a->ValueString.len  == b->ValueString.len &&
  144.         !memcmp(a->ValueString.s,b->ValueString.s,a->ValueString.len);
  145.     case ValueCode:
  146.       if(b->Tag == ValueLateLabel) {
  147.         Value v = valueLateToCode(b->ValueLate.i,b->ValueLate.late);
  148.         int res = a->ValueCode.len == v.ValueCode.len &&
  149.                   codeEqual(a->ValueCode.len,a->ValueCode.c,v.ValueCode.c);
  150.         valueFree(v);
  151.         return res;
  152.       } else {
  153.        return b->Tag == ValueCode && 
  154.               a->ValueCode.len == b->ValueCode.len &&
  155.               codeEqual(a->ValueCode.len,a->ValueCode.c,b->ValueCode.c);
  156.       }
  157.     case ValueLateLabel:
  158.        return b->Tag == ValueLateLabel &&
  159.               a->ValueLate.i   == b->ValueLate.i &&
  160.               lateInfoEqual(a->ValueLate.late,b->ValueLate.late);
  161.     default:
  162.       error(ErrorSerious,FALSE,"Internal valueEqual: Illegal value.");
  163.   }
  164.   return FALSE;
  165. }
  166.