protected internal virtual void TraverseOperator(Operator op) { op.Unsupported(); } 
 protected internal override Node TransformOperator(Operator op)
 {
     return Dispatch(op);
 }
 protected internal override void TraverseOperator(Operator op)
 {
     Dispatch(op);
 }
        protected internal override void TraverseOperator(Operator op)
        {
            op.Args.ForEach(Traverse);

            // todo. also support nullables and lifted versions of operators
            op.Args.Any(arg => Types[arg].IsNullable()).AssertFalse();

            var impArgs = op.Args;
            var anyBool = impArgs.Any(arg => Types[arg] == typeof(bool));
            if (anyBool) { Types.Add(op, typeof(bool)); return; }

            var opt = op.OperatorType;
            if (opt.IsAssign() || opt == OperatorType.Coalesce || 
                opt == OperatorType.LeftShift || opt == OperatorType.RightShift)
            {
                Types.Add(op, Types[op.Args.First()]);
            }
            else if (opt == OperatorType.AndAlso || opt == OperatorType.OrElse || opt == OperatorType.Not ||
                opt == OperatorType.GreaterThan || opt == OperatorType.GreaterThanOrEqual ||
                opt == OperatorType.Equal || opt == OperatorType.NotEqual ||
                opt == OperatorType.LessThan || opt == OperatorType.LessThanOrEqual)
            {
                Types.Add(op, typeof(bool));
            }
            else
            {
                if (op.IsUnary())
                {
                    var t_target = Types[op.Unary().Target];
                    if (t_target == null) Types.Add(op, null);
                    else
                    {
                        (t_target.IsInteger() || t_target.IsFloatingPoint()).AssertTrue();
                        Types.Add(op, t_target);
                    }
                }
                else if (op.IsBinary())
                {
                    var t_lhs = Types[op.Binary().Lhs];
                    var t_rhs = Types[op.Binary().Rhs];
                    if (t_lhs == null || t_rhs == null) Types.Add(op, null);
                    else
                    {
                        if (t_lhs.IsInteger() && t_rhs.IsInteger())
                        {
                            Func<Type, int> bitness = t => 
                                t == typeof(sbyte) || t == typeof(byte) ? 8 :
                                t == typeof(short) || t == typeof(ushort) ? 16 :
                                t == typeof(int) || t == typeof(uint) ? 32 :
                                t == typeof(long) || t == typeof(ulong) ? 64 :
                                ((Func<int>)(() => { throw AssertionHelper.Fail(); }))();
                            Func<Type, bool> signed = t => 
                                t == typeof(sbyte) || t == typeof(short) ||
                                t == typeof(int) || t == typeof(long) ? true :
                                t == typeof(byte) || t == typeof(ushort) ||
                                t == typeof(uint) || t == typeof(ulong) ? false :
                                ((Func<bool>)(() => { throw AssertionHelper.Fail(); }))();
                            Func<int, bool, Type> mk_int = (n_bits, is_signed) =>
                            {
                                if (n_bits == 8) return is_signed ? typeof(sbyte) : typeof(byte);
                                if (n_bits == 16) return is_signed ? typeof(short) : typeof(ushort);
                                if (n_bits == 32) return is_signed ? typeof(int) : typeof(uint);
                                if (n_bits == 64) return is_signed ? typeof(long) : typeof(ulong);
                                throw AssertionHelper.Fail();
                            };

                            // todo. the rules below are specific to C#
                            Func<Type, Type, bool> has_cast_to = (wb, t) => wb == t || bitness(wb) < bitness(t);
                            Func<Type, Type, bool> args_match = (t1, t2) => has_cast_to(t_lhs, t1) && has_cast_to(t_rhs, t2);
                            Type t_result = null;
                            if (args_match(typeof(int), typeof(int))) t_result = typeof(int);
                            else if (args_match(typeof(uint), typeof(uint))) t_result = typeof(uint);
                            else if (args_match(typeof(long), typeof(long))) t_result = typeof(long);
                            else if (args_match(typeof(ulong), typeof(ulong))) t_result = typeof(ulong);
                            else t_result.AssertNotNull();

                            Types.Add(op, t_result);
                        }
                        else
                        {
                            (t_lhs.IsFloatingPoint() && t_rhs.IsFloatingPoint()).AssertTrue();
                            if (t_lhs == typeof(double) || t_rhs == typeof(double)) Types.Add(op, typeof(double));
                            else if (t_lhs == typeof(float) || t_rhs == typeof(float)) Types.Add(op, typeof(float));
                            else throw AssertionHelper.Fail();
                        }
                    }
                }
                else
                {
                    throw AssertionHelper.Fail();
                }
            }
        }
