예제 #1
0
        public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
        {
            Subject = _GetOptimizedNode(target, Subject);
            Type = (AstTypeExpr) _GetOptimizedNode(target, Type);

            expr = null;

            var constType = Type as AstConstantTypeExpression;
            if (constType == null)
                return false;

            //Constant cast
            var constSubject = Subject as AstConstant;
            if (constSubject != null)
                return _tryOptimizeConstCast(target, constSubject, constType, out expr);

            //Redundant cast
            AstTypecast castSubject;
            AstConstantTypeExpression sndCastType;
            if ((castSubject = Subject as AstTypecast) != null &&
                (sndCastType = castSubject.Type as AstConstantTypeExpression) != null)
            {
                if (Engine.StringsAreEqual(sndCastType.TypeExpression, constType.TypeExpression))
                {
                    //remove the outer cast.
                    expr = castSubject;
                    return true;
                }
            }

            return false;
        }
예제 #2
0
파일: AstExpand.cs 프로젝트: SealedSun/prx
 public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
 {
     //Do not optimize the macros arguments! They should be passed to the macro in their original form.
     //  the macro should decide whether or not to apply AST-optimization to the arguments or not.
     expr = null;
     return false;
 }
예제 #3
0
        public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
        {
            //Optimize condition
            _OptimizeNode(target, ref Condition);
            // Invert condition when unary logical not
            AstIndirectCall unaryCond;
            while (Condition.IsCommandCall(Commands.Core.Operators.LogicalNot.DefaultAlias, out unaryCond))
            {
                Condition = unaryCond.Arguments[0];
                IsNegative = !IsNegative;
            }

            //Constant conditions
            if (Condition is AstConstant)
            {
                var constCond = (AstConstant) Condition;
                PValue condValue;
                if (
                    !constCond.ToPValue(target).TryConvertTo(
                        target.Loader, PType.Bool, out condValue))
                    expr = null;
                else if (((bool) condValue.Value) ^ IsNegative)
                    expr = IfExpression;
                else
                    expr = ElseExpression;
                return expr != null;
            }

            expr = null;
            return false;
        }
예제 #4
0
 public AstKeyValuePair(
     string file, int line, int column, AstExpr key, AstExpr value)
     : base(file, line, column)
 {
     Key = key;
     Value = value;
 }
예제 #5
0
 public AstLogicalOr(
     string file,
     int line,
     int column,
     AstExpr leftCondition,
     AstExpr rightCondition)
     : base(file, line, column, leftCondition, rightCondition)
 {
 }
예제 #6
0
 public AstUnaryOperator(ISourcePosition position, UnaryOperator op, AstExpr operand)
     : base(position)
 {
     if (operand == null)
         throw new ArgumentNullException("operand");
     
     _operator = op;
     _operand = operand;
 }
예제 #7
0
 public AstConditionalExpression(
     string file, int line, int column, AstExpr condition, bool isNegative)
     : base(file, line, column)
 {
     if (condition == null)
         throw new ArgumentNullException("condition");
     Condition = condition;
     IsNegative = isNegative;
 }
예제 #8
0
 public AstCondition(ISourcePosition p, AstBlock parentBlock, AstExpr condition, bool isNegative = false)
     : base(p)
 {
     IfBlock = new AstScopedBlock(p,parentBlock,prefix: "if");
     ElseBlock = new AstScopedBlock(p,parentBlock,prefix:"else");
     if (condition == null)
         throw new ArgumentNullException("condition");
     Condition = condition;
     IsNegative = isNegative;
 }
예제 #9
0
 public AstTypecast(string file, int line, int column, AstExpr subject, AstTypeExpr type)
     : base(file, line, column)
 {
     if (subject == null)
         throw new ArgumentNullException("subject");
     if (type == null)
         throw new ArgumentNullException("type");
     Subject = subject;
     Type = type;
 }
예제 #10
0
        public AstPostExpression([NotNull] ISourcePosition position, [NotNull] AstExpr expression, [NotNull] AstNode action) : base(position)
        {
            if (expression == null)
                throw new ArgumentNullException("expression");

            if (action == null)
                throw new ArgumentNullException("action");
            
            _expression = expression;
            _action = action;
        }
