view interps/dimensifuck/dimensifuck.py @ 9554:23f43464694e

<Zarutian> le/rn Frams\xc3\xb3knarflokkurinn/A, now defunct, political party in Iceland. Like its sister party Sj\xc3\xa1lfst\xc3\xa6\xc3\xb0isflokkurinn it is named by the antonym of what it is. (The name means the Progressive Party but they have nearly always been highly regressive). Think dumb Hill-Billies in ill fitting suits and you get their constiuents.
author HackBot
date Sun, 30 Oct 2016 14:33:24 +0000
parents 859f9b4339e6
children
line wrap: on
line source

#!/usr/bin/env python
from numarray import *
import sys

def dimensionSubstr(line):
    a = enumerate(line)
    try:
        b = a.next()
    except:
        return ["", line]
    try:
        while 1:
            if b[1] not in "0123456789": return [line[0:b[0]], line[b[0]:]]
            b = a.next()
            while b[1] != ".":
                if b[1] not in "0123456789": return [line[0:b[0]], line[b[0]:]]
                b = a.next()
            b = a.next()
            if b[1] == ".":
                return None #syntax error
    except:
        return [line[0:b[0]], ""]

class Dimensifuck:
    def __init__(self):
        self.dimensions = 0
        self.dimensionSizes = []
        self.matrix = array(type=Int8)
        self.tape = [0]
        self.pointer = 0
    def run(self, verbose=False):
        location = [0] * self.dimensions
        dimension = 0
        nextDimension = 0
        direction = 1
        while 1:
            op = self._getMatrixAt(location)
            if verbose:
                print "Location: ", location
                print "Opcode:", "+-.,<>=_^vX "[op]
            if op == 0:
                self.tape[self.pointer] = (self.tape[self.pointer] + 1) & 255
            elif op == 1:
                self.tape[self.pointer] = (self.tape[self.pointer] - 1) & 255
            elif op == 2:
                print chr(self.tape[self.pointer]),
            elif op == 3:
                self.tape[self.pointer] = ord(sys.stdin.read(1))
            elif op == 4:
                self.pointer -= 1
                if self.pointer < 0:
                    self.tape = [0] + self.tape
                    self.pointer = 0
            elif op == 5:
                self.pointer += 1
                if self.pointer == len(self.tape):
                    self.tape.append(0)
            elif op == 6:
                nextDimension += 1
            elif op == 7:
                nextDimension -= 1
            elif op == 8:
                if self.tape[self.pointer]:
                    dimension = nextDimension
                    direction = 1
            elif op == 9:
                if self.tape[self.pointer]:
                    dimension = nextDimension
                    direction = -1
            elif op == 10:
                return self.tape[self.pointer]
            location[dimension] += direction
    def loadMatrix(self, code):
        self.dimensions = 0
        code = [dimensionSubstr(i) for i in code.split('\n')]
        lines = []
        for i, j in enumerate(code):
            if j is None:
                print "Syntax error on line ", i
                return False
            if j[0]:
                lines.append(j)
                self.dimensions = max(self.dimensions, j[0].count(".") + 2)
            else:
                lines[-1][1] += j[1]
        self.dimensionSizes = [0] * self.dimensions
        for i in xrange(len(lines)):
            lines[i][0] = [len(lines[i][1])] + [int(j) for j in lines[i][0].split(".")]
            lines[i][0] += [0] * (len(lines[i][0]) - self.dimensions)
        for i in xrange(self.dimensions):
            self.dimensionSizes[i] = max([a[0][i] + 1 for a in lines])
        for i in xrange(self.dimensions):
            self.matrix = array([-1], type=Int8)
            self.matrix.resize(self.dimensionSizes)
        for i in lines:
            location = list(i[0])
            location[0] = 0
            for j in i[1]:
                self._setMatrixAt(location, self._getValue(j))
                location[0] += 1
        
    def loadFile(self, filename):
        self.loadMatrix(file(filename, "r").read())

    def _getMatrixAt(self, location):
        for i in location:
            if i < 0:
                return 10
        try:
            return reduce(lambda x, y: x[y], location, self.matrix)
        except:
            return 10
    def _setMatrixAt(self, location, value):
        array = self.matrix
        while len(location) > 1:
            array = array[location[0]]
            location = location[1:]
        array[location[0]] = value
    def _getValue(self, char):
        return "+-.,<>=_^vX".find(char)