int prEvent_IsRest(struct VMGlobals *g, int numArgsPushed) { PyrSlot *dictslots = slotRawObject(g->sp)->slots; PyrSlot *arraySlot = dictslots + ivxIdentDict_array; if (isKindOfSlot(arraySlot, class_array)) { PyrSlot key, typeSlot; static PyrSymbol *s_type = getsym("type"); static PyrSymbol *s_rest = getsym("rest"); PyrSymbol *typeSym; // test 'this[\type] == \rest' first SetSymbol(&key, s_type); identDict_lookup(slotRawObject(g->sp), &key, calcHash(&key), &typeSlot); if(!slotSymbolVal(&typeSlot, &typeSym) && typeSym == s_rest) { SetBool(g->sp, 1); return errNone; } else { PyrObject *array = slotRawObject(arraySlot); PyrSymbol *slotSym; static PyrSymbol *s_empty = getsym(""); static PyrSymbol *s_r = getsym("r"); static PyrClass *class_rest = getsym("Rest")->u.classobj; static PyrClass *class_metarest = getsym("Meta_Rest")->u.classobj; PyrSlot *slot; int32 size = array->size; int32 i; slot = array->slots + 1; // scan only the odd items for (i = 1; i < size; i += 2, slot += 2) { if (isKindOfSlot(slot, class_rest) || isKindOfSlot(slot, class_metarest) ) { SetBool(g->sp, 1); return errNone; } else if(!slotSymbolVal(slot, &slotSym)) { if(slotSym == s_empty || slotSym == s_r || slotSym == s_rest ) { SetBool(g->sp, 1); return errNone; } } // why no 'else'? // slotSymbolVal nonzero return = not a symbol; // non-symbols don't indicate rests, so, ignore them. } } } else { return errWrongType; } SetBool(g->sp, 0); return errNone; }
int prEvent_Delta(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a, key, dur, stretch, delta; double fdur, fstretch; int err; a = g->sp; // dict SetSymbol(&key, s_delta); identDict_lookup(slotRawObject(a), &key, calcHash(&key), &delta); if (NotNil(&delta)) { slotCopy(a,&delta); } else { SetSymbol(&key, s_dur); identDict_lookup(slotRawObject(a), &key, calcHash(&key), &dur); err = slotDoubleVal(&dur, &fdur); if (err) { if (NotNil(&dur)) return err; SetNil(a); return errNone; } SetSymbol(&key, s_stretch); identDict_lookup(slotRawObject(a), &key, calcHash(&key), &stretch); err = slotDoubleVal(&stretch, &fstretch); if (err) { if (NotNil(&stretch)) return err; SetFloat(a, fdur); return errNone; } SetFloat(a, fdur * fstretch ); } return errNone; }
int prEvent_IsRest(struct VMGlobals *g, int numArgsPushed) { PyrSlot *dictslots = slotRawObject(g->sp)->slots; PyrSlot *arraySlot = dictslots + ivxIdentDict_array; static int isRestCount = 0; if (!isKindOfSlot(arraySlot, class_array)) { return errWrongType; } PyrSlot key, typeSlot; PyrSymbol *typeSym; // easy tests first: 'this[\type] == \rest' SetSymbol(&key, s_type); identDict_lookup(slotRawObject(g->sp), &key, calcHash(&key), &typeSlot); if(!slotSymbolVal(&typeSlot, &typeSym) && typeSym == s_rest) { SetBool(g->sp, 1); return errNone; } // and, 'this[\isRest] == true' SetSymbol(&key, s_isRest); identDict_lookup(slotRawObject(g->sp), &key, calcHash(&key), &typeSlot); if(IsTrue(&typeSlot)) { if (isRestCount == 0) post("\nWARNING: Setting isRest to true in an event is deprecated. See the Rest helpfile for supported ways to specify rests.\n\n"); isRestCount = (isRestCount + 1) % 100; SetBool(g->sp, 1); return errNone; } // failing those, scan slot values for something rest-like PyrObject *array = slotRawObject(arraySlot); SetBool(g->sp, dictHasRestlikeValue(array) ? 1 : 0); return errNone; }
int prSymbol_envirGet(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a, result; int objClassIndex; a = g->sp; // key PyrSlot* currentEnvironmentSlot = &g->classvars->slots[1]; PyrObject *dict = slotRawObject(currentEnvironmentSlot); if (!IsObj(currentEnvironmentSlot)) return errFailed; if (!ISKINDOF(dict, class_identdict_index, class_identdict_maxsubclassindex)) return errFailed; identDict_lookup(dict, a, calcHash(a), &result); slotCopy(a,&result); return errNone; }
int prIdentDict_At(struct VMGlobals *g, int numArgsPushed) { PyrSlot* a = g->sp - 1; // dict PyrSlot* key = g->sp; // key PyrObject *dict = slotRawObject(a); bool knows = IsTrue(dict->slots + ivxIdentDict_know); if (knows && IsSym(key)) { if (slotRawSymbol(key) == s_parent) { slotCopy(a,&dict->slots[ivxIdentDict_parent]); return errNone; } if (slotRawSymbol(key) == s_proto) { slotCopy(a,&dict->slots[ivxIdentDict_proto]); return errNone; } } identDict_lookup(dict, key, calcHash(key), a); return errNone; }
bool identDict_lookup(PyrObject *dict, PyrSlot *key, int hash, PyrSlot *result) { again: PyrSlot *dictslots = dict->slots; PyrSlot *arraySlot = dictslots + ivxIdentDict_array; if (isKindOfSlot(arraySlot, class_array)) { PyrObject *array = slotRawObject(arraySlot); int index = arrayAtIdentityHashInPairsWithHash(array, key, hash); if (SlotEq(key, array->slots + index)) { slotCopy(result,&array->slots[index + 1]); return true; } } PyrClass *identDictClass = s_identitydictionary->u.classobj; PyrSlot *parentSlot = dictslots + ivxIdentDict_parent; PyrSlot * protoSlot = dictslots + ivxIdentDict_proto; if (isKindOfSlot(parentSlot, identDictClass)) { if (isKindOfSlot(protoSlot, identDictClass)) { // recursive call. if (identDict_lookup(slotRawObject(protoSlot), key, hash, result)) return true; } dict = slotRawObject(parentSlot); goto again; // tail call } else { if (isKindOfSlot(protoSlot, identDictClass)) { dict = slotRawObject(protoSlot); goto again; // tail call } } SetNil(result); return false; }
int prEvent_Delta(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a, key, dur, stretch, delta; double fdur, fstretch; int err; PyrClass *restClass = getsym("Rest")->u.classobj; PyrSlot *slot; a = g->sp; // dict SetSymbol(&key, s_delta); identDict_lookup(slotRawObject(a), &key, calcHash(&key), &delta); if (NotNil(&delta)) { if (isKindOfSlot(&delta, restClass)) { slot = slotRawObject(&delta)->slots; err = slotDoubleVal(slot, &fdur); } else { err = slotDoubleVal(&delta, &fdur); } if (err) { return err; } else { SetFloat(a, fdur); return errNone; } } else { SetSymbol(&key, s_dur); identDict_lookup(slotRawObject(a), &key, calcHash(&key), &dur); err = slotDoubleVal(&dur, &fdur); if (err) { if (IsNil(&dur)) { SetNil(g->sp); return errNone; } else if (isKindOfSlot(&dur, restClass)) { slot = slotRawObject(&dur)->slots; err = slotDoubleVal(slot, &fdur); if (err) return err; } else { return errWrongType; } } SetSymbol(&key, s_stretch); identDict_lookup(slotRawObject(a), &key, calcHash(&key), &stretch); err = slotDoubleVal(&stretch, &fstretch); if (err) { if (NotNil(&stretch)) { if (isKindOfSlot(&stretch, restClass)) { slot = slotRawObject(&stretch)->slots; err = slotDoubleVal(slot, &fstretch); if (err) return err; } else { return errWrongType; } } else { SetFloat(a, fdur); return errNone; } } SetFloat(a, fdur * fstretch); } return errNone; }