private static FormulaValue ReplaceChecker(IRContext irContext, int index, FormulaValue arg) { if (index == 1) { if (arg is BlankValue) { return(new ErrorValue(irContext, new ExpressionError() { Message = "The second parameter to the Replace function cannot be Blank()", Span = irContext.SourceContext, Kind = ErrorKind.InvalidFunctionUsage })); } var finiteCheckResult = FiniteChecker(irContext, index, arg); if (finiteCheckResult is NumberValue numberArg) { var number = numberArg.Value; if (number <= 0) { return(CommonErrors.ArgumentOutOfRange(irContext)); } } return(finiteCheckResult); } if (index == 2) { return(PositiveNumberChecker(irContext, index, arg)); } return(arg); }
private static FormulaValue AddDateTimeAndDay(IRContext irContext, FormulaValue[] args) { DateTime arg0; switch (args[0]) { case DateTimeValue dtv: arg0 = dtv.Value; break; case DateValue dv: arg0 = dv.Value; break; default: return(CommonErrors.RuntimeTypeMismatch(irContext)); } var arg1 = (NumberValue)args[1]; try { var result = arg0.AddDays(arg1.Value); return(new DateTimeValue(irContext, result)); } catch { return(CommonErrors.ArgumentOutOfRange(irContext)); } }
// https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/functions/function-left-mid-right public static FormulaValue Mid(IRContext irContext, FormulaValue[] args) { var errors = new List <ErrorValue>(); NumberValue start = (NumberValue)args[1]; if (double.IsNaN(start.Value) || double.IsInfinity(start.Value) || start.Value <= 0) { errors.Add(CommonErrors.ArgumentOutOfRange(start.IRContext)); } NumberValue count = (NumberValue)args[2]; if (double.IsNaN(count.Value) || double.IsInfinity(count.Value) || count.Value < 0) { errors.Add(CommonErrors.ArgumentOutOfRange(count.IRContext)); } if (errors.Count != 0) { return(ErrorValue.Combine(irContext, errors)); } StringValue source = (StringValue)args[0]; var start0Based = (int)(start.Value - 1); if (source.Value == "" || start0Based >= source.Value.Length) { return(new StringValue(irContext, "")); } var minCount = Math.Min((int)count.Value, source.Value.Length - start0Based); var result = source.Value.Substring(start0Based, minCount); return(new StringValue(irContext, result)); }
// https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/functions/function-value // Convert string to number public static FormulaValue Value(EvalVisitor runner, SymbolContext symbolContext, IRContext irContext, FormulaValue[] args) { var arg0 = args[0]; if (arg0 is NumberValue n) { return(n); } if (arg0 is DateValue dv) { return(DateToNumber(irContext, new DateValue[] { dv })); } if (arg0 is DateTimeValue dtv) { return(DateTimeToNumber(irContext, new DateTimeValue[] { dtv })); } var str = ((StringValue)arg0).Value.Trim(); var styles = NumberStyles.Any; if (string.IsNullOrEmpty(str)) { return(new BlankValue(irContext)); } double div = 1; if (str[str.Length - 1] == '%') { str = str.Substring(0, str.Length - 1); div = 100; styles = NumberStyles.Number; } else if (str[0] == '%') { str = str.Substring(1, str.Length - 1); div = 100; styles = NumberStyles.Number; } if (!double.TryParse(str, styles, runner.CultureInfo, out var val)) { return(CommonErrors.InvalidNumberFormatError(irContext)); } if (IsInvalidDouble(val)) { return(CommonErrors.ArgumentOutOfRange(irContext)); } val /= div; return(new NumberValue(irContext, val)); }
private static FormulaValue FiniteChecker(IRContext irContext, int index, FormulaValue arg) { if (arg is NumberValue numberValue) { var number = numberValue.Value; if (IsInvalidDouble(number)) { return(CommonErrors.ArgumentOutOfRange(irContext)); } } return(arg); }
private static FormulaValue StrictPositiveNumberChecker(IRContext irContext, int index, FormulaValue arg) { var finiteCheckResult = FiniteChecker(irContext, index, arg); if (finiteCheckResult is NumberValue numberArg) { var number = numberArg.Value; if (number <= 0) { return(CommonErrors.ArgumentOutOfRange(irContext)); } } return(arg); }
// https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/show-text-dates-times // https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/functions/function-dateadd-datediff public static FormulaValue DateAdd(IRContext irContext, FormulaValue[] args) { DateTime datetime; switch (args[0]) { case DateTimeValue dtv: datetime = dtv.Value; break; case DateValue dv: datetime = dv.Value; break; default: return(CommonErrors.RuntimeTypeMismatch(irContext)); } var delta = (NumberValue)args[1]; var units = (StringValue)args[2]; try { DateTime newDate; switch (units.Value.ToLower()) { case "milliseconds": newDate = datetime.AddMilliseconds(delta.Value); break; case "seconds": newDate = datetime.AddSeconds(delta.Value); break; case "minutes": newDate = datetime.AddMinutes(delta.Value); break; case "hours": newDate = datetime.AddHours(delta.Value); break; case "days": newDate = datetime.AddDays(delta.Value); break; case "months": newDate = datetime.AddMonths((int)delta.Value); break; case "quarters": newDate = datetime.AddMonths((int)delta.Value * 3); break; case "years": newDate = datetime.AddYears((int)delta.Value); break; default: // TODO: Task 10723372: Implement Unit Functionality in DateAdd, DateDiff Functions return(CommonErrors.NotYetImplementedError(irContext, "DateAdd Only supports Days for the unit field")); } if (args[0] is DateTimeValue) { return(new DateTimeValue(irContext, newDate)); } else { return(new DateValue(irContext, newDate.Date)); } } catch { return(CommonErrors.ArgumentOutOfRange(irContext)); } }