Brain**** Interpreter

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
antimicro
User
Beiträge: 151
Registriert: Sonntag 29. Februar 2004, 16:24

Hi,
ich bin mir sicher das kann man an einigen Stellen auch eleganter lösen, aber ich bin ein schlechter 'Programmierer' :)
bitte Kritik:

Code: Alles auswählen

#---------------------------+
#     tmachine.py           |
# von Sebastian (mepnet.de) |
# Datum: 11.4.2006          |
#---------------------------+

class machine:
	def __init__(self,space=1024):
		self.memory = [0 for i in xrange(0,space,1)] #Speicher
		self.pointer = 0 #Speicherzeiger
		self.loop_count = 0 #Schleifenzaehler (Syntaktisch [-] etc.)
		self.loops = 0 #Schleifenzaehler (Anzahl)
		self.loop_source = "" #Source fuer neue Maschineninst.

	def load_orders(self,string):
		"""Laed global Befehle fuer diese Maschineninstanz
				Parameter:
					string: String mit BF Syntax"""
		self.orders = string
	
	def run(self):
		"""Arbeitet alle Befehle ab die mit load_orders geladen wurden"""
		for command in self.orders: #Iteriert alle BF Befehle
			if command == "[": #Beginn einer Schleife
				self.loop_count += 1 #fuer verschachtelte Schleifen
				self.loops = self.memory[self.pointer] #Anzahl der Schleifendurchgaenge
			elif command == "]":									
				self.loop_count -= 1								
				if self.loop_count == 0: #Wenn die Schleifensyntax zuende ist dann...
					loop_machine = machine() #neues Objekt das den Code in der Schleife ausfuehrt
					loop_machine.set_memory_and_pointer(self.memory,self.pointer)
					loop_machine.load_orders(self.loop_source[1:])
					for i in xrange(0,self.loops,1): #sooft wie die Schleife ausgefuehrt werden muss
						loop_machine.run() #lauft run()
						self.memory,self.pointer = loop_machine.get_memory_and_pointer()
			
			if self.loop_count: #den Code einer Schleife aufzeichnen
				self.loop_source += command
			elif self.loop_count == 0: #aber vielleicht gibt es ja gar keine Schleife ?! dann...
				self.memory,self.pointer = self.do_command(command,self.memory,self.pointer)
	
	def do_command(self,command,memory,pointer):
		"""do_command fuehrt ein BF Befehl aus
			Parameter:
				command: der BF Befehl <,>,+,+,,,.,[ oder ]
				memory: PythonListe vom Speicher
				pointer: Pos. wo der S/L Kopf steht
			Ergebnisse:
				(memory,pointer): Tupel"""
		if command == "+":
			memory[pointer] += 1
		elif command == "-":
			memory[pointer] -= 1
		elif command == ">":
			pointer += 1
		elif command == "<":
			pointer -= 1
		elif command == ".":
			print chr(memory[pointer]),
		elif command == ",":
			memory[pointer] = ord(raw_input(":"))
		
		return (memory,pointer)
	
	def get_memory_and_pointer(self):
		"""Gibt den Speicher und die Pos. vom S/L Kopf zurueck
			Ergebnisse:
				(memory,pointer): Tupel"""
		return self.memory,self.pointer
	
	def set_memory_and_pointer(self,memory,pointer):
		"""Laed Speicher und Pos. vom S/L Kopf fuer diese Klasse"""
		self.memory = memory
		self.pointer = pointer
	
	def show_memory(self):
		"""Zeigt den Speicher"""
		print "-- MemoryDump --"
		print self.memory
		print "-- MemoryDump End --"
				
if __name__ == "__main__":
	maschine = machine()
	code = """
		Beispiel von Wikipedia
		++++++++++
		[>+++++++>++++++++++>+++>+<<<<-] Schleife zur Vorbereitung der Textausgabe
		>++. Ausgabe von 'H'
		>+. Ausgabe von 'e'
		+++++++. 'l'
		. 'l'
		+++. 'o'
		>++. Leerzeichen
		<<+++++++++++++++. 'W'
		>. 'o'
		+++. 'r'
		------. 'l'
		--------. 'd'
		>+. '!'
		>.
	"""
	maschine.load_orders(code)
	maschine.run()
	#maschine.show_memory()

