Ejemplo n.º 1
0
        /// <summary>Reads a new operation from the given lexer.</summary>
        /// <param name="sr">The lexer to read the operation from.</param>
        /// <param name="parent">The fragment to parent the operation to.</param>
        public OperationFragment(CodeLexer sr, CodeFragment parent)
        {
            ParentFragment = parent;
            LineNumber     = sr.LineNumber;
            bool localMode = false;

            while (true)
            {
                char peek = sr.Peek();

                if (peek == StringReader.NULL)
                {
                    return;
                }

                if (peek == ';' || peek == ',')
                {
                    // Read it off:
                    sr.Read();
                    return;
                }

                Handler handler = Handlers.Find(peek);

                if (handler == Handler.Stop)
                {
                    return;
                }

                // Handle the fragment:
                CodeFragment fragment;

                try{
                    // Try to get the code fragment:
                    fragment = Handlers.Handle(handler, sr);
                }catch (CompilationException e) {
                    if (e.LineNumber == -1)
                    {
                        // Setup line number:
                        e.LineNumber = LineNumber;
                    }

                    // Rethrow:
                    throw e;
                }

                if (localMode)
                {
                    // Should always be a VariableFragment:

                    if (fragment.GetType() == typeof(VariableFragment))
                    {
                        VariableFragment local = (VariableFragment)fragment;
                        local.AfterVar = true;
                    }

                    localMode = false;
                }

                // Try adding the fragment to the operation:
                AddResult status = fragment.AddTo(this, sr);

                // What was the outcome?
                switch (status)
                {
                case AddResult.Stop:
                    // Halt.
                    return;

                case AddResult.Local:
                    // Local next:
                    localMode = true;
                    break;
                    // Ok otherwise.
                }
            }
        }