예제 #11
0
 public AstGetSetMemberAccess(
     string file, int line, int column, PCall call, AstExpr subject, string id)
     : base(file, line, column, call)
 {
     if (subject == null)
         throw new ArgumentNullException("subject");
     if (id == null)
         id = "";
     Subject = subject;
     Id = id;
 }
예제 #12
0
 protected AstLazyLogical(
     string file,
     int line,
     int column,
     AstExpr leftExpression,
     AstExpr rightExpression)
     : base(file, line, column)
 {
     AddExpression(leftExpression);
     AddExpression(rightExpression);
 }
예제 #13
0
        public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
        {
            expr = null;

            var isConstant = true;
            var buffer = new StringBuilder(TypeId);
            buffer.Append("(");

            //Optimize arguments
            AstExpr oArg;
            foreach (var arg in Arguments.ToArray())
            {
                oArg = _GetOptimizedNode(target, arg);
                if (!ReferenceEquals(oArg, arg))
                {
                    Arguments.Remove(arg);
                    Arguments.Add(oArg);
                }

                var constValue = oArg as AstConstant;
                var constType = oArg as AstConstantTypeExpression;

                if (constValue == null && constType == null)
                {
                    isConstant = false;
                }
                else if (isConstant)
                {
                    if (constValue != null)
                    {
                        buffer.Append('"');
                        buffer.Append(
                            StringPType.Escape(
                                constValue.ToPValue(target).CallToString(target.Loader)));
                        buffer.Append('"');
                    }
                    else //if(constType != null)
                        buffer.Append(constType.TypeExpression);
                    buffer.Append(",");
                }
            }
            if (!isConstant)
                return false;

            buffer.Remove(buffer.Length - 1, 1); //remove , or (
            if (Arguments.Count != 0)
                buffer.Append(")"); //Add ) if necessary

            expr = new AstConstantTypeExpression(File, Line, Column, buffer.ToString());
            return true;
        }
예제 #14
0
 public void AddExpression(AstExpr expr)
 {
     //Flatten hierarchy
     var lazy = expr as AstLazyLogical;
     if (lazy != null && lazy.GetType() == GetType())
     {
         foreach (var cond in lazy._conditions)
             AddExpression(cond);
     }
     else
     {
         _conditions.AddLast(expr);
     }
 }
예제 #15
0
        public AstStringConcatenation(ISourcePosition position, AstGetSet simpleConcatPrototype, AstGetSet multiConcatPrototype, params AstExpr[] arguments)
            : base(position)
        {
            if (simpleConcatPrototype == null)
                throw new ArgumentNullException("simpleConcatPrototype");
            if (multiConcatPrototype == null)
                throw new ArgumentNullException("multiConcatPrototype");
            
            if (arguments == null)
                arguments = new AstExpr[] {};

            _arguments.AddRange(arguments);
            _simpleConcatPrototype = simpleConcatPrototype;
            _multiConcatPrototype = multiConcatPrototype;
        }
예제 #16
0
        public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
        {
            expr = null;

            _typeExpr = (AstTypeExpr) _GetOptimizedNode(target, _typeExpr);

            //Optimize arguments
            for (var i = 0; i < _arguments.Count; i++)
            {
                var arg = _arguments[i];
                var oArg = _GetOptimizedNode(target, arg);
                if (ReferenceEquals(oArg, arg))
                    continue;
                _arguments[i] = oArg;
            }

            return false;
        }
예제 #17
0
 public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
 {
     foreach (var arg in Elements.ToArray())
     {
         if (arg == null)
             throw new PrexoniteException(
                 "Invalid (null) argument in ListLiteral node (" + ToString() +
                     ") detected at position " + Elements.IndexOf(arg) + ".");
         var oArg = _GetOptimizedNode(target, arg);
         if (!ReferenceEquals(oArg, arg))
         {
             var idx = Elements.IndexOf(arg);
             Elements.Insert(idx, oArg);
             Elements.RemoveAt(idx + 1);
         }
     }
     expr = null;
     return false;
 }
예제 #18
0
파일: AstGetSet.cs 프로젝트: SealedSun/prx
        public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
        {
            expr = null;

            //Optimize arguments
            for (var i = 0; i < Arguments.Count; i++)
            {
                var arg = Arguments[i];
                if (arg == null)
                    throw new PrexoniteException(
                        "Invalid (null) argument in GetSet node (" + ToString() +
                            ") detected at position " + Arguments.IndexOf(arg) + ".");
                var oArg = _GetOptimizedNode(target, arg);
                if (!ReferenceEquals(oArg, arg))
                    Arguments[i] = oArg;
            }

            return false;
        }
