Affine Mess is an esoteric programming language created by User:Caenbe. Its purpose is to explore what is possible when the programmer can use XOR and NOT freely, but can't use AND except where the language allows. How well it accomplishes that purpose is debatable, because the programmer is also hindered by the fact that there are only 25 bits in the memory. Despite this, some popular problems are possible (with some caveats). There may be another language in the future based on this one which implements infinite memory. This language inspired by XOṘ Mạchịne. Like that language, the only command is the XOR command. I/O and AND operations are memory mapped, and the entire program runs in an implicit loop.
The lowercase letters of the Latin alphabet (excluding l) represent the 25 bits. 1 represents the constant bit 1. Every pair of bit names, e.g.
ab, stores a XOR b in a. 11 is used to open and close comments.
These are the steps taken to execute a program. Note: bytes are represented most significant bit first.
- All bits are initialized to 0.
- A byte from the input stream is stored in i-q. If none is available, 0s are used.
- All XOR commands in the program are run.
- The byte r-y is sent to the output.
- The bitwise AND of a-h and i-q is stored in r-y.
- If z==1, terminate. Otherwise, return to step 2.
zm zq t1 u1 y1 yz
Hello World: (Actually prints "Hi World")
11 Sliding memory. A single 1 starts at a, and slides to h, where it causes the program to halt. 11 hggg zh gfff feee eddd dccc cbbb baaa abacadaeafagaha1 11 Print 'Hi World' 11 sa va sb tb vb yb tc sd ud wd xd yd se te ve we xe ye sf tf uf xf sg tg vg wg sh th wh
Cat program: (Note: 4 null characters are printed after the input is echoed)
aa bb cc dd ee ff gg hh ai bj ck dm en fo gp hq ii jj kk mm nn oo pp qq ir js kt mu nv ow px qy rr ss tt uu vv ww xx yy ra sb tc ud ve wf xg yh a1 b1 c1 d1 e1 f1 g1 h1 eiieei fjjffj gkkggk hmmhhm gnnggn hoohho hpphhp zh
Written in Python 3.
# Affine Mess Interpreter # Author: Caenbe # Version 0.2 import sys, os CMDS = "abcdefghijkmnopqrstuvwxyz1" def main(): filename = input("File name: ") # Ask the user for the file to run f = open(os.path.join(sys.path, filename), "r") program = f.read() f.close() p = ''.join(program.split('11')[::2]) # Remove comments # Translate every command to a number instructions = list(filter(lambda x: x > -1, map(lambda c: CMDS.find(c), p))) print("Program read!") # Get input (this is done before execution, because getting input during would be annoying) prgmInput = input("Supply input: ") inputIndex = 0 memory = [False] * 25 midInstruction = False while (not memory): # While the halt flag (z) is not set nextChar = chr(0) if (inputIndex < len(prgmInput)): # Input a character nextChar = prgmInput[inputIndex] inputIndex = inputIndex + 1 charIntoBoolList(nextChar, memory, 8) firstHalf = 0 for inst in instructions: if (not midInstruction): # If this is the first half of an instruction, remember it firstHalf = inst midInstruction = True else: if (inst == 25): memory[firstHalf] = not memory[firstHalf] # XOR a variable with 1 (i.e. toggle it) else: memory[firstHalf] = (memory[firstHalf] != memory[inst]) # XOR two variables together midInstruction = False print(charFromBoolList(memory, 16), end='') # Output a character for i in range(8): memory[i + 16] = memory[i] and memory[i + 8] # AND operation # Utility function that puts a character into memory def charIntoBoolList(ch, boolList, start): nextChar = int(ord(ch)) for i in range(8): boolList[start + 7 - i] = (nextChar % 2 == 1) nextChar = int(nextChar / 2) # Utility function that extracts a character from memory def charFromBoolList(boolList, start): outChar = int(0) for i in range(8): outChar = outChar * 2 if boolList[start + i]: outChar = outChar + 1 return chr(outChar) if __name__ == '__main__': main()