Skip to content

Instantly share code, notes, and snippets.

@hornc
Last active January 10, 2023 23:36
Show Gist options
  • Save hornc/7860821f7642e58c9bf217d663ea655e to your computer and use it in GitHub Desktop.
Save hornc/7860821f7642e58c9bf217d663ea655e to your computer and use it in GitHub Desktop.
G_arD^EN CorUtY@rD esolang interpreter
#!/usr/bin/env python
"""
Esoteric programming language interpreter for
G_arD^EN CorUtY@rD
https://esolangs.org/wiki/G_arD%5EEN_CorUtY@rD
Interpreter by Salpynx, 2022.
"""
import sys
import re
from time import sleep
NAME = 'G_arD^EN CorUtY@rD'
ARROWS = '>v<^'
PAUSE = 0.1 # pause time between frames in seconds
DEBUG = False
LIMIT = 3000
PRE = '\033['
RST = PRE + '0m'
CLR = '\033c'
WHITE = '1;37m'
BROWN = '0;33m'
SOIL = BROWN
FENCE = WHITE
LCYAN = '1;36m'
RED = '1;31m'
GREEN = '0;32m'
LG = '1;32m'
BLUE = '0;34m'
PATH = '1;33m'
LGREY = '1;37m'
GREY = '1;30m'
MAGENTA = '1;35m'
COLORS = {
'x': FENCE,
'X': FENCE,
'K': FENCE,
'L': LCYAN,
'#': RED,
'~': GREEN,
'=': SOIL,
'+': BLUE,
'-': PATH,
':': GREY,
'E': GREY,
'T': WHITE,
'_': RED,
'>': LG,
'<': LG,
'^': LG,
'v': LG,
'@': MAGENTA,
}
def color(s):
"""Return an ANSI colored string based on first symbol."""
c = COLORS.get(s[0], '0m')
return PRE + c + s + RST
class GardenCourtyard:
def __init__(self, source):
self.source = source
self.width = len(source[0])
self.height = min([n for n,v in enumerate(source) if '_' in v])
self.ip = self.findfirstchair()
self.dir = 0 # 0: right (down, left, up)
self.soil = self.source[0][:self.source[0].find('K')].replace('x', '0').replace('X', '1')
self.cq = '' # Command queue
self.oq = '' # Output queue
self.output = ''
def findfirstchair(self):
for y, line in enumerate(self.source):
for x, c in enumerate(line):
if c == 'L':
return [x, y]
def show(self):
print(CLR + PRE + MAGENTA + NAME + RST)
for j, line in enumerate(self.source):
if j == 0: # soil / datastring / fence
if len(self.soil) < self.width:
line = self.soil + 'K' + line[len(self.soil) + 1:]
else:
line = self.soil
line = line.replace('0', 'x').replace('1', 'X')
if j == self.ip[1]:
x = self.ip[0]
c = line[x]
line = line[:x] + '@' + line[x+1:]
runs = re.findall(r'((.)\2*)', line)
for run in runs:
block, symbol = run
print(color(block), end='')
print()
def process(self, c):
if c == '~':
self.cq += '0'
self.dir = 1
elif c == '+':
self.cq += '1'
self.dir = 0
elif c == '-':
if self.soil[-1] == '0':
self.dir = 0
else:
self.dir = 1
elif c == ':':
self.cq += c
self.dir = 1
elif c == '=':
cc = self.cq[0]
self.cq = self.cq[1:]
if cc == ':':
self.soil = self.soil[1:]
else:
if self.soil[0] == '1':
self.soil = self.soil + cc
elif c == 'E':
self.oq += self.soil[0]
self.soil = self.soil[1:]
if len(self.oq) == 8:
self.output += chr(int(self.oq, 2))
self.oq = ''
#self.dir = 0
elif c in ARROWS:
self.dir = ARROWS.find(c)
d = self.dir
x, y = self.ip
if d & 1:
y += 1 - (d - 1)
else:
x += 1 - d
self.ip = [x, y]
def run(self):
running = True
i = 0
while running:
x, y = self.ip
if y == self.height:
break
self.show()
c = self.source[y][x]
self.process(c)
if DEBUG:
print('Current command:', c)
print(self.ip, self.dir)
print('DATA STRING:', self.soil)
print(i)
print('CQ:', self.cq)
print('OQ:', self.oq)
print(f'>:{self.output}')
sleep(PAUSE)
i += 1
if i > LIMIT:
break
if __name__ == '__main__':
sourcefile = sys.argv[1]
source = []
width = 0
with open(sourcefile, 'r') as f:
for line in f.readlines():
line = line.strip("\n")
width = len(line)
source.append(line)
gc = GardenCourtyard(source)
gc.run()
@hornc
Copy link
Author

hornc commented Aug 3, 2022

This is my attempt at an animated ANSI graphics version of an interpreter for G_arD^EN CorUtY@rD

The input command T is not yet implemented, and there may be issues with the spec and/or my interpretation of it.

The language was designed by https://esolangs.org/wiki/User:BoundedBeans , not me.

Currently the one example Hi program prints iH using this 🤷 , but it still looks pretty, UPDATE: FIXED

The language appealed to me because it was a bitwise cyclic tag variant, and I have been working with BCT a bit so thought it'd be easy to figure out how it was supposed to work, and because the ASCII garden / grid layout has a pleasing game-like feel, and I could see it working with ANSI colours.

I hope someone enjoys this. I'll consider working on it further or moving the code to a proper repo if there is any interest.

image

@hornc
Copy link
Author

hornc commented Aug 3, 2022

I've figured out what is wrong with the reversed output. I mis-interpreted K as ignorable padding. It actually ends the initial datastring. That makes more sense and I know what to fix. Won't happen today though.

UPDATE: FIXED K:
I've also made the first fence row update to represent the current datastring / 'soil' as the program runs to indicate the current internal state.
The 'soil' modifies the 'fence' -- not sure that makes sense, but it's more to look at.
The command queue is not represented on screen, that might be nice, but all the current examples never get beyong one item in the command queue anyway.

@hornc
Copy link
Author

hornc commented Jan 10, 2023

Moved to a repo, now part of: https://github.com/hornc/esointerpreters

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment