コード例 #1
0
ファイル: SemanticAnalyser.cs プロジェクト: kostic017/pigeon
        public override void ExitBinaryExpression([NotNull] PigeonParser.BinaryExpressionContext context)
        {
            var left  = Types.Get(context.expr(0));
            var right = Types.Get(context.expr(1));

            if (!BinaryOperator.TryGetResType(context.op.Text, left, right, out var type))
            {
                errorBag.ReportInvalidTypeBinaryOperator(context.op.GetTextSpan(), context.op.Text, left, right);
            }
            Types.Put(context, type);
        }
コード例 #2
0
        public override object VisitBinaryExpression([NotNull] PigeonParser.BinaryExpressionContext context)
        {
            var left    = Visit(context.expr(0));
            var right   = Visit(context.expr(1));
            var resType = analyser.Types.Get(context);

            var areBothInt =
                analyser.Types.Get(context.expr(0)) == PigeonType.Int &&
                analyser.Types.Get(context.expr(1)) == PigeonType.Int;

            switch (context.op.Text)
            {
            case "==":
                return(left.Equals(right));

            case "!=":
                return(!left.Equals(right));

            case "&&":
                return((bool)left && (bool)right);

            case "||":
                return((bool)left || (bool)right);

            case "<":
                if (areBothInt)
                {
                    return((int)left < (int)right);
                }
                return(Convert.ToSingle(left) < Convert.ToSingle(right));

            case ">":
                if (areBothInt)
                {
                    return((int)left > (int)right);
                }
                return(Convert.ToSingle(left) > Convert.ToSingle(right));

            case "<=":
                if (areBothInt)
                {
                    return((int)left <= (int)right);
                }
                return(Convert.ToSingle(left) <= Convert.ToSingle(right));

            case ">=":
                if (areBothInt)
                {
                    return((int)left >= (int)right);
                }
                return(Convert.ToSingle(left) >= Convert.ToSingle(right));

            case "+":
                if (resType == PigeonType.Int)
                {
                    return((int)left + (int)right);
                }
                else if (resType == PigeonType.Float)
                {
                    return(Convert.ToSingle(left) + Convert.ToSingle(right));
                }
                else
                {
                    return(left.ToString() + right.ToString());
                }

            case "-":
                if (resType == PigeonType.Int)
                {
                    return((int)left - (int)right);
                }
                return(Convert.ToSingle(left) - Convert.ToSingle(right));

            case "*":
                if (resType == PigeonType.Int)
                {
                    return((int)left * (int)right);
                }
                return(Convert.ToSingle(left) * Convert.ToSingle(right));

            case "/":
                if (resType == PigeonType.Int)
                {
                    return((int)left / (int)right);
                }
                return(Convert.ToSingle(left) / Convert.ToSingle(right));

            case "%":
                return((int)left % (int)right);

            default:
                throw new InternalErrorException($"Unsupported binary operator {context.op.Text}");
            }
        }