#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Briefly based on work by  Øyvind Grønnesby <oyving@pvv.ntnu.no>
# Copyright 2012 David Francos Cuartero
# This entire program is licensed under the terms of GPL-2+
import sys

class GenericTuringInterpreter(object):
    pointer, current_position, memory, jump_to = 0, 0, [0], False
    def __init__(self, file_, language):
        self.language = language
        with open(file_) as fileo:
            self.code = self.massage(fileo.readlines())
        if not self.is_code_sane():
            raise Exception("Code not sane, might have std's.")

    def run(self):
        for num, code_ in enumerate(self.code):
            if self.jump_to:
                if self.jump_to != num:
                    next
                self.jump_to = False
            self.current_position = num
            getattr(self, self.language[code_])()

    @property
    def mem(self):
        return self.memory[self.pointer]

    def increase_pointer(self):
        self.memory[self.pointer] += 1

    def decrease_pointer(self):
        self.memory[self.pointer] -= 1

    def move_pointer_up(self):
        self.pointer += 1
        if len(self.memory) <= self.pointer:
            self.memory.append(0)

    def move_pointer_down(self):
        self.pointer = self.pointer - 1 if self.pointer > 0 else len(self.memory) - 1

    def readc(self):
        self.memory[self.pointer] = ord(sys.stdin.read(1))

    def printc(self):
        sys.stdout.write(chr(self.mem))

    def if_(self):
        if self.memory[self.pointer] != 0: self.ifelse()

    def else_(self):
        if self.memory[self.pointer] == 0: self.ifelse()

    def ifelse(self):
        while curr_code != "FapEnd" :
            self.current_position += 1
            curr_code = self.code[self.current_position]
        if curr_code != "FapEnd":
            raise Exception("Unmatched Fap?")

class FapCodeInterpreter(GenericTuringInterpreter):
    def is_code_sane(self):
        return True 

    def massage(self, text):
        ret = []
        for line in text:
            if line[0] != ";" and line != "\n" and line != "":
                ret += [ token.strip() for token in line.split(' ') if token != "" ]
        return ret

if __name__ == '__main__':
    FapCodeInterpreter(sys.argv[1], { 'FapUp' : "move_pointer_up", 'FapDown.' : "move_pointer_down", 'FapFapFap' : "increase_pointer", 'Pr0n' : "decrease_pointer", 'Slurp' : "readc", 'Cum' : "printc", 'Fap?' : "if_", 'Fap!' : "else_", }).run()
