aboutsummaryrefslogtreecommitdiffstats
path: root/asm/ffi.py
diff options
context:
space:
mode:
authorGravatar Peter McGoron 2023-02-18 16:05:09 +0000
committerGravatar Peter McGoron 2023-02-18 16:05:09 +0000
commit48827c5b747eca6d56555f69cae37291feb5fcda (patch)
tree063bc21af510fe961a7002678e0cdf9dbb8bc228 /asm/ffi.py
parentadd data, remove labels and make jumps absolute (diff)
adjust python assembler to new API
Diffstat (limited to 'asm/ffi.py')
-rw-r--r--asm/ffi.py77
1 files changed, 26 insertions, 51 deletions
diff --git a/asm/ffi.py b/asm/ffi.py
index 41faba3..13731dd 100644
--- a/asm/ffi.py
+++ b/asm/ffi.py
@@ -24,10 +24,9 @@ class CompileRet(Enum):
ARG_MALFORMED = 4
LAST_READ_ERROR = 5
LAST_MALFORMED = 6
- LABEL_OVERFLOW = 7
+ DATA_OVERFLOW = 7
TYPE_ERROR = 8
- CLEARED_INSTRUCTION = 9
- PROGRAM_OVERFLOW = 10
+ PROGRAM_OVERFLOW = 9
class RunRet(Enum):
CONTINUE = 0
@@ -35,44 +34,36 @@ class RunRet(Enum):
STOP = 2
STACK_OVERFLOW = 3
STACK_UNDERFLOW = 4
- LABEL_OVERFLOW = 5
+ DECODE_ERROR = 5
REGISTER_OVERFLOW = 6
UNKNOWN_OPCODE = 7
DIVIDE_BY_ZERO = 8
HIGH_BIT_MALFORMED = 9
+ JUMP_OVERFLOW = 10
def is_halt(self):
return not (self == RunRet.CONTINUE or self == RunRet.SYSCALL)
-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 Reader:
+ def __init__(self, s):
+ self.buf = (c_ubyte * len(s))()
+ self.buf[:] = s[:]
+ self.rd = CReader(self.buf, len(s))
class CEnv(Structure):
_fields_ = [
+ ("dats", POINTER(POINTER(c_ubyte))),
+ ("datlen", c_size_t),
("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)
+ ("r_current", CReader),
+ ("r_start", CReader)
]
class RegisterOverflowError(Exception):
@@ -122,38 +113,34 @@ class Environment:
stk = stk - 1
return self.cenv.stk[stk]
- def __init__(self, prog=None, reglen=32, lablen=32, stklen=4096, prglen=4096):
+ def reset(self):
+ self.cenv.r_current = self.cenv.r_start
+
+ def __init__(self, prog=None, reglen=32, datlen=32, stklen=4096, prglen=4096):
cenv = CEnv()
+ cenv.dats = (POINTER(c_ubyte) * datlen)()
+ cenv.datlen = datlen
+
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
if prog is not None:
+ if type(prog) is creole.Program:
+ prog = prog()
r = self.load(prog)
if r is not CompileRet.OK:
raise CompileError(r)
- 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))
+ self.reader = Reader(prog)
+ self.cenv.r_current = self.reader.rd
+ self.cenv.r_start = self.cenv.r_current
+ ret = dll.creole_compile(byref(self.cenv), byref(self.cenv.r_current))
return CompileRet(ret)
def syscall(self, sc):
@@ -168,15 +155,3 @@ class Environment:
if debug:
print(self.cenv.reg[0])
return 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)))