Hi Guys,

I just ran the first moderately complex ctfe function successfully through newCTFE!

This is the code that works now :

module bf_parser;

enum BFTokenEnum
{
    IncPtr = '>',
    DecPtr = '<',
    IncVal = '+',
    DecVal = '-',
    OutputVal = '.',
    InputVal = ',',
    LoopBegin = '[',
    LoopEnd = ']',

    ProgrammBegin,
    ProgrammEnd,
}

struct RepeatedToken
{
    uint _token;
    alias _token this;

    @property BFTokenEnum token() const pure
    {
        return cast(BFTokenEnum)(_token >> 24);
    }

    @property uint count() const pure
    {
        return _token & 0x00_FF_FF_FF;
    }
}

RepeatedToken Token(BFTokenEnum token) pure
{
    return cast(RepeatedToken)(token << 24 | 1);
}

const(RepeatedToken[]) parseBf(const string input) pure
{
    uint pos;
    RepeatedToken[] result;
    result.length = input.length + 2;
// the maximal number of diffrent tokens is equal to the chars in the input
    // plus the begin and end token

    result[0] = Token(BFTokenEnum.ProgrammBegin);
    uint resultLen = 0;

    while (pos < input.length)
    {
        final switch (input[pos++]) with (BFTokenEnum)
        {
        case '>':
if ((result[resultLen] & 0xFF_00_00_00) >> 24 == IncPtr)
            {
                result[resultLen]++;
            }
            else
            {
                result[++resultLen] = Token(IncPtr);
            }
            break;
        case '<':
if ((result[resultLen] & 0xFF_00_00_00) >> 24 == DecPtr)
            {
                result[resultLen]++;
            }
            else
            {
                result[++resultLen] = Token(DecPtr);
            }
            break;
        case '+':
if ((result[resultLen] & 0xFF_00_00_00) >> 24 == IncVal)
            {
                result[resultLen]++;
            }
            else
            {
                result[++resultLen] = Token(IncVal);
            }
            break;
        case '-':
if ((result[resultLen] & 0xFF_00_00_00) >> 24 == DecVal)
            {
                result[resultLen]++;
            }
            else
            {
                result[++resultLen] = Token(DecVal);
            }
            break;
        case '.':
if ((result[resultLen] & 0xFF_00_00_00) >> 24 == OutputVal)
            {
                result[resultLen]++;
            }
            else
            {
                result[++resultLen] = Token(OutputVal);
            }
            break;
        case ',':
if ((result[resultLen] & 0xFF_00_00_00) >> 24 == InputVal)
            {
                result[resultLen]++;
            }
            else
            {
                result[++resultLen] = Token(InputVal);
            }
            break;
        case '[':
if ((result[resultLen] & 0xFF_00_00_00) >> 24 == LoopBegin)
            {
                result[resultLen]++;
            }
            else
            {
                result[++resultLen] = Token(LoopBegin);
            }
            break;
        case ']':
if ((result[resultLen] & 0xFF_00_00_00) >> 24 == LoopEnd)
            {
                result[resultLen]++;
            }
            else
            {
                result[++resultLen] = Token(LoopEnd);
            }
            break;
        case '\r':
            pos++;
            goto case '\n';
        case '\n':
            //TODO handle lines and proper position information;
            break;
        }
    }

    result[++resultLen] = Token(BFTokenEnum.ProgrammEnd);
    return result[0 .. resultLen + 1];
}

pragma(msg, parseBf("[,....]")[3].token);

It has been a year of work to get to this point.
And it might seem a little trivial.

But this is actually the a showcase of methods, slices, strings and structs interacting.

Reply via email to