#! /usr/bin/python3 import os, sys # brainfuck interpreter - Jean-Christophe Beumier - GPLv3 license # ver 1.0 - 2009.07.28 : python2, ISO-8859-1 # ver 2.0 - 2020.11.28 : python3, UTF-8, -d =debug mode # ver 2.1 - 2023.04.15 : better command-line treatment # Brainfuck was created by Urban Müller in 1993. # There are only eight useful signs/functions : # > to the next unsigned byte pointer; unlimited # < to the previous unsigned byte pointer # + increments the pointed byte (256 =0) # - decrements the pointed byte (-1 =255) # [ jumps after related ] if the pointed byte =0 # ] goes back to related [ if the pointed byte !=0 # . prints chr(pointed byte) # , gets a character, its ascii value is put on the pointed byte # any other character is a comment, with no < > + - [ ] . , i =0 ; ptr =0 ; ptrs =[0] comm ="" ; deb=0 ; args =sys.argv # gestion des paramètres debug =0 if len(args) ==1 : input("Use: bf.py myfile.bf or bf.py -d myfile.bf") if len(args) ==2 : # case bf.py myfile.bf fichier =sys.argv[1] comm ="" elif len(args) ==3 : # case bf.py -d myfile.bf fichier =sys.argv[2] comm =sys.argv[1] else : input("Missing '.bf' file") sys.exit() try: with open(fichier) as fd : prg =fd.read() end =len(prg) except: input("'%s' doesn't exist. Strike a key" %fichier) ; sys.exit() if comm : if comm[0] !="-" : print("Command chain must begin with '-' ; no one considered") else : comm =comm[1:] ; deb =0 for c in comm : if c =="d" : deb =1 else : print("%s is not implemented" %c) def debug(chaine): global i, char if deb : print("%7d %s %s %4d" %(i, char, chaine, ptrs[ptr])) while (i < end): char =prg[i] # spells the program string if (char == '>'): # ptr =(ptr +1) %256 # to limit pointer up to 255 ptr =ptr +1 if ptr >len(ptrs) -1: ptrs +=[0] debug("Pointer +1") if (char =='<'): # ptr =(ptr -1) %256 # to limit pointer up to 255 ptr =ptr -1 debug("Pointer -1") if (ptr <0): print("*** Negative pointer, doesn't work ***") if (char=='+') : ptrs[ptr] =ptrs[ptr]+1 if ptrs[ptr] ==256 : ptrs[ptr] =0 debug("ptr[%s] +1" %ptr) if (char =='-'): ptrs[ptr] =ptrs[ptr] -1 debug("ptr[%s] -1" %ptr) if ptrs[ptr] ==-1: ptrs[ptr] =255 if (char =="["): if (ptrs[ptr] ==0): # pointed byte ==0: doesn't enter the loop debug("Not entering!") level =1 while(level >0): # => going forward until the same level ']' i +=1 if prg[i] =="[": level +=1 if prg[i] =="]": level -=1 else: debug("Loop in") if (char =="]"): if (ptrs[ptr] >0): # pointed byte >0: loop is on debug("Loop on") level =1 while(level >0): # => going backward until the same level '[' i =i -1 if prg[i] =="]": level +=1 if prg[i] =="[": level -=1 else: # exits a loop if pointed byte ==0 debug("Loop out ") if (char =='.'): put =chr(ptrs[ptr]) debug("put[0] :%s" %put) print(put, end="") if (char ==','): get =input(":") ptrs[ptr] =ord(get) debug("get[0] :%s" %get) i =i +1 input("\n### Program's ending up. Exit with [Enter] ###")