Esempio n. 1
0
        private void AddMethod(MethodInfo methodInfo)
        {
            SprakConversionAttribute conversionAttribute = methodInfo.GetCustomAttribute <SprakConversionAttribute>();
            bool isConversion = conversionAttribute != null;

            SprakOperatorAttribute opAttribute = methodInfo.GetCustomAttribute <SprakOperatorAttribute>();
            bool isOperator = opAttribute != null;

            if (isConversion && isOperator)
            {
                throw new ArgumentException($"{MethodName(methodInfo)} is declared to be both an operator and a conversion");
            }

            if (isConversion)
            {
                AddConversion(methodInfo, conversionAttribute.IsPerfect);
            }

            else if (isOperator)
            {
                AddOperator(methodInfo, opAttribute);
            }

            else
            {
                AddFunction(methodInfo);
            }
        }
Esempio n. 2
0
        private void AddOperator(MethodInfo methodInfo, SprakOperatorAttribute meta)
        {
            BuiltInFunction function = new BuiltInFunction(methodInfo, this);

            if (!Operator.TryParse(out Operator op, name: meta.OperatorName))
            {
                string message = $"{MethodName(methodInfo)} is declared to be an unrecognized operator: \"{meta.OperatorName}\"";
                throw new ArgumentException(message);
            }

            int paramCount = function.Parameters.Count;

            bool binary        = meta.InputsHint == InputSides.Both;
            int  requiredCount = binary ? 2 : 1;

            if (paramCount != requiredCount)
            {
                string desc = binary ? "binary" : "unary";

                string message = $"{MethodName(methodInfo)} was declared to be the {desc} operator \"{meta.OperatorName}\", " +
                                 $"but has {function.Parameters.Count} Sprak arguments";

                throw new ArgumentException(message);
            }

            InputSides inputs = meta.InputsHint;

            SprakType left  = null;
            SprakType right = null;

            switch (inputs)
            {
            case InputSides.Both:
                left  = function.Parameters[0];
                right = function.Parameters[1];
                break;

            case InputSides.Left:
                left = function.Parameters[0];
                break;

            case InputSides.Right:
                right = function.Parameters[0];
                break;
            }

            OperatorTypeSignature typeSignature
                = new OperatorTypeSignature(left, right, inputs);

            OperatorSignature signature = new OperatorSignature(op.Name, typeSignature);

            _operators.Add(signature, function);
        }