home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * value.c
- * Copyright © 1992 Niklas Röjemo
- */
-
- #include <stdlib.h>
- #include <string.h>
- #include "value.h"
- #include "code.h"
- #include "error.h"
-
- /* Code demands at least one Lateinfo */
- Value valueLateToCode(int offset,LateInfo *late)
- {
- LateInfo *l;
- Value value;
- int factor;
- int size;
-
- for(size=1, l= late; l; l= l->next) {
- if((factor = l->factor) == -1 || factor == 1)
- size += 2;
- else if(factor != 0)
- size += 4;
- }
- if(offset == 0) {
- size -= 2; /* No need to include offset ... */
- if(late->factor == -1) size++; /* ... but must insert an unary - */
- }
- value.ValueCode.c = malloc(size*sizeof(Code));
-
- if(value.ValueCode.c) {
- value.Tag = ValueCode;
- value.ValueCode.len = size;
- size = 0;
- if(offset != 0) {
- value.ValueCode.c[size ].Tag = CodeValue;
- value.ValueCode.c[size ].CodeValue.value.Tag = ValueInt;
- value.ValueCode.c[size++].CodeValue.value.ValueInt.i = offset;
- }
- for(l=late; l; l=l->next) {
- if((factor = l->factor) == -1 || factor == 1) {
- value.ValueCode.c[size ].Tag = CodeSymbol;
- value.ValueCode.c[size++].CodeSymbol.symbol = l->symbol;
- if(size != 1) { /* Add offset */
- value.ValueCode.c[size ].Tag = CodeOperator;
- value.ValueCode.c[size++].CodeOperator.op = (factor>0?Op_add:Op_sub);
- } else if(factor == -1) {
- value.ValueCode.c[size ].Tag = CodeOperator;
- value.ValueCode.c[size++].CodeOperator.op = Op_neg;
- }
- } else if(factor != 0) {
- value.ValueCode.c[size ].Tag = CodeSymbol;
- value.ValueCode.c[size++].CodeSymbol.symbol = l->symbol;
- value.ValueCode.c[size ].Tag = CodeValue;
- value.ValueCode.c[size ].CodeValue.value.Tag = ValueInt;
- value.ValueCode.c[size++].CodeValue.value.ValueInt.i = factor;
- value.ValueCode.c[size ].Tag = CodeOperator;
- value.ValueCode.c[size++].CodeOperator.op = Op_mul;
- if(size != 3) { /* Add offset */
- value.ValueCode.c[size ].Tag = CodeOperator;
- value.ValueCode.c[size++].CodeOperator.op = Op_add;
- }
- }
- }
- } else {
- error(ErrorSerious,FALSE,"Out of memory in valueLateToCode.");
- value.Tag = ValueIllegal;
- }
- return value;
- }
-
-
- Value valueCopy(Value value)
- {
- switch(value.Tag) {
- case ValueIllegal:
- case ValueInt:
- case ValueFloat:
- case ValueBool:
- break;;
- case ValueString:
- error(ErrorSerious,FALSE,"Internal valueCopy: Can not handle string.");
- break;
- case ValueCode:
- value.ValueCode.c = codeCopy(value.ValueCode.len,value.ValueCode.c);
- break;
- case ValueLateLabel:
- value = valueLateToCode(value.ValueLate.i,value.ValueLate.late);
- break;
- default:
- error(ErrorSerious,FALSE,"Internal valueCopy: Illegal value.");
- value.Tag = ValueIllegal;
- }
- return value;
- }
-
- void valueFree(Value value)
- {
- switch(value.Tag) {
- case ValueIllegal:
- case ValueInt:
- case ValueFloat:
- case ValueBool:
- break;
- case ValueString:
- error(ErrorSerious,FALSE,"Internal valueFree: Can not handle string.");
- break;
- case ValueCode:
- free(value.ValueCode.c);
- break;
- case ValueLateLabel:
- error(ErrorSerious,FALSE,"Internal valueFree: Can not handle late label.");
- break;
- default:
- error(ErrorSerious,FALSE,"Internal valueFree: Illegal value.");
- }
- }
-
- static int lateInfoEqual(LateInfo *a, LateInfo *b)
- {
- for(; a || b; a = a->next, b = b->next) {
- if(!a || !b) return FALSE;
- if(a->factor != b->factor) return FALSE;
- if(a->symbol != b->symbol) return FALSE;
- }
- return TRUE;
- }
-
- int valueEqual(Value *a, Value *b)
- {
- if(a->Tag == ValueLateLabel) { /* Prevent valueEqual(ValueLateLabel,ValueCode) */
- Value *t = a; a = b; b = t;
- }
- switch(a->Tag) {
- case ValueIllegal: return b->Tag == ValueIllegal;
- case ValueInt: return b->Tag == ValueInt && a->ValueInt.i == b->ValueInt.i;
- case ValueFloat: return b->Tag == ValueFloat && a->ValueFloat.f == b->ValueFloat.f;
- case ValueBool: return b->Tag == ValueBool && a->ValueBool.b == b->ValueBool.b;
- case ValueString:
- return b->Tag == ValueString &&
- a->ValueString.len == b->ValueString.len &&
- !memcmp(a->ValueString.s,b->ValueString.s,a->ValueString.len);
- case ValueCode:
- if(b->Tag == ValueLateLabel) {
- Value v = valueLateToCode(b->ValueLate.i,b->ValueLate.late);
- int res = a->ValueCode.len == v.ValueCode.len &&
- codeEqual(a->ValueCode.len,a->ValueCode.c,v.ValueCode.c);
- valueFree(v);
- return res;
- } else {
- return b->Tag == ValueCode &&
- a->ValueCode.len == b->ValueCode.len &&
- codeEqual(a->ValueCode.len,a->ValueCode.c,b->ValueCode.c);
- }
- case ValueLateLabel:
- return b->Tag == ValueLateLabel &&
- a->ValueLate.i == b->ValueLate.i &&
- lateInfoEqual(a->ValueLate.late,b->ValueLate.late);
- default:
- error(ErrorSerious,FALSE,"Internal valueEqual: Illegal value.");
- }
- return FALSE;
- }
-