/// <summary> /// Implements relative path interpolation /// </summary> internal static EvaluationResult Interpolate(Context context, ModuleLiteral env, EvaluationStackFrame args) { Args.CheckArgumentIndex(args, 1); var rest = Args.AsArrayLiteral(args, 1); return(Interpolate(context, args[0], rest.Values)); }
private static EvaluationResult NotEqualOrEqual(Context context, bool expectedEqual, ModuleLiteral env, EvaluationStackFrame args) { var expected = args[0]; Args.CheckArgumentIndex(args, 0); var actual = args[1]; Args.CheckArgumentIndex(args, 1); if (expectedEqual != expected.Equals(actual)) { var expectedString = ToStringConverter.ObjectToString(context, expected); var actualString = ToStringConverter.ObjectToString(context, actual); if (expectedEqual) { throw new EqualException(expectedString, actualString); } else { throw new NotEqualException(expectedString, actualString); } } return(EvaluationResult.Undefined); }
/// <summary> /// Function for converting AbsolutePath to DirectoryArtifact conforming to the 'InvokeAmbient' signature. /// </summary> private static EvaluationResult FromPath(Context context, ModuleLiteral env, EvaluationStackFrame args) { Args.CheckArgumentIndex(args, 0); return(args[0].IsUndefined ? EvaluationResult.Undefined : EvaluationResult.Create(DirectoryArtifact.CreateWithZeroPartialSealId(Converter.ExpectPath(args[0], strict: false, context: new ConversionContext(pos: 1))))); }
/// <summary> /// Implements path interpolation /// </summary> public static EvaluationResult Interpolate(ImmutableContextBase context, ModuleLiteral env, EvaluationStackFrame args) { // TODO: Path.interpolate(x, y, z) is similar to x.combinePaths(y, z). The latter can be slightly more efficient because no look-up for "Path" identifier. Args.CheckArgumentIndex(args, 1); var rest = Args.AsArrayLiteral(args, 1); return(Interpolate(context, args[0], rest.Values)); }
/// <summary> /// DScript exposes a value cache. The backing store is kept inside of 'IEvaluationScheduler'. /// Values from this cache should never be returned directly; instead, the result should be cloned first /// (to avoid exposing an observable side effect). /// </summary> private EvaluationResult GetOrAdd(Context context, ModuleLiteral env, EvaluationStackFrame args) { Args.CheckArgumentIndex(args, 0); var key = args[0]; var closure = Args.AsClosure(args, 1); return(DoGetOrAdd(context, env, key, null, closure)); }
/// <summary> /// Function for converting AbsolutePath to FileArtifact conforming to the 'InvokeAmbient' signature. /// </summary> private static EvaluationResult FromPath(Context context, ModuleLiteral env, EvaluationStackFrame args) { Args.CheckArgumentIndex(args, 0); // TODO:ST: this block should use ExpectsOptionalPath?!? return((args[0].IsUndefined) ? EvaluationResult.Undefined : EvaluationResult.Create(FileArtifact.CreateSourceFile(Converter.ExpectPath(args[0], false, new ConversionContext(pos: 1))))); }
private EvaluationResult GetOrAdd(Context context, ModuleLiteral env, EvaluationStackFrame args) { Args.CheckArgumentIndex(args, 0); var key = args[0]; var closure = Args.AsClosure(args, 1); var helper = new HashingHelper(context.PathTable, recordFingerprintString: false); // Add the qualifier to the key var qualifierId = context.LastActiveModuleQualifier.QualifierId; var qualifierDisplayString = context.ContextTree.FrontEndContext.QualifierTable.GetQualifier(qualifierId).ToDisplayString(StringTable); helper.Add(qualifierDisplayString); if (!TryHashValue(key, helper)) { return(EvaluationResult.Error); } var keyFingerprint = helper.GenerateHash(); var resultToClone = context.ContextTree.ValueCache.GetOrAdd( keyFingerprint, _ => { int paramsCount = closure.Function.Params; var newValue = context.InvokeClosure(closure, closure.Frame); if (newValue.IsErrorValue) { return(EvaluationResult.Error); } return(newValue); } ); // The object returned will always be a cloned copy. // DScript is a side effect free language, but we use object identity // for equality comparison so to avoid making cache hits observable to // users we opt to clone the value from the cache each time, even after the // first time we add it to the cache. // This is also the reason why we don't have separate functions for inspecting or simply adding // because the results would be observable and potentially invalidating all the // incremental evaluations in DScript. return(DeepCloneValue(resultToClone)); }
/// <summary> /// Implements relative path interpolation /// </summary> private static EvaluationResult Interpolate(Context context, ModuleLiteral env, EvaluationStackFrame args) { Args.CheckArgumentIndex(args, 1); var stringTable = context.FrontEndContext.StringTable; PathAtom pathAtom = Converter.ExpectPathAtomFromStringOrPathAtom(stringTable, args[0], new ConversionContext(pos: 1)); var rest = Args.AsArrayLiteral(args, 1); for (int i = 0; i < rest.Length; i++) { pathAtom = pathAtom.Concat( stringTable, Converter.ExpectPathAtomFromStringOrPathAtom( stringTable, rest[i], new ConversionContext(pos: i + 1, objectCtx: rest))); } return(EvaluationResult.Create(pathAtom)); }
/** * Returns an integer array of increasing elements from 'start' to 'stop' (including both 'start' and 'stop'). * If 'start > stop' the function returns the empty array. */ private static EvaluationResult Range(Context context, ModuleLiteral env, EvaluationStackFrame args) { Args.CheckArgumentIndex(args, 0); var start = Converter.ExpectNumber(args[0], position: 0); Args.CheckArgumentIndex(args, 1); var stop = Converter.ExpectNumber(args[1], position: 1); var entry = context.TopStack; if (start > stop) { return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(CollectionUtilities.EmptyArray <EvaluationResult>(), entry.InvocationLocation, entry.Path))); } var step = (args.Length > 2 && !args[2].IsUndefined) ? Converter.ExpectNumber(args[2], position: 2) : 1; if (step <= 0) { throw Converter.CreateException("Expected positive step in Array.range", EvaluationResult.Create(step), new ConversionContext(objectCtx: args, pos: 2)); } var length = (stop - start + step - 1) / step + 1; var result = new List <EvaluationResult>(length); for (int i = start; i < stop; i += step) { result.Add(EvaluationResult.Create(i)); } result.Add(EvaluationResult.Create(stop)); return(EvaluationResult.Create(ArrayLiteral.CreateWithoutCopy(result.ToArray(), entry.InvocationLocation, entry.Path))); }