A brainfuck parser works now with newCTFE

Stefan Koch via Digitalmars-d digitalmars-d at puremagic.com
Sat Jul 29 18:15:50 PDT 2017


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.



More information about the Digitalmars-d mailing list