class NumberOperatorWithTimeAndString : IYCNumberOperator<object>
{
public static readonly YCBasicNumberOperators.Double Base = YCBasicNumberOperators.Double.Instance;
public bool TryParseConstant(string repr, out object value)
{
//first try redirecting to the base implementation for type double
if (Base.TryParseConstant(repr, out var unboxedValue))
{
value = unboxedValue;
return true;
}
return TryParseStringConstant(repr, out value);
}
//just redirect to the base implementation for type double
public FormatException ValidateIdentifier(string identifier)
=> Base.ValidateIdentifier(identifier);
//just a really basic way of recognizing a single-quote string and getting its contents
bool TryParseStringConstant(string repr, out object value)
{
if (repr.Length >= 2 && repr[0] == '\'' && repr[^1] == '\'')
{
value = repr.Substring(1, repr.Length - 2).Replace("\\'", "'").Replace("''", "'"); //replace escaped quotes and double quotes inside the raw string with just quotes
return true;
}
value = null;
return false;
}
object UnsupportedType(object a, object b)
=> throw new ArgumentException($"Unsupported operand type of '{a?.GetType()}' and '{b?.GetType()}'");
public object Add(object a, object b)
=> a switch
{
string s => s + b,
double d => d + (double)b,
TimeSpan t => t + (TimeSpan)b,
_ => UnsupportedType(a, b)
};
public object Subtract(object a, object b)
=> a switch
{
double d => d - (double)b,
TimeSpan t => t - (TimeSpan)b,
_ => UnsupportedType(a, b)
};
public object Multiply(object a, object b)
=> (double)a * (double)b;
public object Divide(object a, object b)
=> (double)a / (double)b;
public object Modulo(object a, object b)
=> (double)a % (double)b;
public object UnaryMinus(object a)
=> -(double)a;
public object Power(object a, object power)
=> Base.Power((double)a, (double)power);
public object IsEqual(object a, object b)
=> a.Equals(b);
public object IsLess(object a, object b)
=> Base.IsLess((double)a, (double)b);
public object IsLessOrEqual(object a, object b)
=> Base.IsLessOrEqual((double)a, (double)b);
public bool IsTrue(object a)
=> Base.IsTrue((double)a);
public object NegateLogical(object a)
=> Base.NegateLogical((double)a);
}
public static class UsageSample
{
public static void Main()
{
var compiler = IYCCompiler<object>.Make(new NumberOperatorWithTimeAndString());
var calculator = IYoowzxCalculator<object>.Make(compiler: compiler);
calculator.AddFunction<Func<object, object>>("fromSeconds", d => TimeSpan.FromSeconds((double)d));
var f = calculator.Compile<Func<object, object, object>>
("f(mins, secs) := 'This much seconds: ' + fromSeconds(mins*60 + secs) + ' seconds'");
Console.WriteLine(f(2D, 43D)); //make sure you're passing args of type double and not int
}
}