Untitled

mail@pastecode.io avatar
unknown
csharp
2 years ago
3.4 kB
10
Indexable
Never
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) + fromSeconds(10)) + ' seconds'");

        Console.WriteLine(f(2D, 43D));  //make sure you're passing args of type double and not int
    }
}