Plattformunabhängigkeit und getch(curses)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
darktrym
User
Beiträge: 700
Registriert: Freitag 24. April 2009, 09:26

Beitragvon darktrym » Sonntag 26. April 2009, 08:38

Das Problem wäre dann aber das alles nur unter best. Vorraussetzungen funktioniert. Die gängiste Methode wäre dann den Code umwandeln in Assembler und ihn lokal übersetzen lassen & ausführen.

Ich dachte da mehr an einen Präprozessor oder JIT Optimierung. Ein kleines Beispiel:
BF: +++++ 5mal lesen & auswerten
OBF: 5+ 2mal lesen & auswerten
-----
Ergebnis: sauschnell :twisted:
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

Beitragvon BlackJack » Sonntag 26. April 2009, 08:53

Also ich würde mir da wohl die Arbeit sparen, denn BF lässt sich *sehr* einfach nach C übersetzen, und ein optimierender C-Compiler sollte aus 5× inkrementieren nacheinander *eine* Addition machen.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Beitragvon sma » Sonntag 26. April 2009, 08:57

Stichwort Compiler: In einem anderen Thread hatte ich mal einen BF-Compiler geschrieben, der dann nochmals von mitsuhiko in Eleganz und Kürze übertroffen wurde.

Stefan
Benutzeravatar
darktrym
User
Beiträge: 700
Registriert: Freitag 24. April 2009, 09:26

Beitragvon darktrym » Sonntag 26. April 2009, 09:35

@BlackJack: Sicher kann das der gcc optimieren, viel mehr aber nicht. Am Muster, Ausführen irgendwelcher Anweisungen kommt er nicht dran vorbei, da er(Compiler) niemals weiß was das Programm letztendlich für eine Aufgabe hat, halten sich die Optimierungen in Grenzen. z.B. Zählschleifen um eine Zelle auf einen bestimmten Wert zu setzen, könnte man zu einfach "Wert setzen" optimieren. Erkennt ein Compiler so etwas?

@sma: Ich dachte, das getch und std.read nicht das gleiche Verhalten haben. Siehe Posting 2 und 3. Frage. Kannst du mir sagen wie ich dein Code starte bzw. einbinde? Auch bekomme ich einen Syntaxfehler in deiner letzten Zeile!?
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Beitragvon sma » Sonntag 26. April 2009, 09:45

Rufe `run_brainfuck("....Programm...")` auf. Wenn du einen Syntaxfehler bekommst, hast du wahrscheinlich Python 3. Mache Klammern um das `exec`, da es kein Statement mehr ist sondern eine Funktion geworden ist.

Das sys.stdin.read(1) Zeichen nicht unmittelbar liest, ist mir bekannt, war aber für das Beispiel egal. Es gibt halt keinen plattformunabhängigen Weg, ein einzelnes Zeichen einzulesen, da Python für Windows keine curses-Emulation mitbringt.

Stefan
Benutzeravatar
darktrym
User
Beiträge: 700
Registriert: Freitag 24. April 2009, 09:26

Beitragvon darktrym » Sonntag 26. April 2009, 12:25

Hallo sma,
ich habe dein Code mit meinen gekreuzt um zu testen wie schnell deine Variante ist. Leider kommt er nur bis "91 Bottles of beer\nTake one down and pass it around"

Gibts eine python interne Beschränkung für deinen Code? Oder habe ich einen Fehler gemacht?

Nochmals "unseren" Code:

Code: Alles auswählen

import sys
import platform

def compile_brainfuck(src):
    program = ["def bf():", " import sys", " cells, ptr = [0] * 1000, 0"]
    indent = 1
    def emit(line): program.append(" " * indent + line)
    for s in src:
        if s == ">": emit("ptr += 1")
        elif s == "<": emit("ptr -= 1")
        elif s == "+": emit("cells[ptr] += 1")
        elif s == "-": emit("cells[ptr] -= 1")
        elif s == ".": emit("sys.stdout.write(chr(cells[ptr]))")
        elif s == ",": emit("cells[ptr] = ord(sys.stdin.read(1))")
        elif s == "[": emit("while cells[ptr]:"); indent += 1
        elif s == "]": emit("pass"); indent -= 1
    indent -= 1; emit("bf()")
    return "\n".join(program)
   

try:
   filehandler = open(sys.argv[1],"r")
except IndexError:
   print("wrong syntax: no source file")
   exit(-1)
   
code = ""
brainfucksymbols = ('+','-','>','<','.',',','[',']')
while True:
   line = filehandler.readline()
   if line == "":
      break
   for char in line:
      if char in brainfucksymbols:
         code+=char

exec (compile_brainfuck(code))
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github

Wer ist online?

Mitglieder in diesem Forum: Astorek