Esempio n. 1
0
        /// <summary>
        /// Process a generic `Range` statement.
        /// </summary>
        /// <param name="nsType"></param>
        protected void ProcessRange()
        {
            DmlSyntaxError badRange = DmlSyntaxError.BadRangeStatement();
            Advance(exception: badRange);

            // Parse the loop variable.
            if (!DmlTokens.IsName(CurrentToken))
                throw badRange;

            string loopVariable = CurrentToken;

            Advance(exception: badRange);

            // Parse the range start.
            List<String> startTokens;
            try {
                startTokens = new List<String>(GetUntil(DmlTokens.ELLIPSES));
            } catch (ParserError) {
                throw badRange;
            }
            ExpressionBuilder startExpressionBuilder = new ExpressionBuilder(startTokens.ToArray(), currentLine);
            startExpressionBuilder.Parse();
            var startInstructions = (Instruction[])startExpressionBuilder.GetResult();

            Advance(exception: badRange);

            // Parse the range end and range step.
            List<String> endTokens;
            try {
                endTokens = new List<String>(GetUntil(DmlTokens.LANGLE));
            } catch (ParserError) {
                throw badRange;
            }

            // Check if the range operator is extended to include a step.
            int stepIndex = endTokens.IndexOf(DmlTokens.TRANSOP);
            List<String> stepTokens;

            if (stepIndex == endTokens.Count - 1)
                throw badRange;
            else if (stepIndex != -1)
            {
                stepTokens = new List<string>(endTokens.Skip(stepIndex + 1));
                endTokens = new List<string>(endTokens.Take(stepIndex));
            }
            else
                // Default step size is 1.
                stepTokens = new List<String>() { "1" };

            ExpressionBuilder endExpressionBuilder = new ExpressionBuilder(endTokens.ToArray(), currentLine);
            ExpressionBuilder stepExpressionBuilder = new ExpressionBuilder(stepTokens.ToArray(), currentLine);

            endExpressionBuilder.Parse();
            stepExpressionBuilder.Parse();

            var endInstructions = (Instruction[])endExpressionBuilder.GetResult();
            var stepInstructions = (Instruction[])stepExpressionBuilder.GetResult();

            /*
            if (DmlParser.IsSimpleConstant(startInstructions) &&
                DmlParser.IsSimpleConstant(endInstructions) &&
                DmlParser.IsSimpleConstant(stepInstructions)
                )
            {
                double start, end, step;
                try
                {
                    start = (double)(new CodeBlock(startInstructions).Evaluate(null, null).Value);
                    end   = (double)(new CodeBlock(endInstructions).Evaluate(null, null).Value);
                    step  = (double)(new CodeBlock(stepInstructions).Evaluate(null, null).Value);
                    InlineRange(loopVariable, start, end, step);
                }
                catch (InvalidCastException)
                {
                    // InlineRange can only handle double values.
                    ComplexRange(loopVariable, startInstructions, endInstructions, stepInstructions);
                }
            }
            else
             */
            // FIXME:
            // So there's a problem with InlineRange. If there are jump statements inside the code within
            // the Range block, the labels and the jumps will get repeated, so all jumps lead to the same
            // spot, which leads to infinite recursion.

            // Not sure why but sometimes the current token is set to the left namespace delimiter,
            // and sometimes its set to the first token after the delimiter. It doesn't seem to be
            // dependent on the presense of the step operator \> either. For now this works.
            if (DmlTokens.IsMatch(CurrentToken, DmlTokens.LANGLE))
                Advance();
            ComplexRange(loopVariable, startInstructions, endInstructions, stepInstructions);
        }
Esempio n. 2
0
        /// <summary>
        /// Parse a function call using the given loading instruction.
        /// </summary>
        /// <param name="load"></param>
        private void ParseFuncCall(Instruction load)
        {
            int parenthDepth = 1;

            DmlSyntaxError badCall = new DmlSyntaxError(
                "Invalid syntax; mismatched brackets for function call.");

            var subExpressions = new List<List<string>>();
            var currentExpression = new List<string>();

            while (true)
            {
                Advance(exception: badCall);
                if (DmlTokens.IsMatch(CurrentToken, DmlTokens.LPAR))
                    parenthDepth++;
                else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.RPAR))
                    parenthDepth--;
                else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.COMMA) && parenthDepth == 1) 
                {
                    subExpressions.Add(currentExpression);
                    currentExpression = new List<string>();
                    continue;
                }
                if (parenthDepth == 0) 
                {
                    if (currentExpression.Count > 0)
                        subExpressions.Add(currentExpression);
                    break;
                }
                currentExpression.Add(CurrentToken);
            }

            ExpressionBuilder eb;
            foreach (var subExpression in subExpressions)
            {
                eb = new ExpressionBuilder(subExpression.ToArray(), currentLine);
                eb.Parse();

                foreach (Instruction instruction in (Instruction[])(eb.GetResult()))
                    instructions.Add(instruction);
            }

            instructions.Add(load);
            instructions.Add(new CallFunction(subExpressions.Count));
        }
Esempio n. 3
0
 /// <summary>
 /// Process an array of tokens as an expression and append the instructions to a list.
 /// </summary>
 /// <param name="tokens"></param>
 protected void ProcessExpression(string[] tokens)
 {
     ExpressionBuilder eb = new ExpressionBuilder(tokens, currentLine);
     eb.Parse();
     Instruction[] expression_instructions = (Instruction[])eb.GetResult();
     foreach (Instruction instruction in expression_instructions)
         Instructions.Add(instruction);
 }