Beispiel #1
0
        /// <summary>
        /// The shunting yard algorithm that processes a postfix list of expressions/operators.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="parser"></param>
        /// <param name="stack"></param>
        /// <returns></returns>
        public static Expr ProcessShuntingYardList(Context context, Parser.Parser parser, List <object> stack)
        {
            int  index    = 0;
            Expr finalExp = null;

            // Shunting yard algorithm handles POSTFIX operations.
            while (index < stack.Count && stack.Count > 0)
            {
                // Keep moving forward to the first operator * - + / && that is found
                // This is a postfix algorithm so it works by creating an expression
                // from the last 2 items behind an operator.
                if (!(stack[index] is TokenData))
                {
                    index++;
                    continue;
                }

                // At this point... we hit an operator
                // So get the last 2 items on the stack ( they have to be expressions )
                // left  is 2 behind current position
                // right is 1 behind current position
                var       left  = stack[index - 2] as Expr;
                var       right = stack[index - 1] as Expr;
                TokenData tdata = stack[index] as TokenData;
                Token     top   = tdata.Token;
                Operator  op    = Operators.ToOp(top.Text);
                Expr      exp   = null;

                if (Operators.IsMath(op))
                {
                    exp = Exprs.Binary(left, op, right, tdata);
                }
                else if (Operators.IsConditional(op))
                {
                    exp = Exprs.Condition(left, op, right, tdata);
                }
                else if (Operators.IsCompare(op))
                {
                    exp = Exprs.Compare(left, op, right, tdata);
                }

                parser.SetupContext(exp, tdata);
                stack.RemoveRange(index - 2, 2);
                index        = index - 2;
                stack[index] = exp;
                index++;
            }
            finalExp = stack[0] as Expr;
            return(finalExp);
        }
Beispiel #2
0
        /// <summary>
        /// run step 123.
        /// </summary>
        /// <returns></returns>
        public override Expr Parse()
        {
            var startToken     = _tokenIt.NextToken;
            var conditionToken = startToken;
            var assignToken    = startToken;
            var incToken       = startToken;
            var loopToken      = startToken;
            var varToken       = startToken;

            _tokenIt.ExpectIdText("repeat");
            Expr     varnameExpr = null;
            Expr     startVal    = null;
            Expr     endVal      = null;
            Expr     incVal      = null;
            Operator op          = Operator.LessThanEqual;

            // Case 1: repeat to 10
            if (_tokenIt.NextToken.Token.Text == "to")
            {
                var result = ParseTo();
                startVal = Exprs.Const(new LNumber(1.0), startToken);
                op       = result.Item1;
                endVal   = result.Item2;
                incVal   = result.Item3;
            }
            // Case 2: repeat 1 to 10
            else if (_tokenIt.NextToken.Token.Kind == TokenKind.LiteralNumber)
            {
                var num    = _tokenIt.ExpectNumber();
                var result = ParseTo();
                startVal = Exprs.Const(new LNumber(num), startToken);
                op       = result.Item1;
                endVal   = result.Item2;
                incVal   = result.Item3;
            }
            // Case 3: repeat ndx to 10
            else if (_tokenIt.NextToken.Token.Kind == TokenKind.Ident)
            {
                var variableName = _tokenIt.ExpectId();
                varnameExpr = Exprs.Ident(variableName, _tokenIt.LastToken);
                if (_tokenIt.NextToken.Token.Type == TokenTypes.Assignment)
                {
                    _tokenIt.Advance();

                    // Upto "to"
                    startVal = ParseExpr(_terminatorForTo);
                }
                else
                {
                    startVal = Exprs.Const(new LNumber(0), startToken);
                }
                var result = ParseTo();
                op     = result.Item1;
                endVal = result.Item2;
                incVal = result.Item3;
            }
            // auto-create variable name.
            if (varnameExpr == null)
            {
                varnameExpr = Exprs.Ident("it", _tokenIt.LastToken);
            }

            // Now setup the stmts
            var start     = Exprs.Assign(true, varnameExpr, startVal, varToken);
            var condition = Exprs.Compare(varnameExpr, op, endVal, varToken);
            var incExp    = Exprs.Unary(varnameExpr.ToQualifiedName(), incVal, 0, Operator.PlusEqual, incToken);
            var incStmt   = Exprs.Assign(false, varnameExpr, incExp, assignToken);
            var loopStmt  = Exprs.For(start, condition, incStmt, loopToken);

            ParseBlock(loopStmt as BlockExpr);
            return(loopStmt);
        }