Exemplo n.º 5
0
        protected override void TraverseOperator(Operator op)
        {
            var lhs = op.Args.FirstOrDefault();
            var rhs = op.Args.SecondOrDefault();
            var targ = op.Args.FirstOrDefault();

            var opt = op.OperatorType;
            if (opt.IsAssign())
            {
                // todo. implement this with the use of SafeExpandOpAssign
                var equiv = op.UnsafeExpandOpAssign();
                Traverse(equiv);
            }
            else if (opt == OperatorType.AndAlso)
            {
                var equiv = new Conditional(lhs, rhs, new Const(false));
                Traverse(equiv);
            }
            else if (opt == OperatorType.OrElse)
            {
                var equiv = new Conditional(lhs, new Const(true), rhs);
                Traverse(equiv);
            }
            else
            {
                op.Args.ForEach(Traverse);

                switch (opt)
                {
                    case OperatorType.Add:
                        il.add();
                        break;
                    case OperatorType.And:
                        il.and();
                        break;
                    case OperatorType.Divide:
                        il.div();
                        break;
                    case OperatorType.Equal:
                        il.ceq();
                        break;
                    case OperatorType.GreaterThan:
                        il.cgt();
                        break;
                    case OperatorType.GreaterThanOrEqual:
                        il.cge();
                        break;
                    case OperatorType.LeftShift:
                        il.shl();
                        break;
                    case OperatorType.LessThan:
                        il.clt();
                        break;
                    case OperatorType.LessThanOrEqual:
                        il.cle();
                        break;
                    case OperatorType.Modulo:
                        il.rem();
                        break;
                    case OperatorType.Multiply:
                        il.mul();
                        break;
                    case OperatorType.Negate:
                        il.neg();
                        break;
                    case OperatorType.Not:
                        var is_bool = targ.Type() == typeof(bool);
                        if (is_bool) il.ldc_i4(0).ceq();
                        else il.not();
                        break;
                    case OperatorType.NotEqual:
                        il.cne();
                        break;
                    case OperatorType.Or:
                        il.or();
                        break;
                    case OperatorType.RightShift:
                        il.shr();
                        break;
                    case OperatorType.Subtract:
                        il.sub();
                        break;
                    case OperatorType.Xor:
                        il.xor();
                        break;
                    default:
                        throw AssertionHelper.Fail();
                }
            }
        }
Exemplo n.º 6
0
        protected override void TraverseOperator(Operator op)
        {
            var lhs = op.Args.FirstOrDefault();
            var rhs = op.Args.SecondOrDefault();
            var targ = op.Args.FirstOrDefault();

            var opt = op.OperatorType;
            if (opt.IsAssign())
            {
                var equiv = op.UnsafeExpandOpAssign();
                _ptx.ld(equiv);
            }
            else if (opt == OperatorType.AndAlso)
            {
                var equiv = new Conditional(lhs, rhs, new Const(false));
                _ptx.ld(equiv);
            }
            else if (opt == OperatorType.OrElse)
            {
                var equiv = new Conditional(lhs, new Const(true), rhs);
                _ptx.ld(equiv);
            }
            else
            {
                op.Args.ForEach(arg => _ptx.ld(arg));

                switch (opt)
                {
                    case OperatorType.Add:
                        _ptx.op("add");
                        break;
                    case OperatorType.And:
                        _ptx.op("and");
                        break;
                    case OperatorType.Divide:
                        _ptx.op("div");
                        break;
                    case OperatorType.Equal:
                        _ptx.op("setp.eq");
                        break;
                    case OperatorType.GreaterThan:
                        _ptx.op("setp.gt");
                        break;
                    case OperatorType.GreaterThanOrEqual:
                        _ptx.op("setp.ge");
                        break;
                    case OperatorType.LeftShift:
                        _ptx.op("shl");
                        break;
                    case OperatorType.LessThan:
                        _ptx.op("setp.lt");
                        break;
                    case OperatorType.LessThanOrEqual:
                        _ptx.op("setp.le");
                        break;
                    case OperatorType.Modulo:
                        _ptx.op("rem");
                        break;
                    case OperatorType.Multiply:
                        var t = _ptx.peek_expr().Type;
                        _ptx.op(t.is_int() ? "mul.lo" : "mul");
                        break;
                    case OperatorType.Negate:
                        _ptx.op("neg");
                        break;
                    case OperatorType.Not:
                        _ptx.ld("not");
                        break;
                    case OperatorType.NotEqual:
                        _ptx.op("setp.ne");
                        break;
                    case OperatorType.Or:
                        _ptx.op("or");
                        break;
                    case OperatorType.RightShift:
                        _ptx.op("shr");
                        break;
                    case OperatorType.Subtract:
                        _ptx.op("sub");
                        break;
                    case OperatorType.Xor:
                        _ptx.op("xor");
                        break;
                    default:
                        throw AssertionHelper.Fail();
                }
            }
        }
        protected internal override void TraverseOperator(Operator op)
        {
            var opt = op.OperatorType;
            if (op.IsUnary())
            {
                if (!opt.ToString().StartsWith("Post"))
                    _writer.Write(opt.ToCSharpSymbol());

                Traverse(op.Args.First());

                if (opt.ToString().StartsWith("Post"))
                    _writer.Write(opt.ToCSharpSymbol());
            }
            else if (op.IsBinary())
            {
                Traverse(op.Args.First());
                _writer.Write(" " + opt.ToCSharpSymbol() + " ");
                Traverse(op.Args.Second());
            }
            else
            {
                op.Unsupported();
            }
        }
 protected internal virtual Node TransformOperator(Operator op) { return op.AcceptTransformer(this, true); }