public bool TryConvertValue(Value source, SprakType destinationType, out Value destination) { if (source.Type == destinationType) { destination = source; return(true); } if (destinationType == SprakType.Any) { destination = source; return(true); } if (destinationType == SprakType.String) { destination = source.ToSprakString(); return(true); } ConversionTypeSignature signature = new ConversionTypeSignature(source.Type, destinationType); SignatureLookupResult result = _resolver.TryFindMatch(signature); if (!result.Success) { destination = null; return(false); } destination = result.BuiltInFunction.Call(new Value[] { source }, _context); return(true); }
private void AddConversion(MethodInfo methodInfo, bool perfect) { BuiltInFunction function = new BuiltInFunction(methodInfo, this); if (function.Parameters.Count != 1) { string message = $"{MethodName(methodInfo)} must have a single Sprak parameter in order to be a conversion"; throw new ArgumentException(message); } ConversionTypeSignature signature = new ConversionTypeSignature(function.Parameters[0], function.ReturnType, perfect); _conversions.Add(signature, function); }
private void AddConversion(ConversionTypeSignature conversion) { HashSet <SprakType> innerSet; if (!_possibleConversions.TryGetValue(conversion.Output, out innerSet)) { innerSet = new HashSet <SprakType>(); _possibleConversions.Add(conversion.Output, innerSet); } innerSet.Add(conversion.Input); if (conversion.IsPerfectHint.HasValue) { _informationLoss.Add(conversion, conversion.IsPerfectHint.Value); } }
public SignatureLookupResult TryFindMatch(ConversionTypeSignature signature) { SignatureLookupResult result = new SignatureLookupResult(); if (_conversionBindingLookup.TryGetValue(signature, out Func <Op> value)) { result.Success = true; result.OpBuilder = value; } else if (_builtinConversionLookup.TryGetValue(signature, out BuiltInFunction builtIn)) { result.Success = true; result.BuiltInFunction = builtIn; result.FunctionInfo = builtIn.Info; } return(result); }
public bool IsPerfect(SprakType source, SprakType destination) { if (IsDirect(source, destination)) { return(true); } ConversionTypeSignature signature = new ConversionTypeSignature(source, destination); if (_informationLoss.TryGetValue(signature, out bool perfect)) { return(perfect); } else { throw new ArgumentException($"Unrecognized conversion from {source} to {destination}"); } }
public ConversionOpBinding(Func <Op> builder, ConversionTypeSignature signature) : base(builder) { Signature = signature; }