예제 #1
0
        protected async IAsyncEnumerable <Token> DoPreprocess(IAsyncStream <Token> input)
        {
            while (!await input.Eof())
            {
                Token token;
                if ((await input.Peek()).Kind == Pound)
                {
                    await input.Read();

                    if ((await input.Peek()).Kind == Identifier)
                    {
                        switch ((await input.Read() as ValueToken <string>) !.Value.ToLower())
                        {
예제 #2
0
 protected async IAsyncEnumerable <string> asyncStreamFuncQueries(IAsyncStream <string> input)
 {
     while (!await input.Eof())
     {
         yield return((await input.Read()) + "?");
     }
 }
예제 #3
0
        protected async IAsyncEnumerable <char> CountLines(IAsyncStream <char> input)
        {
            await foreach (char c in input)
            {
                yield return(c);

                if (c == '\r')
                {
                    if (!await input.Eof() && await input.Peek() == '\n')
                    {
                        yield return(await input.Read());
                    }
                    TranslationUnit.CurrentLine++;
                    TranslationUnit.CurrentColumn = 1;
                }
                else if (c == '\n')
                {
                    TranslationUnit.CurrentLine++;
                    TranslationUnit.CurrentColumn = 1;
                }
                else if (c == '\t')
                {
                    // TODO: Is this the expectation for tabs?
                    TranslationUnit.CurrentColumn += TAB_WIDTH - ((TranslationUnit.CurrentColumn - 1) % TAB_WIDTH);
                }
                else
                {
                    TranslationUnit.CurrentColumn++;
                }
            }
        }
예제 #4
0
 protected async IAsyncEnumerable <string> asyncStreamFuncLessThan6(IAsyncStream <int> input)
 {
     while (!await input.Eof())
     {
         if (await input.Peek() <= 5)
         {
             yield return((await input.Read()).ToString());
         }
         else
         {
             yield break;
         }
     }
 }
예제 #5
0
        protected async Task ProcessIncludeFileLine(IAsyncStream <Token> input, BufferBlock <Token> tokenBuffer)
        {
            Terminal?t = default;

            if ((await input.Peek()).Kind == Pound)
            {
                var poundToken = (await input.Read());
                if ((await input.Peek()).Kind == Identifier)
                {
                    ValueToken <string> directiveToken;
                    switch ((directiveToken = (ValueToken <string>)(await input.Read())).Value.ToLower())
                    {
                    case "include":
                        if ((t = (await input.Peek()).Kind) == LessThan || t == StringLiteral)
                        {
                            string?filename = null;
                            if (t == StringLiteral)
                            {
                                var token = await input.Read();

                                filename = ((ValueToken <string>)token).Value;
                                if (!await input.Eof())
                                {
                                    if ((await input.Peek()).Kind != Newline)
                                    {
                                        // TODO: Error
                                    }
                                    else
                                    {
                                        tokenBuffer.Post(await input.Read());
                                    }
                                    // TODO: Error
                                }
                            }
                            else
                            {
                                try
                                {
                                    var token = await input.Read();

                                    TranslationUnit.LexerState = LexerState.LexingLibraryFilename;
                                    if ((await input.Peek()).Kind == Filename)
                                    {
                                        filename = ((ValueToken <string>) await input.Read()).Value;
                                    }
                                }
                                finally
                                {
                                    TranslationUnit.LexerState = LexerState.LexerReady;
                                }
                                if ((await input.Peek()).Kind != GreaterThan)
                                {
                                    // TODO: Error
                                }
                                else
                                {
                                    await input.Read();
                                }
                                if (!await input.Eof())
                                {
                                    if ((await input.Peek()).Kind != Newline)
                                    {
                                        // TODO: Error
                                    }
                                    else
                                    {
                                        tokenBuffer.Post(await input.Read());
                                    }
                                    // TODO: Error
                                }
                            }
                            if (filename != null)
                            {
                                var dummyTask = tokenBuffer.PostAllAsync(
                                    ProcessPipeline(filename, IncludePipeline() !
                                                    .Chain(FilterEof !)))
                                                .ContinueWith(_ => tokenBuffer.Complete());
                            }
                        }
                        break;

                    default:
                    {
                        // Pass directive on to the rest of the pipeline
                        // (this method only handles the #include directive)
                        tokenBuffer.Post(poundToken);
                        tokenBuffer.Post(directiveToken);
                        while (!await input.Eof())
                        {
                            var token = await input.Read();

                            tokenBuffer.Post(token);
                            if (token.Kind == Newline)
                            {
                                break;
                            }
                        }
                        tokenBuffer.Complete();
                        break;
                    }
                    }
                }
                else
                {
                    // Pass line on to the rest of the pipeline
                    tokenBuffer.Post(poundToken);
                    while (!await input.Eof())
                    {
                        var token = await input.Read();

                        tokenBuffer.Post(token);
                        if (token.Kind == Newline)
                        {
                            break;
                        }
                    }
                    tokenBuffer.Complete();
                }
            }
            else
            {
                while (!await input.Eof())
                {
                    var token = await input.Read();

                    tokenBuffer.Post(token);
                    if (token.Kind == Newline)
                    {
                        break;
                    }
                }
                tokenBuffer.Complete();
            }
        }
예제 #6
0
        protected async IAsyncEnumerable <char> SpliceLines(IAsyncStream <char> input)
        {
            char c;

            while (!await input.Eof())
            {
                switch (c = await input.Read())
                {
                // Splice lines ending in '\' with the next line.
                case '\\':
                    bool whitespace = false;
                    while (!await input.Eof() && (await input.Peek() == ' ' || await input.Peek() == '\t'))
                    {
                        whitespace = true;
                        await input.Read();
                    }
                    if (await input.Eof())
                    {
                        if (whitespace)
                        {
                            yield return(' ');
                        }
                        yield return('\\');
                    }
                    else
                    {
                        c = await input.Read();

                        if (c == '\r')
                        {
                            if (!await input.Eof() && await input.Peek() == '\n')
                            {
                                await input.Read();
                            }
                        }
                        else if (c != '\n')
                        {
                            yield return('\\');

                            if (whitespace)
                            {
                                yield return(' ');
                            }
                            yield return(c);
                        }
                    }
                    break;

                case '\r':     // Convert "\r\n" to "\n"
                    if (!await input.Eof() && await input.Peek() == '\n')
                    {
                        await input.Read();
                    }
                    yield return('\n');

                    break;

                default:
                    yield return(c);

                    break;
                }
            }
        }
예제 #7
0
        protected async IAsyncEnumerable <char> ReplaceTrigraphs(IAsyncStream <char> input)
        {
            int  num_question_marks = 0;
            char c;

            while (!await input.Eof())
            {
                switch (c = await input.Read())
                {
                case '?':
                    num_question_marks++;
                    break;

                default:
                    if (num_question_marks >= 2)
                    {
                        while (num_question_marks > 2)
                        {
                            yield return('?');

                            num_question_marks--;
                        }
                        switch (c)
                        {
                        case '=':
                            yield return('#');

                            break;

                        case '/':
                            yield return('\\');

                            break;

                        case '\'':
                            yield return('^');

                            break;

                        case '(':
                            yield return('[');

                            break;

                        case ')':
                            yield return(']');

                            break;

                        case '!':
                            yield return('|');

                            break;

                        case '<':
                            yield return('{');

                            break;

                        case '>':
                            yield return('}');

                            break;

                        case '-':
                            yield return('~');

                            break;

                        default:
                            while (num_question_marks > 0)
                            {
                                yield return('?');
                            }
                            yield return(c);

                            break;
                        }
                        num_question_marks = 0;
                    }
                    else
                    {
                        yield return(c);
                    }
                    break;
                }
            }
            while (num_question_marks > 0)
            {
                yield return('?');
            }
        }