Seite 2 von 2

Verfasst: Sonntag 26. April 2009, 08:38
von darktrym
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:

Verfasst: Sonntag 26. April 2009, 08:53
von BlackJack
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.

Verfasst: Sonntag 26. April 2009, 08:57
von sma
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

Verfasst: Sonntag 26. April 2009, 09:35
von darktrym
@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!?

Verfasst: Sonntag 26. April 2009, 09:45
von sma
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

Verfasst: Sonntag 26. April 2009, 12:25
von darktrym
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))