- Befunge 98 with concurrency and file io!

This commit is contained in:
Wim Pomp
2022-11-26 20:05:58 +01:00
parent 91462bea57
commit 1429c32976
27 changed files with 621 additions and 233 deletions

View File

@@ -1,6 +1,5 @@
# Befunge # Befunge
[Befunge](https://en.wikipedia.org/wiki/Befunge) interpreter and debugger for Befunge 93, [Befunge](https://en.wikipedia.org/wiki/Befunge) interpreter and debugger for Befunge 93/98: [Funges](https://github.com/catseye/Funge-98/blob/master/doc/funge98.markdown#Whatis).
the first of the [Funges](https://web.archive.org/web/20041225010717/http://quadium.net/funge/spec98.html).
## Installation ## Installation
`pip install befunge@git+https://github.com/wimpomp/befunge.git` `pip install befunge@git+https://github.com/wimpomp/befunge.git`
@@ -9,4 +8,4 @@ the first of the [Funges](https://web.archive.org/web/20041225010717/http://quad
`befunge --help` `befunge --help`
## Examples ## Examples
`befunge examples/factorial0.bf -i 20 -d 0.05` `befunge examples/factorial0.bf 20 -d 0.05`

View File

@@ -1,35 +1,19 @@
from enum import Enum import os
import sys
import re
import curses
from random import randint from random import randint
from argparse import ArgumentParser from argparse import ArgumentParser
from pathlib import Path from pathlib import Path
from time import sleep from time import sleep
from io import StringIO from io import StringIO
from itertools import chain from itertools import chain, takewhile, dropwhile
from curses import wrapper from datetime import datetime
from ._version import __version__
class OperatorException(Exception): class StopExecution(Exception):
def __init__(self, op): pass
super().__init__(f'Could not parse operator {op}')
class Direction(Enum):
RIGHT = 0
UP = 1
LEFT = 2
DOWN = 3
def __add__(self, other):
return Direction((self.value + other) % len(Direction))
def __radd__(self, other):
return self + other
def __sub__(self, other):
return Direction((self.value - other) % len(Direction))
def __rsub__(self, other):
return self - other
class Input(list): class Input(list):
@@ -37,49 +21,441 @@ class Input(list):
return self.pop(0) return self.pop(0)
class Grid(dict): class Stack(list):
def __init__(self, code=None, version=None): def copy(self):
self.version = version or 'b93' return __class__(super().copy())
self.cursor = True
if self.version == 'b93': def pop(self, *args, **kwargs):
self.shape = 80, 25 try:
return super().pop()
except IndexError:
return 0
def push(self, value):
self.append(value)
class StackStack(list):
def __repr__(self):
return '\n'.join(str(stack) for stack in self[::-1])
def copy(self):
return __class__(stack.copy() for stack in self)
def push(self, value):
self.append(value)
class IP:
def __init__(self, funge, stackstack=None, position=(0, 0), delta=(1, 0), offset=(0, 0), version=982):
self.funge = funge
self.id = len([ip.id for ip in self.funge.ips]) if hasattr(self.funge, 'ip') else 0
self.stackstack = stackstack or StackStack([Stack()])
self.position = position
self.delta = delta
self.offset = offset
self.version = version
self.string = False
self.fingerprint_ops = {}
if self.op in (ord(' '), ord(';')):
self.advance()
@property
def stack(self):
if not self.stackstack:
self.stackstack.append(Stack())
return self.stackstack[-1]
@stack.setter
def stack(self, stack):
if self.stackstack:
self.stackstack[-1] = stack
else: else:
self.shape = None self.stackstack.append(stack)
self._ip = [0, 0]
self.direction = Direction.RIGHT @property
def op(self):
return self.funge[self.position]
def copy(self):
return __class__(self.funge, self.stackstack.copy(), self.position, self.delta)
def reverse(self):
self.delta = -self.delta[0], -self.delta[1]
def turn_right(self):
self.delta = -self.delta[1], self.delta[0]
def turn_left(self):
self.delta = self.delta[1], -self.delta[0]
def read_string(self):
string = ''
while True:
f = self.stack.pop()
if f == 0:
return string
else:
string += chr(f)
def read_fingerprint(self):
n = self.stack.pop()
t = 0
for _ in range(n):
t *= 256
t += self.stack.pop()
return t
def not_implemented(self):
print(f'operator {self.op} at {self.position} not implemented', file=self.funge.output)
self.reverse()
def get_info(self, n):
time = datetime.now()
match n:
case 1:
yield 15
case 2:
yield 2**1024 # as much as the memory can hold
case 3:
yield sum([256 ** i * ord(char) for i, char in enumerate('wpfunge')])
case 4:
yield __version__.replace('.', '')
case 5:
yield 1
case 6:
yield ord(os.path.sep)
case 7:
yield 2
case 8:
yield self.id
case 9:
yield 0
case 10:
yield from self.position
case 11:
yield from self.delta
case 12:
yield from self.offset
case 13:
yield from self.funge.extent[::2]
case 14:
yield from self.funge.extent[1::2]
case 15:
yield (time.year - 1900) * 256 * 256 + time.month * 256 + time.day
case 16:
yield time.hour * 256 * 256 + time.minute * 256 + time.second
case 17:
yield len(self.stackstack)
case 18:
yield from (len(stack) for stack in self.stackstack[::-1])
case 19:
yield 0
yield from [ord(char) for arg in sys.argv[2:] for char in f'{arg}\x00'][::-1]
yield 0
yield from [ord(char) for char in Path(sys.argv[1]).name][::-1]
case 20:
yield 0
yield from [ord(char) for key, value in os.environ.items() for char in f'{key}={value}\x00'][::-1]
case i:
i -= 20
yield self.stack[-i] if len(self.stack) >= i else 0
def step(self, k=False):
if self.string:
match chr(self.op):
case '"':
self.string = False
case s:
self.stack.push(ord(s))
elif self.op in self.fingerprint_ops:
try:
self.fingerprint_ops[self.op]()
except Exception:
self.reverse()
elif 0 <= self.op < 255:
match chr(self.op):
case '+':
self.stack.push(self.stack.pop() + self.stack.pop())
case '-':
b, a = self.stack.pop(), self.stack.pop()
self.stack.push(a - b)
case '*':
self.stack.push(self.stack.pop() * self.stack.pop())
case '/':
b, a = self.stack.pop(), self.stack.pop()
self.stack.push(a // b)
case '%':
b, a = self.stack.pop(), self.stack.pop()
self.stack.push(a % b)
case '!':
self.stack.push(int(not self.stack.pop()))
case '`':
self.stack.push(int(self.stack.pop() < self.stack.pop()))
case '>':
self.delta = 1, 0
case '<':
self.delta = -1, 0
case '^':
self.delta = 0, -1
case 'v':
self.delta = 0, 1
case '?':
self.delta = ((-1, 0), (1, 0), (0, -1), (0, 1))[randint(0, 3)]
case '_':
self.delta = ((1, 0), (-1, 0))[bool(self.stack.pop())]
case '|':
self.delta = ((0, 1), (0, -1))[bool(self.stack.pop())]
case '"':
self.string = True
case ':':
a = self.stack.pop()
self.stack.push(a)
self.stack.push(a)
case '\\':
b, a = self.stack.pop(), self.stack.pop()
self.stack.push(b)
self.stack.push(a)
case '$':
self.stack.pop()
case '.':
print(str(self.stack.pop()) + ' ', end='', file=self.funge.output)
case ',':
print(chr(self.stack.pop()), end='', file=self.funge.output)
case '#':
self.move()
case 'p':
y, x, a = self.stack.pop(), self.stack.pop(), self.stack.pop()
self.funge[x + self.offset[0], y + self.offset[1]] = a
case 'g':
y, x = self.stack.pop(), self.stack.pop()
self.stack.push(self.funge[x + self.offset[0], y + self.offset[1]])
case '&':
try:
self.stack.push(int(''.join(
takewhile(lambda i: i.isdigit(), dropwhile(lambda i: not i.isdigit(), self.funge.input())))))
except Exception:
self.delta = -self.delta[0], -self.delta[1]
case '~':
try:
self.stack.push(ord(self.funge.input()))
except Exception:
self.reverse()
case '@':
return
case ' ':
self.advance()
yield self.step()
return
# 98 from here
case '[':
self.turn_left()
case ']':
self.turn_right()
case '\'':
self.move()
self.stack.push(self.op)
case '{':
n = self.stack.pop()
cells = -n * [0] if n < 0 else self.stack[-n:][::-1]
for coordinate in self.offset:
self.stack.push(coordinate)
self.stackstack.push(Stack())
for cell in cells:
self.stack.push(cell)
self.offset = self.next_pos
case '}':
n = self.stack.pop()
cells = -n * [0] if n < 0 else [self.stack.pop() for _ in range(n)][::-1]
self.stackstack.pop()
y, x = self.stack.pop(), self.stack.pop()
self.offset = x, y
for cell in cells:
self.stack.push(cell)
case '=':
self.stack.push(os.system(self.read_string()))
case '(':
# no fingerprints are implemented
self.read_fingerprint()
# self.fingerprint_ops[] = lambda i: i
self.reverse()
case ')':
self.read_fingerprint()
# self.fingerprint_ops.pop()
case 'i':
file = Path(self.read_string())
flags, y0, x0 = self.stack.pop(), self.stack.pop(), self.stack.pop()
try:
text = file.read_text()
if flags % 2:
width, height = len(text), 1
for x, char in enumerate(text, x0):
self.funge[x, y0] = char
else:
text = text.splitlines()
height = len(text)
width = max([len(line) for line in text])
self.funge.insert_code([line + ' ' * (width - len(line)) for line in text], x0, y0)
except Exception:
width, height = 0, 0
self.stack.push(x0)
self.stack.push(y0)
self.stack.push(width)
self.stack.push(height)
case 'j':
for _ in range(self.stack.pop()):
self.move()
case 'k':
self.advance()
ips = [self]
for n in range(self.stack.pop()):
ips = [i for ip in ips for i in ip.step(True)]
yield from ips
return
case 'n':
self.stack = Stack()
case 'o':
file = Path(self.read_string())
flags, x0, y0, width, height = (self.stack.pop() for _ in range(5))
try:
if flags % 2:
text = '\n'.join([''.join([chr(self.funge[x, y]) for x in range(x0, x0 + width)]).rstrip(' ')
for y in range(y0, y0 + height)]).rstrip('\n')
else:
text = '\n'.join([''.join([chr(self.funge[x, y]) for x in range(x0, x0 + width)])
for y in range(y0, y0 + height)])
file.write_text(text)
except Exception:
self.reverse()
case 'q':
raise StopExecution()
case 'r':
self.reverse()
case 's':
self.move()
self.funge[self.position] = self.stack.pop()
case 't':
new = self.copy()
new.reverse()
yield new.advance()
case 'u':
if len(self.stackstack) > 1:
n = self.stack.pop()
for _ in range(abs(n)):
toss = self.stackstack.pop()
toss.push(self.stack.pop())
self.stackstack.push(toss)
else:
self.reverse()
case 'w':
b, a = self.stack.pop(), self.stack.pop()
if a < b:
self.turn_left()
elif a > b:
self.turn_right()
case 'x':
dy, dx = self.stack.pop(), self.stack.pop()
self.delta = dx, dy
case 'y':
n = self.stack.pop()
if n <= 0:
for j in range(1, 21):
for i in self.get_info(j):
self.stack.push(i)
else:
for i in self.get_info(n):
self.stack.push(i)
case 'z':
pass
case d:
if d in '1234567890':
self.stack.push(int(d))
elif d in 'abcdef':
self.stack.push(ord(d) - 87)
else:
self.not_implemented()
else:
self.not_implemented()
if not k:
self.advance()
yield self
@property
def next_pos(self):
pos = tuple(p + d for p, d in zip(self.position, self.delta))
# TODO: analytic solution
if not all(a <= p < b for p, a, b in zip(pos, self.funge.extent[::2], self.funge.extent[1::2])):
while True:
pos = tuple(p - d for p, d in zip(pos, self.delta))
if not all(a <= p < b for p, a, b in zip(pos, self.funge.extent[::2], self.funge.extent[1::2])):
break
pos = tuple(p + d for p, d in zip(pos, self.delta))
return pos
def move(self):
self.position = self.next_pos
def advance(self):
""" move the ip to the next valid instruction """
if self.string:
if self.op == ord(' ') and self.version // 10 > 93:
while self.op == ord(' '):
self.move()
else:
self.move()
else:
while True:
if self.op != ord(';'):
self.move()
if self.op == ord(';'):
self.move()
while self.op != ord(';'):
self.move()
self.move()
while self.op == ord(' '):
self.move()
if self.op != ord(';'):
break
return self
class Befunge(dict):
def __init__(self, code=None, inputs=None):
super().__init__() super().__init__()
for y, line in enumerate(code.splitlines()): self.extent = [0, 0, 0, 0] # xl, xr, yt, yb
for x, char in enumerate(line): if code.startswith(r'#!/usr/bin/env befunge') or code.startswith(r'#!/usr/bin/env -S befunge'):
self[(x, y)] = char code = '\n'.join(code.splitlines()[1:])
self.insert_code(code)
def wrap(self, value, dim): self.output = None
if self.shape is None: if inputs is None:
return value self.input = input
else: else:
return value % self.shape[dim] self.input = Input(inputs)
self.string = False
self.steps = 0
self.terminated = False
self.ips = [IP(self)]
@property def insert_code(self, code, x0=0, y0=0):
def x(self): if isinstance(code, str):
return self._ip[0] code = code.splitlines()
for y, line in enumerate(code, y0):
@x.setter for x, char in enumerate(line, x0):
def x(self, value): self[x, y] = char
self._ip[0] = self.wrap(value, 0)
@property
def y(self):
return self._ip[1]
@y.setter
def y(self, value):
self._ip[1] = self.wrap(value, 1)
def __getitem__(self, key): def __getitem__(self, key):
return self.get(key, ord(' ')) return self.get(key, ord(' '))
def __setitem__(self, key, value): def __setitem__(self, key, value):
super().__setitem__(tuple(self.wrap(k, i) for i, k in enumerate(key)), if key[0] < self.extent[0]:
ord(value) if isinstance(value, str) else value) self.extent[0] = key[0]
if key[0] >= self.extent[1]:
self.extent[1] = key[0] + 1
if key[1] < self.extent[2]:
self.extent[2] = key[2]
if key[1] >= self.extent[3]:
self.extent[3] = key[1] + 1
super().__setitem__(key, ord(value) if isinstance(value, str) else value)
def __repr__(self): def __repr__(self):
lines = [] lines = []
@@ -89,70 +465,16 @@ class Grid(dict):
while len(lines[y]) <= x: while len(lines[y]) <= x:
lines[y].append(' ') lines[y].append(' ')
lines[y][x] = chr(value) if 32 <= value <= 126 or 161 <= value <= 255 else chr(164) lines[y][x] = chr(value) if 32 <= value <= 126 or 161 <= value <= 255 else chr(164)
lines = [''.join(line) for line in lines]
if self.cursor:
return '\n'.join(lines[:self.y] +
[lines[self.y][:self.x] +
'\x1b[37m\x1b[40m' + lines[self.y][self.x] + '\033[0m' +
lines[self.y][self.x + 1:]] +
lines[self.y + 1:])
else:
return '\n'.join(lines)
@property for ip in self.ips:
def op(self): lines[ip.position[1]][ip.position[0]] = f'\x1b[37m\x1b[40m{lines[ip.position[1]][ip.position[0]]}\033[0m'
return self[self.x, self.y] return 'grid:\n' + '\n'.join([''.join(line) for line in lines]) + '\n\n' + \
'stacks:\n' + '\n-\n'.join(str(ip.stackstack) for ip in self.ips)
def advance(self):
match self.direction:
case Direction.RIGHT:
self.x += 1
case Direction.UP:
self.y -= 1
case Direction.LEFT:
self.x -= 1
case Direction.DOWN:
self.y += 1
class Stack(list):
def pop(self, index=-1):
try:
return super().pop(index)
except IndexError:
return 0
def push(self, value):
self.append(value)
class Befunge(Grid):
def __init__(self, code=None, version=None, inputs=None):
super().__init__(code, version)
self.output = None
if inputs is None:
self.input = input
else:
self.input = Input(inputs)
self.stack = Stack()
self.string = False
self.steps = 0
self.terminated = False
self.operations = {'b93': '+-*/%!`><^v?_|":\\$.,#pg&~@ 1234567890'}[self.version]
@staticmethod @staticmethod
def from_file(file, version=None, inputs=None): def from_file(file, inputs=None):
file = Path(file) file = Path(file)
if version is None: return Befunge(file.read_text(), inputs)
match file.suffix:
case '.bf':
version = 'b93'
case suffix:
version = suffix.strip('.')
return Befunge(file.read_text(), version, inputs)
def __repr__(self):
return f'grid:\n{super().__repr__()}\n\nstack:\n{self.stack}'
def __iter__(self): def __iter__(self):
return self return self
@@ -166,146 +488,84 @@ class Befunge(Grid):
for _ in self: for _ in self:
pass pass
def debug(self, time_step): def debug(self, time_step=None):
def fun(stdscr): def fun(stdscr):
def scr_input(): def scr_input():
height, width = stdscr.getmaxyx() height, width = stdscr.getmaxyx()
stdscr.move(height - 1, 0) stdscr.move(height - 1, 0)
stdscr.clrtoeol() stdscr.clrtoeol()
stdscr.addstr(height - 1, 0, 'input?') stdscr.addstr(height - 1, 0, 'input?'[:width])
stdscr.move(self.y + 1, self.x)
stdscr.refresh() stdscr.refresh()
return stdscr.getstr() return stdscr.getstr()
curses.curs_set(False)
curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE)
pattern = re.compile(r'\x1b\[[\d;]+m')
self.output = StringIO() self.output = StringIO()
self.cursor = False
if not isinstance(self.input, Input): if not isinstance(self.input, Input):
self.input = scr_input self.input = scr_input
stdscr.clear() stdscr.clear()
stdscr.refresh() stdscr.refresh()
for b in chain((self,), self): for b in chain((self,), self, (self,)):
height, width = stdscr.getmaxyx() height, width = stdscr.getmaxyx()
stdscr.clear() stdscr.clear()
stdscr.addstr(f'{b}\n\noutput:\n{b.output.getvalue()}\n\nstep:\n{b.steps}') b_str = re.sub(pattern, '', str(b))
if time_step > 0: for y, line in enumerate(f'{b_str}\n\noutput:\n{b.output.getvalue()}\n\nstep:\n{b.steps}'.splitlines()):
stdscr.move(b.y + 1, b.x) if y >= height:
stdscr.refresh() break
sleep(time_step) stdscr.addstr(y, 0, line[:width])
else:
stdscr.addstr(height - 1, 0, 'Press any key to continue.') for ip in b.ips:
stdscr.move(b.y + 1, b.x) x, y = ip.position
if x < width and y < height:
stdscr.addstr(y + 1, x, b_str.splitlines()[y + 1][x], curses.color_pair(1))
if b.terminated:
stdscr.addstr(height - 1, 0, 'Press any key to quit.'[:width])
stdscr.refresh() stdscr.refresh()
stdscr.getch() stdscr.getch()
elif time_step is None:
height, width = stdscr.getmaxyx() stdscr.addstr(height - 1, 0, 'Press any key to continue.'[:width])
stdscr.move(height - 1, 0) stdscr.refresh()
stdscr.clrtoeol() stdscr.getch()
stdscr.addstr(height - 1, 0, 'Press any key to quit.') else:
stdscr.move(self.y + 1, self.x) stdscr.refresh()
stdscr.getch() sleep(time_step)
try: try:
wrapper(fun) curses.wrapper(fun)
except KeyboardInterrupt: except KeyboardInterrupt:
pass pass
def step(self, n=1): def step(self, n=1):
m = 0 for i in range(n):
while m < n: self.steps += 1
if self.string: try:
if self.op == ord('"'): self.ips = [i for ip in self.ips for i in ip.step()]
self.string = False except StopExecution:
else: self.ips = []
self.stack.push(self.op) if not self.ips:
elif chr(self.op) in self.operations: self.terminated = True
match chr(self.op): return self
case '+':
self.stack.push(self.stack.pop() + self.stack.pop())
case '-':
self.stack.push(self.stack.pop(-2) - self.stack.pop())
case '*':
self.stack.push(self.stack.pop() * self.stack.pop())
case '/':
self.stack.push(self.stack.pop(-2) // self.stack.pop())
case '%':
self.stack.push(self.stack.pop(-2) % self.stack.pop())
case '!':
self.stack.push(int(not self.stack.pop()))
case '`':
self.stack.push(int(self.stack.pop() < self.stack.pop()))
case '>':
self.direction = Direction.RIGHT
case '<':
self.direction = Direction.LEFT
case '^':
self.direction = Direction.UP
case 'v':
self.direction = Direction.DOWN
case '?':
self.direction = Direction(randint(0, 3))
case '_':
self.direction = Direction(2 * bool(self.stack.pop()))
case '|':
self.direction = Direction(3 - 2 * bool(self.stack.pop()))
case '[':
self.direction += 1
case ']':
self.direction -= 1
case '"':
self.string = True
case ':':
if len(self.stack):
self.stack.push(self.stack[-1])
case '\\':
if len(self.stack) > 1:
self.stack.push(self.stack.pop(-2))
case '$':
self.stack.pop()
case '.':
print(str(self.stack.pop()) + ' ', end='', file=self.output)
case ',':
print(chr(self.stack.pop()), end='', file=self.output)
case '#':
self.advance()
case 'p':
self[self.stack.pop(-2), self.stack.pop()] = self.stack.pop(-3)
case 'g':
self.stack.push(self[self.stack.pop(-2), self.stack.pop()])
case '&':
self.stack.push(int(self.input()))
case '~':
self.stack.push(ord(self.input()))
case '@':
self.terminated = True
case ' ':
pass
case op:
self.stack.append(int(op))
else:
raise OperatorException(self.op)
self.advance()
if not (not self.string and self.op == ord(' ')):
m += 1
self.steps += 1
return self return self
def main(): def main():
parser = ArgumentParser(description='Display info and save as tif') parser = ArgumentParser(description='Funge interpreter and debugger')
group = parser.add_mutually_exclusive_group() parser.add_argument('input', help='funge code file or string')
group.add_argument('file', help='funge code file', nargs='?') parser.add_argument('args', help='arguments to the funge (& or ~)', nargs='*')
group.add_argument('-s', '--string', help='funge code string', default=None) parser.add_argument('-v', '--version', help='show interpreter\'s version number and exit',
parser.add_argument('-v', '--version', help='funge version: b93, b98', type=str, default=None) action='version', version=__version__)
parser.add_argument('-d', '--debug', help='debug, steps / second, 0: continue on key press', type=float, default=-1) parser.add_argument('-d', '--debug', help='debug, step on key press or steps / second',
parser.add_argument('-i', '--inputs', help='inputs for when befunge asks for it', nargs='*') type=float, default=False, nargs='?')
args = parser.parse_args() args = parser.parse_args()
if args.file:
befunge = Befunge.from_file(args.file, args.version, args.inputs)
else:
befunge = Befunge(args.string, args.version, args.inputs)
if args.debug < 0: if Path(args.input).exists():
befunge = Befunge.from_file(args.input, args.args or None)
else:
befunge = Befunge(args.input, args.args or None)
if args.debug is False:
befunge.run() befunge.run()
else: else:
befunge.debug(args.debug) befunge.debug(args.debug)

12
examples/99.bf Executable file
View File

@@ -0,0 +1,12 @@
#!/usr/bin/env befunge
992+*: v: <
v" ".:<_091+".reeb fo selttob erom on ,llaw eht no reeb fo selttob erom oN">:v
,v"Go to the store and buy some more, 99 bottles of beer on the wall."+910<^,_v
>:#,_@>:101-*+v >$0" ,llaw eht no reeb fo ">:#,_$:.1v ^ $<
>0\ >> ^ v_0"elttob">:#,_$\:!| >091+".reeb fo ">:#,_$ v
>0"selttob"^ >1-!| >" ",\v
>$2\ ^\2<," ".< >091+:".llaw eht no reeb fo "v
^_v > ^ |:< v!:<"Take one down and pass it around, "0< v!:<
!,v ^ ^:-1$_, ^ v$_>,^
>^ ^ <
^:<"no more "0< > ^

4
examples/cat_v.bf Executable file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env befunge
w4110'vin10
"<v"
>>#,:#<_@

3
examples/concurrent.bf Executable file
View File

@@ -0,0 +1,3 @@
#!/usr/bin/env befunge
v
@000_1t111@

9
examples/dna.bf Executable file
View File

@@ -0,0 +1,9 @@
#!/usr/bin/env befunge
7^DN>vA
v_#v? v
7^<""""
3 ACGT
90!""""
4*:>>>v
+8^-1,<
> ,+,@)

0
examples/ex1.bf Normal file → Executable file
View File

0
examples/factorial.bf Normal file → Executable file
View File

2
examples/factorial0.bf Normal file → Executable file
View File

@@ -1,5 +1,5 @@
#!/usr/bin/env befunge
v v
0
& &
>>:1v >>:1v
|:-< |:-<

3
examples/factorial_eso.bf Executable file
View File

@@ -0,0 +1,3 @@
#!/usr/bin/env befunge
&>:1-:v v *_$.@
^ _$>\:^

1
examples/factorial_heap.bf Normal file → Executable file
View File

@@ -1,2 +1,3 @@
#!/usr/bin/env befunge
&:>00p1-::v &:>00p1-::v
^ *g00 _g.25*,@ ^ *g00 _g.25*,@

2
examples/fibonacci.bf Executable file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env befunge
j1\:b0p+:.' 1

25
examples/guess.bf Executable file
View File

@@ -0,0 +1,25 @@
#!/usr/bin/env befunge
vv < <
2
^ v<
v1<?>3v4
^ ^
> >?> ?>5^
v v
v9<?>7v6
v v<
8
> > ^
vv < <
2
^ v<
v1<?>3v4
^ ^
> >?> ?>5^
v v v ,*25 <<
v9<?>7v6 ,,
v v< ""
8 ><
> > ^ ""v
>*: >0"!rebmun tupnI">:#,_$25*,:&:99p`|^< _0"!niw uoY">:#,_$25*,@
^ < >:99g01-*+^

16
examples/guess2.bf Executable file
View File

@@ -0,0 +1,16 @@
#!/usr/bin/env befunge
v>>> > v>>> > v
012 3 012 3
^?^ ^?^
>>?#v?4>>?#v?4v
v?v v?v
98765 98765
>>>>> ^>>>>> v
v 0 + * + : 5 <
>"!sseuG">:#,_v
0v_v#:-&:,+:5$<
, v>0"!niw uoY"
+0>:#,_$5:+,@
:>`0\"!"\v
v"small"_"gib"
^>" ooT">:#,_$5

2
examples/hello_b98.bf Executable file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env befunge
<>:#,_# @#"Hello, World!"

0
examples/hello_world.bf Normal file → Executable file
View File

0
examples/hello_world2.bf Normal file → Executable file
View File

9
examples/mill.bf Executable file
View File

@@ -0,0 +1,9 @@
#!/usr/bin/env befunge
] v
>v
v?t1?
1 t
t 1
?1t?v
v< <
>29*y.@

0
examples/multiplier.bf Normal file → Executable file
View File

4
examples/pi.bf Executable file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env befunge
"^a&EPm=kY}t/qYC+i9wHye$m N@~x+"v
"|DsY<"-"z6n<[Yo2x|UP5VD:">:#v_@>
-:19+/"0"+,19+%"0"+, ^ >39*

2
examples/quine1.bf Executable file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env befunge
01->1# +# :# 0# g# ,# :# 5# 8# *# 4# +# -# _@

0
examples/random.bf Normal file → Executable file
View File

6
examples/random_n.bf Executable file
View File

@@ -0,0 +1,6 @@
#!/usr/bin/env befunge
& :v>00g2/.@
v00_^#!`/2g00:<
>0p:1>>:10p` !|
>+00p^?<*2g01:<
^ g00:<

5
examples/sieve.bf Executable file
View File

@@ -0,0 +1,5 @@
#!/usr/bin/env befunge
2>:3g" "-!v\ g30 <
|!`"O":+1_:.:03p>03g+:"O"`|
@ ^ p3\" ":<
2 234567890123456789012345678901234567890123456789012345678901234567890123456789

23
examples/soup.bf Executable file
View File

@@ -0,0 +1,23 @@
#!/usr/bin/env befunge
060p070 p'O80v
pb2*90p4$4> $4$>v>
v4$>4$>4$>4$># ARGH>!
<{[BEFUNGE_97]}> FUNGE!
##:-:## #####* 4$*>4$ >060p> 60g80g -!#v_ 60g1+ 60p60v
#vOOGAH **>4$>^!!eg nufeB^ $4$4$4 $4<v#<<v-*2a:: v7-1g<
#>70g>90g-! #@_^Befunge!! 123456 123456 VvVv!#!>Weird! >0ggv*
^$4$4p07+1g07 ,a<$4< <$4$4< <$4$4< <$4$4< <<#<*-=-=-=-=-* -=-=v*
::48*-#v_>,4$> 4$4$4 $4$4$ 4$4$4$ 4$4$4$ 4$^*!* XXXXXX XXX>
BOINK>$60g1-7 0g+d2* %'A+,1 $1$1$1 $1$1$1 $>^<$ HAR!!! 8888
Befunge_is such_a pretty langua ge,_is n't_i t?_It_ 8888
looks_so much_l ike_li ne_noi se_and it's_ STILL_ 88
Turing- Complet e!_Cam ouflag e_your code!! Confu se_the
hell_out of_every one_re ading_ your_co de._Oh, AND_y ou.:-) ,o88o.
Once_this_thing_i s_code d,_rea ding_it_back_ver ges_on the_imp 888888
ossible._Obfusc ate_the_obfus cated!_Befunge_ debuggers_are__ 888888
your_friends! By:_Alexios Chouchou las... X-X-X-X-X-X-X! 888888
-=*##*=- \*****/ 9797* -=97=- !@-*= ***** "88P
*!@-*
=*!@-
-=*!@
@-=*!

2
examples/test.bf Executable file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env befunge
45*1-y>>#,:#<_$:w@

1
examples/v Executable file
View File

@@ -0,0 +1 @@
Hello world!