Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
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;
}