July 12, 2023

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...

July 13

On Wednesday, 12 July 2023 at 07:31:23 UTC, Salih Dincer wrote:

>

Sürüm 2'ye inşaallah, son sürüm aşağıda:

Sanırım böyle basit bir yorumlayıcı için v1.5 erkendi ama aynı sürüme dahil edilebilecek küçük bir std.ascii : isPrintable güncellemesi akıllıca gözüküyor! Böylece sizi modifiye edilmiş isWhite'dan kurtarıyor :)

import std.stdio, std.conv, std.format;
void main()
{
  InterpretBF!64 run; // Kod Adı: Beyin Farkı v1.5
  run.code = CODE.dup;
  run.writeln;
  run.n.writefln!"Toplam Döngü: %s";
  run.x.writefln!"Atlanan Harf: %s";
}

struct InterpretBF(size_t memSize, T = ushort)
{
  private {
    size_t ptr, index, stackIndex;
    T[memSize] memory;
    T[memSize << 2] stack;
  }
  char[] code;
  enum ver = 1.5;

  import std.ascii : isPrintable;
  void skipComment()
  {
    if(code[++index] == '/') // 9 Numaralı Komut
    {
      while(!code[++index].isPrintable){}
      while( code[++index].isPrintable){}
    } else --index;
  }
 //...

Öte taraftan, dilimleme yapmadığım için dinamik diziden ve ileride -betterC sürümü için sınıf yapısından uzaklaştım.

Sizce "bu yanlış" ya da "bu da olsa iyi olur" (misal alt program mekanizması nasıl olur?) dediğiniz bir şey varsa yazın lütfen.

Teşekkürler...