Omnis Clocha Clochabilis in Clocherio Clochando Clochans Clochativo Clochare facit Clochabiliter Clochantes/refimpl
		
		
		
		Jump to navigation
		Jump to search
		
- Note: there may be errors in the reference implementation. It's still young.
 
#!/bin/python3                                                                  
import sys, re, string, os.path as op
_regex = re.compile('[' + re.escape(string.punctuation) + ']')
bf2oc9 = {
    '>': 'clochans',
    '<': 'clochare',
    '+': 'clochando',
    '-': 'clocherio',
    ',': 'clochantes',
    '.': 'clochativo',
    '[': 'clochabilis',
    ']': 'clochabiliter',
}
oc92bf = {v: n for n, v in bf2oc9.items()}
class ClochaClochareClochansError(Exception): pass
usage_msg = '''Usage: {}  PROG1  [ PROG2, ... ]                                 
Executes one or more programs written in Omnis Clocha Clochabilis in Clocherio  
Clochando Clochans Clochativo Clochare facit Clochabiliter Clochantes.          
'''
def remove_punctuation(s):
    return _regex.sub(' ', s).lower()
def brainfuck_to_OC9(bf):
    'You have to add the `clocha` yourself.'
    return ' '.join(bf2oc9[c] for c in bf if c in bf2oc9)
def OC9_to_brainfuck(oc9):
    oc9 = remove_punctuation(oc9).split()
    since_last_clocha = 0
    ret = []
    for s in oc9:
        if not s: continue
        since_last_clocha += 1
        if s == 'clocha':
            since_last_clocha = 0
        elif s in oc92bf:
            ret.append(oc92bf[s])
        if since_last_clocha >= 10:
            raise ClochaClochareClochansError('Needs more clocha!')
    return ''.join(ret)
def _exec_bf(code, tape = None):
    if tape is None: tape = {}
    call_stack = []
    head = 0
    i = 0
    while i < len(code):
        c = code[i]
        i += 1
        if c == '>':
            head += 1
        elif c == '<':
            head -= 1
        elif c == '+':
            tape[head] = tape.get(head, 0) + 1
        elif c == '-':
            tape[head] = tape.get(head, 0) - 1
        elif c == ',':
            tape[head] = ord(sys.stdin.read(1))
        elif c == '.':
            sys.stdout.write(chr(tape.get(head, 0)))
        elif c == '[':
            call_stack.append(i)
        elif c == ']':
            if tape.get(head, 0): i = call_stack[-1]
            else: call_stack.pop()
def exec_file(path):
    with open(path, 'r') as f:
        code = f.read()
    exec_code(code)
def exec_code(code):
    try:
        bf = OC9_to_brainfuck(code)
    except ClochaClochareClochansError as e:
        sys.stderr.write(e + '\n')
    _exec_bf(bf)
def usage(prog_name):
    sys.stdout.write(usage_msg.format(prog_name))
def main():
    if len(sys.argv) <= 1 or '--help' in sys.argv:
        usage(sys.argv[0])
        return
    for arg in sys.argv[1:]:
        if op.exists(arg):
            exec_file(arg)
        else:
            sys.stderr.write('File \'{}\' does not exist\n'.format(arg))
if __name__ == '__main__': main()