Files
Upsilon/Upsilon/Binder/BoundBinaryOperator.cs

83 lines
2.9 KiB
C#

using System;
using System.Linq;
using Upsilon.Parser;
using Type = Upsilon.BaseTypes.Type;
namespace Upsilon.Binder
{
public class BoundBinaryOperator
{
public enum OperatorKind
{
Addition, Subtraction, Multiplication, Division, Equality, Inequality
}
public Type LeftType { get; }
public Type RightType { get; }
public Type OutType { get; }
public OperatorKind Kind { get; }
public BoundBinaryOperator(OperatorKind kind, Type outType)
{
Kind = kind;
LeftType = outType;
RightType = outType;
OutType = outType;
}
public BoundBinaryOperator(OperatorKind kind, Type leftType, Type rightType, Type outType)
{
Kind = kind;
LeftType = leftType;
RightType = rightType;
OutType = outType;
}
public static BoundBinaryOperator[] Operators = new BoundBinaryOperator[]
{
// Math operators
new BoundBinaryOperator(OperatorKind.Addition, Type.Number),
new BoundBinaryOperator(OperatorKind.Subtraction, Type.Number),
new BoundBinaryOperator(OperatorKind.Multiplication, Type.Number),
new BoundBinaryOperator(OperatorKind.Division, Type.Number),
// Number equality
new BoundBinaryOperator(OperatorKind.Equality, Type.Number, Type.Number, Type.Boolean),
new BoundBinaryOperator(OperatorKind.Inequality, Type.Number, Type.Number, Type.Boolean),
// Boolean equality
new BoundBinaryOperator(OperatorKind.Equality, Type.Boolean),
new BoundBinaryOperator(OperatorKind.Inequality, Type.Boolean),
};
public static BoundBinaryOperator BindBinaryOperator(SyntaxKind operatorToken, Type left, Type right)
{
OperatorKind kind;
switch (operatorToken)
{
case SyntaxKind.Plus:
kind = OperatorKind.Addition;
break;
case SyntaxKind.Minus:
kind = OperatorKind.Subtraction;
break;
case SyntaxKind.Star:
kind = OperatorKind.Multiplication;
break;
case SyntaxKind.Slash:
kind = OperatorKind.Division;
break;
case SyntaxKind.EqualsEquals:
kind = OperatorKind.Equality;
break;
case SyntaxKind.TildeEquals:
kind = OperatorKind.Inequality;
break;
default:
throw new Exception("Unknown binary operator token: " + operatorToken);
}
return Operators.FirstOrDefault(op => op.Kind == kind && op.LeftType == left && op.RightType == right);
}
}
}