예제 #1
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);
            }
        }
예제 #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));
        }
예제 #3
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);
        }
    }
예제 #4
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));
        }
예제 #5
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);
        }
예제 #6
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);
 }