예제 #1
0
 public AstBinary(AstBinaryType type, AstExpression left, Source src, AstExpression right)
     : base(src)
 {
     Type  = type;
     Left  = left;
     Right = right;
 }
예제 #2
0
파일: AstReader.cs 프로젝트: mortend/uno
 public AstBinary ReadBinary(AstBinaryType type)
 {
     return(new AstBinary(type,
                          ReadExpression(),
                          ReadSource(),
                          ReadExpression()));
 }
예제 #3
0
 public TokenAttribute(string value, Precedence prec, OperatorType binOp, AstBinaryType binary)
 {
     Value          = value;
     Precedence     = prec;
     BinaryType     = binary;
     BinaryOperator = binOp;
 }
예제 #4
0
 public TokenAttribute(string value, Precedence prec, AstUnaryType unary, AstBinaryType binary)
 {
     Value      = value;
     Precedence = prec;
     UnaryType  = unary;
     BinaryType = binary;
 }
예제 #5
0
 public TokenAttribute(string value, Precedence prec, AstBinaryType binary = 0, Associativity assoc = Associativity.LeftToRight)
 {
     Value         = value;
     Precedence    = prec;
     BinaryType    = binary;
     Associativity = assoc;
 }
예제 #6
0
        Expression CompileBinOp(Source src, AstBinaryType binOp, Expression left, Expression right)
        {
            if (left.IsInvalid || right.IsInvalid)
            {
                return(Expression.Invalid);
            }

            if ((left.ReturnType is NullType || left.ReturnType is MethodGroupType) && right.ReturnType.IsReferenceType)
            {
                var leftCast = TryCompileImplicitCast(src, right.ReturnType, left);
                if (leftCast != null)
                {
                    left = leftCast;
                }
            }
            else if ((right.ReturnType is NullType || right.ReturnType is MethodGroupType) && left.ReturnType.IsReferenceType)
            {
                var rightCast = TryCompileImplicitCast(src, left.ReturnType, right);
                if (rightCast != null)
                {
                    right = rightCast;
                }
            }

            var args = new[] { left, right };
            var opOp = binOp.ToSymbol();
            var op   = TryResolveOperatorOverload(src,
                                                  NameResolver.GetTypeOperators(left.ReturnType, right.ReturnType, opOp),
                                                  args);

            if (op != null)
            {
                return(new CallBinOp(src, op, args[0], args[1]));
            }

            switch (binOp)
            {
            case AstBinaryType.LogAnd:
            case AstBinaryType.LogOr:
            {
                left  = CompileImplicitCast(src, Essentials.Bool, left);
                right = CompileImplicitCast(src, Essentials.Bool, right);
                return(new BranchOp(
                           src, Essentials.Bool,
                           binOp == AstBinaryType.LogAnd
                            ? BranchType.And
                            : BranchType.Or,
                           left, right));
            }

            case AstBinaryType.Null:
            {
                if (left.ReturnType.IsNull)
                {
                    return(right);
                }
                if (!left.ReturnType.IsReferenceType)
                {
                    return(Error(src, ErrorCode.E2015, "'??' cannot be used on operand of type " + left.ReturnType.Quote() + " because it is not a reference type"));
                }

                right = CompileImplicitCast(src, left.ReturnType, right);
                return(new NullOp(src, left, right));
            }

            case AstBinaryType.Equal:
            case AstBinaryType.NotEqual:
            {
                if (left.ReturnType.IsReferenceType && right.ReturnType.IsReferenceType)
                {
                    return(new ReferenceOp(src, Essentials.Bool, binOp == AstBinaryType.Equal ? EqualityType.Equal : EqualityType.NotEqual, left, right));
                }
                break;
            }

            case AstBinaryType.Sequence:
                return(new SequenceOp(left, right));
            }

            return(Error(src, ErrorCode.E2016, left.ReturnType.Quote() + " has no operators " + binOp.ToSymbol().Quote() + " matching the argument list"));
        }
예제 #7
0
파일: AstOperators.cs 프로젝트: mortend/uno
        public static string ToSymbol(this AstBinaryType s)
        {
            switch (s)
            {
            case AstBinaryType.Assign: return("=");

            case AstBinaryType.AddAssign: return("+=");

            case AstBinaryType.SubAssign: return("-=");

            case AstBinaryType.MulAssign: return("*=");

            case AstBinaryType.DivAssign: return("/=");

            case AstBinaryType.ModAssign: return("%=");

            case AstBinaryType.BitwiseAndAssign: return("&=");

            case AstBinaryType.BitwiseXorAssign: return("^=");

            case AstBinaryType.BitwiseOrAssign: return("|=");

            case AstBinaryType.ShiftLeftAssign: return("<<=");

            case AstBinaryType.ShiftRightAssign: return(">>=");

            case AstBinaryType.LogOr: return("||");

            case AstBinaryType.LogAnd: return("&&");

            case AstBinaryType.BitwiseOr: return("|");

            case AstBinaryType.BitwiseXor: return("^");

            case AstBinaryType.BitwiseAnd: return("&");

            case AstBinaryType.Equal: return("==");

            case AstBinaryType.NotEqual: return("!=");

            case AstBinaryType.LessThan: return("<");

            case AstBinaryType.GreaterThan: return(">");

            case AstBinaryType.LessThanOrEqual: return("<=");

            case AstBinaryType.GreaterThanOrEqual: return(">=");

            case AstBinaryType.ShiftLeft: return("<<");

            case AstBinaryType.ShiftRight: return(">>");

            case AstBinaryType.Add: return("+");

            case AstBinaryType.Sub: return("-");

            case AstBinaryType.Mul: return("*");

            case AstBinaryType.Div: return("/");

            case AstBinaryType.Mod: return("%");

            case AstBinaryType.Null: return("??");

            case AstBinaryType.Sequence: return(",");

            default: throw new Exception("invalid binop: " + s);
            }
        }