from ctypes import * from enum import Enum dll = CDLL("./libcreole.so") class CompileRet(Enum): OK = 0 OPCODE_READ_ERROR = 1 OPCODE_MALFORMED = 2 ARG_READ_ERROR = 3 ARG_MALFORMED = 4 LAST_READ_ERROR = 5 LAST_MALFORMED = 6 LABEL_OVERFLOW = 7 TYPE_ERROR = 8 CLEARED_INSTRUCTION = 9 class CIns(Structure): _fields_ = [("opcode", c_int), ("w_flags", c_ubyte * 3), ("w", c_uint * 3)] class CReader(Structure): _fields_ = [("p", POINTER(c_ubyte)), ("left", c_size_t)] def make_uchar_buf(s): buf = (c_ubyte * len(s))() buf[:] = s[:] return buf def make_reader(s): buf = make_uchar_buf(s) return CReader(buf, len(s)) class CEnv(Structure): _fields_ = [ ("reg", POINTER(c_uint)), ("reglen", c_size_t), ("lab", POINTER(c_size_t)), ("lablen", c_size_t), ("stk", POINTER(c_uint)), ("stkptr", c_size_t), ("stklen", c_size_t), ("prg", POINTER(CIns)), ("prgptr", c_size_t), ("prgend", c_size_t), ("prglen", c_size_t) ] class ExecutionEnvironment: def __init__(self, reglen=32, lablen=32, stklen=4096, prglen=4096): cenv = CEnv() cenv.reglen = reglen cenv.reg = (c_uint * reglen)() cenv.lablen = lablen cenv.lab = (c_size_t * lablen)() cenv.stklen = stklen cenv.stk = (c_uint * stklen)() cenv.stkptr = 0 cenv.prglen = prglen cenv.prg = (CIns * prglen)() cenv.prgptr = 0 cenv.prgend = 0 self.cenv = cenv def restart(self): self.cenv.stkptr = 0 self.cenv.prgptr = 0 self.cenv.prgend = 0 def load(self, prog): rd = make_reader(prog) self.restart() ret = dll.creole_compile(byref(self.cenv), byref(rd)) return CompileRet(ret) class CParseLineException(Exception): pass def parse_line(line): rd = make_reader(line) ins = CIns() ret = dll.creole_parse_line(byref(ins), byref(rd)) if ret != CompileRet.OK.value: raise CParseLineException(CompileRet(ret).name) return (ins.opcode, list(zip(ins.w_flags, ins.w)))