CFCK

From Esolang
Jump to navigation Jump to search

CFCK is an esoteric programming language by User:FluixMakesEsolangs, the offical compiler is made in Python, and is 1.58kb. This Programming language was made as for the challenge of writing a compiler for brainfuck. This language is still in active development!

How the language Works

The language has 11 instructions:

  • PUSH - Pushes value onto stack
  • POP - Pops top value from stack
  • SWAP - Swaps top 2 values, if theres an argument it swaps the top value and the n of the argument relative to the size of the stack
  • DUP - Duplicates top 2 values on stack
  • OUT - Prints current value from ascii value
  • IN - Takes in input as ascii value
  • INC - Increments current value
  • DEC - Decrements current value
  • ADD - Pops top value and adds it to the next top value
  • SUB - Pops top value and subtracts it from the next top value
  • COND - Begins block that only runs if top value is 1
  • ENDWHILE - Ends block and loops
  • ENDIF - Ends block and doesnt loop

Examples

Cat: (ends when you input !)

PUSH, 1;
COND;
  POP;
  IN;
  OUT;
  PUSH, 33;
  SUB;
ENDWHILE;

Truth Machine:

IN;
OUT;
PUSH, 48;
SUB;
COND;
  PUSH, 49;
  OUT;
  POP;
  PUSH, 48;
  SUB;
ENDWHILE;

Known Implementation

Official Implementation:

def compile(uprog):
    prog = uprog.split(";")
    compiled = ">"
    c = 0
    inwhile = False
    while c < len(prog):
        i = prog[c].strip()
        
        if not i:
            c += 1
            continue
        
        if '#' in i:
            i = i.split('#')[0].strip()
        
        args = i.split(",")
        
        match args[0].strip():
            case "PUSH":
                if len(args) < 2:
                    print("Not enough arguments for PUSH!")
                    exit(1)
                else:
                    x = 0
                    if args[1].strip().isdigit():
                        x = int(args[1].strip())
                        if x >= 256:
                            print("Cannot push 256 to stack!")
                            exit(1)
                    else:
                        x = ord(args[1][0])
                    compiled += ">[>]"
                    for y in range(x):
                        compiled += "+"
            case "POP":
                compiled += "[-]<"
            case "SWAP":
                if len(args) < 2:
                    compiled += "[->+<]<[->+<]>>[-<<+>>]<"
                else:
                    if args[1].strip().isdigit():
                        x = int(args[1].strip())
                        if x == 0:
                            print("Warning: SWAP, 0 will produce nothing!")
                        else:compiled += "[->+<]"
                        compiled += "<" * x
                        compiled += "[" + ">" * x + "+" + "<" * x + "-]"
                        compiled += ">" * (x + 1)
                        compiled += "[" + "<" * (x + 1) + "+" + ">" * (x + 1) + "-]"
                        compiled += "<"
                    else:
                        print("Argument must be an integer!")
                        exit(1)
            case "DUP":
                compiled += "[->+>+<<]>>[-<<+>>]<"
            case "OUT":
                compiled += "."
            case "IN":
                compiled += ",>"
            case "INC":
                compiled += "+"
            case "DEC":
                compiled += "-"
            case "ADD":
                compiled += "[-<+>]<"
            case "SUB":
                compiled += "[-<->]"
            case "COND":
                compiled += "["
                xc = c + 1
                index = 1
                while xc < len(prog) and index > 0:
                    if prog[xc] == "COND":
                        depth += 1
                    elif prog[xc] == "ENDWHILE" or prog[xc] == "ENDIF":
                        if prog[xc] == "ENDWHILE":
                            inwhile = True
                        break
                    xc += 1
            case "ENDWHILE":
                compiled += "]"
                inwhile = False
            case "ENDIF":
                if inwhile:
                    compiled += ">]"
                else:
                    compiled += ">]<"
            
        c += 1
    return compiled

if __name__ == "__main__":
    import sys
    import os
    
    if len(sys.argv) < 3:
        print("CFCK <input> <output>")
        exit(1)
    
    try:
        with open(sys.argv[1], "r", encoding="utf-8") as file:
            program = file.read()
            result = compile(program)
            with open(sys.argv[2], 'w') as outfile:
                outfile.write(result)
    except FileNotFoundError:
        print("File not found!")
        exit(1)

Comments in this compiler need to be marked with the End of line marker by ';'