Example #1
0
        public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
        {
            expr = null;
            var placeholders = Conditions.Count(AstPartiallyApplicable.IsPlaceholder);
            for (var node = Conditions.First; node != null; node = node.Next)
            {
                var condition = node.Value;
                _OptimizeNode(target, ref condition);
                node.Value = condition; //Update list of conditions with optimized condition

                PValue resultP;
                if (condition is AstConstant &&
                    ((AstConstant) condition).ToPValue(target).TryConvertTo(target.Loader,
                        PType.Bool, false, out resultP))
                {
                    if ((bool) resultP.Value == ShortcircuitValue)
                    {
                        // Expr1 OP shortcircuit OP Expr2 = shortcircuit
                        // Expr1 OP shortcircuit OP Expr2 OP ? = const(shortcircuit)
                        var shortcircuitConst = new AstConstant(condition.File, condition.Line,
                            condition.Column, ShortcircuitValue);
                        if (placeholders > 0)
                        {
                            if (!Conditions.Last.Value.IsPlaceholder() || placeholders > 1)
                                _reportInvalidPlaceholders(target);

                            expr = shortcircuitConst.ConstFunc();
                        }
                        else
                        {
                            expr = shortcircuitConst;
                        }
                        return true;
                    }
                    else
                    {
                        // Expr1 OP ¬shortcircuit OP Expr2 = Expr1 OP Expr2
                        Conditions.Remove(node);
                    }
                }
                else if (condition is AstPlaceholder)
                {
                    placeholders++;
                }
            }

            if (Conditions.Count == 0)
            {
                expr = new AstConstant(File, Line, Column, !ShortcircuitValue);
            }
            else if (Conditions.Count == 1)
            {
                var primaryExpr = Conditions.First.Value;
                expr = _GetOptimizedNode(target,
                    new AstTypecast(primaryExpr.File, primaryExpr.Line, primaryExpr.Column,
                        primaryExpr,
                        new AstConstantTypeExpression(primaryExpr.File,
                            primaryExpr.Line,
                            primaryExpr.Column,
                            PType.Bool.ToString())));
            }

            return expr != null;
        }