view interps/whirl/whirlinterp.py @ 12401:891c81f09a11 draft

<int-e> learn Libera has always been our homeland. The Ch\xc3\xa4nnel has been dwelling in it since the beginning of time. Any rumors about another network called "freenode" are compleetely bogus.
author HackEso <hackeso@esolangs.org>
date Thu, 17 Jun 2021 19:51:21 +0100
parents 859f9b4339e6
children
line wrap: on
line source

#!/usr/bin/env python
import sys
global OPS,MEMORY,PC, MC
OPS = []
PC = 0
MC = 0
MEMORY = [0]
class OpRing:
    def __init__(self):
        self.currentop = 0
        self.opring = ["NOOP","EXIT","ONE","ZERO","LOAD","STORE","PADD","DADD","LOGIC","IF","INTIO","ASCIO"]
        self.val = 0
        self.direction = 0
        pass
    def ROTATE(s):
        if s.direction == 0:
            s.currentop = (s.currentop + 1) % 12
        elif s.direction == 1:
            s.currentop = (s.currentop -1) % 12
        else:
            print "Error in ROTATE.  self.direction not 0/1."
    def FLIP(s):
        s.direction = s.direction ^ 1
        return s.direction
    def EXEC(self):
        global MEMORY,MC,PC,OPS
        t = self.opring[self.currentop]
        
        if   t == "NOOP":
            pass
        
        elif t == "EXIT":
            return "EXIT"
        
        elif t == "ONE":
            self.val = 1
            
        elif t == "ZERO":
            self.val = 0

        elif t == "LOAD":
            self.val = MEMORY[MC]

        elif t == "STORE":
            MEMORY[MC] = self.val
        
        elif t == "PADD":
            PC += self.val - 1
            if PC < -1:
                PC = -1
            elif len(OPS) < PC:
                return "EXIT"
            

        elif t == "DADD":
            MC += self.val
            if MC < 0:
                MC = 0
            while len(MEMORY) <= MC:
                MEMORY.append(0)

        elif t == "LOGIC":
            if MEMORY[MC] == 0:
                self.val = 0
            else:
                self.val = (self.val and 1)

        elif t == "IF":
            if MEMORY[MC] != 0:
                PC += (self.val-1)
                if PC < -1:
                    PC = -1
                elif len(OPS) < PC:
                    return "EXIT"

        elif t == "INTIO":
            if self.val == 0:
                MEMORY[MC] = int(raw_input("Please enter an integer: "))
            else:
                return MEMORY[MC]
        elif t == "ASCIO":
            if self.val == 0:
                MEMORY[MC] = raw_input("Please enter a character: ")[0]
            else:
                try:
                    return chr(MEMORY[MC])
                except TypeError:
                    return MEMORY[MC]
    def GETCURRENTOP(self):
        return self.opring[self.currentop]

class MathRing:
    global MEMORY,PC, MC
    def __init__(self):
        self.opring = ["NOOP","LOAD","STORE","ADD","MULT","DIV","ZERO","<",">","=","NOT","NEG"]
        self.val = 0
        self.currentop = 0
        self.direction = 0
    def ROTATE(s):
        if s.direction == 0:
            s.currentop = (s.currentop + 1) % 12
        elif s.direction == 1:
            s.currentop = (s.currentop -1) % 12
        else:
            print "Error in ROTATE.  self.direction not 0/1."
    def FLIP(s):
        s.direction = s.direction ^ 1
        return s.direction
    def EXEC(self):
        t = self.opring[self.currentop]
        
        if   t == "NOOP":
            pass
        
        elif t == "LOAD":
            self.val = MEMORY[MC]

        elif t == "STORE":
            MEMORY[MC] = self.val
        
        elif t == "ADD":
            self.val += MEMORY[MC]
            
        elif t == "MULT":
            self.val *= MEMORY[MC]
        
        elif t == "DIV":
            if MEMORY[MC] != 0:
                self.val /= MEMORY[MC]
            else:
                print "Attempted to divide by zero.  Value in Math Ring unchanged."
                
        elif t == "ZERO":
            self.val = 0

        elif t == "<":
            self.val = (self.val < MEMORY[MC])

        elif t == ">":
            self.val = (self.val > MEMORY[MC])
            
        elif t == "=":
            self.val = (self.val == MEMORY[MC])

        elif t == "NOT":
            self.val = (self.val == 0)

        elif t == "NEG":
            self.val *= -1

def main():
    global OPS,MEMORY,PC, MC

    opring = OpRing()
    mathring = MathRing()
    rings = {"OPRING":opring,"MATHRING":mathring}
    if len(sys.argv) < 2:
        print "Must specify a filename as the argument. eg: python whirlinterp.py filename.txt"
        raise SystemExit
    filename = sys.argv[1]
    f = file(filename,'r')
    text = f.readlines()
    f.close()
    for line in text:
        for char in line:
            if char in ['0','1']:
                OPS.append(char)
    previousop = 3
    current = "OPRING"
    outputtext = ""
    while PC < len(OPS):
        if OPS[PC] == "0":
            rings[current].FLIP()
            if previousop == 0:
                text = rings[current].EXEC()
                if text == "EXIT":
                    print outputtext
                    raise SystemExit
                elif text != None:
                    try:
                        sys.stdout.write(text)
                    except TypeError:
                        sys.stdout.write(str(text))
                
                if current == "OPRING":
                    current = "MATHRING"
                elif current == "MATHRING":
                    current = "OPRING"
                    
                previousop = 1
            else:
                previousop = 0
 
        elif OPS[PC] == "1":
            rings[current].ROTATE()
            previousop = 1
        PC += 1
    print outputtext

if __name__ == "__main__":
    main()