brainfuck-Compiler TMP style



  • Ich hab versucht, einen Interpreter zu schreiben... bin fast fertig (bin bei der Schleife 😃 ).



  • So, meine erste Version ist jetzt fertig. Bitte Verbesserungsvorschläge!
    Das Hello-World Programm von Wikipedia wird problemlos interpretiert 😃

    /**
          Brainfuck interpreter with Turing-completeness.
          @date: 16/05/2012
    
    */
    
    #include <iostream>
    #include <string>
    #include <deque>
    #include <stdexcept>
    #include <fstream>
    #include <cstdlib>
    #include <sstream>
    #include <unordered_multiset>
    
    typedef std::deque<char> list_type;
    
    list_type array(1);
    
    list_type::iterator iterator(array.begin());
    
    void processString(std::string const& code, std::ostream& output, std::istream& input)
    {
          for(auto strIter(code.begin());strIter != code.end();++strIter)
                switch(*strIter)
                {
                      case '.':
                            output.put(*iterator);
                            break;
    
                      case ',':
                            input.get(*iterator);
                            break;
    
                      case '>':
                      {
                            if(iterator + 1 == array.end())
                                  array.push_back(0);
                            ++iterator;
                      }
                            break;
    
                      case '<':
                      {
                            if(iterator == array.begin())
                                  array.push_front(0);
                            --iterator;
                      }
                            break;
    
                      case '+':
    
                            ++*iterator;
                            break;
    
                      case '-':
                            --*iterator;
                            break;
    
                      case '[':
                      {
    
                            auto braceClosePos = strIter + 1;
                            for(size_t counter(0);;++braceClosePos)
                            {
                                  if(*braceClosePos == '[')
                                        ++counter;
                                  if(*braceClosePos == ']')
                                  {
                                        if(counter)
                                              --counter;
                                        else break;
                                  }
                            }
    
                            std::string str(strIter + 1, braceClosePos);
    
                            while(*iterator)
                                  processString(str, output, input);
    
                            strIter = braceClosePos;
                      }
                }
    }
    
    int main(int argn, char const** params) try
    {
          #ifdef N_DEBUG
                if(argn < 2)
                      throw std::invalid_argument("No file to interpret. STOP.");
    
                std::ifstream stream(params[1]);
          #else
                std::ifstream stream("test.bff");
          #endif
    
          if(!stream)
                throw std::runtime_error("Stream operation failure. Check, wether file isn't corrupted.");
    
          std::ostringstream rdbufstream;
          rdbufstream << stream.rdbuf();
    
          {
                std::unordered_multiset<char> characterset(rdbufstream.str().begin(), rdbufstream.str().end());
                if(characterset.count('[') != characterset.count(']'))
                      throw std::logic_error("The amounts of opening and closing braces don't match!");
          }
    
          processString(rdbufstream.str(), std::cout, std::cin);
    }
    catch(std::exception& e)
    {
          std::cerr << "\nERROR: " << e.what() << '\n';
    }
    catch(...)
    {
          std::cerr << "\nAn unknown error occured.\n";
    }
    

    EDit: Jetzt oben was verbessert... 😃

    EDit²: Schleifen-logik Fehler verbessert (danke Ethon)



  • Deine Logik bei Klammern stinkt.

    [.........] ... ]
    

    Rate mal was da passiert. 😉



  • Ethon schrieb:

    Deine Logik bei Klammern stinkt.

    [.........] ... ]
    

    Rate mal was da passiert. 😉

    Ich weiß, die letzte wird ignoriert 😃
    Aber das lässt sich einfach korigieren (man müsste nur die Anzahl öffnender und schließender Klammern vergleichen) und ist jetzt nicht wichtig.

    Das ROT13-Programm von Wikipedia funktioniert nicht 😞

    Edit: AHHHH, shit:

    [..][..]
    

    funktioniert natürlich nicht 😃



  • Kann man die Threads bitte trennen? Ich finde, die haben so ziemlich gar nichts miteinander zu tun.



  • So, editiert ^^
    Jetzt dürfte jedes (syntaktisch korrekte) Programm funktionieren (und auch Ethons Problematik ist geklärt).



  • Brainfuck-Interpreter gibts auch hier: http://www.c-plusplus.net/forum/292057

    314159265358979 schrieb:

    Kann man die Threads bitte trennen?

    Ja, bitte.



  • Bashar schrieb:

    Brainfuck-Interpreter gibts auch hier: http://www.c-plusplus.net/forum/292057

    Gibts da denn einen in C++? Ist doch C# 😉



  • Und schon hab ich ein Ziel für Heute Nacht: Ein TMP-BF-Interpreter, also ein Interpreter im Compiler. 😋



  • 314159265358979 schrieb:

    Und schon hab ich ein Ziel für Heute Nacht: Ein TMP-BF-Interpreter, also ein Interpreter im Compiler. 😋

    Hä? Kannstes nochmal erklären? 🙂



  • Anstatt wie bei camper, das BF-Programm zur Laufzeit auszuführen, wird das Programm bei mir bereits zur Compilezeit ausgeführt.



  • Wie willste in-/output zur Compilezeit machen?



  • template <unsigned char...>
    struct memory
    {};
    

    :p



  • Also nur 'pseudo'.
    Trotzdem interessant, mach mal. 😉



  • Ethon schrieb:

    Also nur 'pseudo'.
    Trotzdem interessant, mach mal. 😉

    Was gibts eig. noch interessantes in der Richtung? Hab da grad voll Bock drauf 😃



  • Hacker schrieb:

    [...] Hab da grad voll Bock drauf 😃

    Lustmolch! 🤡



  • Hacker schrieb:

    Ethon schrieb:

    Also nur 'pseudo'.
    Trotzdem interessant, mach mal. 😉

    Was gibts eig. noch interessantes in der Richtung? Hab da grad voll Bock drauf 😃

    Unendlich viel. Schreib nen Mathe-Parser. Schreib einen Mergesort für Wert-Parameter. etc.



  • Wenn jemand mit TMP-Durchblick Lust auf ein interessantes Projekt hat, ich habe da gerade eine Idee (die sogar sinnvoll anwendbar ist), aber mir fehlt es etwas an Hintergrundwissen. Also wenn jemandem langweilig ist ... 😉



  • Sag halt. :p



  • Also, da muss ich etwas weiter ausholen. 😋
    Ich schreibe gerne Hacks für Spiele, die im Speicherbereich eines anderen Prozesses laufen, also per DLL-Injection. Nun benutze ich Linux und mache das auch mit Windows-Programmen, per Wine. Nun ist es aber so, dass unter Windows manche Funktionen gänzlich andersaufgerufen werden müssen ( http://en.wikipedia.org/wiki/X86_calling_conventions ), auch wenn der GCC da helfen kann, es funktioniert nicht immer. Die dreckige Lösung: Inline Assembler.

    Jetzt dachte ich mir, es wäre nett diese Calling-Conventions direkt in C++ zu definieren (Der Nte Integer/Float Parameter kommt in Register X), sollte zur Compilezeit kein Problem sein. Und dann damit und mit AsmJit ( http://code.google.com/p/asmjit/ ) zur Compilezeit Wrapperfunktionen bauen, in etwa so habe ich mir das vorgestellt:

    typedef calling_convention<RCX, RDX, R8, R9> windows_64;
    typedef calling_convention<RDI, RSI, RDX, RCX, R8, R9> system_v_amd64;
    auto malloc_wrapper = system_v_amd64::wrap_call<windows_64, void*, std::size_t>(&std::malloc);
    void* ptr = malloc_wrapper(123);
    

    Habe mir dazu schon einiges an Gedanken gemacht, leider macht mein mangelndes Können in Sachen TMP immer wieder alles kaputt. 🤡


Anmelden zum Antworten