ソースを参照

More test & more bugfixes

Now have separated tests for CTurmit and Turmit
Yann Weber 6年前
コミット
dc1311ad36
7個のファイルの変更381行の追加29行の削除
  1. 1
    10
      gte/__init__.py
  2. 36
    2
      libs/cturmit.c
  3. 2
    2
      libs/cturmit.h
  4. 49
    7
      libs/turmit.c
  5. 3
    1
      libs/turmit.h
  6. 289
    3
      tests/test_cturmit.py
  7. 1
    4
      tests/test_turmit.py

+ 1
- 10
gte/__init__.py ファイルの表示

@@ -1,13 +1,4 @@
1 1
 ##@brief GTE Genetic Turmits Evolver
2 2
 
3
-try:
4
-	import cturmit as turmit
5
-	print(turmit.CTurmit)
6
-	Turmit = turmit.CTurmit
7
-	print("WOO")
8
-except ImportError:
9
-	from . import turmit
10
-	from .turmit import Turmit
11
-
12
-
3
+from . import turmit
13 4
 from . import rpnlib

+ 36
- 2
libs/cturmit.c ファイルの表示

@@ -79,7 +79,7 @@ but %ld found", sz);
79 79
 	{
80 80
 		PyErr_Restore(errtype, errvalue, errbck);
81 81
 		PyErr_SetString(PyExc_TypeError,
82
-			"stack_size expected to be an integer");
82
+			"int_max expected to be an integer");
83 83
 		return -1;
84 84
 	}
85 85
 	if(int_max)
@@ -93,7 +93,7 @@ but %ld found", sz);
93 93
 	}
94 94
 	else
95 95
 	{
96
-		arg_int_max = 0x100000;
96
+		arg_int_max = 0x10000;
97 97
 	}
98 98
 
99 99
 	expr = PyMapping_GetItemString(kwds, "prog");
@@ -152,6 +152,40 @@ CTurmit_dealloc(CTurmit *self)
152 152
 	Py_TYPE(self)->tp_free((PyObject*)self);
153 153
 }
154 154
 
155
+PyObject* CTurmit_call(PyObject *func, PyObject *args, PyObject *kwds)
156
+{
157
+	turmit_int res;
158
+	PyObject *arg;
159
+	CTurmit *self;
160
+	turmit_int exec_args[5];
161
+	char *argsname[5] = {"x", "y", "r", "g", "b"}; // see TURMIT_VAR_L
162
+	char err_msg[64];
163
+	int i;
164
+	PyObject *errtype, *errvalue, *errbck;
165
+
166
+	self = (CTurmit*)func;
167
+	
168
+	PyErr_Fetch(&errtype, &errvalue, &errbck);
169
+
170
+	for(i=0; i<5; i++)
171
+	{
172
+		arg = PyMapping_GetItemString(kwds, argsname[i]);
173
+		if(PyErr_Occurred())
174
+		{
175
+			PyErr_Restore(errtype, errvalue, errbck);
176
+			snprintf(err_msg, 64, "Argument %s missing",
177
+				argsname[i]);
178
+			PyErr_SetString(PyExc_TypeError,
179
+				err_msg);
180
+			Py_RETURN_NONE;
181
+		}
182
+		exec_args[i] = PyLong_AsUnsignedLongLong(arg);
183
+	}
184
+
185
+	res = turmit_exec(self->turmit, exec_args);
186
+	return PyLong_FromUnsignedLongLong(res);
187
+}
188
+
155 189
 Py_ssize_t
156 190
 CTurmit_len(CTurmit *self)
