/** * Implementation of universe.h * * Note: copied over the includes from interp.c, for now. */ #include #include #include "std-macros.h" #include "parse-tree.h" #include "tokens.h" #include "sym.h" #include "sym-aux.h" #include "type-preds.h" #include "type.h" #include "str.h" #include "interp.h" #include "list.h" #include "vlist.h" #include "universe.h" #include "options.h" int addcount = 0; /* * Initializes the universe structure by allocating memory, etc. TBD */ void InitUniverse() { ValueUniverse = AllocSymtab(UNIVERSE_SIZE); ValueUniverse->Level = 0; ValueUniverse->Offset = 0; } /* * Returns the size of the universe (gasp) */ int UniverseGetSize() { return (ValueUniverse ? ValueUniverse->Size : 0); } /* * Returns a ValueList that corresponds to the typename parameter. TBT */ ValueList UniverseGetValueList(char *typename) { ValueStruct v = UniverseGetValueStructFromType(typename); return (v != null) ? v->val.ListVal : null; } /* * Returns the ValueStruct at slot n, or null if nothing there. Note * that if we return something non-null, it will be a ListTag'd ValueStruct. */ ValueStruct UniverseGetValueStructAt(int n) { ValueStruct v = null; TypeSlot ts; /* if out of bounds, return null */ if ((n < 0) || (n >= UniverseGetSize())) return null; ts = ValueUniverse->Entries[n]; /* if something's here, return that ValueStruct */ if (ts) v = ts->Info.Consta.val; return v; } /* * Returns a ValueStruct that corresponds to the typename parameter. * Note that this ValueStruct will be a list. TBT */ ValueStruct UniverseGetValueStructFromType(char *typename) { ValueStruct v = null; TypeSlot typeslot = null; if (typename != null) { /* Look up the type name */ /* save off the current symtab */ PushSymtab(); CurSymtab = ValueUniverse; typeslot = LookupString(typename); /* if we got it back, return the corresponding value list */ if (typeslot) { v = typeslot->Info.Consta.val; } PopSymtab(); } return v; } /* * Returns the symbol at the nth type list, or null if nothing's there. */ char* UniverseGetSymbolAt(int n) { TypeSlot ts; /* if out of bounds, return null */ if ((n < 0) || (n >= UniverseGetSize())) return null; ts = ValueUniverse->Entries[n]; if (ts) return ts->Symbol; return null; } /* * Returns true if the universe has allocated a slot for typename. */ bool UniverseContainsType(char *typename) { /* * if UniverseGetValueList returns a non-null value, we have the type * in this value list. */ return (UniverseGetValueList(typename) != null); } /* * Returns true if the universe contains a value of type typename. TBT */ bool UniverseContainsValue(char *typename, ValueStruct value) { ValueList vlist = null; int i; if (typename != null) { /* get the value list */ if ((vlist = UniverseGetValueList(typename)) != null) { /* look through the list for value. if we find it, return true */ for (i = 1; i <= ListLen(vlist); i++) { if (ValueListEquals((ListElemData*)value, GetListNth(vlist, i))) return true; } // end for } // end if } // typename not null return false; } /* * Initializes a slot for typename in the value universe and returns * the newly created ValueList. TBT */ ValueList UniverseAddType(char *typename) { ValueList vlist = null; TypeSlot typeslot = null; /* * if we don't already have a type slot, allocate some memory * and create an empty list. */ if ((typename != null) && !UniverseContainsType(typename)) { /* set up the list structure */ ValueStruct listValueStruct = MakeVal(RVAL, NilType); listValueStruct->val.ListVal = vlist = NewList(); listValueStruct->tag = ListTag; /* save off the current symtab */ PushSymtab(); MoveToSymtab(ValueUniverse); typeslot = HashAllocSymtabEntry(typename, C_Const, null, 0); Enter(typeslot); typeslot->Info.Consta.val = listValueStruct; /* restore the symtab */ PopSymtab(); } return vlist; } /* * Adds value of type typename to the value universe. If a slot for * typename does not already exist, create one. * * if UniverseDuplicatesOn is not set, then before adding a value to the universe * then we'll search and ensure the value does not already exist. */ void UniverseAddValue1(char *typename, ValueStruct value) { ValueList vlist = null; if ((value == null) or (value->tag == NilTag)) { return; } if (typename != null) { if ((vlist = UniverseGetValueList(typename)) == null) { /* add a slot for this type */ vlist = UniverseAddType(typename); } /* if we aren't adding duplicates, let's check for existence first */ if (!UniverseDuplicatesOn()) { /* if the universe does not already contain this value */ if (!UniverseContainsValue(typename, value)) { /* add to end of the list */ PutList(vlist, (ListElemData*)value); } } // end if no duplicates else { /* add to end of the list */ PutList(vlist, (ListElemData*)value); } } // end if typename != null } /* * Adds value to the value universe. */ void UniverseAddValue(ValueStruct value) { if (value and value->tag != NilTag) { UniverseAddValue1(value->type->components.type.resolvedname, value); } } /* * For a given value list, returns the nth value. */ ValueStruct ValueListGetNth(ValueList list, int n) { return (ValueStruct)GetListNth(list, n); } /* * Returns the length of list */ int ValueListLength(ValueList list) { return ListLen(list); }