More test & more bugfixes

Now have separated tests for CTurmit and Turmit
This commit is contained in:
Yann Weber 2018-08-25 21:18:31 +02:00
commit dc1311ad36
7 changed files with 381 additions and 29 deletions

View file

@ -1,13 +1,4 @@
##@brief GTE Genetic Turmits Evolver
try:
import cturmit as turmit
print(turmit.CTurmit)
Turmit = turmit.CTurmit
print("WOO")
except ImportError:
from . import turmit
from .turmit import Turmit
from . import turmit
from . import rpnlib

View file

@ -79,7 +79,7 @@ but %ld found", sz);
{
PyErr_Restore(errtype, errvalue, errbck);
PyErr_SetString(PyExc_TypeError,
"stack_size expected to be an integer");
"int_max expected to be an integer");
return -1;
}
if(int_max)
@ -93,7 +93,7 @@ but %ld found", sz);
}
else
{
arg_int_max = 0x100000;
arg_int_max = 0x10000;
}
expr = PyMapping_GetItemString(kwds, "prog");
@ -152,6 +152,40 @@ CTurmit_dealloc(CTurmit *self)
Py_TYPE(self)->tp_free((PyObject*)self);
}
PyObject* CTurmit_call(PyObject *func, PyObject *args, PyObject *kwds)
{
turmit_int res;
PyObject *arg;
CTurmit *self;
turmit_int exec_args[5];
char *argsname[5] = {"x", "y", "r", "g", "b"}; // see TURMIT_VAR_L
char err_msg[64];
int i;
PyObject *errtype, *errvalue, *errbck;
self = (CTurmit*)func;
PyErr_Fetch(&errtype, &errvalue, &errbck);
for(i=0; i<5; i++)
{
arg = PyMapping_GetItemString(kwds, argsname[i]);
if(PyErr_Occurred())
{
PyErr_Restore(errtype, errvalue, errbck);
snprintf(err_msg, 64, "Argument %s missing",
argsname[i]);
PyErr_SetString(PyExc_TypeError,
err_msg);
Py_RETURN_NONE;
}
exec_args[i] = PyLong_AsUnsignedLongLong(arg);
}
res = turmit_exec(self->turmit, exec_args);
return PyLong_FromUnsignedLongLong(res);
}
Py_ssize_t
CTurmit_len(CTurmit *self)
{

View file

@ -117,7 +117,7 @@ CTurmit_init(CTurmit *self, PyObject *args, PyObject *kwds);
void
CTurmit_dealloc(CTurmit *self);
PyObject* CTurmit_call(PyObject *func, PyObject *args, PyObject *kwds);
static PyTypeObject CTurmitType = {
PyVarObject_HEAD_INIT(NULL, 0)
@ -134,7 +134,7 @@ static PyTypeObject CTurmitType = {
0, /* tp_as_sequence */
CTurmit_asmapping, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
CTurmit_call, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */

View file

@ -152,8 +152,15 @@ turmit_t *turmit_init(turmit_t *turmit, ssize_t stack_sz, ssize_t int_max,
turmit->op_expr_sz = 0;
turmit->op_cur = 0;
turmit->stack_sz = stack_sz;
turmit->stack = malloc(sizeof(turmit_int) * turmit->stack_sz);
turmit->stack_cur = turmit->stack_sz - 1;
turmit->stack = malloc(sizeof(turmit_int) * turmit->stack_sz);
if(!turmit->stack)
{
perror("Unable to allocate turmit's stack's memory");
return turmit;
}
bzero(turmit->stack, sizeof(turmit_int) * turmit->stack_sz);
if(turmit->flags & TURMIT_AUTOCOMP)
{
@ -185,13 +192,13 @@ turmit_int turmit_exec(turmit_t *turmit, const turmit_int args[5])
op = &(turmit->op_expr[turmit->op_cur]);
switch(op->value)
{
case 1:
case TURMIT_SYM_OP:
op->op.op(turmit);
break;
case 2:
case TURMIT_SYM_VAL:
SPUSH(turmit, op->op.val);
break;
case 3:
case TURMIT_SYM_VAR:
SPUSH(turmit, args[op->op.var]);
break;
default:
@ -200,6 +207,7 @@ turmit_int turmit_exec(turmit_t *turmit, const turmit_int args[5])
turmit->op_cur = turmit->op_expr_sz;
break;
}
//_turmit_stack_dump(turmit);
turmit->op_cur++;
}
return SCUR(turmit);
@ -223,7 +231,7 @@ int turmit_compile(turmit_t *turmit)
turmit->op_expr = malloc(sizeof(turmit_op_t) * turmit->op_expr_sz);
bzero(turmit->op_expr, sizeof(turmit_op_t) * turmit->op_expr_sz);
opcur = 0;
cur = turmit->expr;
while(*cur != '\0')
{
@ -263,6 +271,7 @@ int turmit_compile(turmit_t *turmit)
if(TURMIT_VAR_L[i] != '\0') { continue; }
//Checking for values
//hex
if(strcasecmp("0x", cur) == 0)
{
cur+= 2;
@ -280,13 +289,30 @@ int turmit_compile(turmit_t *turmit)
cur = endptr;
continue;
}
//decimal
if(*cur <= '9' && *cur >= '0')
{
iret = strtol(cur, &endptr, 10);
err = errno;
if(err)
{
fprintf(stderr, "Invalid constant %s : %s\n",
cur, strerror(err));
goto turmit_compile_err;
}
turmit->op_expr[opcur].op.val = iret;
turmit->op_expr[opcur].value = TURMIT_SYM_VAL;
opcur++;
cur = endptr;
continue;
}
//Checking for op
isym = tsym;
while(isym->str != NULL)
{
if(strcasecmp(isym->str, cur) == 0 ||
(isym->alias && strncmp(cur, isym->alias,3)))
if((strncasecmp(isym->str, cur, strlen(isym->str)) == 0) ||
(isym->alias && strncmp(cur, isym->alias,3) == 0))
{
cur += strlen(isym->str);
turmit->op_expr[opcur].op.op = isym->op_fun;
@ -296,7 +322,12 @@ int turmit_compile(turmit_t *turmit)
}
isym++;
}
if(isym->str != NULL)
{
continue;
}
//unrecognized symbol :'(
fprintf(stderr, "Unrecognized op, dropping char : '%s'\n", cur);
cur++;
}
turmit->op_expr_sz = opcur + 1;
@ -320,3 +351,14 @@ int turmit_compile(turmit_t *turmit)
return 1;
}
void _turmit_stack_dump(turmit_t *turmit)
{
int i;
fprintf(stderr, "Stack cur = %lu\n[", turmit->stack_cur);
for(i=0; i<turmit->stack_sz; i++)
{
fprintf(stderr,"%llu, ", turmit->stack[i]);
}
fprintf(stderr, "]\n");
}

View file

@ -33,7 +33,7 @@ typedef void (*turmit_op_f)(turmit_t*);
#define TURMIT_SYM_OP 1
#define TURMIT_SYM_VAL 2
#define TURMIT_SYM_VAR 2
#define TURMIT_SYM_VAR 3
#define TURMIT_VAR_L "xyrgb"
@ -143,6 +143,8 @@ turmit_int turmit_exec(turmit_t *turmit, const turmit_int args[5]);
*/
int turmit_compile(turmit_t *turmit);
void _turmit_stack_dump(turmit_t *turmit);
TURMIT_OP(mem_sz);
TURMIT_OP(add);

View file

@ -1,8 +1,294 @@
import unittest
import inspect
import cturmit
from cturmit import CTurmit as Turmit
from gte.rpnlib import _op_list
class CTurmitTestCase(unittest.TestCase):
class TurmitTestCase(unittest.TestCase):
def test_init(self):
ct = cturmit.CTurmit()
''' Test Turmit class __init__ '''
t = Turmit(42)
self.assertEqual(len(t._stack), 42)
self.assertEqual(t.shead, 0)
self.assertEqual(len(t._stack) - 1 , t._cur)
def test_init_args(self):
''' Test Turmit __init__ arguments '''
t = Turmit()
t = Turmit(prog_size = 42)
t = Turmit(prog = 'G R B 44 MOD ADD 43 MOD ADD 42 MOD')
t = Turmit(prog = 'G R B ADD ADD 42 MOD', max_int = 0xFFFF,
signed_int = False, stack_size=42)
def test_call(self):
''' Test Turmit.__call__ '''
t = Turmit(prog = 'G R B ADD ADD 42 MOD', max_int = 0xFFFF,
signed_int = False, stack_size=42)
r = t(x=1, y=2, r=255, g=255, b=255)
self.assertEqual(r, 9)
r = t(x=2, y=2, r=255, g=0, b=0)
self.assertEqual(r, 3)
def test_init_badargs(self):
''' Test Turmit __init__ bad arguments '''
with self.assertRaises(RuntimeError):
t = Turmit(foobar=42)
with self.assertRaises(ValueError):
t = Turmit(-1)
with self.assertRaises(ValueError):
t = Turmit(max_int = -1)
with self.assertRaises(ValueError):
t = Turmit(prog='foobar')
class TurmitOperationTestCase(unittest.TestCase):
def test_push(self):
''' Test Turmit _push() method '''
t = Turmit()
t._push(1)
self.assertEqual(t.shead, 1)
t._push(2)
self.assertEqual(t.shead, 2)
def _rpn(self, rpn, narg = 2):
if rpn not in _op_list:
raise unittest.SkipTest('"%s" not implemented' % rpn)
method, wrapped = _op_list[rpn]
if narg != len(inspect.signature(method).parameters) - 1:
self.fail('Expected %s to take %d arguments, but Turmit.%s() takes \
%d arguments' % (rpn, narg, rpn, len(inspect.signature(method).parameters) - 1))
def test_add(self):
''' Test turmit add method '''
self._rpn('add')
t = Turmit()
t._push(42)
t._push(8)
t.add()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 50)
t._push(42)
t._push(8)
t.add()
self.assertEqual(t._cur, 1)
self.assertEqual(t.shead, 50)
t.add()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 100)
def test_mem_sz(self):
''' Test turmit mem_sz() operation '''
self._rpn('mem_sz', 1)
t = Turmit(8)
self.assertEqual(len(t._stack), 8)
t._push(42)
t.mem_sz()
self.assertEqual(len(t._stack), 42)
self.assertEqual(t._cur, 7)
t._push(42)
t._push(8)
t.mem_sz()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 42)
def test_sub(self):
''' Test turmit sub() method '''
self._rpn('sub')
t = Turmit()
t._push(50)
t._push(8)
t.sub()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 42)
t._push(50)
t._push(8)
t.sub()
self.assertEqual(t._cur, 1)
self.assertEqual(t.shead, 42)
t.sub()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 0)
def test_mul(self):
''' Test turmit mul() method '''
self._rpn('mul')
t = Turmit()
t._push(7)
t._push(6)
t.mul()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 42)
t._push(7)
t._push(6)
t.mul()
self.assertEqual(t._cur, 1)
self.assertEqual(t.shead, 42)
t.mul()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 42 *42)
def test_div(self):
''' Test turmit division capabilities '''
self._rpn('div')
t = Turmit()
t._push(43)
t._push(7)
t.div()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 6)
def test_mod(self):
''' Test turmit mod() method '''
self._rpn('mod')
t = Turmit()
t._push(42)
t._push(4)
t.mod()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 2)
def test_pow(self):
''' Test turmit pow() method '''
self._rpn('pow')
t = Turmit()
t._push(2)
t._push(4)
t.pow()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 16)
def test_sqrt(self):
''' Test turmit sqrt() method '''
self._rpn('sqrt', 1)
t = Turmit()
t._push(42)
t.sqrt()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 6)
def test_and(self):
''' Test turmit binary and() method '''
self._rpn('bin_and')
t = Turmit()
t._push(10)
t._push(42)
t.bin_and()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 10)
def test_or(self):
''' Test turmit binary or() method '''
self._rpn('bin_or')
t = Turmit()
t._push(42)
t._push(7)
t.bin_or()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 47)
def test_xor(self):
''' Test turmit binary xor() method '''
self._rpn('bin_xor')
t = Turmit()
t._push(42)
t._push(11)
t.bin_xor()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 33)
def test_rshift(self):
''' Test turmit rshift method '''
self._rpn('rshift')
t = Turmit()
t._push(42)
t._push(2)
t.rshift()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 10)
def test_lshift(self):
''' Test turmit lshift method '''
self._rpn('lshift')
t = Turmit()
t._push(10)
t._push(2)
t.lshift()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 40)
def test_dup(self):
''' Test turmit dup() method '''
self._rpn('dup', 1)
t = Turmit()
t._push(42)
t.dup()
self.assertEqual(t._cur, 1)
self.assertEqual(t.shead, 42)
def test_pop(self):
''' Test turmit pop() method '''
self._rpn('pop', 1)
t = Turmit()
t._push(10)
t._push(2)
t.pop()
self.assertEqual(t._cur, 0)
self.assertEqual(t.shead, 10)
t.pop()
self.assertEqual(t._cur, len(t._stack) - 1)
def test_swp(self):
''' Test turmit swp() method '''
self._rpn('swp', 2)
t = Turmit()
t._push(42)
t._push(1337)
t.swp()
self.assertEqual(t._cur, 1)
self.assertEqual(t.shead, 42)
t._pop()
self.assertEqual(t.shead, 1337)

View file

@ -1,10 +1,7 @@
import unittest
import inspect
import gte
Turmit = gte.Turmit
#from gte import Turmit
print(Turmit)
from gte.turmit import Turmit
from gte.rpnlib import _op_list
class TurmitTestCase(unittest.TestCase):