KRITSADA icon

# Brainfox: A brainf*ck interpreter for microbit.

KRITSADA | PRO | 11/29/19 06:09:19 AM UTC | 0 ⭐ | 683 👁️ | Never ⏰ | []
Python |

5.13 KB

|

None

|

0 👍

/

0 👎

# Brainfox: A brainf*ck interpreter for microbit.
# (C) 2017 Alynna Trypnotk, GPL3
# Be selective here to save RAM
from microbit import uart, display, button_a, button_b, sleep, Image, reset
from gc import collect, mem_free
from os import remove
collect() # DEFPROG is Hello World.  These strings are defined here to get them in flash, not RAM.
DEFPROG = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."
PROGNAME = "prog.bf"
INPUTNAME = "input.bf"
PRIMS = "+-<>[],.#|"
PRAGMA = "FX"          # Default PRAGMA and DELAY.
DELAY = 100             # You can set these freely.
CELLS = 256             # CELLS available. This is configurabale
                        # and will cost its value in bytes.
def receive():
    global PRAGMA
    print("* Enter program, [/ ENTER] to submit *")
    DC = 0
    getProg = 2
    while True:
        AC = str(input())
        if getProg == 2:    # Prevents null programs.
            file = open(PROGNAME, "wt")
            getProg = 1
        if AC[0] == '/': 
            PRAGMA = AC[1:].upper() if len(AC)>1 else PRAGMA
            break
        if AC[0] == '_':
            getProg = 0
            file.close()
            file = open(INPUTNAME, "wt")
            DC = 0
            continue
        if getProg: AC = ''.join([x for x in AC if x in PRIMS])
        DC += len(AC)
        file.write(str(AC))
        print(DC)
        collect()
    file.close()
if button_a.is_pressed():
    try:
        remove(PROGNAME)
        remove(INPUTNAME)
    except: pass
    display.show(Image.PACMAN, wait=False)
    receive()
    reset() 
def get_input():
    if "R" in PRAGMA:
        while not uart.any(): sleep(1)
        return str(uart.read(1),"ascii");
    else:
        x = file.read(1)
        return '\0' if x == "" else x
def bfprint(c):
    print(chr(c),sep='',end='')
    if not "T" in PRAGMA:
        display.show(chr(c) if c>32 else " ")
        sleep(DELAY)
def leppard():
    try:
        print("CP:",repr(cell[0:CP+8])[11:-1])
    except:
        print("CP:",repr(cell[CP-8:CP+8])[11:-1])
def debug():
    print("{0}PC={1} CP={2} [CP]={3} LV={4} {5}#{6}: {7}"
        .format("["*len(stack), PC, CP, cell[CP], LEVEL, repr(stack),
                len(stack), "END OF LINE" if PC>=len(prog) else prog[PC]))
    if "C" in PRAGMA: leppard()
def crash(text):
    global CRASHED
    CRASHED = True
    print("\n[ERROR]",text,"... Debugging.")
display.show(Image.HEART,wait=False)
try:
    prog = open(PROGNAME).read()
except Exception as e:
    prog = DEFPROG
    with open(PROGNAME,"wt") as f: f.write(prog)
    print("{0}. Using Hello World.\n".format(e))
    reset()
CRASHED = False         # Semaphore indicating an interpreter error.
LEVEL = 0               # When zero, we are executing primitives.
                        # When non-zero, we are seeking our matching ]
PC = 0                  # Program Counter
CP = 0                  # Cell Pointer
cell = bytearray(CELLS) # Fixed memory of byte sized cells.
stack = []              # [] stack.  Allocate last because it grows and shrinks.
uart.init(115200)
print("Brainfox Initalized.")
if button_b.is_pressed():
    PRAGMA = input("Pragmas: ").upper()
if not "R" in PRAGMA:
    try:
        file = open(INPUTNAME)
    except: 
        PRAGMA += "R"
DEBUG = "D" in PRAGMA
if "F" in PRAGMA: DELAY = 0
display.show(Image.HAPPY, wait=False)
collect()
print("Prog size: {0}; Free: {1}B ({2} stk)".format(len(prog),mem_free(),int(mem_free()/4)))
while True:
    if PC >= len(prog):
        if LEVEL: crash("Unbalanced [")
        break
    if DEBUG or button_a.is_pressed(): debug()
    if "T" in PRAGMA:
        display.show(prog[PC])
        sleep(DELAY)
    if prog[PC] in "[]": 
        if prog[PC] == "[":
            stack += [PC]
            if cell[CP] == 0 and not LEVEL:
                LEVEL = len(stack)
        else:
            if not (cell[CP] == 0) and not LEVEL:
                PC = stack[-1]+1
                continue
            if stack == []:
                crash("Unbalanced ]")
                break
            else:
                stack = stack[:-1]
            if len(stack) < LEVEL: LEVEL = 0
        if DEBUG: debug()
    if not LEVEL: 
        if prog[PC] == ">":
            CP +=1
            if CP+1 >= CELLS: CP = 0
        elif prog[PC] == "<":
            CP -= 1
            if CP < 0: CP = CELLS - 1
        elif prog[PC] == "+":
            cell[CP] = cell[CP] + 1
        elif prog[PC] == "-":
            cell[CP] = cell[CP] - 1
        elif prog[PC] == ",":
            cell[CP] = ord(get_input())
        elif prog[PC] == ".":
            bfprint(cell[CP])
        elif "X" in PRAGMA and prog[PC] == "#":
            DEBUG = not DEBUG
        elif "X" in PRAGMA and prog[PC] == "|":
            sleep(DELAY)
    if CRASHED or button_b.is_pressed():
        break
    else:
        PC+=1
try:    file.close()
except: pass
print("\n--")
debug()
leppard()
print("* Game Over. Hold A to upload or press B to reset *")
while not button_a.is_pressed() and not button_b.is_pressed(): sleep(10)
reset()

Comments