public AstBinary(AstBinaryType type, AstExpression left, Source src, AstExpression right) : base(src) { Type = type; Left = left; Right = right; }
public AstBinary ReadBinary(AstBinaryType type) { return(new AstBinary(type, ReadExpression(), ReadSource(), ReadExpression())); }
public TokenAttribute(string value, Precedence prec, OperatorType binOp, AstBinaryType binary) { Value = value; Precedence = prec; BinaryType = binary; BinaryOperator = binOp; }
public TokenAttribute(string value, Precedence prec, AstUnaryType unary, AstBinaryType binary) { Value = value; Precedence = prec; UnaryType = unary; BinaryType = binary; }
public TokenAttribute(string value, Precedence prec, AstBinaryType binary = 0, Associativity assoc = Associativity.LeftToRight) { Value = value; Precedence = prec; BinaryType = binary; Associativity = assoc; }
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")); }
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); } }