CES source

From Esolang
Jump to navigation Jump to search

Note: This page may be updated at any time due to CES updates. The CES update log can also be found.

utils.py

from copy import deepcopy

class ExpandableList:
    """A list that expands when indexed out of bounds.
    ExpandableList(default) -> object"""
    def __init__(self, default):
        self.items = [deepcopy(default)]
        self.default = default
    def __expand_to(self, pos):
        if pos < 0: self.items = [deepcopy(self.default) for _ in range(-pos)] + self.items
        elif pos >= len(self.items): self.items += [deepcopy(self.default) for _ in range(pos-len(self.items)+1)]
        return max(pos, 0)
    def __getitem__(self, pos):
        pos = self.__expand_to(pos)
        return self.items[pos]
    def __setitem__(self, pos, item):
        pos = self.__expand_to(pos)
        self.items[pos] = item
    def __len__(self):
        return len(self.items)
    def __repr__(self):
        return repr(self.items)

class Tape(ExpandableList):
    """An ExpandableList with a pointer.
    Tape(default) -> object"""
    def __init__(self, default):
        super().__init__(default)
        self.ptr = 0
    def move_right(self, count=1):
        self.ptr += count
        self.current
    def move_left(self, count=1):
        self.ptr -= count
        self.current
        self.ptr = max(self.ptr,0)
    @property
    def current(self):
        return self[self.ptr]
    @current.setter
    def current(self, current):
        self[self.ptr] = current

class BoundedTape(Tape):
    """A bounded list with a pointer.
    BoundedTape(default, size) -> object"""
    def __init__(self, default, size):
        self.default = default
        self.items = [deepcopy(default) for _ in range(size)]
        self.ptr = 0
    def move_right(self, count=1):
        if self.ptr + count >= len(self.items): raise IndexError
        self.ptr += count
    def move_left(self, count=1):
        if self.ptr - count < 0: raise IndexError
        self.ptr -= count

class Stack:
    """A stack.
    Stack() -> object"""
    def __init__(self):
        self.items = []
    def push(self, item):
        self.items.append(item)
    def pop(self):
        return self.items.pop()

def __combine_dicts(d1, d2): return dict(list(d1.items())+list(d2.items()))

def __get_jump_dict_single_match(code, from_char, to_char):
    jumps = {}
    to_add = []
    for pos in range(len(code)):
        c = code[pos]
        if c == from_char: to_add.append(pos)
        elif c == to_char: jumps[to_add.pop()] = pos
    return jumps

def get_jump_dict(code, matches, bidi=True):
    """Gets the jump dictionary for code.
    Arguments:
        code:  The code to find jumps in.
        matches: A dictionary of jump characters
            (e.g. to jump from [ to ], {'[':']'})
        bidi: Whether or not the jumps are bidirectional."""
    total = {}
    for fc, tc in matches.items():
        new_jumps = __get_jump_dict_single_match(code, fc, tc)
        total = __combine_dicts(total, new_jumps)
    if bidi:
        reversed_total = {v:k for k,v in total.items()}
        total = __combine_dicts(total, reversed_total)
    return total

char_esolang.py

def make_char_esolang(file):
    with open(file+".ces") as f: ces_data = [line.rstrip("\n").replace("    ","\t") for line in f.readlines()]
    sections = {}
    current_section = None
    for line in ces_data:
        if line.startswith("## ") and line.endswith(" ##"):
            current_section = line[3:-3]
            sections[current_section] = []
        elif line: sections[current_section].append(line)
    ces_py = ""
    if "UTILS" in sections.keys(): ces_py += "from utils import %s\n"%(", ".join(sections["UTILS"]))
    ces_py += "import sys\n\ndef __get_input(default):\n\tglobal __prgm_input\n\t"
    ces_py += "if not __prgm_input: __prgm_input += input()\n\t"
    ces_py += "if not __prgm_input: return default\n\t"
    ces_py += "output, __prgm_input = __prgm_input[0], __prgm_input[1:]\n\t"
    ces_py += "return output\n\n"
    ces_py += "def run_%s(CODE):\n\tglobal __prgm_input\n\t"%file
    ces_py += "\n\t".join(sections.get("DECLARE",[]))+"\n\t"
    ces_py += "__ip = 0\n\t__prgm_input = \"\"\n\t"
    ces_py += "while __ip<len(CODE):\n\t\t__instr = CODE[__ip]\n\t\t"
    instrs = ""
    for instr in sections["INSTRUCTIONS"]:
        if len(instr) == 1: instrs += "elif __instr == \"%s\":\n"%instr
        elif instr.startswith("\t"): instrs += instr + "\n"
        else: instrs += "elif __instr == \"%s\":\n\t%s\n"%(instr[0],instr[2:])
    instrs = instrs[2:-1].replace("\n","\n\t\t")
    instrs = instrs.replace("JUMP","__ip = JUMPS[__ip]")
    instrs = instrs.replace("GET_CHAR","__get_input")
    instrs = instrs.replace("HALT","sys.exit()")
    between = "\n\t\t".join(sections.get("BETWEEN",[]))
    ces_py += instrs+"\n\t\t"+between+"\n\t\t__ip += 1"
    with open(file+".py","w") as f: f.write(ces_py)

brainfuck.ces

## UTILS ##
Tape
get_jump_dict

## DECLARE ##
tape = Tape(0)
JUMPS = get_jump_dict(CODE, {"[":"]"})

## INSTRUCTIONS ##
+ tape.current = (tape.current+1)%256
- tape.current = (tape.current-1)%256
> tape.move_right()
< tape.move_left()
, tape.current = ord(GET_CHAR(chr(0)))
. print(chr(tape.current), end="")
[ if tape.current == 0: JUMP
] if tape.current != 0: JUMP

Other .ces files can be found on the CES files page.

Notes

All CES pages: