home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * symbol.c
- * Copyright © 1992 Niklas Röjemo
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "symbol.h"
- #include "global.h"
- #include "error.h"
- #include "AofFile.h"
- #include "code.h"
- #include "help_lex.h"
-
- static Symbol *symbolTabel[SYMBOL_TABELSIZE];
-
- static Symbol *symbolNew(int len,char *str)
- {
- Symbol *result;
- char *dst;
- if((result = (Symbol *)malloc(sizeof(Symbol)+len))!=0) {
- result->next = 0;
- result->type = result->offset = 0;
- result->value.Tag = ValueIllegal;
- result->used = -1;
- result->len = len;
- dst = &(result->str[0]);
- while(len--)
- *dst++ = *str++;
- *dst = 0;
- } else
- error(ErrorSerious,FALSE,"Inrenal symbolNew: Out of memory!");
- return result;
- }
-
- static BOOL EqSymLex(Symbol *str, Lex *lx)
- {
- char *s,*l;
- int i;
- if(str->len != lx->LexId.len)
- return FALSE;
- for(i = str->len, s = str->str, l = lx->LexId.str; i>0; i--)
- if(*s++ != *l++)
- return FALSE;
- return TRUE;
- }
-
- static char er[1024];
-
-
- Symbol *symbolAdd(Lex l)
- {
- Symbol **isearch = &symbolTabel[l.LexId.hash];
- if(l.tag != LexId)
- error(ErrorSerious,FALSE,"Internal symbolAdd: Non-Id.");
- while(*isearch) {
- if(EqSymLex(*isearch,&l)) {
- if((*isearch)->type & SYMBOL_DEFINED) {
- strncpy(er,l.LexId.str,l.LexId.len);
- er[l.LexId.len] = 0;
- error(ErrorError,TRUE,"Reddefinition of %s",er);
- } else {
- if((*isearch)->type & SYMBOL_AREA) {
- strncpy(er,l.LexId.str,l.LexId.len);
- er[l.LexId.len] = 0;
- error(ErrorError,TRUE,"Area %s is already defined",er);
- } else {
- (*isearch)->type |= SYMBOL_DEFINED;
- return *isearch;
- }
- }
- }
- isearch = &((*isearch)->next);
- }
- *isearch = symbolNew(l.LexId.len,l.LexId.str);
- (*isearch)->type |= SYMBOL_DEFINED;
- return *isearch;
- }
-
- Symbol *symbolGet(Lex l)
- {
- Symbol **isearch;
- if(l.tag != LexId) {
- if(l.tag == LexNone) {
- isearch = &symbolTabel[0];
- while(*isearch)
- isearch = &((*isearch)->next);
- *isearch = symbolNew(7,"|Dummy|");
- } else
- error(ErrorSerious,FALSE,"Internal symbolGet: Non-Id.");
- } else {
- isearch = &symbolTabel[l.LexId.hash];
- while(*isearch) {
- if(EqSymLex(*isearch,&l))
- return *isearch;
- else
- isearch = &((*isearch)->next);
- }
- }
- *isearch = symbolNew(l.LexId.len,l.LexId.str);
- return *isearch;
- }
-
- static int stringtabelsize = -1;
-
- int symbolFix(void) /* Returns number of symbols */
- {
- int nosym = 0;
- int strsize = 4; /* Always contains its length */
- int i;
- Symbol *sym;
-
- for(i=0; i<SYMBOL_TABELSIZE; i++) {
- for(sym = symbolTabel[i]; sym; sym = sym->next){
- if(sym->type == SYMBOL_AREA) {
- sym->offset = strsize;
- strsize += sym->len+1;
- } else if(sym->used >= 0 || sym->type & SYMBOL_REFERENCE) {
- sym->offset = strsize;
- strsize += sym->len+1;
- sym->used = nosym++;
- }
- }
- }
- stringtabelsize = strsize;
- return nosym;
- }
-
- int symbolStringSize(void)
- {
- if(stringtabelsize<0)
- error(ErrorSerious,FALSE,"Internal error stringtabelsize < 0.\n");
- return stringtabelsize;
- }
-
- void symbolStringOutput(FILE *outfile) /* Count already output */
- {
- int i;
- Symbol *sym;
-
- for(i=0; i<SYMBOL_TABELSIZE; i++)
- for(sym = symbolTabel[i]; sym; sym = sym->next)
- if(sym->used >= 0 || sym->type == SYMBOL_AREA)
- fwrite((void *)sym->str,1,sym->len+1,outfile);
-
- }
-
- void symbolSymbolOutput(FILE *outfile)
- {
- int i;
- Symbol *sym;
- Value value;
- int v;
- AofSymbol asym;
-
- for(i=0; i<SYMBOL_TABELSIZE; i++)
- for(sym = symbolTabel[i]; sym; sym = sym->next)
- if(sym->type != SYMBOL_AREA && sym->used >= 0) {
- asym.Name = sym->offset;
- if(sym->type & SYMBOL_DEFINED) {
- if(sym->value.Tag == ValueCode) {
- codeInit();
- value = codeEvalLow(ValueAll,sym->value.ValueCode.len,sym->value.ValueCode.c);
- } else {
- value = sym->value;
- }
- switch(value.Tag) {
- case ValueIllegal:
- errorLine(0,ErrorError,TRUE,"Symbol %s can not be evaluated.",sym->str);
- v = 0;
- break;
- case ValueInt:
- v = value.ValueInt.i;
- break;
- case ValueFloat:
- errorLine(0,ErrorError,TRUE,"Linker does not understand float constants (%s).",sym->str);
- v = (int) value.ValueFloat.f;
- break;
- case ValueString:
- v = lexChar2Int(FALSE,value.ValueString.len,value.ValueString.s);
- break;
- case ValueBool:
- v = value.ValueBool.b;
- break;
- case ValueCode:
- errorLine(0,ErrorError,TRUE,"Linker does not understand code constants (%s).",sym->str);
- v = 0;
- break;
- case ValueLateLabel:
- if(!value.ValueLate.late->next && /* Only one late label */
- value.ValueLate.late->factor == 1 && /* ... occuring one time */
- value.ValueLate.late->symbol->type & SYMBOL_AREA) { /* ... and it is an area */
- if(sym->type & SYMBOL_ABSOLUTE) { /* Change absolute to relative */
- sym->type &= ~SYMBOL_ABSOLUTE;
- v = value.ValueLate.i;
- sym->area.ptr = value.ValueLate.late->symbol;
- } else
- if(sym->area.ptr != value.ValueLate.late->symbol)
- errorLine(0,ErrorError,TRUE,"Linker can not have 2 areas for the same symbol (%s).",sym->str);
- } else {
- errorLine(0,ErrorError,TRUE,"Linker can not have many late labels for the same symbol (%s).",sym->str);
- }
- break;
- default:
- errorLine(0,ErrorSerious,FALSE,"Huh? This should not be possible.(%s)",sym->str);
- }
- asym.Value = v;
- if((asym.Type = sym->type) & SYMBOL_ABSOLUTE)
- asym.AreaName = 0;
- else
- asym.AreaName = sym->area.ptr->offset;
- } else {
- asym.Type = sym->type | TYPE_REFERENCE;
- asym.Value = 0;
- asym.AreaName = 0;
- }
- fwrite((void *)&asym,sizeof(AofSymbol),1,outfile);
- }
- }
-