Curlyfrick/Interpreter
Jump to navigation
Jump to search
#Curlyfrick Interpreter #Absolutely no rights reserved import math ''' OpCode | What | Psuedo 0001 | Print Value | PRINT val 0010 | Print Variable | PRINT VAR 0011 | Store value in var | VAR val 0100 | Increment variable ptr | INC PTR val 0101 | Decrement variable ptr | DEC PTR val 0110 | Input Variable | INPUT var 0111 | If condition | IF var 1000 | While loop | WHILE var 1001 | Comment | // 1010 | End statement | END 1011 | Increment variable | INC val 1100 | Decrement variable | DEC val 1101 | Print value as char | PRINT CHR(val) 1110 | Print var as char | PRINT CHR(VAR) 1111 | Zero the value of var | VAR 0 ''' # Opcode made of {}s and " "s # Value made of {}s, and +-*/%~!√^ CMD = "cmd" VAL = "val" OPS = { "...{}" : "OUT", "..{}." : "OUTV", "..{}{}": "STR", ".{}.." : "INC PTR", ".{}.{}": "DEC PTR", ".{}{}.": "PUT", ".{}{}{}": "IF", "{}..." : "WHILE", "{}..{}": "//", "{}.{}.": "END", "{}.{}{}": "INC", "{}{}..": "DEC", "{}{}.{}": "OUT CHR", "{}{}{}.": "OUTV CHR", "{}{}{}{}": "VAR 0" } def brackets_to_expr(src): src = src.replace("^", "**") src = src.replace("√", "math.sqrt(") src = src.replace("{}", "1") return eval(src) def ast(code): bricks = [] for line in code: try: op, data = line.split("\t") except: continue if op not in OPS: continue bricks.append({"cmd" : OPS[op], "val" : brackets_to_expr(data)}) return bricks class Interpreter(): def __init__(self, code): self.registers = [] self.program = code self.raw = ast(self.program) self.vp = 0 #variable pointer self.ip = 0 #instruction pointer self.do_skip = False self.jumps = [] def execute(self, num_vars): self.registers = [0]*num_vars while self.ip < len(self.raw): cmd = self.raw[self.ip] if self.do_skip: if cmd[CMD] == "END": self.do_skip = False else: self.ip += 1 continue if cmd[CMD] == "OUT": print(cmd[VAL], end="") elif cmd[CMD] == "OUTV": print(self.registers[self.vp], end="") elif cmd[CMD] == "STR": registers[self.vp] = cmd[VAL] elif cmd[CMD] == "INC PTR": self.vp = (self.vp + cmd[VAL]) % len(self.registers) elif cmd[CMD] == "DEC PTR": self.vp = (self.vp - cmd[VAL]) % len(self.registers) elif cmd[CMD] == "PUT": temp = input(">") try: self.registers[self.vp] = int(temp) except: self.registers[self.vp] = temp elif cmd[CMD] == "INC": if type(registers[self.vp]) is str: temp = "" for char in registers[self.vp]: temp += chr(ord(char) + cmd[VAL]) self.registers[self.vp] = temp else: self.registers[self.vp] += cmd[VAL] elif cmd[CMD] == "DEC": if type(self.registers[self.vp]) is str: temp = "" for char in self.registers[self.vp]: temp += chr(ord(char) - cmd[VAL]) self.registers[self.vp] = temp else: self.registers[self.vp] -= 1 elif cmd[CMD] == "OUT CHR": print(chr(cmd[VAL]), end="") elif cmd[CMD] == "OUTV CHR": if type(self.registers[self.vp]) is str: print(self.registers[self.vp], end="") else: print(ord(self.registers[self.vp]), end="") elif cmd[CMD] == "VAR 0": self.registers[self.vp] = 0 elif cmd[CMD] == "IF": if not self.registers[self.vp]: self.do_skip = True elif cmd[CMD] == "WHILE": if self.registers[self.vp]: self.jumps.append(self.ip) else: self.do_skip = True elif cmd[CMD] == "END": if len(self.jumps): if self.registers[self.vp]: self.ip = self.jumps[-1] else: self.jumps.pop() self.ip += 1 if __name__ == "__main__": import argparse parser = argparse.ArgumentParser() parser.add_argument("file", help="The location of the cf file to open") parser.add_argument("-v","--vars", help="The number of variables in the regs", type=int) args = parser.parse_args() try: file = open(args.file) except: print("File not found") exit() code = file.read() code = code.strip("\n").split("\n") x = Interpreter(code) if args.vars: x.execute(args.var) else: x.execute(30000) print()