예제 #19
0
 public static bool TryCreateConstant(
     CompilerTarget target,
     ISourcePosition position,
     PValue value,
     out AstExpr expr)
 {
     expr = null;
     if (value.Type is ObjectPType)
         target.Loader.Options.ParentEngine.CreateNativePValue(value.Value);
     if (value.Type is IntPType 
         || value.Type is RealPType 
         || value.Type is BoolPType 
         || value.Type is StringPType 
         || value.Type is NullPType 
         || _isModuleName(value))
         expr = new AstConstant(position.File, position.Line, position.Column, value.Value);
     else //Cannot represent value in a constant instruction
         return false;
     return true;
 }
예제 #20
0
        public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
        {
            expr = null;

            //Optimize arguments
            for (var i = 0; i < _expressions.Count; i++)
            {
                var arg = _expressions[i];
                if (arg == null)
                    throw new PrexoniteException(
                        "Invalid (null) argument in GetSet node (" + ToString() +
                            ") detected at position " + _expressions.IndexOf(arg) + ".");
                var oArg = _GetOptimizedNode(target, arg);
                if (!ReferenceEquals(oArg, arg))
                    _expressions[i] = oArg;
            }

            var nonNullExpressions = _expressions.Where(_exprIsNotNull).ToArray();
            _expressions.Clear();
            _expressions.AddRange(nonNullExpressions);

            if (_expressions.Count == 1)
            {
                var pExpr = _expressions[0];
                expr = pExpr is AstPlaceholder ? ((AstPlaceholder) pExpr).IdFunc() : pExpr;
                return true;
            }
            else if (_expressions.Count == 0)
            {
                expr = new AstNull(File, Line, Column);
                return true;
            }
            else
            {
                return false;
            }
        }
예제 #21
0
 private static AstExpr _genCompare(MacroContext context, AstExpr retVar,
     ReturnVariant expected)
 {
     var inv = context.Invocation;
     AstExpr expectedNode = new AstConstant(inv.File,
         inv.Line,
         inv.Column, (int) expected);
     return context.Factory.BinaryOperation(inv.Position, retVar, BinaryOperator.Equality, expectedNode);
 }
예제 #22
0
 public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
 {
     var constant = Expression as AstConstant;
     if (constant != null)
     {
         // Constants have no side-effects, convert this to a block with a return value
         var block = target.Factory.Block(Position);
         block.Add(Action);
         block.Expression = Expression;
         expr = block;
         return true;
     }
     else
     {
         expr = null;
         return false;
     }
 }
예제 #23
0
파일: CallStar.cs 프로젝트: SealedSun/prx
 private static bool _isPartialList(AstExpr expr, out AstListLiteral lit)
 {
     lit = expr as AstListLiteral;
     return lit != null && lit.CheckForPlaceholders();
 }
예제 #24
0
파일: CallStar.cs 프로젝트: SealedSun/prx
 private static bool _isPartialList(AstExpr expr)
 {
     AstListLiteral lit;
     return _isPartialList(expr, out lit);
 }
