aboutsummaryrefslogtreecommitdiffstats
path: root/asm/ffi.py
diff options
context:
space:
mode:
authorGravatar Peter McGoron 2023-02-11 20:49:39 +0000
committerGravatar Peter McGoron 2023-02-11 20:49:39 +0000
commit5f3275cf2d3e1f371595f3ef15831e2ee788f780 (patch)
tree97b2bbe678cc5f45aaca568ff5d4c9edd3a41005 /asm/ffi.py
parentmore test (diff)
add signed division IDIV
Diffstat (limited to 'asm/ffi.py')
-rw-r--r--asm/ffi.py32
1 files changed, 30 insertions, 2 deletions
diff --git a/asm/ffi.py b/asm/ffi.py
index a1907c6..4c1ca15 100644
--- a/asm/ffi.py
+++ b/asm/ffi.py
@@ -1,4 +1,5 @@
from ctypes import *
+import creole
from enum import Enum
dll = CDLL("./libcreole.so")
@@ -24,6 +25,7 @@ class RunRet(Enum):
RUN_LABEL_OVERFLOW = 5
REGISTER_OVERFLOW = 6
UNKNOWN_OPCODE = 7
+ DIVIDE_BY_ZERO = 8
def is_halt(self):
return not (self == RunRet.CONTINUE or self == RunRet.SYSCALL)
@@ -59,8 +61,30 @@ class CEnv(Structure):
("prglen", c_size_t)
]
+class RegisterOverflowError(Exception):
+ def __init__(self, reg):
+ self.reg = reg
+class StackOverflowError(Exception):
+ def __init__(self, pos):
+ self.pos = pos
+class InvalidSyscallError(Exception):
+ def __init__(self, sc):
+ self.sc = sc
+class CompileError(Exception):
+ def __init__(self, r):
+ self.r = r
+
class Environment:
- def __init__(self, reglen=32, lablen=32, stklen=4096, prglen=4096):
+ def getreg(self, reg):
+ if reg >= self.cenv.reglen or reg < 0:
+ raise RegisterOverflowError(r)
+ return creole.from_2c(self.cenv.reg[reg])
+ def getstk(self, stk):
+ if stk >= self.cenv.stklen or stk < 0:
+ raise StackOverflowError(r)
+ return creole.from_2c(self.cenv.stk[stk])
+
+ def __init__(self, prog=None, reglen=32, lablen=32, stklen=4096, prglen=4096):
cenv = CEnv()
cenv.reglen = reglen
cenv.reg = (c_uint * reglen)()
@@ -78,6 +102,10 @@ class Environment:
cenv.prgend = 0
self.cenv = cenv
+ if prog is not None:
+ r = self.load(prog)
+ if r is not CompileRet.OK:
+ raise CompileError(r)
def restart(self):
self.cenv.stkptr = 0
@@ -91,7 +119,7 @@ class Environment:
return CompileRet(ret)
def syscall(self, sc):
- pass
+ raise InvalidSyscallError(sc)
def __call__(self):
sc = c_size_t()
ret = RunRet.CONTINUE