157 191
 {

+ 2
- 2
libs/cturmit.h ファイルの表示

@@ -117,7 +117,7 @@ CTurmit_init(CTurmit *self, PyObject *args, PyObject *kwds);
117 117
 void
118 118
 CTurmit_dealloc(CTurmit *self);
119 119
 
120
-
120
+PyObject* CTurmit_call(PyObject *func, PyObject *args, PyObject *kwds);
121 121
 
122 122
 static PyTypeObject CTurmitType = {
123 123
 	PyVarObject_HEAD_INIT(NULL, 0)
@@ -134,7 +134,7 @@ static PyTypeObject CTurmitType = {
134 134
 	0,						/* tp_as_sequence */
135 135
 	CTurmit_asmapping,				/* tp_as_mapping */
136 136
 	0,						/* tp_hash  */
137
-	0,						/* tp_call */
137
+	CTurmit_call,					/* tp_call */
138 138
 	0,						/* tp_str */
139 139
 	0,						/* tp_getattro */
140 140
 	0,						/* tp_setattro */

+ 49
- 7
libs/turmit.c ファイルの表示

@@ -152,8 +152,15 @@ turmit_t *turmit_init(turmit_t *turmit, ssize_t stack_sz, ssize_t int_max,
152 152
 	turmit->op_expr_sz = 0;
153 153
 	turmit->op_cur = 0;
154 154
 	turmit->stack_sz = stack_sz;
155
-	turmit->stack = malloc(sizeof(turmit_int) * turmit->stack_sz);
156 155
 	turmit->stack_cur = turmit->stack_sz - 1;
156
+	turmit->stack = malloc(sizeof(turmit_int) * turmit->stack_sz);
157
+
158
+	if(!turmit->stack)
159
+	{
160
+		perror("Unable to allocate turmit's stack's memory");
161
+		return turmit;
162
+	}
163
+	bzero(turmit->stack, sizeof(turmit_int) * turmit->stack_sz);
157 164
 
158 165
 	if(turmit->flags & TURMIT_AUTOCOMP)
159 166
 	{
@@ -185,13 +192,13 @@ turmit_int turmit_exec(turmit_t *turmit, const turmit_int args[5])
185 192
 		op = &(turmit->op_expr[turmit->op_cur]);
186 193
 		switch(op->value)
187 194
 		{
188
-		case 1:
195
+		case TURMIT_SYM_OP:
189 196
 			op->op.op(turmit);
190 197
 			break;
191
-		case 2:
198
+		case TURMIT_SYM_VAL:
192 199
 			SPUSH(turmit, op->op.val);
193 200
 			break;
194
-		case 3:
201
+		case TURMIT_SYM_VAR:
195 202
 			SPUSH(turmit, args[op->op.var]);
196 203
 			break;
197 204
 		default:
@@ -200,6 +207,7 @@ turmit_int turmit_exec(turmit_t *turmit, const turmit_int args[5])
200 207
 			turmit->op_cur = turmit->op_expr_sz;
201 208
 			break;
202 209
 		}
210
+//_turmit_stack_dump(turmit);
203 211
 		turmit->op_cur++;
204 212
 	}
205 213
 	return SCUR(turmit);
@@ -223,7 +231,7 @@ int turmit_compile(turmit_t *turmit)
223 231
 	turmit->op_expr = malloc(sizeof(turmit_op_t) * turmit->op_expr_sz);
224 232
 	bzero(turmit->op_expr, sizeof(turmit_op_t) * turmit->op_expr_sz);
225 233
 	opcur = 0;
226
-	
234
+
227 235
 	cur = turmit->expr;
228 236
 	while(*cur != '\0')
229 237
 	{
@@ -263,6 +271,7 @@ int turmit_compile(turmit_t *turmit)
263 271
 		if(TURMIT_VAR_L[i] != '\0') { continue; }
264 272
 
265 273
 		//Checking for values
274
+		//hex
266 275
 		if(strcasecmp("0x", cur) == 0)
267 276
 		{
268 277
 			cur+= 2;
@@ -280,13 +289,30 @@ int turmit_compile(turmit_t *turmit)
280 289
 			cur = endptr;
281 290
 			continue;
282 291
 		}
292
+		//decimal
293
+		if(*cur <= '9' && *cur >= '0')
294
+		{
295
+			iret = strtol(cur, &endptr, 10);
296
+			err = errno;
297
+			if(err)
298
+			{
299
+				fprintf(stderr, "Invalid constant %s : %s\n",
300
+					cur, strerror(err));
301
+				goto turmit_compile_err;
302
+			}
303
+			turmit->op_expr[opcur].op.val = iret;
304
+			turmit->op_expr[opcur].value = TURMIT_SYM_VAL;
305
+			opcur++;
306
+			cur = endptr;
307
+			continue;
308
+		}
283 309
 		
284 310
 		//Checking for op
285 311
 		isym = tsym;
286 312
 		while(isym->str != NULL)
287 313
 		{
288
-			if(strcasecmp(isym->str, cur) == 0 ||
289
-				(isym->alias && strncmp(cur, isym->alias,3)))
314
+			if((strncasecmp(isym->str, cur, strlen(isym->str)) == 0) ||
315
+				(isym->alias && strncmp(cur, isym->alias,3) == 0))
290 316
 			{
291 317
 				cur += strlen(isym->str);
292 318
 				turmit->op_expr[opcur].op.op = isym->op_fun;
@@ -296,7 +322,12 @@ int turmit_compile(turmit_t *turmit)
296 322
 			}
297 323
 			isym++;
298 324
 		}
325
+		if(isym->str != NULL)
326
+		{
327
+			continue;
328
+		}
299 329
 		//unrecognized symbol :'(
330
+		fprintf(stderr, "Unrecognized op, dropping char : '%s'\n", cur);
300 331
 		cur++;
301 332
 	}
302 333
 	turmit->op_expr_sz = opcur + 1;
@@ -320,3 +351,14 @@ int turmit_compile(turmit_t *turmit)
320 351
 		return 1;
321 352
 }
322 353
 
354
+void _turmit_stack_dump(turmit_t *turmit)
355
+{
356
+	int i;
357
+	fprintf(stderr, "Stack cur = %lu\n[", turmit->stack_cur);
358
+	for(i=0; i<turmit->stack_sz; i++)
359
+	{
360
+		fprintf(stderr,"%llu, ", turmit->stack[i]);
361
+	}
362
+	fprintf(stderr, "]\n");
363
+}
364
+

+ 3
- 1
libs/turmit.h ファイルの表示

@@ -33,7 +33,7 @@ typedef void (*turmit_op_f)(turmit_t*);
33 33
 
34 34
 #define TURMIT_SYM_OP		1
35 35
 #define TURMIT_SYM_VAL		2
36
-#define TURMIT_SYM_VAR		2
36
+#define TURMIT_SYM_VAR		3
37 37
 
38 38
 #define TURMIT_VAR_L		"xyrgb"
39 39
 
@@ -143,6 +143,8 @@ turmit_int turmit_exec(turmit_t *turmit, const turmit_int args[5]);
143 143
  */
144 144
 int turmit_compile(turmit_t *turmit);
145 145
 
146
+void _turmit_stack_dump(turmit_t *turmit);
147
+
146 148
 TURMIT_OP(mem_sz);
147 149
 
148 150
 TURMIT_OP(add);

+ 289
- 3
tests/test_cturmit.py ファイルの表示

@@ -1,8 +1,294 @@
1 1
 import unittest
2
+import inspect
2 3
 
3
-import cturmit
4
+from cturmit import CTurmit as Turmit
5
+from gte.rpnlib import _op_list
4 6
 
5
-class CTurmitTestCase(unittest.TestCase):
7
+class TurmitTestCase(unittest.TestCase):
6 8
     
7 9
     def test_init(self):
8
-        ct = cturmit.CTurmit()
10
+        ''' Test Turmit class __init__ '''
11
+        t = Turmit(42)
12
+        self.assertEqual(len(t._stack), 42)
13
+        self.assertEqual(t.shead, 0)
14
+        self.assertEqual(len(t._stack) - 1 , t._cur)
15
+
16
+    def test_init_args(self):
17
+        ''' Test Turmit __init__ arguments '''
18
+        t = Turmit()
19
+        t = Turmit(prog_size = 42)
20
+        t = Turmit(prog = 'G R B 44 MOD ADD 43 MOD ADD 42 MOD')
21
+        t = Turmit(prog = 'G R B ADD ADD 42 MOD', max_int = 0xFFFF,
22
+                   signed_int = False, stack_size=42)
23
+
24
+    def test_call(self):
25
+        ''' Test Turmit.__call__ '''
26
+        t = Turmit(prog = 'G R B ADD ADD 42 MOD', max_int = 0xFFFF,
27
+                   signed_int = False, stack_size=42)
28
+        r = t(x=1, y=2, r=255, g=255, b=255)
29
+        self.assertEqual(r, 9)
30
+        r = t(x=2, y=2, r=255, g=0, b=0)
31
+        self.assertEqual(r, 3)
32
+
33
+    def test_init_badargs(self):
34
+        ''' Test Turmit __init__ bad arguments '''
35
+        with self.assertRaises(RuntimeError):
36
+            t = Turmit(foobar=42)
37
+        with self.assertRaises(ValueError):
38
+            t = Turmit(-1)
39
+        with self.assertRaises(ValueError):
40
+            t = Turmit(max_int = -1)
41
+        with self.assertRaises(ValueError):
42
+            t = Turmit(prog='foobar')
43
+
44
+
45
+
46
+class TurmitOperationTestCase(unittest.TestCase):
47
+    
48
+    def test_push(self):
49
+        ''' Test Turmit _push() method '''
50
+        t = Turmit()
51
+        t._push(1)
52
+        self.assertEqual(t.shead, 1)
53
+        t._push(2)
54
+        self.assertEqual(t.shead, 2)
55
+
56
+    def _rpn(self, rpn, narg = 2):
57
+        if rpn not in _op_list:
58
+            raise unittest.SkipTest('"%s" not implemented' % rpn)
59
+        method, wrapped = _op_list[rpn]
60
+        if narg != len(inspect.signature(method).parameters) - 1:
61
+            self.fail('Expected %s to take %d arguments, but Turmit.%s() takes \
62
+%d arguments' % (rpn, narg, rpn, len(inspect.signature(method).parameters) - 1))
63
+
64
+    def test_add(self):
65
+        ''' Test turmit add method '''
66
+        self._rpn('add')
67
+
68
+        t = Turmit()
69
+        t._push(42)
70
+        t._push(8)
71
+        t.add()
72
+        self.assertEqual(t._cur, 0)
73
+        self.assertEqual(t.shead, 50)
74
+
75
+        t._push(42)
76
+        t._push(8)
77
+        t.add()
78
+        self.assertEqual(t._cur, 1)
79
+        self.assertEqual(t.shead, 50)
80
+
81
+        t.add()
82
+
83
+        self.assertEqual(t._cur, 0)
84
+        self.assertEqual(t.shead, 100)
85
+
86
+    def test_mem_sz(self):
87
+        ''' Test turmit mem_sz() operation '''
88
+        self._rpn('mem_sz', 1)
89
+
90
+        t = Turmit(8)
91
+        self.assertEqual(len(t._stack), 8)
92
+
93
+        t._push(42)
94
+        t.mem_sz()
95
+        self.assertEqual(len(t._stack), 42)
96
+        self.assertEqual(t._cur, 7)
97
+
98
+        t._push(42)
99
+        t._push(8)
100
+        t.mem_sz()
101
+        self.assertEqual(t._cur, 0)
102
+        self.assertEqual(t.shead, 42)
103
+
104
+    def test_sub(self):
105
+        ''' Test turmit sub() method '''
106
+        self._rpn('sub')
107
+
108
+        t = Turmit()
109
+
110
+        t._push(50)
111
+        t._push(8)
112
+
113
+        t.sub()
114
+        self.assertEqual(t._cur, 0)
115
+        self.assertEqual(t.shead, 42)
116
+
117
+        t._push(50)
118
+        t._push(8)
119
+        t.sub()
120
+        self.assertEqual(t._cur, 1)
121
+        self.assertEqual(t.shead, 42)
122
+
123
+        t.sub()
124
+        self.assertEqual(t._cur, 0)
125
+        self.assertEqual(t.shead, 0)
126
+
127
+    def test_mul(self):
128
+        ''' Test turmit mul() method '''
129
+        self._rpn('mul')
130
+
131
+        t = Turmit()
132
+
133
+        t._push(7)
134
+        t._push(6)
135
+
136
+        t.mul()
137
+        self.assertEqual(t._cur, 0)
138
+        self.assertEqual(t.shead, 42)
139
+
140
+        t._push(7)
141
+        t._push(6)
142
+        t.mul()
143
+        self.assertEqual(t._cur, 1)
144
+        self.assertEqual(t.shead, 42)
145
+
146
+        t.mul()
147
+        self.assertEqual(t._cur, 0)
148
+        self.assertEqual(t.shead, 42 *42)
149
+    
150
+    def test_div(self):
151
+        ''' Test turmit division capabilities '''
152
+        self._rpn('div')
153
+
154
+        t = Turmit()
155
+
156
+        t._push(43)
157
+        t._push(7)
158
+
159
+        t.div()
160
+        self.assertEqual(t._cur, 0)
161
+        self.assertEqual(t.shead, 6)
162
+
163
+    def test_mod(self):
164
+        ''' Test turmit mod() method '''
165
+        self._rpn('mod')
166
+
167
+        t = Turmit()
168
+        t._push(42)
169
+        t._push(4)
170
+
171
+        t.mod()
172
+        self.assertEqual(t._cur, 0)
173
+        self.assertEqual(t.shead, 2)
174
+
175
+    def test_pow(self):
176
+        ''' Test turmit pow() method '''
177
+        self._rpn('pow')
178
+
179
+        t = Turmit()
180
+        t._push(2)
181
+        t._push(4)
182
+
183
+        t.pow()
184
+        self.assertEqual(t._cur, 0)
185
+        self.assertEqual(t.shead, 16)
186
+
187
+    def test_sqrt(self):
188
+        ''' Test turmit sqrt() method '''
189
+        self._rpn('sqrt', 1)
190
+
191
+        t = Turmit()
192
+        t._push(42)
193
+
194
+        t.sqrt()
195
+
196
+        self.assertEqual(t._cur, 0)
197
+        self.assertEqual(t.shead, 6)
198
+
199
+    def test_and(self):
200
+        ''' Test turmit binary and() method '''
201
+        self._rpn('bin_and')
202
+
203
+        t = Turmit()
204
+        t._push(10)
205
+        t._push(42)
206
+
207
+        t.bin_and()
208
+
209
+        self.assertEqual(t._cur, 0)
210
+        self.assertEqual(t.shead, 10)
211
+
212
+    def test_or(self):
213
+        ''' Test turmit binary or() method '''
214
+        self._rpn('bin_or')
215
+
216
+        t = Turmit()
217
+        t._push(42)
218
+        t._push(7)
219
+
220
+        t.bin_or()
221
+        
222
+        self.assertEqual(t._cur, 0)
223
+        self.assertEqual(t.shead, 47)
224
+
225
+    def test_xor(self):
226
+        ''' Test turmit binary xor() method '''
227
+        self._rpn('bin_xor')
228
+
229
+        t = Turmit()
230
+        t._push(42)
231
+        t._push(11)
232
+
233
+        t.bin_xor()
234
+        self.assertEqual(t._cur, 0)
235
+        self.assertEqual(t.shead, 33)
236
+
237
+    def test_rshift(self):
238
+        ''' Test turmit rshift method '''
239
+        self._rpn('rshift')
240
+
241
+        t = Turmit()
242
+        t._push(42)
243
+        t._push(2)
244
+
245
+        t.rshift()
246
+        self.assertEqual(t._cur, 0)
247
+        self.assertEqual(t.shead, 10)
248
+
249
+    def test_lshift(self):
250
+        ''' Test turmit lshift method '''
251
+        self._rpn('lshift')
252
+
253
+        t = Turmit()
254
+        t._push(10)
255
+        t._push(2)
256
+        t.lshift()
257
+        self.assertEqual(t._cur, 0)
258
+        self.assertEqual(t.shead, 40)
259
+
260
+    def test_dup(self):
261
+        ''' Test turmit dup() method '''
262
+        self._rpn('dup', 1)
263
+
264
+        t = Turmit()
265
+        t._push(42)
266
+        t.dup()
267
+        self.assertEqual(t._cur, 1)
268
+        self.assertEqual(t.shead, 42)
269
+
270
+    def test_pop(self):
271
+        ''' Test turmit pop() method '''
272
+        self._rpn('pop', 1)
273
+
274
+        t = Turmit()
275
+        t._push(10)
276
+        t._push(2)
277
+        t.pop()
278
+        self.assertEqual(t._cur, 0)
279
+        self.assertEqual(t.shead, 10)
280
+        t.pop()
281
+        self.assertEqual(t._cur, len(t._stack) - 1)
282
+
283
+    def test_swp(self):
284
+        ''' Test turmit swp() method '''
285
+        self._rpn('swp', 2)
286
+
287
+        t = Turmit()
288
+        t._push(42)
289
+        t._push(1337)
290
+        t.swp()
291
+        self.assertEqual(t._cur, 1)
292
+        self.assertEqual(t.shead, 42)
293
+        t._pop()
294
+        self.assertEqual(t.shead, 1337)

+ 1
- 4
tests/test_turmit.py ファイルの表示

@@ -1,10 +1,7 @@
1 1
 import unittest
2 2
 import inspect
3 3
 
4
-import gte
5
-Turmit = gte.Turmit
6
-#from gte import Turmit
7
-print(Turmit)
4
+from gte.turmit import Turmit
8 5
 from gte.rpnlib import _op_list
9 6
 
10 7
 class TurmitTestCase(unittest.TestCase):

読み込み中…
キャンセル
保存