예제 #25
0
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Value)
                throw new NotSupportedException("While loops do not produce values and can thus not be used as expressions.");
            if (!IsInitialized)
                throw new PrexoniteException("AstWhileLoop requires Condition to be set.");

            //Optimize unary not condition
            _OptimizeNode(target, ref Condition);
            // Invert condition when unary logical not
            AstIndirectCall unaryCond;
            while (Condition.IsCommandCall(Commands.Core.Operators.LogicalNot.DefaultAlias, out unaryCond))
            {
                Condition = unaryCond.Arguments[0];
                IsPositive = !IsPositive;
            }

            //Constant conditions
            var conditionIsConstant = false;
            if (Condition is AstConstant)
            {
                var constCond = (AstConstant) Condition;
                PValue condValue;
                if (
                    !constCond.ToPValue(target).TryConvertTo(
                        target.Loader, PType.Bool, out condValue))
                    goto continueFull;
                else if ((bool) condValue.Value == IsPositive)
                    conditionIsConstant = true;
                else
                {
                    //Condition is always false
                    if (!IsPrecondition) //If do-while, emit the body without loop code
                    {
                        target.BeginBlock(Block);
                        Block.EmitEffectCode(target);
                        target.EndBlock();
                    }
                    return;
                }
            }
            continueFull:

            target.BeginBlock(Block);
            if (!Block.IsEmpty) //Body exists -> complete loop code?
            {
                if (conditionIsConstant) //Infinite, hopefully user managed, loop ->
                {
                    target.EmitLabel(Position, Block.ContinueLabel);
                    target.EmitLabel(Position, Block.BeginLabel);
                    Block.EmitEffectCode(target);
                    target.EmitJump(Position, Block.ContinueLabel);
                }
                else
                {
                    if (IsPrecondition)
                        target.EmitJump(Position, Block.ContinueLabel);

                    target.EmitLabel(Position, Block.BeginLabel);
                    Block.EmitEffectCode(target);

                    _emitCondition(target);
                }
            }
            else //Body does not exist -> Condition loop
            {
                target.EmitLabel(Position, Block.BeginLabel);
                _emitCondition(target);
            }

            target.EmitLabel(Position, Block.BreakLabel);
            target.EndBlock();
        }
예제 #26
0
 internal AstLogicalOr(Parser p, AstExpr leftCondition, AstExpr rightCondition)
     : base(p, leftCondition, rightCondition)
 {
 }
예제 #27
0
        public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
        {
            if (Key == null)
                throw new PrexoniteException("AstKeyValuePair.Key must be initialized.");
            if (Value == null)
                throw new ArgumentNullException("target");

            _OptimizeNode(target, ref Key);
            _OptimizeNode(target, ref Value);

            expr = null;

            return false;
        }
예제 #28
0
 internal AstKeyValuePair(Parser p, AstExpr key, AstExpr value)
     : base(p)
 {
     Key = key;
     Value = value;
 }
예제 #29
0
            private void _implementMergeRules(MacroContext context, AstExpr ce,
                                              IEnumerable<AstNode> fs, AstExpr fe)
            {
                var contextBlock = context.Block;
                //cs  is already stored in contextBlock, 
                //  the rules position cs always at the beginning, thus no need to handle cs.

                //At this point
                //  {   ce   }  iff (ce ∧ fs ∧ fe)
                //  {tmp = ce}  iff (ce ∧ fs ∧ ¬fe)
                //  {        }  otherwise
                if (ce != null && fs != null)
                {
                    if (fe != null)
                    {
                        contextBlock.Add(ce);
                    }
                    else
                    {
                        //Might at a later point become a warning
                        var invocationPosition = context.Invocation.Position;
                        context.ReportMessage(Message.Create(MessageSeverity.Info,
                                                             String.Format(
                                                                 Resources.MacroFunctionExpander__UsedTemporaryVariable,
                                                                 HumanId),
                                                             invocationPosition, MessageClasses.BlockMergingUsesVariable));

                        var tmpV = context.AllocateTemporaryVariable();

                        //Generate assignment to temporary variable
                        var tmpVRef = context.Factory.Reference(invocationPosition, EntityRef.Variable.Local.Create(tmpV));
                        var assignTmpV = context.Factory.IndirectCall(invocationPosition,tmpVRef,PCall.Set);
                        assignTmpV.Arguments.Add(ce);
                        contextBlock.Add(assignTmpV);

                        //Generate lookup of computed value
                        ce = context.Factory.IndirectCall(invocationPosition,tmpVRef);
                    }
                }

                //At this point
                //  {fs}    iff (fs)
                //  {  }    otherwise

                if (fs != null)
                {
                    foreach (var stmt in fs)
                        contextBlock.Add(stmt);
                }

                //Finally determine expression
                //  = fe    iff (ce ∧ fe)
                //  = ce    iff (ce ∧ ¬fe ∧ ¬fs)
                //  = tmp   iff (ce ∧ ¬fe ∧ fs)
                //  = ⊥     otherwise
                if (fe != null)
                    contextBlock.Expression = fe;
                else if (ce != null)
                    contextBlock.Expression = ce; //if tmp is involved, it has replaced ce
                else
                    contextBlock.Expression = null; //macro session will cover this case
            }
예제 #30
0
 public override bool TryOptimize(CompilerTarget target, out AstExpr expr)
 {
     expr = null;
     return false;
 }