/*************************************************** NAME : BsaveDefaultSlotExpressions DESCRIPTION : Writes expressions for default slot values to binary file INPUTS : 1) The defclass 2) The binary file pointer RETURNS : Nothing useful SIDE EFFECTS : Slot value expressions written NOTES : None ***************************************************/ static void BsaveDefaultSlotExpressions( struct constructHeader *theDefclass, void *buf) { DEFCLASS *cls = (DEFCLASS *) theDefclass; register unsigned i; EXPRESSION *tmpexp; for (i = 0 ; i < cls->slotCount ; i++) { if (cls->slots[i].defaultValue != NULL) { if (cls->slots[i].dynamicDefault) BsaveExpression((EXPRESSION *) cls->slots[i].defaultValue,(FILE *) buf); else { /* ================================================= Static default values are stotred as data objects and must be converted into expressions ================================================= */ tmpexp = ConvertValueToExpression((DATA_OBJECT *) cls->slots[i].defaultValue); BsaveExpression(tmpexp,(FILE *) buf); ReturnExpression(tmpexp); } } } }
/*************************************************** NAME : BsaveSlots DESCRIPTION : Writes class slots binary data INPUTS : 1) The defclass 2) The binary file pointer RETURNS : Nothing useful SIDE EFFECTS : Defclass slots binary data written NOTES : None ***************************************************/ static void BsaveSlots( struct constructHeader *theDefclass, void *buf) { DEFCLASS *cls = (DEFCLASS *) theDefclass; register unsigned i; BSAVE_SLOT_DESC dummy_slot; SLOT_DESC *sp; EXPRESSION *tmpexp; for (i = 0 ; i < cls->slotCount ; i++) { sp = &cls->slots[i]; dummy_slot.dynamicDefault = sp->dynamicDefault; dummy_slot.noDefault = sp->noDefault; dummy_slot.shared = sp->shared; dummy_slot.multiple = sp->multiple; dummy_slot.composite = sp->composite; dummy_slot.noInherit = sp->noInherit; dummy_slot.noWrite = sp->noWrite; dummy_slot.initializeOnly = sp->initializeOnly; dummy_slot.reactive = sp->reactive; dummy_slot.publicVisibility = sp->publicVisibility; dummy_slot.createReadAccessor = sp->createReadAccessor; dummy_slot.createWriteAccessor = sp->createWriteAccessor; dummy_slot.cls = DefclassIndex(sp->cls); dummy_slot.slotName = SlotNameIndex(sp->slotName); dummy_slot.overrideMessage = (long) sp->overrideMessage->bucket; if (sp->defaultValue != NULL) { dummy_slot.defaultValue = ExpressionCount; if (sp->dynamicDefault) ExpressionCount += ExpressionSize((EXPRESSION *) sp->defaultValue); else { tmpexp = ConvertValueToExpression((DATA_OBJECT *) sp->defaultValue); ExpressionCount += ExpressionSize(tmpexp); ReturnExpression(tmpexp); } } else dummy_slot.defaultValue = -1L; dummy_slot.constraint = ConstraintIndex(sp->constraint); GenWrite((void *) &dummy_slot,(UNLN) sizeof(BSAVE_SLOT_DESC),(FILE *) buf); } }
static struct expr *GetSlotAssertValues( struct templateSlot *slotPtr, struct expr *firstSlot, int *error) { struct expr *slotItem; struct expr *newArg, *tempArg; DATA_OBJECT theDefault; char *nullBitMap = "\0"; /*==================================================*/ /* Determine if the slot is assigned in the assert. */ /*==================================================*/ slotItem = FindAssertSlotItem(slotPtr,firstSlot); /*==========================================*/ /* If the slot is assigned, use that value. */ /*==========================================*/ if (slotItem != NULL) { newArg = slotItem->argList; slotItem->argList = NULL; } /*=================================*/ /* Otherwise, use a default value. */ /*=================================*/ else { /*================================================*/ /* If the (default ?NONE) attribute was specified */ /* for the slot, then a value must be supplied. */ /*================================================*/ if (slotPtr->noDefault) { PrintErrorID("TMPLTRHS",1,TRUE); PrintRouter(WERROR,"Slot "); PrintRouter(WERROR,slotPtr->slotName->contents); PrintRouter(WERROR," requires a value because of its (default ?NONE) attribute.\n"); *error = TRUE; return(NULL); } /*===================================================*/ /* If the (default ?DERIVE) attribute was specified */ /* (the default), then derive the default value from */ /* the slot's constraints. */ /*===================================================*/ else if ((slotPtr->defaultPresent == FALSE) && (slotPtr->defaultDynamic == FALSE)) { DeriveDefaultFromConstraints(slotPtr->constraints,&theDefault, (int) slotPtr->multislot); newArg = ConvertValueToExpression(&theDefault); } /*=========================================*/ /* Otherwise, use the expression contained */ /* in the default attribute. */ /*=========================================*/ else { newArg = CopyExpression(slotPtr->defaultList); } } /*=======================================================*/ /* Since a multifield slot default can contain a list of */ /* values, the values need to have a store-multifield */ /* function called wrapped around it to group all of the */ /* values into a single multifield value. */ /*=======================================================*/ if (slotPtr->multislot) { tempArg = GenConstant(FACT_STORE_MULTIFIELD,AddBitMap((void *) nullBitMap,1)); tempArg->argList = newArg; newArg = tempArg; } /*==============================================*/ /* Return the value to be asserted in the slot. */ /*==============================================*/ return(newArg); }
static void MarkDefclassItems( struct constructHeader *theDefclass, void *buf) { #if MAC_MPW || MAC_MCW || IBM_MCW #pragma unused(buf) #endif DEFCLASS *cls = (DEFCLASS *) theDefclass; register unsigned i; EXPRESSION *tmpexp; MarkConstructHeaderNeededItems(&cls->header,ClassCount++); LinkCount += cls->directSuperclasses.classCount + cls->directSubclasses.classCount + cls->allSuperclasses.classCount; #if DEFMODULE_CONSTRUCT cls->scopeMap->neededBitMap = TRUE; #endif /* =================================================== Mark items needed by slot default value expressions =================================================== */ for (i = 0 ; i < cls->slotCount ; i++) { cls->slots[i].bsaveIndex = SlotCount++; cls->slots[i].overrideMessage->neededSymbol = TRUE; if (cls->slots[i].defaultValue != NULL) { if (cls->slots[i].dynamicDefault) { ExpressionCount += ExpressionSize((EXPRESSION *) cls->slots[i].defaultValue); MarkNeededItems((EXPRESSION *) cls->slots[i].defaultValue); } else { /* ================================================= Static default values are stotred as data objects and must be converted into expressions ================================================= */ tmpexp = ConvertValueToExpression((DATA_OBJECT *) cls->slots[i].defaultValue); ExpressionCount += ExpressionSize(tmpexp); MarkNeededItems(tmpexp); ReturnExpression(tmpexp); } } } /* ======================================== Count canonical slots needed by defclass ======================================== */ TemplateSlotCount += cls->instanceSlotCount; if (cls->instanceSlotCount != 0) SlotNameMapCount += cls->maxSlotNameID + 1; /* =============================================== Mark items needed by defmessage-handler actions =============================================== */ for (i = 0 ; i < cls->handlerCount ; i++) { cls->handlers[i].name->neededSymbol = TRUE; ExpressionCount += ExpressionSize(cls->handlers[i].actions); MarkNeededItems(cls->handlers[i].actions); } HandlerCount += cls->handlerCount; }
globle struct expr *ParseDefault( void *theEnv, char *readSource, int multifield, int dynamic, int evalStatic, int *noneSpecified, int *deriveSpecified, int *error) { struct expr *defaultList = NULL, *lastDefault = NULL; struct expr *newItem, *tmpItem; struct token theToken; DATA_OBJECT theValue; CONSTRAINT_RECORD *rv; int specialVarCode; *noneSpecified = FALSE; *deriveSpecified = FALSE; SavePPBuffer(theEnv,(char*)" "); GetToken(theEnv,readSource,&theToken); /*===================================================*/ /* Read the items contained in the default attribute */ /* until a closing right parenthesis is encountered. */ /*===================================================*/ while (theToken.type != RPAREN) { /*========================================*/ /* Get the next item in the default list. */ /*========================================*/ newItem = ParseAtomOrExpression(theEnv,readSource,&theToken); if (newItem == NULL) { ReturnExpression(theEnv,defaultList); *error = TRUE; return(NULL); } /*===========================================================*/ /* Check for invalid variable usage. With the expection of */ /* ?NONE for the default attribute, local variables may not */ /* be used within the default or default-dynamic attributes. */ /*===========================================================*/ if ((newItem->type == SF_VARIABLE) || (newItem->type == MF_VARIABLE)) { if (strcmp(ValueToString(newItem->value),"NONE") == 0) { specialVarCode = 0; } else if (strcmp(ValueToString(newItem->value),"DERIVE") == 0) { specialVarCode = 1; } else { specialVarCode = -1; } if ((dynamic) || (newItem->type == MF_VARIABLE) || (specialVarCode == -1) || ((specialVarCode != -1) && (defaultList != NULL))) { if (dynamic) SyntaxErrorMessage(theEnv,(char*)"default-dynamic attribute"); else SyntaxErrorMessage(theEnv,(char*)"default attribute"); ReturnExpression(theEnv,newItem); ReturnExpression(theEnv,defaultList); *error = TRUE; return(NULL); } ReturnExpression(theEnv,newItem); /*============================================*/ /* Check for the closing right parenthesis of */ /* the default or default dynamic attribute. */ /*============================================*/ GetToken(theEnv,readSource,&theToken); if (theToken.type != RPAREN) { if (dynamic) SyntaxErrorMessage(theEnv,(char*)"default-dynamic attribute"); else SyntaxErrorMessage(theEnv,(char*)"default attribute"); PPBackup(theEnv); SavePPBuffer(theEnv,(char*)" "); SavePPBuffer(theEnv,theToken.printForm); *error = TRUE; } if (specialVarCode == 0) *noneSpecified = TRUE; else *deriveSpecified = TRUE; return(NULL); } /*====================================================*/ /* Look to see if any variables have been used within */ /* expressions contained within the default list. */ /*====================================================*/ if (ExpressionContainsVariables(newItem,FALSE) == TRUE) { ReturnExpression(theEnv,defaultList); ReturnExpression(theEnv,newItem); *error = TRUE; if (dynamic) SyntaxErrorMessage(theEnv,(char*)"default-dynamic attribute"); else SyntaxErrorMessage(theEnv,(char*)"default attribute"); return(NULL); } /*============================================*/ /* Add the default value to the default list. */ /*============================================*/ if (lastDefault == NULL) { defaultList = newItem; } else { lastDefault->nextArg = newItem; } lastDefault = newItem; /*=======================================*/ /* Begin parsing the next default value. */ /*=======================================*/ SavePPBuffer(theEnv,(char*)" "); GetToken(theEnv,readSource,&theToken); } /*=====================================*/ /* Fix up pretty print representation. */ /*=====================================*/ PPBackup(theEnv); PPBackup(theEnv); SavePPBuffer(theEnv,(char*)")"); /*=========================================*/ /* A single field slot's default attribute */ /* must contain a single value. */ /*=========================================*/ if (multifield == FALSE) { if (defaultList == NULL) { *error = TRUE; } else if (defaultList->nextArg != NULL) { *error = TRUE; } else { rv = ExpressionToConstraintRecord(theEnv,defaultList); rv->multifieldsAllowed = FALSE; if (UnmatchableConstraint(rv)) *error = TRUE; RemoveConstraint(theEnv,rv); } if (*error) { PrintErrorID(theEnv,(char*)"DEFAULT",1,TRUE); EnvPrintRouter(theEnv,WERROR,(char*)"The default value for a single field slot must be a single field value\n"); ReturnExpression(theEnv,defaultList); return(NULL); } } /*=======================================================*/ /* If the dynamic-default attribute is not being parsed, */ /* evaluate the expressions to make the default value. */ /*=======================================================*/ if (dynamic || (! evalStatic) || (defaultList == NULL)) return(defaultList); tmpItem = defaultList; newItem = defaultList; defaultList = NULL; while (newItem != NULL) { SetEvaluationError(theEnv,FALSE); if (EvaluateExpression(theEnv,newItem,&theValue)) *error = TRUE; if ((theValue.type == MULTIFIELD) && (multifield == FALSE) && (*error == FALSE)) { PrintErrorID(theEnv,(char*)"DEFAULT",1,TRUE); EnvPrintRouter(theEnv,WERROR,(char*)"The default value for a single field slot must be a single field value\n"); *error = TRUE; } if (*error) { ReturnExpression(theEnv,tmpItem); ReturnExpression(theEnv,defaultList); *error = TRUE; return(NULL); } lastDefault = ConvertValueToExpression(theEnv,&theValue); defaultList = AppendExpressions(defaultList,lastDefault); newItem = newItem->nextArg; } ReturnExpression(theEnv,tmpItem); /*==========================*/ /* Return the default list. */ /*==========================*/ return(defaultList); }