Ach ja: ich hab irgendwo im Netz einen wesentlich kleineren Interpreter gefunden, allerdings den Code überhaupt nicht verstanden :(
Zuletzt geändert von antimicro am Mittwoch 12. April 2006, 08:52, insgesamt 1-mal geändert.
greetings
sebi
henning
User
Beiträge: 274
Registriert: Dienstag 26. Juli 2005, 18:37

Sieht interessant aus.
Aber sehe ich das richtig, dass die Zahl der Schleifendurchgänge vor dem ausführen der Schleife schon festgelegt ist?
Wenn ich mich recht entsinne gab es in Brainfuck so Konstrukte wie die z.B. eine Position auf Null gesetzt haben.
Dazu muss aber self.memory[self.pointer] in jedem Schleifendurchlauf neu geprüft werden, da man ja nicht weiß, wie ein Durchlauf den Wert verändert, oder?
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Was mir direkt in die Augen fällt, sind die Kommentare... Das macht wohl wirklich keiner so ;) Warum nicht diese normal in den Code einrücken? Ist viel übersichtlicher ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Kleine Rechtschreib-Anmerkung: Das heisst entweder "Maschine" oder "Machine". :-)
antimicro
User
Beiträge: 151
Registriert: Sonntag 29. Februar 2004, 16:24

@BlackJack:
danke für den Hinweis, hab’s geändert

@jens:
Was meist du mit „normal in den Code einrücken“. Direkt dahinter, so wie jetzt, oder wie?

@henning:
ist das wirklich so? Ich hatte mich schon gefragt wie man eine Endlosschleife basteln will. Dann ändere ich das mal..
aber
[-]
sollte trotzdem Funktionieren :)
greetings
sebi
henning
User
Beiträge: 274
Registriert: Dienstag 26. Juli 2005, 18:37

Wie gesagt, ich bin nicht sicher, aber es macht in meinen Augen mehr Sinn, bei allen anderen Sprachen wird die Schleifenbedingung ja auch bei jedem Durchlauf geprüft.

Und was ist mit

Code: Alles auswählen

 [+] 
oder

Code: Alles auswählen

 [--] 
Hier mal ein kleiner test, wenn der unter deinem und einem anderen Brainfuck-Interpreter jeweils "B" ausgibt, hattest du recht und wenn er bei nem anderen nichts (Bzw. das 0-Zeichen) ausgibt, funktionieren BF-Loops so wie ich vermute.

Wenn ich deinen Code richtig gelesen habe, müsste das heir bei dir auf jeden Fall ein "B" ausgeben.
Man beachte, dass ich absichtlich oben keine Schleife verwendet habe, da die ja grade getestet werden sollen und ichs nicht unnötig kompliziert machen wollte.

Code: Alles auswählen

++++++++++
++++++++++
++++++++++
+++
[+]
.
thelittlebug
User
Beiträge: 188
Registriert: Donnerstag 20. Juli 2006, 20:46
Wohnort: Wien
Kontaktdaten:

Hi,

da ich Brain**** nicht wirklich kann kommt von mir nur eine Kleinigkeit um mit neu gelerntem Anzugeben :D

statt

Code: Alles auswählen

self.memory = [0 for i in xrange(0,space,1)] #Speicher
xrange(0,self.loops,1)

verwende ich immer

Code: Alles auswählen

self.memory = [0]*space #Speicher
xrange(self.loops)
lg tlb
Malle
User
Beiträge: 29
Registriert: Freitag 11. August 2006, 19:04
Wohnort: Coswig
Kontaktdaten:

sry aber hab ich hier irgend etwas missverstanden oder gibt das Programm wirklich nur HALLO WELT aus?
BlackJack

Das Brainfuck Programm? Ja das gibt "Hello World" aus.
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Hi all,

ich vermute, Malle hat genauso wenig Ahnung was Brain**** ist, wie ich bis eben. Vielleicht klären uns die Eingeweihten mal der Vollständigkeit halber auf. Grundinfo habe ich von http://de.wikipedia.org/wiki/Brainfuck

Danke,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
BlackJack

Ich glaube mit dem Wikipedia-Artikel weisst Du schon alles wichtige. Ist halt 'ne ziemlich minimalistische Programmiersprache. Gut als Gag oder für Wettbewerbe. Eine grosse Anwendung will man damit aber nicht schreiben. Im Grunde nicht mal eine kleine Anwendung. ;-)
Antworten