/// <summary> /// Look up the given identifier in the given sequence, walking the type chain /// until we either find it, or fail. /// </summary> /// <param name="sequence">Sequence (object) to look in.</param> /// <param name="identifier">Identifier to look for.</param> /// <param name="context">Context.</param> public static Value Resolve(Value sequence, string identifier, TAC.Context context, out ValMap valueFoundIn) { var includeMapType = true; valueFoundIn = null; int loopsLeft = 1000; // (max __isa chain depth) while (sequence != null) { if (sequence is ValTemp || sequence is ValVar) { sequence = sequence.Val(context); } if (sequence is ValMap) { // If the map contains this identifier, return its value. Value result = null; var idVal = TempValString.Get(identifier); bool found = ((ValMap)sequence).map.TryGetValue(idVal, out result); TempValString.Release(idVal); if (found) { valueFoundIn = (ValMap)sequence; return(result); } // Otherwise, if we have an __isa, try that next. if (loopsLeft < 0) { return(null); // (unless we've hit the loop limit) } if (!((ValMap)sequence).map.TryGetValue(ValString.magicIsA, out sequence)) { // ...and if we don't have an __isa, try the generic map type if allowed if (!includeMapType) { throw new KeyException(identifier); } sequence = context.vm.mapType ?? Intrinsics.MapType(); includeMapType = false; } } else if (sequence is ValList) { sequence = context.vm.listType ?? Intrinsics.ListType(); includeMapType = false; } else if (sequence is ValString) { sequence = context.vm.stringType ?? Intrinsics.StringType(); includeMapType = false; } else if (sequence is ValNumber) { sequence = context.vm.numberType ?? Intrinsics.NumberType(); includeMapType = false; } else if (sequence is ValFunction) { sequence = context.vm.functionType ?? Intrinsics.FunctionType(); includeMapType = false; } else { throw new TypeException("Type Error (while attempting to look up " + identifier + ")"); } loopsLeft--; } return(null); }
/// <summary> /// Look up the given identifier in the given sequence, walking the type chain /// until we either find it, or fail. /// </summary> /// <param name="sequence">Sequence (object) to look in.</param> /// <param name="identifier">Identifier to look for.</param> /// <param name="context">Context.</param> public static Value Resolve(Value sequence, string identifier, Context context, out ValMap valueFoundIn) { var includeMapType = true; valueFoundIn = null; int loopsLeft = 1000; // (max __isa chain depth) while (sequence != null) { int seqTypeInt = sequence.GetBaseMiniscriptType(); //if (sequence is ValTemp || sequence is ValVar) if (seqTypeInt == MiniscriptTypeInts.ValTempTypeInt || seqTypeInt == MiniscriptTypeInts.ValVarTypeInt) { sequence = sequence.Val(context, false); seqTypeInt = sequence == null ? -1 : sequence.GetBaseMiniscriptType(); } //if (sequence is ValMap) { if (seqTypeInt == MiniscriptTypeInts.ValMapTypeInt) { // If the map contains this identifier, return its value. ValMap seqMap = sequence as ValMap; Value result = null; var idVal = ValString.Create(identifier); bool found = seqMap.TryGetValue(idVal, out result); idVal.Unref(); if (found) { valueFoundIn = seqMap; return(result); } // Otherwise, if we have an __isa, try that next. if (loopsLeft < 0) { return(null); // (unless we've hit the loop limit) } if (!seqMap.TryGetValue(ValString.magicIsA, out sequence)) { // ...and if we don't have an __isa, try the generic map type if allowed if (!includeMapType) { throw new KeyException(identifier); } sequence = context.vm.mapType ?? Intrinsics.MapType(); includeMapType = false; } //} else if (sequence is ValList) { } else if (seqTypeInt == MiniscriptTypeInts.ValListTypeInt) { sequence = context.vm.listType ?? Intrinsics.ListType(); includeMapType = false; //} else if (sequence is ValString) { } else if (seqTypeInt == MiniscriptTypeInts.ValStringTypeInt) { sequence = context.vm.stringType ?? Intrinsics.StringType(); includeMapType = false; //} else if (sequence is ValNumber) { } else if (seqTypeInt == MiniscriptTypeInts.ValNumberTypeInt) { sequence = context.vm.numberType ?? Intrinsics.NumberType(); includeMapType = false; //} else if (sequence is ValFunction) { } else if (seqTypeInt == MiniscriptTypeInts.ValFunctionTypeInt) { sequence = context.vm.functionType ?? Intrinsics.FunctionType(); includeMapType = false; } else if (seqTypeInt == MiniscriptTypeInts.ValCustomTypeInt) { ValCustom custom = sequence as ValCustom; if (custom.Resolve(identifier, out Value result)) { //valueFoundIn return(result); } return(null); } else { throw new TypeException("Type Error (while attempting to look up " + identifier + ")"); } loopsLeft--; } return(null); }