Forth

Code-Stücke können hier veröffentlicht werden.
BlackJack

Dann hätte ich die beiden vielleicht doch in einem Thema belassen sollen. :twisted:
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Entweder Troll oder er ist noch sehr jung, dass er so komisch schreibt. Vielleicht ist er auch das Kind von Alfons Mittelmeyer. :o
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

@Alfons Mittelmeyer: Anmerkungen zum Code:

Wenn ich ein Interpreter-Objekt habe, würde ich nicht davon ausgehen, dass daneben noch eine Menge globaler Variablen existieren, und es nur einen Interpreter geben kann. Da ist nämlich die Interpreter-Klasse gar keine, sondern eine einfache Funktion. Klassenattribute sind kein Ersatz für Instanzattribute, die Klassenattribute bei IP und Interpreter sollten eigentlich Instanzattribute sein und in __init__ gesetzt werden.

Das ganze mal objektorientiert:

Code: Alles auswählen

import sys
 
class Interpreter:
    def __init__(self, code, functions=None):
        self.code = code
        self.functions = functions
        self.ip = 0
        self.running = False
        self.stack = []
        self.returnstack = []
        self.loopstack = []
    
    def next_code(self):
        self.ip += 1
        return self.code[self.ip - 1]
            
    def run(self):
        self.running = True
        while self.running:
            try:
                command = self.next_code()
            except IndexError:
                if not self.returnstack:
                    break
                self.code, self.ip = self.returnstack.pop()
            else:
                getattr(self, 'cmd_' + command)()
 
    def cmd_abort(self):
        self.running = False
 
    def cmd_semis(self):
        self.code, self.ip = self.returnstack.pop()
 
    def cmd_lit(self):
        self.stack.append(self.next_code())
 
    def cmd_output(self):
        sys.stdout.write('{}'.format(self.stack.pop()))
 
    def cmd_emit(self):
        sys.stdout.write(chr(self.stack.pop()))
 
    def cmd_do(self):
        self.loopstack.append([self.stack.pop(), self.stack.pop(), self.ip])
 
    def cmd_i(self):
        self.stack.append(self.loopstack[-1][0])
 
    def cmd_loop(self):
        self.loopstack[-1][0] += 1
        cur, end, ip = self.loopstack[-1]
        if cur < end:
            self.ip = ip
        else:
            self.loopstack.pop()

    def cmd_call(self):
        function = self.functions[self.next_code()]
        self.returnstack.append((self.code, self.ip))
        self.code = function
        self.ip = 0


code_nl = ('lit','\n','output','semis')
code = ('lit',96,'lit',65,'do','i','output','lit',' ','output','i','emit','call', 'nl', 'loop','abort')
interpreter = Interpreter(code, {'nl': code_nl})
interpreter.run()
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Code: Alles auswählen

    def cmd_output(self):
        sys.stdout.write('{}'.format(self.stack.pop()))
Warum nicht einfach print(self.stack.pop(), end='')?
BlackJack

@snafu: Wegen dem Zeilenumbruch würde ich sagen.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Selbst wenn man über write() gehen will, finde ich ein str(x) besser als ein '{}'.format(x).
Benutzeravatar
noisefloor
User
Beiträge: 3829
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Entweder Troll oder er ist noch sehr jung, dass er so komisch schreibt.
Aus einem anderem Thread geht hervor, das jan.b einen Raspi hat. Bei Raspi-Neulingen und auch Nutzern ist die Motivation, Python vernünftig zu lernen, gerne eher gering. Sieht man auch immer wieder in diversen Threads im deutschen Raspi-Forum...
Vielleicht ist er auch das Kind von Alfons Mittelmeyer.
*fg* Ich bin auch für einen Vaterschaftstest ;-)

Gruß, noisefloor
Antworten