Mercurial > lcfOS
annotate test/testc3.py @ 389:2ec730e45ea1
Added check for recursive struct
author | Windel Bouwman |
---|---|
date | Fri, 16 May 2014 12:29:31 +0200 |
parents | c2ddc8a36f5e |
children | 6ae782a085e0 |
rev | line source |
---|---|
167 | 1 import unittest |
355 | 2 import logging |
287 | 3 import io |
342 | 4 from ppci.c3 import Builder, Lexer |
5 from ppci.target import SimpleTarget | |
6 import ppci | |
148 | 7 |
8 | |
204 | 9 class testLexer(unittest.TestCase): |
293 | 10 def setUp(self): |
11 diag = ppci.DiagnosticsManager() | |
300 | 12 self.l = Lexer(diag) |
293 | 13 |
205 | 14 def testUnexpectedCharacter(self): |
287 | 15 snippet = io.StringIO(""" var s \u6c34 """) |
205 | 16 with self.assertRaises(ppci.CompilerError): |
293 | 17 list(self.l.tokenize(snippet)) |
18 | |
19 def check(self, snippet, toks): | |
20 toks2 = list(tok.typ for tok in self.l.tokenize(io.StringIO(snippet))) | |
21 self.assertSequenceEqual(toks, toks2) | |
205 | 22 |
204 | 23 def testBlockComment(self): |
293 | 24 snippet = """ |
204 | 25 /* Demo */ |
26 var int x = 0; | |
293 | 27 """ |
204 | 28 toks = ['var', 'ID', 'ID', '=', 'NUMBER', ';', 'END'] |
293 | 29 self.check(snippet, toks) |
205 | 30 |
204 | 31 def testBlockCommentMultiLine(self): |
293 | 32 snippet = """ |
204 | 33 /* Demo |
34 bla1 | |
35 bla2 | |
36 */ | |
37 var int x = 0; | |
293 | 38 """ |
204 | 39 toks = ['var', 'ID', 'ID', '=', 'NUMBER', ';', 'END'] |
293 | 40 self.check(snippet, toks) |
204 | 41 |
287 | 42 |
204 | 43 class testBuilder(unittest.TestCase): |
215 | 44 def setUp(self): |
45 self.diag = ppci.DiagnosticsManager() | |
301 | 46 self.builder = Builder(self.diag, SimpleTarget()) |
215 | 47 self.diag.clear() |
355 | 48 # Add a null logging handler to disable warning log messages: |
49 nh = logging.NullHandler() | |
50 logging.getLogger().addHandler(nh) | |
215 | 51 |
306 | 52 def makeFileList(self, snippet): |
53 """ Try to make a list with opened files """ | |
54 if type(snippet) is list: | |
55 l2 = [] | |
56 for s in snippet: | |
57 if type(s) is str: | |
58 l2.append(io.StringIO(s)) | |
59 else: | |
60 l2.append(s) | |
61 return l2 | |
62 else: | |
63 return [io.StringIO(snippet)] | |
64 | |
215 | 65 def expectErrors(self, snippet, rows): |
66 """ Helper to test for expected errors on rows """ | |
389 | 67 list(self.builder.build([io.StringIO(snippet)])) |
215 | 68 actualErrors = [err.row for err in self.diag.diags] |
69 if rows != actualErrors: | |
306 | 70 self.diag.printErrors() |
215 | 71 self.assertSequenceEqual(rows, actualErrors) |
287 | 72 # self.assertFalse(all(ircode)) |
215 | 73 |
287 | 74 def expectOK(self, snippet): |
306 | 75 """ Expect a snippet to be OK """ |
76 ircode = list(self.builder.build(self.makeFileList(snippet))) | |
77 if len(self.diag.diags) > 0: | |
78 self.diag.printErrors() | |
287 | 79 self.assertTrue(all(ircode)) |
306 | 80 self.assertEqual(0, len(self.diag.diags)) |
217 | 81 return ircode |
215 | 82 |
251
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
249
diff
changeset
|
83 def testPackage(self): |
284 | 84 p1 = """module p1; |
251
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
249
diff
changeset
|
85 type int A; |
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
249
diff
changeset
|
86 """ |
284 | 87 p2 = """module p2; |
251
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
249
diff
changeset
|
88 import p1; |
306 | 89 var p1.A b; |
251
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
249
diff
changeset
|
90 """ |
306 | 91 self.expectOK([p1, p2]) |
251
6ed3d3a82a63
Added another c3 example. First import attempt
Windel Bouwman
parents:
249
diff
changeset
|
92 |
288 | 93 def testPackageMutual(self): |
94 p1 = """module p1; | |
95 import p2; | |
96 type int A; | |
97 var p2.B b; | |
98 """ | |
99 p2 = """module p2; | |
100 import p1; | |
101 var p1.A a; | |
102 """ | |
306 | 103 self.expectOK([p1, p2]) |
288 | 104 |
313 | 105 def testConstant(self): |
106 snip = """module C; | |
107 const int a = 2; | |
108 """ | |
389 | 109 self.expectOK(snip) |
313 | 110 |
111 @unittest.skip('Not checked yet') | |
112 def testConstantMutual(self): | |
113 snip = """module C; | |
114 const int a = b + 1; | |
115 const int b = a + 1; | |
116 function void f() | |
117 { | |
118 return b; | |
119 } | |
120 """ | |
389 | 121 self.expectOK(snip) |
313 | 122 |
293 | 123 def testPackageNotExists(self): |
124 p1 = """module p1; | |
125 import p23; | |
126 """ | |
306 | 127 self.expectErrors(p1, [0]) |
293 | 128 |
215 | 129 def testFunctArgs(self): |
287 | 130 snippet = """ |
284 | 131 module testargs; |
167 | 132 function void t2(int a, double b) |
133 { | |
134 t2(2, 2); | |
135 t2(2); | |
136 t2(1, 1.2); | |
137 } | |
287 | 138 """ |
139 self.expectErrors(snippet, [5, 6]) | |
148 | 140 |
303 | 141 def testReturn(self): |
142 snippet = """ | |
143 module testreturn; | |
144 function void t() | |
145 { | |
146 return; | |
147 } | |
148 """ | |
149 self.expectOK(snippet) | |
150 | |
151 def testReturn2(self): | |
152 snippet = """ | |
153 module testreturn; | |
154 function int t() | |
155 { | |
156 return 2; | |
157 } | |
158 """ | |
159 self.expectOK(snippet) | |
160 | |
215 | 161 def testExpressions(self): |
287 | 162 snippet = """ |
284 | 163 module test; |
167 | 164 function void t(int a, double b) |
165 { | |
166 var int a2; | |
167 var bool c; | |
168 | |
169 a2 = b * a; | |
170 c = a; | |
171 } | |
287 | 172 """ |
307 | 173 self.expectErrors(snippet, [8, 9]) |
205 | 174 |
230 | 175 def testExpression1(self): |
287 | 176 snippet = """ |
284 | 177 module testexpr1; |
230 | 178 function void t() |
179 { | |
180 var int a, b, c; | |
181 a = 1; | |
182 b = a * 2 + a * a; | |
183 c = b * a - 3; | |
184 } | |
287 | 185 """ |
186 self.expectOK(snippet) | |
230 | 187 |
215 | 188 def testEmpty(self): |
287 | 189 snippet = """ |
190 module A | |
191 """ | |
192 self.expectErrors(snippet, [3]) | |
205 | 193 |
215 | 194 def testEmpty2(self): |
287 | 195 snippet = "" |
196 self.expectErrors(snippet, [1]) | |
205 | 197 |
215 | 198 def testRedefine(self): |
287 | 199 snippet = """ |
200 module test; | |
201 var int a; | |
202 var int b; | |
203 var int a; | |
204 """ | |
205 self.expectErrors(snippet, [5]) | |
205 | 206 |
215 | 207 def testWhile(self): |
287 | 208 snippet = """ |
209 module tstwhile; | |
210 function void t() | |
211 { | |
306 | 212 var int i; |
213 i = 0; | |
169
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
214 while (i < 1054) |
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
215 { |
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
216 i = i + 3; |
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
217 } |
307 | 218 } |
219 """ | |
220 self.expectOK(snippet) | |
205 | 221 |
307 | 222 def testWhile2(self): |
223 snippet = """ | |
224 module tstwhile; | |
225 function void t() | |
226 { | |
205 | 227 while(true) |
228 { | |
229 } | |
230 | |
231 while(false) | |
232 { | |
233 } | |
287 | 234 } |
235 """ | |
236 self.expectOK(snippet) | |
215 | 237 |
238 def testIf(self): | |
239 snippet = """ | |
287 | 240 module tstIFF; |
241 function void t(int b) | |
242 { | |
180 | 243 var int a; |
169
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
244 a = 2; |
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
245 if (a > b) |
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
246 { |
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
247 if (a > 1337) |
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
248 { |
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
249 b = 2; |
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
250 } |
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
251 } |
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
252 else |
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
253 { |
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
254 b = 1; |
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
255 } |
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
256 |
ee0d30533dae
Added more tests and improved the diagnostic update
Windel Bouwman
parents:
168
diff
changeset
|
257 return b; |
287 | 258 } |
215 | 259 """ |
260 self.expectOK(snippet) | |
225 | 261 |
308 | 262 def testAndCondition(self): |
263 snippet = """ | |
264 module tst; | |
265 function void t() { | |
266 if (4 > 3 and 1 < 10) { | |
267 } | |
268 } | |
269 """ | |
270 self.expectOK(snippet) | |
271 | |
272 def testOrCondition(self): | |
273 snippet = """ | |
274 module tst; | |
275 function void t() { | |
276 if (3 > 4 or 3 < 10) { | |
277 } | |
278 } | |
279 """ | |
280 self.expectOK(snippet) | |
281 | |
282 def testNonBoolCondition(self): | |
283 snippet = """ | |
284 module tst; | |
285 function void t() { | |
311 | 286 if (3+3) { |
308 | 287 } |
288 } | |
289 """ | |
290 self.expectErrors(snippet, [4]) | |
291 | |
225 | 292 def testTypeDef(self): |
293 snippet = """ | |
284 | 294 module testtypedef; |
225 | 295 type int my_int; |
296 function void t() | |
297 { | |
298 var my_int a; | |
299 var int b; | |
300 a = 2; | |
301 b = a + 2; | |
302 } | |
303 """ | |
304 self.expectOK(snippet) | |
305 | |
230 | 306 def testLocalVariable(self): |
307 snippet = """ | |
284 | 308 module testlocalvar; |
230 | 309 function void t() |
310 { | |
311 var int a, b; | |
312 a = 2; | |
313 b = a + 2; | |
314 } | |
315 """ | |
268 | 316 self.expectOK(snippet) |
230 | 317 |
249 | 318 def testUnknownType(self): |
284 | 319 snippet = """module testlocalvar; |
249 | 320 function void t() |
321 { | |
322 var int2 a; | |
323 } | |
324 """ | |
325 self.expectErrors(snippet, [4]) | |
326 | |
230 | 327 def testStruct1(self): |
328 snippet = """ | |
284 | 329 module teststruct1; |
230 | 330 function void t() |
331 { | |
332 var struct {int x, y;} a; | |
333 a.x = 2; | |
334 a.y = a.x + 2; | |
335 } | |
336 """ | |
268 | 337 self.expectOK(snippet) |
230 | 338 |
308 | 339 def testStruct2(self): |
340 """ Select struct member from non struct type """ | |
341 snippet = """ | |
342 module teststruct1; | |
343 function void t() { | |
344 var int a; | |
345 a.z = 2; | |
346 } | |
347 """ | |
348 self.expectErrors(snippet, [5]) | |
349 | |
354 | 350 def testArray(self): |
351 snippet = """ | |
352 module testarray; | |
353 function void t() | |
354 { | |
355 var int[100] x; | |
356 var int a, b; | |
357 a = 2; | |
358 b = x[a*2+9 - a] * x[22+12]; | |
359 x[1] = x[2]; | |
360 } | |
361 """ | |
362 self.expectOK(snippet) | |
363 | |
364 def testArrayFail(self): | |
365 snippet = """ | |
366 module testarray; | |
367 function void t() | |
368 { | |
369 var bool c; | |
370 c = false; | |
371 var int[100] x; | |
372 x[1] = x[c]; | |
373 } | |
374 """ | |
375 self.expectErrors(snippet, [8]) | |
376 | |
377 def testArrayFail2(self): | |
378 snippet = """ | |
379 module testarray; | |
380 function void t() | |
381 { | |
382 var int c; | |
383 var int x; | |
384 c = x[2]; | |
385 } | |
386 """ | |
387 self.expectErrors(snippet, [7]) | |
388 | |
355 | 389 @unittest.skip('TODO') |
390 def testArrayFail3(self): | |
391 snippet = """ | |
392 module testarray; | |
393 function void t() | |
394 { | |
395 int c[20]; | |
396 } | |
397 """ | |
398 self.expectErrors(snippet, [7]) | |
399 | |
293 | 400 def testStructCall(self): |
401 snippet = """ | |
402 module teststruct1; | |
403 function void t() | |
404 { | |
405 var struct {int x, y;} a; | |
307 | 406 a.x(9); |
293 | 407 } |
408 """ | |
308 | 409 self.expectErrors(snippet, [6]) |
293 | 410 |
353 | 411 def testString(self): |
412 snippet = """ | |
413 module teststring; | |
414 function void t() | |
415 { | |
416 var string a; | |
417 a = "Hello world"; | |
418 print(a); | |
419 print("Moi"); | |
420 } | |
421 function void print(string a) | |
422 { | |
423 } | |
424 """ | |
425 self.expectOK(snippet) | |
426 | |
225 | 427 def testPointerType1(self): |
428 snippet = """ | |
284 | 429 module testpointer1; |
225 | 430 var int* pa; |
431 function void t() | |
432 { | |
433 var int a; | |
434 pa = &a; | |
435 *pa = 22; | |
308 | 436 a = *pa + *pa * 8; |
225 | 437 } |
438 """ | |
439 self.expectOK(snippet) | |
440 | |
215 | 441 def testPointerType(self): |
213 | 442 snippet = """ |
284 | 443 module testpointer; |
225 | 444 var int* pa, pb; |
213 | 445 function void t(int a, double b) |
446 { | |
280
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
447 var int a2; |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
448 a2 = a; // parameters cannot be escaped for now.. |
02385f62f250
Rework from str interface to Instruction interface
Windel Bouwman
parents:
272
diff
changeset
|
449 pa = &a2; |
225 | 450 pb = pa; |
213 | 451 *pa = 22; |
452 } | |
453 """ | |
215 | 454 self.expectOK(snippet) |
213 | 455 |
221 | 456 def testPointerTypeInCorrect(self): |
457 snippet = """ | |
284 | 458 module testpointerincorrect; |
221 | 459 var int* pa; |
460 function void t(int a, double b) | |
461 { | |
462 pa = 2; // type conflict | |
463 pa = &a; | |
307 | 464 pa = &2; // No valid lvalue |
221 | 465 &a = pa; // No valid lvalue |
466 **pa = 22; // Cannot deref int | |
467 } | |
468 """ | |
307 | 469 self.expectErrors(snippet, [6, 8, 9, 10]) |
221 | 470 |
230 | 471 def testPointerTypeIr(self): |
472 snippet = """ | |
284 | 473 module testptr_ir; |
230 | 474 function void t() |
475 { | |
476 var int* a; | |
477 a = cast<int*>(40); | |
478 *a = 2; | |
479 } | |
480 """ | |
268 | 481 self.expectOK(snippet) |
230 | 482 |
483 def testPointerTypeIr2(self): | |
484 snippet = """ | |
284 | 485 module testptr_ir; |
230 | 486 type struct {int x,y;}* gpio; |
487 function void t() | |
488 { | |
489 var gpio a; | |
490 a = cast<gpio>(40); | |
491 a->x = 2; | |
492 a->y = a->x - 14; | |
493 } | |
494 """ | |
268 | 495 self.expectOK(snippet) |
230 | 496 |
497 def testWrongCast(self): | |
498 snippet = """ | |
284 | 499 module testptr_ir; |
230 | 500 type struct {int x,y;}* gpio; |
501 function void t() | |
502 { | |
503 var gpio a; | |
504 *cast<gpio>(*a); | |
505 } | |
506 """ | |
308 | 507 self.expectErrors(snippet, [7]) |
230 | 508 |
389 | 509 def testLinkedList(self): |
510 """ | |
511 Test if a struct can contain a field with a pointer to itself | |
512 """ | |
513 snippet = """ | |
514 module testlinkedlist; | |
515 | |
516 type struct { | |
517 int x; | |
518 list_t* next; | |
519 } list_t; | |
520 | |
521 function void t() | |
522 { | |
523 var list_t* a; | |
524 a = a->next; | |
525 } | |
526 """ | |
527 self.expectOK(snippet) | |
528 | |
529 def testInfiniteStruct(self): | |
530 """ | |
531 Test if a struct can contain a field with itself as type? | |
532 This should not be possible! | |
533 """ | |
534 snippet = """ | |
535 module testnestedstruct; | |
536 | |
537 type struct { | |
538 int x; | |
539 list_t inner; | |
540 } list_t; | |
541 | |
542 """ | |
543 self.expectErrors(snippet, [0]) | |
544 | |
545 def testMutualStructs(self): | |
546 """ | |
547 Test if two structs can contain each other! | |
548 This should not be possible! | |
549 """ | |
550 snippet = """ | |
551 module testnestedstruct; | |
552 | |
553 type struct { | |
554 int x; | |
555 B other; | |
556 } A; | |
557 | |
558 type struct { | |
559 int x; | |
560 A other; | |
561 } B; | |
562 | |
563 """ | |
564 self.expectErrors(snippet, [0]) | |
565 | |
215 | 566 def testComplexType(self): |
213 | 567 snippet = """ |
284 | 568 module testpointer; |
213 | 569 type int my_int; |
570 | |
571 type struct { | |
572 int x, y; | |
573 } point; | |
574 | |
575 type struct { | |
576 int mem1; | |
577 int memb2; | |
578 point P1; | |
579 } my_struct; | |
580 | |
581 type my_struct* my_sptr; | |
225 | 582 var int* pa; |
213 | 583 |
227 | 584 function void t(int a, int b, my_sptr x) |
213 | 585 { |
586 var my_struct *msp; | |
587 | |
225 | 588 var my_struct u, v; |
589 var point *pt; | |
590 | |
591 pt = &msp->P1; | |
213 | 592 msp = x; |
225 | 593 *pa = 22 + u.mem1 * v.memb2 - u.P1.x; |
213 | 594 x->memb2 = *pa + a * b; |
595 | |
225 | 596 msp->P1.x = a * x->P1.y; |
213 | 597 } |
598 """ | |
215 | 599 self.expectOK(snippet) |
205 | 600 |
167 | 601 |
602 if __name__ == '__main__': | |
243 | 603 unittest.main() |