Merhaba,
Sonunda bir takım aksilikleri hallederek 13 ve 14. komutlar gibi nasıl da olmaz dedirten büyük geliştirmeler yaptım!
Belki artık kombine komutlar (birbirini etkileyen ve birbiri ile kombine çalışan vb. şeyler) yapılabilir. Hatta klasik döngü mantığı son eklediklerimle (?¿) değişebilir ve assembly ile uyumlu bir mantığa (adresle, sorgula ve atla) dönüştürülebilir.
Sürüm 2'ye inşaallah, son sürüm aşağıda:
import std.stdio, std.conv, std.format;
//import std.ascii : isWhite;/*
bool isWhite(dchar c) @safe pure nothrow @nogc {
return c >= 0x09 && c <= 0x0D;
}//*/
enum cellTest = ">>+<[>[<-]<[->+<]>]>¿#"; // min. BFv1.1
void main() {
auto encode = new InterpretBF!64(cellTest);
encode.writeln;
encode.n.writefln!"Toplam Döngü: %s";
encode.x.writefln!"Atlanan Harf: %s";
}
class InterpretBF(size_t memSize, T = ushort)
{ // Kod Adı: Beyin Farkı v1.1
size_t ptr, index, stackIndex;
T[] memory, stack;
char[] code;
enum ver = 1.1;
this(string data)
{
code = data.dup;
stack = new T[memSize << 2]; // 3, 4?
memory = new T[memSize];
}
void skipComment()
{
if(code[++index] == '/') // 9 Numaralı Komut
{
while( code[++index].isWhite){}
while(!code[++index].isWhite){}
} else --index;
}
size_t n, x;
// geçici, kaldır ----^
override string toString() { return this.to!string; }
void toString(scope void delegate(in char[]) sink)
{
while(index < code.length)
{
switch(code[index])
{
case '>': ++ptr; break; // orj.command-1
case '<': --ptr; break; // orj.command-2
case '+': ++memory[ptr]; break; // orj.command-3
case '-': --memory[ptr]; break; // orj.command-4
case '/': skipComment();
break; // 9 Numaralı Komut
case '&': memory[++ptr] += memory[ptr - 1];
break; // 10 Numaralı Komut
case '^': memory[ptr] <<= 1;
break; // 11 Numaralı Komut
case 'v': memory[ptr] >>= 1;
break; // 12 Numaralı Komut
case '?': if(memory[ptr]) ++index;
break; // 13 Numaralı Komut
case '¿': if(!memory[ptr]) ++index;
break; // 14 Numaralı Komut
case '[': // Skip and Push
int balance = 1;
if(!memory[ptr]) {
while(balance) {
switch(code[++index]) {
case '[': ++balance; break;
case ']': --balance; break;//*
case '/': /* TODO
auto fark = index + 1;
skipComment();
;n -= index - fark;
break;//*/
default : ++n; // skip char
}
}
} else stack[stackIndex++] = cast(T)index; // push
break; // orj.command-5
case ']': // Pop and Jump
if(memory[ptr]) index = stack[stackIndex - 1];
else --stackIndex;
break; // orj.command-6
case ',': // Input Char.
auto chr = cast(ubyte) readln[0];
memory[ptr] = chr;
break; // orj.command-7
case '.': // Print Char.
auto chr = cast(char) memory[ptr];
sink.formattedWrite("%c", chr);
break; // orj.command-8
case '#': // view first 8 cells of memory
sink.formattedWrite("%s: %s", ptr, memory[0..8]);
break; // 15 Numaralı Komut
case '%': // Reverse Cells
auto önceki = memory[ptr];
memory[ptr] = memory[ptr + 1];
memory[ptr + 1] = önceki;
break; // 16 Numaralı Komut
case '«': // Line Feed
sink.formattedWrite("%c", '\n');
break; // TODO
default: ++x;
} // main-switch-end
++index;
++n;
} // while-end
} // toString-end
}
Tabi lineFeed gibi gereksiz bir komut («) veya etkili olabilecek isFalseJump (¿) komutunun karakterlerinin Extended ASCII'de bulunması işleri karıştırabilir.
Bakcaz...