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