# HG changeset patch # User Windel Bouwman # Date 1384519402 -3600 # Node ID 05184b95fa1671e2e4658b553daa17f3e86199f0 # Parent c9781c73e7e254599f9c870ba9773be4ecf6df23 Moved tests to seperate folder diff -r c9781c73e7e2 -r 05184b95fa16 python/c3/astnodes.py --- a/python/c3/astnodes.py Fri Nov 15 12:26:50 2013 +0100 +++ b/python/c3/astnodes.py Fri Nov 15 13:43:22 2013 +0100 @@ -18,7 +18,8 @@ self.declarations = [] self.imports = [] def __repr__(self): - return 'PACKAGE {}'.format(self.name) + return 'MODULE {}'.format(self.name) + class Designator(Node): def __init__(self, tname, loc): @@ -244,6 +245,7 @@ nm = self.target return 'VAR USE {}'.format(nm) + class Literal(Expression): def __init__(self, val, loc): super().__init__(loc) @@ -251,6 +253,7 @@ def __repr__(self): return 'LITERAL {}'.format(self.val) + class FunctionCall(Expression): def __init__(self, proc, args, loc): super().__init__(loc) @@ -259,6 +262,7 @@ def __repr__(self): return 'CALL {0} '.format(self.proc) + # Statements class Statement(Node): def __init__(self, loc): @@ -284,6 +288,7 @@ def __repr__(self): return 'RETURN STATEMENT' + class Assignment(Statement): def __init__(self, lval, rval, loc): super().__init__(loc) diff -r c9781c73e7e2 -r 05184b95fa16 python/c3/examples/blink.c3 --- a/python/c3/examples/blink.c3 Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* This file blinks a LED on the STM32F4 discovery board. - -the board has 4 leds on PD12, PD13, PD14 and PD15 - -*/ - -package blink; - -import stm32f4xx; - -// Functions: -function void main() -{ - // Memory mapped control registers: - var GPIO_Type GPIOD; - GPIOD = cast(0x40020C00); - var RCC_Type RCC; - RCC = cast(0x40023800); - - // Enable the clock to port D: - RCC->AHB1ENR = RCC->AHB1ENR | 0x8; - - - // PD13 == output (01) - GPIOD->MODER = (1 << 26); - GPIOD->ODR = (1 << 13); - - while(true) {} -} - diff -r c9781c73e7e2 -r 05184b95fa16 python/c3/examples/burn.c3 --- a/python/c3/examples/burn.c3 Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - -This file blinks a LED on the STM32F4 discovery board. - -the board has 4 leds on PD12, PD13, PD14 and PD15 - -*/ - -package burn; - -import stm32f4xx; - -/* -function void init() -{ -} -*/ - -function void main() -{ - //init(); - var RCC_Type RCC; - RCC = cast(0x40023800); - - // Enable the clock to port D: - RCC->AHB1ENR = RCC->AHB1ENR | (1 << 3); - // Memory mapped control registers: - var GPIO_Type GPIOD; - GPIOD = cast(0x40020C00); - - var int pin; - pin = 15; - // PD13 == output (01) - GPIOD->MODER = (1 << (pin << 1)); - GPIOD->ODR = (1 << pin); - - while(true) {} -} - diff -r c9781c73e7e2 -r 05184b95fa16 python/c3/examples/burn2.c3 --- a/python/c3/examples/burn2.c3 Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - -This file blinks a LED on the STM32F4 discovery board. - -the board has 4 leds on PD12, PD13, PD14 and PD15 - -*/ - -package burn2; - -import stm32f4xx; - -function int add(int a, int b) -{ - return a + b; -} - - -function void init(int pin) -{ - if (pin < 12) - { - return; - } - - /*if (pin > 15) - { - return; - }*/ - - var RCC_Type RCC; - RCC = cast(0x40023800); - - // Enable the clock to port D: - RCC->AHB1ENR = RCC->AHB1ENR | (1 << 3); - // Memory mapped control registers: - var GPIO_Type GPIOD; - GPIOD = cast(0x40020C00); - - // PD13 == output (01) - GPIOD->MODER = (1 << (pin << 1)); - GPIOD->ODR = (1 << pin); -} - - -function void main() -{ - // Vary between 12 and 15: - init(13); - - var int a; - a = 0 - while (a < 1000) - { - a = a + 1; - } - - while(true) {} -} - diff -r c9781c73e7e2 -r 05184b95fa16 python/c3/examples/cast.c3 --- a/python/c3/examples/cast.c3 Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ - -/* - Demo of how to type cast -*/ - -package castdemo; - -function int testcast() -{ - var int a; - var int* b; - a = 3; - - b = cast(a); - - return 0; -} - diff -r c9781c73e7e2 -r 05184b95fa16 python/c3/examples/comments.c3 --- a/python/c3/examples/comments.c3 Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ - -/* - block - comment -*/ - -// fjd jjd- -package comments; // hjfkds - -function int tst() -{ - return 0; -} - diff -r c9781c73e7e2 -r 05184b95fa16 python/c3/examples/functions.c3 --- a/python/c3/examples/functions.c3 Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ - -/* - Demo of function usage -*/ - -package functiondemo; - -function void main() -{ - var int a, b, c; - a = 3; - b = a; - a =3; - b = fib(a + 9); - sum(a, b); -} - -function int fib(int x) -{ - return fib(x - 1) * x; -} - -function int sum(int a, int b) -{ - return a + b; -} - diff -r c9781c73e7e2 -r 05184b95fa16 python/c3/examples/stm32f4xx.c3 --- a/python/c3/examples/stm32f4xx.c3 Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ - -package stm32f4xx; - -type struct { - int MODER; - int OTYPER; - int OSPEEDR; - int PUPDR; - int IDR; - int ODR; -}* GPIO_Type; - -type struct { - int CR; - int PLLCFGR; - int CFGR; - int CIR; - int AHB1RSTR; - int AHB2RSTR; - int AHB3RSTR; - int reserved0; - int APB1RSTR; - int APB2RSTR; - int reserved1a, reserved1b; - int AHB1ENR; - int AHB2ENR; - int AHB3ENR; - int reserved2; - int APB1ENR, APB2ENR; -}* RCC_Type; - diff -r c9781c73e7e2 -r 05184b95fa16 python/c3/examples/types.c3 --- a/python/c3/examples/types.c3 Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ - -/* - Demo of how to define types -*/ - -package typedemo; - -type int A; -type int B; -type struct { - int x, y; - A z; -} C; -type struct { - C x; - B y; - int z; -} D; - -type D* E; - -function int testcast() -{ - var A a; - var B b; - a = 3; - b = a; - var C c; - c.x = a; - c.z = c.y; - var D d; - var E e; - var D* e2; - e = &d; - e2 = e; - e2->x.x = 22; - - return 0; -} - diff -r c9781c73e7e2 -r 05184b95fa16 python/c3/lexer.py --- a/python/c3/lexer.py Fri Nov 15 12:26:50 2013 +0100 +++ b/python/c3/lexer.py Fri Nov 15 13:43:22 2013 +0100 @@ -10,7 +10,7 @@ 'else', 'if', 'while', 'return', \ 'function', 'var', 'type', 'const', \ 'struct', 'cast', \ - 'import', 'package' ] + 'import', 'module' ] def tokenize(s): """ diff -r c9781c73e7e2 -r 05184b95fa16 python/c3/parser.py --- a/python/c3/parser.py Fri Nov 15 12:26:50 2013 +0100 +++ b/python/c3/parser.py Fri Nov 15 13:43:22 2013 +0100 @@ -61,7 +61,7 @@ self.Consume(';') def parsePackage(self): - self.Consume('package') + self.Consume('module') name = self.Consume('ID') self.Consume(';') self.mod = astnodes.Package(name.val, name.loc) diff -r c9781c73e7e2 -r 05184b95fa16 python/testasm.py --- a/python/testasm.py Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,318 +0,0 @@ -#!/usr/bin/python - -import unittest, cProfile -from ppci import CompilerError -from asmnodes import AInstruction, ABinop, AUnop, ASymbol, ALabel, ANumber -from asm import tokenize, Assembler -import msp430 -import cortexm3 as arm -import outstream -from target import Label - -class AssemblerLexingCase(unittest.TestCase): - """ Tests the assemblers lexer """ - - def testLex0(self): - """ Check if the lexer is OK """ - asmline, toks = 'mov rax, rbx ', ['ID', 'ID', ',', 'ID'] - self.assertSequenceEqual([tok.typ for tok in tokenize(asmline)], toks) - - def testLex1(self): - """ Test if lexer correctly maps some tokens """ - asmline, toks = 'lab1: mov rax, rbx ', ['ID', ':', 'ID', 'ID', ',', 'ID'] - self.assertSequenceEqual([tok.typ for tok in tokenize(asmline)], toks) - - def testLex1(self): - """ Test if lexer correctly maps some tokens """ - asmline, toks = 'mov 3.13 0xC 13', ['ID', 'REAL', 'NUMBER', 'NUMBER'] - self.assertSequenceEqual([tok.typ for tok in tokenize(asmline)], toks) - - def testLex2(self): - """ Test if lexer fails on a token that is invalid """ - asmline = '0z4: mov rax, rbx $ ' - with self.assertRaises(CompilerError): - list(tokenize(asmline)) - -class AssemblerParsingTestCase(unittest.TestCase): - """ - Tests the assembler parts - """ - def setUp(self): - self.a = Assembler() - - def testParse(self): - asmline = 'lab1: mov rax, rbx' - self.a.parse_line(asmline) - - def expectTree(self, asmline, stack): - self.a.parse_line(asmline) - self.assertSequenceEqual(stack, self.a.stack) - - def testParse2(self): - asmline = 'a: mov rax, [rbx + 2]' - output = [] - output.append(ALabel('a')) - output.append(AInstruction('mov', [ASymbol('rax'), AUnop('[]', ASymbol('rbx') + ANumber(2))])) - self.expectTree(asmline, output) - - def testParse3(self): - # A label must be optional: - asmline = 'mov rax, 1' - output = [AInstruction('mov', [ASymbol('rax'), ANumber(1)])] - self.expectTree(asmline, output) - - def testParse4(self): - # Test 3 operands: - asmline = 'add rax, [4*rbx + 22], rcx' - ops = [] - ops.append(ASymbol('rax')) - ops.append(AUnop('[]', ANumber(4) * ASymbol('rbx') + ANumber(22))) - ops.append(ASymbol('rcx')) - output = [AInstruction('add', ops)] - self.expectTree(asmline, output) - - def testParse5(self): - # An instruction must be optional: - asmline = 'lab1:' - output = [] - output.append(ALabel('lab1')) - self.expectTree(asmline, output) - - def testParse6(self): - # A line can be empty - self.a.parse_line('') - -class AssemblerOtherTestCase(unittest.TestCase): - def testWithoutTarget(self): - a = Assembler() - with self.assertRaises(CompilerError): - a.assemble_line('') - - @unittest.skip - def testX86(self): - testsrc = """ ; tst - begin: - mov rax, rbx ; 0x48, 0x89, 0xd8 - xor rcx, rbx ; 0x48, 0x31, 0xd9 - inc rcx ; 0x48 0xff 0xc1 - """ - a = Assembler() - a.assemble(testsrc) - # Compare with nasm output: - nasmbytes = [0x48, 0x89, 0xd8, 0x48, 0x31, 0xd9, 0x48, 0xff, 0xc1] - - -class OustreamTestCase(unittest.TestCase): - def test1(self): - o = outstream.BinOutputStream() - o.selectSection('.text') - o.emit(Label('a')) - self.assertSequenceEqual(bytes(), o.Data) - - -class AsmTestCaseBase(unittest.TestCase): - def feed(self, line): - self.a.assemble(line) - - def check(self, hexstr): - self.assertSequenceEqual(bytes.fromhex(hexstr), self.o.Data) - - -class AssemblerMSP430TestCase(AsmTestCaseBase): - def setUp(self): - self.t = msp430.msp430target - self.o = outstream.BinOutputStream() - self.o.selectSection('.text') - self.a = Assembler(target=self.t, stream=self.o) - - def testMapMovInstruction(self): - i = AInstruction('mov', [ASymbol('r14'), ASymbol('r15')]) - ri = self.t.mapInstruction(i) - - def testMapRetiInstruction(self): - i = AInstruction('reti', []) - ri = self.t.mapInstruction(i) - - @unittest.skip - def testMapOperand(self): - o = ASymbol('r14') - mo = self.t.mapOperand(o) - self.assertEqual(mo, msp430.r14) - - @unittest.skip - def testMapOperandIndirection(self): - o = AUnop('[]', ASymbol('r14')) - mo = self.t.mapOperand(o) - - def testMov(self): - line1 = "mov r14, r15" - self.feed(line1) - self.check('0F4E') - - def testMov1337(self): - line1 = "mov 0x1337, r12" - self.feed(line1) - self.check('3C403713') - - def testAdd(self): - line1 = "add r15, r13" - self.feed(line1) - self.check('0D5F') - - def testReti(self): - line1 = "reti" - self.feed(line1) - self.check('0013') - - def testMSPinstructionCount(self): - """ Check that there are 27 instructions """ - self.assertEqual(27, len(self.t.instructions)) - - -class AssemblerARMTestCase(AsmTestCaseBase): - def setUp(self): - self.t = arm.armtarget - self.o = outstream.BinOutputStream() - self.o.selectSection('.text') - self.a = Assembler(target=self.t, stream=self.o) - - def testMapOperand(self): - pass - - def testMovImm8(self): - self.feed('mov r4, 100') - self.check('6424') - - @unittest.skip - def testMovExt(self): - self.feed('mov r3, sp') - self.check('') - - def testYield(self): - self.feed('yield') - self.check('10bf') - - def testPush(self): - self.feed('push {r2,r3,lr}') - self.check('0cb5') - - def testPop(self): - self.feed('pop {r4-r6, pc}') - self.check('70bd') - - def testStr5(self): - self.feed('str r4, [r1 + 0]') - self.check('0c60') - - def testLdr5(self): - self.feed('ldr r4, [r0 + 0]') - self.check('0468') - - def testLdrSpRel(self): - self.feed('ldr r0, [sp + 4]') - self.check('0198') - - def testStrSpRel(self): - self.feed('str r0, [sp + 4]') - self.check('0190') - - def testLdrPcRel(self): - self.feed('ldr r7, henkie') - self.feed('ldr r6, henkie') - self.feed('ldr r1, henkie') - self.feed('align 4') - self.feed('dcd 1') - self.feed('henkie: dcd 2') - self.check('024F024E 01490000 01000000 02000000') - - def testBranch(self): - self.feed('start: b henkie') - self.feed('beq henkie') - self.feed('bne henkie') - self.feed('henkie: b start') - self.feed('eof: b eof') - self.check('01e000d0 ffd1fbe7 fee7') - - def testConditions(self): - self.feed('blt x') - self.feed('bgt x') - self.feed('x:') - self.check('00dbffdc') - - def testBoff(self): - self.feed('b henkie') - self.feed('b henkie') - self.feed('b henkie') - self.feed('b henkie') - self.feed('b henkie') - self.feed('b henkie') - self.feed('b henkie') - self.feed('henkie:') - self.feed('b henkie') - self.feed('b henkie') - self.feed('b henkie') - self.feed('b henkie') - self.check('05e004e0 03e002e0 01e000e0 ffe7fee7 fde7fce7 fbe7') - - def testBl(self): - self.feed('bl henkie') - self.feed('bl henkie') - self.feed('henkie:') - self.feed('bl henkie') - self.feed('bl henkie') - self.check('00f0 02f8 00f0 00f8 fff7 feff fff7 fcff') - - def testCmpRegReg(self): - self.feed('cmp r0, r1') - self.check('8842') - - def testAddimm3(self): - self.feed('add r3, r5, 2') - self.feed('add r4, r1, 6') - self.check('ab1c8c1d') - - def testSubImm3(self): - self.feed('sub r3, r5, 2') - self.feed('sub r4, r1, 6') - self.check('ab1e8c1f') - - def testLeftShift(self): - self.feed('lsl r3, r5') - self.check('ab40') - - def testAddSp(self): - self.feed('add sp,sp,8') - self.feed('add sp,sp,16') - self.check('02b004b0') - - def testSubSp(self): - self.feed('sub sp,sp,32') - self.feed('sub sp,sp,4') - self.check('88b081b0') - - def testSequence1(self): - self.feed('mov r5, 3') - self.feed('add r4, r5, 0') - self.feed('loop: add r6, r4, 7') - self.feed('cmp r6, 5') - self.check('0325 2c1c e61d 052e') - - def testSequence2(self): - self.feed('henkie:') - self.feed('push {r1,r4,r5}') - self.feed('add r5, r2, r4') - self.feed('cmp r4, r2') - self.feed('ldr r0, [sp + 4]') - self.feed('str r3, [sp + 16]') - self.feed('pop {r1, r4, r5}') - self.feed('lsl r3, r4') - self.feed('cmp r3, r5') - self.feed('beq henkie') - self.feed('bne henkie') - self.feed('b henkie') - self.check('32b41519 94420198 049332bc a340ab42 f6d0f5d1 f4e7') - -if __name__ == '__main__': - #cProfile.run('unittest.main()') - unittest.main() - diff -r c9781c73e7e2 -r 05184b95fa16 python/testc3.py --- a/python/testc3.py Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,435 +0,0 @@ -import c3 -import time, ppci, x86, ir -import unittest -import glob - -testsrc = """package test; - -/* - demo of the source that is correct :) -*/ -var int c, d; -var double e; -var int f; - -const int A = 1337; - -function void test1() -{ - var int bdd; - var int a = 10; - bdd = 20; - var int buf; - var int i; - i = 2; - var int zero = i - 2; - if (i > 1) - { - buf = b + 22 * i - 13 + (55 * 2 *9-2) / 44 - 1; - } - else - { - ;;; - } - - t2(2, 3); -} - -function int t2(int a, int b) -{ - if (a > 0) - { - a = 2 + t2(a - 1, 10); - } - - return a + b; -} - -var int a, b; - -function int t3(int aap, int blah) -{ - if (a > blah and blah < 45 + 33 or 33 > aap or 6 > 2 and true) - { - a = 2 + t2(a - 1, 0); - } - - return a + b; -} - -var int hahaa = 23 * 2; - - -""" - -class testLexer(unittest.TestCase): - def testUnexpectedCharacter(self): - snippet = """ var s \u6c34 """ - with self.assertRaises(ppci.CompilerError): - list(c3.lexer.tokenize(snippet)) - - def testBlockComment(self): - snippet = """ - /* Demo */ - var int x = 0; - """ - toks = ['var', 'ID', 'ID', '=', 'NUMBER', ';', 'END'] - self.assertSequenceEqual([tok.typ for tok in c3.lexer.tokenize(snippet)], toks) - - def testBlockCommentMultiLine(self): - snippet = """ - /* Demo - bla1 - bla2 - */ - var int x = 0; - """ - toks = ['var', 'ID', 'ID', '=', 'NUMBER', ';', 'END'] - self.assertSequenceEqual([tok.typ for tok in c3.lexer.tokenize(snippet)], toks) - -class testBuilder(unittest.TestCase): - def setUp(self): - self.diag = ppci.DiagnosticsManager() - self.builder = c3.Builder(self.diag) - self.diag.clear() - - def testSrc(self): - self.expectOK(testsrc) - - def expectErrors(self, snippet, rows): - """ Helper to test for expected errors on rows """ - ircode = self.builder.build(snippet) - actualErrors = [err.row for err in self.diag.diags] - if rows != actualErrors: - self.diag.printErrors(snippet) - self.assertSequenceEqual(rows, actualErrors) - self.assertFalse(ircode) - - def expectOK(self, snippet, pack_dir=None): - ircode = self.builder.build(snippet, pack_dir=pack_dir) - if not ircode: - self.diag.printErrors(snippet) - self.assertTrue(ircode) - return ircode - - def testPackage(self): - p1 = """package p1; - type int A; - """ - self.assertTrue(self.builder.build(p1)) - p2 = """package p2; - import p1; - var A b; - """ - self.expectOK(p2) - - def testFunctArgs(self): - snippet = """ - package testargs; - function void t2(int a, double b) - { - t2(2, 2); - t2(2); - t2(1, 1.2); - } - """ - self.expectErrors(snippet, [5, 6]) - - def testExpressions(self): - snippet = """ - package test; - function void t(int a, double b) - { - var int a2; - var bool c; - - a2 = b * a; - c = a; - c = b > 1; - } - """ - self.expectErrors(snippet, [8, 9, 10]) - - def testExpression1(self): - snippet = """ - package testexpr1; - function void t() - { - var int a, b, c; - a = 1; - b = a * 2 + a * a; - c = b * a - 3; - } - """ - self.expectOK(snippet) - - def testEmpty(self): - snippet = """ - package A - """ - self.expectErrors(snippet, [3]) - - def testEmpty2(self): - snippet = "" - self.expectErrors(snippet, [1]) - - def testRedefine(self): - snippet = """ - package test; - var int a; - var int b; - var int a; - """ - self.expectErrors(snippet, [5]) - - def testWhile(self): - snippet = """ - package tstwhile; - var int a; - function void t() - { - var int i = 0; - while (i < 1054) - { - i = i + 3; - a = a + i; - } - - while(true) - { - } - - while(false) - { - } - } - """ - self.expectOK(snippet) - - def testIf(self): - snippet = """ - package tstIFF; - function void t(int b) - { - var int a; - a = 2; - if (a > b) - { - if (a > 1337) - { - b = 2; - } - } - else - { - b = 1; - } - - return b; - } - """ - self.expectOK(snippet) - - def testTypeDef(self): - snippet = """ - package testtypedef; - type int my_int; - function void t() - { - var my_int a; - var int b; - a = 2; - b = a + 2; - } - """ - self.expectOK(snippet) - - def testLocalVariable(self): - snippet = """ - package testlocalvar; - function void t() - { - var int a, b; - a = 2; - b = a + 2; - } - """ - self.expectOK(snippet) - - def testUnknownType(self): - snippet = """package testlocalvar; - function void t() - { - var int2 a; - } - """ - self.expectErrors(snippet, [4]) - - def testStruct1(self): - snippet = """ - package teststruct1; - function void t() - { - var struct {int x, y;} a; - a.x = 2; - a.y = a.x + 2; - } - """ - self.expectOK(snippet) - - def testPointerType1(self): - snippet = """ - package testpointer1; - var int* pa; - function void t() - { - var int a; - pa = &a; - *pa = 22; - } - """ - self.expectOK(snippet) - - def testPointerType(self): - snippet = """ - package testpointer; - var int* pa, pb; - function void t(int a, double b) - { - var int a2; - a2 = a; // parameters cannot be escaped for now.. - pa = &a2; - pb = pa; - *pa = 22; - } - """ - self.expectOK(snippet) - - def testPointerTypeInCorrect(self): - snippet = """ - package testpointerincorrect; - var int* pa; - function void t(int a, double b) - { - pa = 2; // type conflict - pa = &a; - pa = &2; - &a = pa; // No valid lvalue - **pa = 22; // Cannot deref int - } - """ - self.expectErrors(snippet, [6, 9, 10]) - - def testPointerTypeIr(self): - snippet = """ - package testptr_ir; - function void t() - { - var int* a; - a = cast(40); - *a = 2; - } - """ - self.expectOK(snippet) - - def testPointerTypeIr2(self): - snippet = """ - package testptr_ir; - type struct {int x,y;}* gpio; - function void t() - { - var gpio a; - a = cast(40); - a->x = 2; - a->y = a->x - 14; - } - """ - self.expectOK(snippet) - - def testWrongCast(self): - snippet = """ - package testptr_ir; - type struct {int x,y;}* gpio; - function void t() - { - var gpio a; - *cast(*a); - } - """ - # TODO: remove the duplicate error: - self.expectErrors(snippet, [7, 7]) - - def testComplexType(self): - snippet = """ - package testpointer; - type int my_int; - - type struct { - int x, y; - } point; - - type struct { - int mem1; - int memb2; - point P1; - } my_struct; - - type my_struct* my_sptr; - var int* pa; - - function void t(int a, int b, my_sptr x) - { - var my_struct *msp; - - var my_struct u, v; - var point *pt; - - pt = &msp->P1; - msp = x; - *pa = 22 + u.mem1 * v.memb2 - u.P1.x; - x->memb2 = *pa + a * b; - - msp->P1.x = a * x->P1.y; - } - """ - self.expectOK(snippet) - - def testExamples(self): - """ Test all examples in the c3/examples directory """ - example_filenames = glob.glob('./c3/examples/*.c3') - for filename in example_filenames: - with open(filename, 'r') as f: - src = f.read() - self.expectOK(src, pack_dir='./c3/examples') - - def test2(self): - # testsrc2 is valid code: - snippet = """ - package test2; - - function void tst() - { - var int a, b; - a = 2 * 33 - 12; - b = a * 2 + 13; - a = b + a; - if (a > b and b == 3) - { - var int x = a; - x = b * 2 - a; - a = x*x; - } - else - { - a = b + a; - } - } - - """ - ircode = self.expectOK(snippet) - self.assertEqual(1, len(ircode.Functions)) - -if __name__ == '__main__': - unittest.main() - - diff -r c9781c73e7e2 -r 05184b95fa16 python/testcg.py --- a/python/testcg.py Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -import unittest -import ppci, codegen, ir -import cortexm3 as arm -import codegenarm -import outstream - -def genTestFunction(): - m = ir.Module('tst') - f = ir.Function('tst') - m.addFunction(f) - return m, f, f.entry - - -class testCodeGeneration(unittest.TestCase): - def setUp(self): - self.cg = codegen.CodeGenerator(arm.armtarget) - - def testFunction(self): - m, f, bb = genTestFunction() - bb.addInstruction(ir.Const(123)) - bb.addInstruction(ir.Jump(f.epiloog)) - m.check() - obj = self.cg.generate(m) - self.assertTrue(obj) - - -class testArmCodeGeneration(unittest.TestCase): - def testStack(self): - s = outstream.OutputStream() - cg = codegenarm.ArmCodeGenerator(s) - m, f, bb = genTestFunction() - bb.addInstruction(ir.Move(ir.Mem(ir.Const(1)), ir.Const(22))) - bb.addInstruction(ir.Jump(f.epiloog)) - m.check() - cg.generate(m) - #s.dump() - - -if __name__ == '__main__': - unittest.main() - diff -r c9781c73e7e2 -r 05184b95fa16 python/testgraph.py --- a/python/testgraph.py Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -#!/usr/bin/python - -import unittest -import graph -import interferencegraph -import flowgraph -import ir -from irmach import AbstractInstruction as AI -from target import Nop - - -class GraphTestCase(unittest.TestCase): - def testEdge(self): - g = graph.Graph() - n1 = graph.Node(g) - g.addNode(n1) - n2 = graph.Node(g) - g.addNode(n2) - g.addEdge(n1, n2) - self.assertTrue(g.hasEdge(n2, n1)) - self.assertTrue(g.hasEdge(n1, n2)) - g.delNode(n1) - g.delNode(n2) - - def testDegree(self): - g = graph.Graph() - n1 = graph.Node(g) - g.addNode(n1) - n2 = graph.Node(g) - g.addNode(n2) - n3 = graph.Node(g) - g.addNode(n3) - g.addEdge(n1, n2) - g.addEdge(n1, n3) - self.assertEqual(2, n1.Degree) - self.assertEqual(1, n2.Degree) - g.delNode(n2) - self.assertEqual(1, n1.Degree) - - -class DigraphTestCase(unittest.TestCase): - pass - - -class InterferenceGraphTestCase(unittest.TestCase): - def testNormalUse(self): - t1 = ir.Temp('t1') - t2 = ir.Temp('t2') - t3 = ir.Temp('t3') - t4 = ir.Temp('t4') - t5 = ir.Temp('t5') - t6 = ir.Temp('t6') - instrs = [] - instrs.append(AI(Nop, dst=[t1])) - instrs.append(AI(Nop, dst=[t2])) - instrs.append(AI(Nop, dst=[t3])) - cfg = flowgraph.FlowGraph(instrs) - ig = interferencegraph.InterferenceGraph(cfg) - - def testCombine(self): - t1 = ir.Temp('t1') - t2 = ir.Temp('t2') - t3 = ir.Temp('t3') - t4 = ir.Temp('t4') - instrs = [] - instrs.append(AI(Nop, dst=[t1])) - instrs.append(AI(Nop, dst=[t2])) - instrs.append(AI(Nop, dst=[t3])) - instrs.append(AI(Nop, dst=[t4], src=[t3])) - instrs.append(AI(Nop, src=[t4])) - instrs.append(AI(Nop, src=[t1])) - instrs.append(AI(Nop, src=[t2])) - cfg = flowgraph.FlowGraph(instrs) - ig = interferencegraph.InterferenceGraph(cfg) - ig.Combine(ig.getNode(t4), ig.getNode(t3)) - self.assertIs(ig.getNode(t4), ig.getNode(t3)) - - -if __name__ == '__main__': - unittest.main() - diff -r c9781c73e7e2 -r 05184b95fa16 python/testhexfile.py --- a/python/testhexfile.py Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -import unittest -import io -from hexfile import HexFile, HexFileException - - -class testHexFile(unittest.TestCase): - def saveload(self, hf): - f = io.StringIO() - hf.save(f) - hf2 = HexFile() - hf2.load(io.StringIO(f.getvalue())) - self.assertEqual(hf, hf2) - - def testSave1(self): - hf = HexFile() - hf.addRegion(0x8000, bytes.fromhex('aabbcc')) - self.saveload(hf) - - def testSave2(self): - hf = HexFile() - hf.addRegion(0x8000, bytes.fromhex('aabbcc')) - hf.addRegion(0x118000, bytes.fromhex('aabbcc')) - self.saveload(hf) - - def testSave3(self): - hf = HexFile() - hf.addRegion(0x8000, bytes.fromhex('aabbcc')) - hf.addRegion(0xFFFE, bytes.fromhex('aabbcc')) - self.saveload(hf) - - def testSave4(self): - hf = HexFile() - hf.addRegion(0xF000, bytes.fromhex('ab')*0x10000) - self.saveload(hf) - - def testSave5(self): - hf = HexFile() - hf.addRegion(0xF003, bytes.fromhex('ab')*0x10000) - self.saveload(hf) - - def testMerge(self): - hf = HexFile() - hf.addRegion(0x10, bytes.fromhex('abcdab')) - hf.addRegion(0x13, bytes.fromhex('abcdab')) - self.assertEqual(1, len(hf.regions)) - - def testOverlapped(self): - hf = HexFile() - hf.addRegion(0x10, bytes.fromhex('abcdab')) - with self.assertRaisesRegex(HexFileException, 'verlap'): - hf.addRegion(0x12, bytes.fromhex('abcdab')) - - def testEqual(self): - hf1 = HexFile() - hf2 = HexFile() - hf1.addRegion(10, bytes.fromhex('aabbcc')) - hf2.addRegion(10, bytes.fromhex('aabbcc')) - self.assertEqual(hf1, hf2) - - def testNotEqual(self): - hf1 = HexFile() - hf2 = HexFile() - hf1.addRegion(10, bytes.fromhex('aabbcc')) - hf2.addRegion(10, bytes.fromhex('aabbdc')) - self.assertNotEqual(hf1, hf2) - - def testNotEqual2(self): - hf1 = HexFile() - hf2 = HexFile() - hf1.addRegion(10, bytes.fromhex('aabbcc')) - hf2.addRegion(10, bytes.fromhex('aabbcc')) - hf2.addRegion(22, bytes.fromhex('aabbcc')) - self.assertNotEqual(hf1, hf2) - - def testLoad(self): - hf = HexFile() - dummyhex = """ - :01400000aa15 - """ - f = io.StringIO(dummyhex) - hf.load(f) - self.assertEqual(1, len(hf.regions)) - self.assertEqual(0x4000, hf.regions[0].address) - self.assertSequenceEqual(bytes.fromhex('aa'), hf.regions[0].data) - - def testIncorrectCrc(self): - hf = HexFile() - txt = ":01400000aabb" - f = io.StringIO(txt) - with self.assertRaisesRegex(HexFileException, 'crc'): - hf.load(f) - - def testIncorrectLength(self): - hf = HexFile() - txt = ":0140002200aabb" - f = io.StringIO(txt) - with self.assertRaisesRegex(HexFileException, 'count'): - hf.load(f) - -if __name__ == '__main__': - unittest.main() - diff -r c9781c73e7e2 -r 05184b95fa16 python/testir.py --- a/python/testir.py Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,162 +0,0 @@ -import unittest, os -import sys -import c3 -import ppci -import ir, x86, transform -import optimize - - -class IrCodeTestCase(unittest.TestCase): - def setUp(self): - self.b = ir.Builder() - self.m = ir.Module('test') - self.b.setModule(self.m) - - def testBuilder(self): - f = self.b.newFunction('add') - self.b.setFunction(f) - bb = self.b.newBlock() - self.b.emit(ir.Jump(bb)) - self.b.setBlock(bb) - self.b.emit(ir.Exp(ir.Const(0))) - self.b.emit(ir.Jump(f.epiloog)) - self.m.check() - # Run interpreter: - # r = self.m.getFunction('add').call(1, 2) - #self.assertEqual(3, r) - - -class PatternMatchTestCase(unittest.TestCase): - def testSimpleTree(self): - t = ir.Term('x') - pat = ir.Binop(ir.Const(2), '+', t) - res, mp = ir.match_tree(ir.Binop(ir.Const(2), '+', 3), pat) - self.assertTrue(res) - self.assertIn(t, mp) - self.assertEqual(3, mp[t]) - - def testSimpleTree2(self): - t = ir.Term('x') - t2 = ir.Term('y') - pat = ir.Binop(ir.Const(2), '+', ir.Binop(t, '-', t2)) - res, mp = ir.match_tree(ir.Binop(ir.Const(2), '+', ir.Binop(2,'-',3)), pat) - self.assertTrue(res) - self.assertIn(t, mp) - self.assertEqual(2, mp[t]) - self.assertIn(t2, mp) - self.assertEqual(3, mp[t2]) - res, mp = ir.match_tree(ir.Const(2), pat) - self.assertFalse(res) - - -class ConstantFolderTestCase(unittest.TestCase): - def setUp(self): - self.b = ir.Builder() - self.cf = transform.ConstantFolder() - self.m = ir.Module('test') - self.b.setModule(self.m) - - def testBuilder(self): - f = self.b.newFunction('test') - self.b.setFunction(f) - bb = self.b.newBlock() - self.b.emit(ir.Jump(bb)) - self.b.setBlock(bb) - v1 = ir.Const(5) - v2 = ir.Const(7) - v3 = ir.Add(v1, v2) - self.b.emit(ir.Jump(f.epiloog)) - self.cf.run(self.m) - - def testAdd0(self): - f = self.b.newFunction('test') - self.b.setFunction(f) - self.b.setBlock(self.b.newBlock()) - v1 = ir.Const(0) - v2 = ir.Const(0) - v3 = ir.Add(v1, v2) - - -testsrc = """ -package test2; - -function void tesssst(int henkie) -{ - var int a, b, cee; - a = 2 * 33 - 12; - b = a * 2 + 13; - a = b + a; - cee = a; - cee = cee * 2 + a + cee * 2; - if (cee + a > b and b *3 - a+8*b== 3*6-b) - { - var int x = a; - x = b * 2 - a; - a = x * x * (x + 22 - a); - } - else - { - a = b + a + (a + b); - } - var int y; - y = a - b * 53; -} -""" - -testsrc2 = """ -function int add2(int x, int y) -{ - var int res; - res = x + y + 2 - 7 + 2; - //if (y < 2) - //{ - // return y - 33; - //} - - res = res + (x + 2 * y) + (x + 2 * y) + (2*8) + (2*8); - - if (x > 13) - { - while (y > 1337) - { - res = res + 2; - y = y - 12; - } - } - return res; -} - -""" - -if __name__ == '__main__': - #unittest.main() - #sys.exit() - diag = ppci.DiagnosticsManager() - builder = c3.Builder(diag) - cgenx86 = x86.X86CodeGenSimple(diag) - ir = builder.build(testsrc) - diag.printErrors(testsrc) - ir.check() - ir.dump() - optimize.optimize(ir) - print('dump IR') - print('dump IR') - print('dump IR') - print('dump IR') - ir.dump() - - # Dump a graphiz file: - with open('graaf.gv', 'w') as f: - ir.dumpgv(f) - os.system('dot -Tsvg -ograaf.svg graaf.gv') - - sys.exit() - asm = cgenx86.genBin(ir) - #for a in asm: - # print(a) - with open('out.asm', 'w') as f: - f.write('BITS 64\n') - for a in asm: - f.write(str(a) + '\n') - print(a) - diff -r c9781c73e7e2 -r 05184b95fa16 python/testparserlib.py --- a/python/testparserlib.py Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -import unittest -from parserlib import OneOrMore, Literal, Or, Sequence, Optional - -class ParserCombinatorTestCase(unittest.TestCase): - def test1(self): - #p = Parser() - # parse and interpret: - n40 = Literal('40') - plus = Literal('+') - n2 = Literal('2') - n40.ParseAction = int - plus.ParseAction = replaceWith(0) - n2.ParseAction = int - p = Sequence([n40,plus,n2]) - p.ParseAction = wordsum - - result = p.parse('40+2') - self.assertEqual(42, result[0]) - -def replaceWith(s): - def _repFunc(*args): - return s - return _repFunc - -wordsum = lambda t: sum(t) - -class WordToNumTestCase(unittest.TestCase): - def setUp(self): - numWords = OneOrMore() - def makeLit(s, val): - ret = Literal(s) - ret.ParseAction = replaceWith(val) - return ret - unitDefs = [('zero', 0), ('three', 3), ('one', 1)] - units = Or( [makeLit(s, v) for s, v in unitDefs] ) - tensDefs = [('twenty', 20)] - tens = Or( [makeLit(s, v) for s, v in tensDefs] ) - - numPart = Sequence([Optional(tens), units]) - numPart.ParseAction = wordsum - self.p = numPart - - def check(self, i, o): - result = self.p.parse(i)[0] - self.assertEqual(o, result) - - def test0(self): - self.check('zero', 0) - - def test23(self): - self.check('twentythree', 23) - - @unittest.skip - def test321(self): - # TODO - self.check('three hundred and twenty one', 321) - - -if __name__ == '__main__': - unittest.main() - diff -r c9781c73e7e2 -r 05184b95fa16 python/testpyy.py --- a/python/testpyy.py Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,220 +0,0 @@ -import unittest, pprint -from pyyacc import Grammar, Item, ParserGenerationException, ParserException, EPS, EOF -from ppci import Token - -def genTokens(lst): - for t in lst: - yield Token(t, t) - -class testLR(unittest.TestCase): - """ Test basic LR(1) parser generator constructs """ - def testSimpleGrammar(self): - # 1. define a simple grammar: - g = Grammar(['identifier', '(', ')', '+', '*']) - g.add_production('input', ['expression']) - g.add_production('expression', ['term']) - g.add_production('expression', ['expression', '+', 'term']) - g.add_production('term', ['factor']) - g.add_production('term', ['term', '*', 'factor']) - g.add_production('factor', ['(', 'expression', ')']) - g.add_production('factor', ['identifier']) - g.start_symbol = 'input' - # 2. define input: - tokens = genTokens(['identifier', '+', 'identifier', '+', 'identifier']) - # 3. build parser: - p = g.genParser() - # 4. feed input: - p.parse(tokens) - def testReduceReduceConflict(self): - """ Check if a reduce-reduce conflict is detected """ - # Define a grammar with an obvious reduce-reduce conflict: - g = Grammar(['id']) - g.add_production('goal', ['a']) - g.add_production('a', ['b']) - g.add_production('a', ['c']) - g.add_production('b', ['id']) - g.add_production('c', ['id']) - g.start_symbol = 'goal' - with self.assertRaises(ParserGenerationException): - p = g.genParser() - def testShiftReduceConflict(self): - """ Must be handled automatically by doing shift """ - g = Grammar([EOF, 'if', 'then', 'else', 'ass']) - # Ambiguous grammar: - g.add_production('if_stmt', ['if', 'then', 'stmt']) - g.add_production('if_stmt', ['if', 'then', 'stmt', 'else', 'stmt']) - g.add_production('stmt', ['if_stmt']) - g.add_production('stmt', ['ass']) - g.start_symbol = 'stmt' - p = g.genParser() - # Ambiguous program: - tokens = genTokens(['if', 'then','if', 'then', 'ass', 'else', 'ass']) - p.parse(tokens) - - def testUndefinedTerminal(self): - """ Test correct behavior when a terminal is undefined """ - g = Grammar(['b']) - g.add_production('goal', ['a']) - g.add_production('a', ['b']) - g.add_production('a', ['c']) - g.start_symbol = 'goal' - with self.assertRaises(ParserGenerationException): - g.genParser() - def testRedefineTerminal(self): - """ Test correct behavior when a terminal is redefined """ - g = Grammar([EOF, 'b', 'c']) - g.add_production('goal', ['a']) - with self.assertRaises(ParserGenerationException): - g.add_production('b', ['c']) # Not allowed - g.add_production('a', ['c']) - g.start_symbol = 'goal' - g.genParser() - def testEmpty(self): - """ Test empty token stream """ - g = Grammar([',']) - g.add_production('input', [',']) - g.start_symbol = 'input' - p = g.genParser() - tokens = genTokens([]) - with self.assertRaises(ParserException): - p.parse(tokens) - - def testEps(self): - """ Test epsilon terminal """ - g = Grammar(['a', 'b']) - g.add_production('input', ['optional_a', 'b']) - g.add_production('optional_a', ['a']) - g.add_production('optional_a', []) - g.start_symbol = 'input' - p = g.genParser() - tokens = genTokens(['b']) - p.parse(tokens) - - def testEps2(self): - g = Grammar(['id', ':']) - g.add_production('input', ['opt_lab', 'ins', 'op1']) - g.add_production('input', ['ins', 'op1']) - g.add_production('opt_lab', ['id', ':']) - g.add_production('ins', ['id']) - g.add_production('op1', ['id']) - g.start_symbol = 'input' - p = g.genParser() - tokens = genTokens(['id', ':', 'id', 'id']) # i.e. "lab_0: inc rax" - p.parse(tokens) - tokens = genTokens(['id', 'id']) # i.e. "inc rax" - p.parse(tokens) - - def test_cb(self): - """ Test callback of one rule and order or parameters """ - self.cb_called = False - def cb(a, c, b): - self.cb_called = True - self.assertEqual(a, 'a') - self.assertEqual(b, 'b') - self.assertEqual(c, 'c') - g = Grammar(['a', 'b', 'c']) - g.add_production('goal', ['a', 'c', 'b'], cb) - g.start_symbol = 'goal' - p = g.genParser() - tokens = genTokens(['a', 'c', 'b']) - p.parse(tokens) - self.assertTrue(self.cb_called) - - -class testExpressionGrammar(unittest.TestCase): - def setUp(self): - g = Grammar(['EOF', 'identifier', '(', ')', '+', '*', 'num']) - g.add_production('input', ['expression']) - g.add_production('expression', ['term']) - g.add_production('expression', ['expression', '+', 'term']) - g.add_production('term', ['factor']) - g.add_production('term', ['term', '*', 'factor']) - g.add_production('factor', ['(', 'expression', ')']) - g.add_production('factor', ['identifier']) - g.add_production('factor', ['num']) - g.start_symbol = 'input' - self.g = g - - def testFirstSimpleGrammar(self): - # 1. define a simple grammar: - first = self.g.calcFirstSets() - self.assertEqual(first['input'], {'identifier', '(', 'num'}) - self.assertEqual(first['term'], {'identifier', '(', 'num'}) - - def testCanonical(self): - s0 = self.g.initialItemSet() - s, gt = self.g.genCanonicalSet(s0) - # Must result in 12 sets: - self.assertEqual(len(s), 24) - -class testPG(unittest.TestCase): - """ Tests several parts of the parser generator """ - def setUp(self): - g = Grammar(['(', ')']) - g.add_production('goal', ['list']) - g.add_production('list', ['list', 'pair']) - g.add_production('list', ['pair']) - g.add_production('pair', ['(', 'pair', ')']) - g.add_production('pair', ['(', ')']) - g.start_symbol = 'goal' - self.g = g - - def testFirstSet(self): - for a in ['(', ')', EOF, 'EPS']: - self.assertEqual(self.g.first[a], {a}) - for nt in ['list', 'pair', 'goal']: - self.assertEqual(self.g.first[nt], {'('}) - - def testInitItemSet(self): - p0, p1, p2, p3, p4 = self.g.productions - s0 = self.g.initialItemSet() - self.assertEqual(len(s0), 9) # 9 with the goal rule included! - self.assertIn(Item(p0, 0, EOF), s0) - self.assertIn(Item(p1, 0, EOF), s0) - self.assertIn(Item(p1, 0, '('), s0) - self.assertIn(Item(p2, 0, EOF), s0) - self.assertIn(Item(p2, 0, '('), s0) - self.assertIn(Item(p3, 0, EOF), s0) - self.assertIn(Item(p3, 0, '('), s0) - self.assertIn(Item(p4, 0, EOF), s0) - self.assertIn(Item(p4, 0, '('), s0) - - def testCanonical(self): - s0 = self.g.initialItemSet() - s, gt = self.g.genCanonicalSet(s0) - # Must result in 12 sets: - self.assertEqual(len(s), 12) - - def testClosure(self): - p0, p1, p2, p3, p4 = self.g.productions - s0 = set() - s0.add(Item(p0, 0, EOF)) - self.assertEqual(len(s0), 1) # 1 rule - self.assertIn(Item(p0, 0, EOF), s0) - - # Invoke closure on set: - s0 = self.g.closure(s0) - self.assertIn(Item(p0, 0, EOF), s0) - self.assertIn(Item(p1, 0, EOF), s0) - self.assertIn(Item(p1, 0, '('), s0) - self.assertIn(Item(p2, 0, EOF), s0) - self.assertIn(Item(p2, 0, '('), s0) - self.assertIn(Item(p3, 0, EOF), s0) - self.assertIn(Item(p3, 0, '('), s0) - self.assertIn(Item(p4, 0, EOF), s0) - self.assertIn(Item(p4, 0, '('), s0) - - def testParser(self): - tokens = ['(', '(', ')', ')', '(', ')'] - # 3. build parser: - p = self.g.genParser() - self.assertEqual(len(p.goto_table), 5) - self.assertEqual(len(p.action_table), 19) - - # 4. feed input: - p.parse(genTokens(tokens)) - -if __name__ == '__main__': - unittest.main() - - diff -r c9781c73e7e2 -r 05184b95fa16 python/testregalloc.py --- a/python/testregalloc.py Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -import unittest -import os -import sys -from irmach import AbstractInstruction as makeIns, Frame -import registerallocator -import ir -from target import Nop - - -class RegAllocTestCase(unittest.TestCase): - def setUp(self): - self.ra = registerallocator.RegisterAllocator() - - def testRegAlloc(self): - f = Frame('tst') - f.regs = [1,2,3,4,5,6] # for test use numbers! - f.tempMap = {} - t1 = ir.Temp('t1') - t2 = ir.Temp('t2') - t3 = ir.Temp('t3') - t4 = ir.Temp('t4') - t5 = ir.Temp('t5') - f.instructions.append(makeIns(Nop, dst=[t1])) - f.instructions.append(makeIns(Nop, dst=[t2])) - f.instructions.append(makeIns(Nop, dst=[t3])) - f.instructions.append(makeIns(Nop, dst=[t4], src=[t1, t2])) - f.instructions.append(makeIns(Nop, dst=[t5], src=[t4, t3])) - f.instructions.append(makeIns(Nop, src=[t5])) - self.ra.allocFrame(f) - self.conflict(t1, t2) - self.conflict(t2, t3) - - def conflict(self, ta, tb): - self.assertNotEqual(self.ra.Node(ta).color, self.ra.Node(tb).color) - - def testRegCoalesc(self): - f = Frame('tst') - f.regs = [1,2,3,4,5,6] # for test use numbers! - f.tempMap = {} - t1 = ir.Temp('t1') - t2 = ir.Temp('t2') - t3 = ir.Temp('t3') - t4 = ir.Temp('t4') - t5 = ir.Temp('t5') - t6 = ir.Temp('t6') - f.instructions.append(makeIns(Nop, dst=[t1])) - f.instructions.append(makeIns(Nop, dst=[t2])) - f.instructions.append(makeIns(Nop, dst=[t3])) - f.instructions.append(makeIns(Nop, dst=[t4], src=[t2, t1])) - f.instructions.append(makeIns(Nop, dst=[t5], src=[t3])) - f.instructions.append(makeIns(Nop, dst=[t5], src=[t4, t5])) - f.instructions.append(makeIns(Nop, dst=[t6], src=[t5])) - f.instructions.append(makeIns(Nop, src=[t6])) - self.ra.allocFrame(f) - self.conflict(t1, t2) - self.conflict(t2, t3) - self.conflict(t1, t3) - -if __name__ == '__main__': - unittest.main() - diff -r c9781c73e7e2 -r 05184b95fa16 python/testx86asm.py --- a/python/testx86asm.py Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -#!/usr/bin/python - -import unittest - - -class AssemblerTestCase(unittest.TestCase): - """ - test methods start with 'test*' - Checks several assembly constructs agains their bytecodes - """ - def setUp(self): - self.skipTest('not implemented yet') - self.assembler = Assembler('x86-64') - - def tstAssembler(self): - """ Check all kind of assembler cases """ - assert(assembler.shortjump(5) == [0xeb, 0x5]) - assert(assembler.shortjump(-2) == [0xeb, 0xfc]) - assert(assembler.shortjump(10,'GE') == [0x7d, 0xa]) - assert(assembler.nearjump(5) == [0xe9, 0x5,0x0,0x0,0x0]) - assert(assembler.nearjump(-2) == [0xe9, 0xf9, 0xff,0xff,0xff]) - assert(assembler.nearjump(10,'LE') == [0x0f, 0x8e, 0xa,0x0,0x0,0x0]) - - def testCall(self): - assert(assembler.call('r10') == [0x41, 0xff, 0xd2]) - assert(assembler.call('rcx') == [0xff, 0xd1]) - def testXOR(self): - assert(assembler.xorreg64('rax', 'rax') == [0x48, 0x31, 0xc0]) - assert(assembler.xorreg64('r9', 'r8') == [0x4d, 0x31, 0xc1]) - assert(assembler.xorreg64('rbx', 'r11') == [0x4c, 0x31, 0xdb]) - - def testINC(self): - assert(assembler.increg64('r11') == [0x49, 0xff, 0xc3]) - assert(assembler.increg64('rcx') == [0x48, 0xff, 0xc1]) - - def testPush(self): - assert(assembler.push('rbp') == [0x55]) - assert(assembler.push('rbx') == [0x53]) - assert(assembler.push('r12') == [0x41, 0x54]) - def testPop(self): - assert(assembler.pop('rbx') == [0x5b]) - assert(assembler.pop('rbp') == [0x5d]) - assert(assembler.pop('r12') == [0x41, 0x5c]) - - def testAsmLoads(self): - # TODO constant add testcases - assert(assembler.mov('rbx', 'r14') == [0x4c, 0x89, 0xf3]) - assert(assembler.mov('r12', 'r8') == [0x4d, 0x89, 0xc4]) - assert(assembler.mov('rdi', 'rsp') == [0x48, 0x89, 0xe7]) - - def testAsmMemLoads(self): - assert(assembler.mov('rax', ['r8','r15',0x11]) == [0x4b,0x8b,0x44,0x38,0x11]) - assert(assembler.mov('r13', ['rbp','rcx',0x23]) == [0x4c,0x8b,0x6c,0xd,0x23]) - - assert(assembler.mov('r9', ['rbp',-0x33]) == [0x4c,0x8b,0x4d,0xcd]) - #assert(assembler.movreg64('rbx', ['rax']) == [0x48, 0x8b,0x18]) - - assert(assembler.mov('rax', [0xb000]) == [0x48,0x8b,0x4,0x25,0x0,0xb0,0x0,0x0]) - assert(assembler.mov('r11', [0xa0]) == [0x4c,0x8b,0x1c,0x25,0xa0,0x0,0x0,0x0]) - - assert(assembler.mov('r11', ['RIP', 0xf]) == [0x4c,0x8b,0x1d,0x0f,0x0,0x0,0x0]) - - def testAsmMemStores(self): - assert(assembler.mov(['rbp', 0x13],'rbx') == [0x48,0x89,0x5d,0x13]) - assert(assembler.mov(['r12', 0x12],'r9') == [0x4d,0x89,0x4c,0x24,0x12]) - assert(assembler.mov(['rcx', 0x11],'r14') == [0x4c,0x89,0x71,0x11]) - - - assert(assembler.mov([0xab], 'rbx') == [0x48,0x89,0x1c,0x25,0xab,0x0,0x0,0x0]) - assert(assembler.mov([0xcd], 'r13') == [0x4c,0x89,0x2c,0x25,0xcd,0x0,0x0,0x0]) - - assert(assembler.mov(['RIP', 0xf], 'r9') == [0x4c,0x89,0x0d,0x0f,0x0,0x0,0x0]) - - def testAsmMOV8(self): - assert(assembler.mov(['rbp', -8], 'al') == [0x88, 0x45, 0xf8]) - assert(assembler.mov(['r11', 9], 'cl') == [0x41, 0x88, 0x4b, 0x09]) - - assert(assembler.mov(['rbx'], 'al') == [0x88, 0x03]) - assert(assembler.mov(['r11'], 'dl') == [0x41, 0x88, 0x13]) - - def testAsmLea(self): - assert(assembler.leareg64('r11', ['RIP', 0xf]) == [0x4c,0x8d,0x1d,0x0f,0x0,0x0,0x0]) - assert(assembler.leareg64('rsi', ['RIP', 0x7]) == [0x48,0x8d,0x35,0x07,0x0,0x0,0x0]) - - assert(assembler.leareg64('rcx', ['rbp', -8]) == [0x48,0x8d,0x4d,0xf8]) - - def testAssemblerCMP(self): - assert(assembler.cmpreg64('rdi', 'r13') == [0x4c, 0x39, 0xef]) - assert(assembler.cmpreg64('rbx', 'r14') == [0x4c, 0x39, 0xf3]) - assert(assembler.cmpreg64('r12', 'r9') == [0x4d, 0x39, 0xcc]) - - assert(assembler.cmpreg64('rdi', 1) == [0x48, 0x83, 0xff, 0x01]) - assert(assembler.cmpreg64('r11', 2) == [0x49, 0x83, 0xfb, 0x02]) - def testAssemblerADD(self): - assert(assembler.addreg64('rbx', 'r13') == [0x4c, 0x01, 0xeb]) - assert(assembler.addreg64('rax', 'rbx') == [0x48, 0x01, 0xd8]) - assert(assembler.addreg64('r12', 'r13') == [0x4d, 0x01, 0xec]) - - assert(assembler.addreg64('rbx', 0x13) == [0x48, 0x83, 0xc3, 0x13]) - assert(assembler.addreg64('r11', 0x1234567) == [0x49, 0x81, 0xc3, 0x67, 0x45,0x23,0x1]) - assert(assembler.addreg64('rsp', 0x33) == [0x48, 0x83, 0xc4, 0x33]) - - def testAssemblerSUB(self): - assert(assembler.subreg64('rdx', 'r14') == [0x4c, 0x29, 0xf2]) - assert(assembler.subreg64('r15', 'rbx') == [0x49, 0x29, 0xdf]) - assert(assembler.subreg64('r8', 'r9') == [0x4d, 0x29, 0xc8]) - - assert(assembler.subreg64('rsp', 0x123456) == [0x48, 0x81, 0xec, 0x56,0x34,0x12,0x0]) - assert(assembler.subreg64('rsp', 0x12) == [0x48, 0x83, 0xec, 0x12]) - - def testAssemblerIDIV(self): - assert(assembler.idivreg64('r11') == [0x49, 0xf7, 0xfb]) - assert(assembler.idivreg64('rcx') == [0x48, 0xf7, 0xf9]) - assert(assembler.idivreg64('rsp') == [0x48, 0xf7, 0xfc]) - - def testAssemblerIMUL(self): - assert(assembler.imulreg64_rax('rdi') == [0x48, 0xf7, 0xef]) - assert(assembler.imulreg64_rax('r10') == [0x49, 0xf7, 0xea]) - assert(assembler.imulreg64_rax('rdx') == [0x48, 0xf7, 0xea]) - - assert(assembler.imulreg64('r11', 'rdi') == [0x4c, 0xf, 0xaf, 0xdf]) - assert(assembler.imulreg64('r12', 'rbx') == [0x4c, 0xf, 0xaf, 0xe3]) - # nasm generates this machine code: 0x4d, 0x6b, 0xff, 0xee - # This also works: 4D0FAFFE (another variant?? ) - assert(assembler.imulreg64('r15', 'r14') == [0x4d, 0x0f, 0xaf, 0xfe]) - - -if __name__ == '__main__': - unittest.main() - diff -r c9781c73e7e2 -r 05184b95fa16 python/testzcc.py --- a/python/testzcc.py Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -import unittest -import glob -import zcc -import outstream -import ppci - -class ZccTestCase(unittest.TestCase): - """ Tests the compiler driver """ - - def do(self, fn): - """ Compile blink.c3 """ - args = zcc.parser.parse_args([fn, '--package_dir', './c3/examples']) - zcc.main(args) - - def testExamples(self): - """ Test all examples in the c3/examples directory """ - example_filenames = glob.glob('./c3/examples/*.c3') - for filename in example_filenames: - self.do(filename) - - def testSectionAddress(self): - src = "package tst; function void t2() {var int t3; t3 = 2;}" - diag = ppci.DiagnosticsManager() - outs = outstream.TextOutputStream() - self.assertTrue(zcc.zcc(src, outs, diag)) - code = outs.getSection('code') - self.assertEqual(0x08000000, code.address) - data = outs.getSection('data') - self.assertEqual(0x20000000, data.address) - - -if __name__ == '__main__': - unittest.main() - diff -r c9781c73e7e2 -r 05184b95fa16 python/trunner.sh --- a/python/trunner.sh Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -#!/usr/bin/bash - -DIR=. -while :; do - python -m unittest - echo "Awaiting changes in $DIR" - inotifywait -r -e modify $DIR -done - - - diff -r c9781c73e7e2 -r 05184b95fa16 python/trunner2.sh --- a/python/trunner2.sh Fri Nov 15 12:26:50 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -#!/usr/bin/bash - -DIR=. -while :; do - python tcodegen.py - - # Create svg from dot file: - #dot -Tpdf -o ir.pdf ir.gv - dot -Tpdf -o cfg.pdf cfg.gv - dot -Tpdf -o ig.pdf ig.gv - echo "Awaiting changes in $DIR" - inotifywait -r -e modify $DIR -done - - - diff -r c9781c73e7e2 -r 05184b95fa16 test/c3examples/blink.c3 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/c3examples/blink.c3 Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,30 @@ +/* This file blinks a LED on the STM32F4 discovery board. + +the board has 4 leds on PD12, PD13, PD14 and PD15 + +*/ + +module blink; + +import stm32f4xx; + +// Functions: +function void main() +{ + // Memory mapped control registers: + var GPIO_Type GPIOD; + GPIOD = cast(0x40020C00); + var RCC_Type RCC; + RCC = cast(0x40023800); + + // Enable the clock to port D: + RCC->AHB1ENR = RCC->AHB1ENR | 0x8; + + + // PD13 == output (01) + GPIOD->MODER = (1 << 26); + GPIOD->ODR = (1 << 13); + + while(true) {} +} + diff -r c9781c73e7e2 -r 05184b95fa16 test/c3examples/burn.c3 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/c3examples/burn.c3 Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,39 @@ +/* + +This file blinks a LED on the STM32F4 discovery board. + +the board has 4 leds on PD12, PD13, PD14 and PD15 + +*/ + +module burn; + +import stm32f4xx; + +/* +function void init() +{ +} +*/ + +function void main() +{ + //init(); + var RCC_Type RCC; + RCC = cast(0x40023800); + + // Enable the clock to port D: + RCC->AHB1ENR = RCC->AHB1ENR | (1 << 3); + // Memory mapped control registers: + var GPIO_Type GPIOD; + GPIOD = cast(0x40020C00); + + var int pin; + pin = 15; + // PD13 == output (01) + GPIOD->MODER = (1 << (pin << 1)); + GPIOD->ODR = (1 << pin); + + while(true) {} +} + diff -r c9781c73e7e2 -r 05184b95fa16 test/c3examples/burn2.c3 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/c3examples/burn2.c3 Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,59 @@ +/* + +This file blinks a LED on the STM32F4 discovery board. + +the board has 4 leds on PD12, PD13, PD14 and PD15 + +*/ + +module burn2; + +import stm32f4xx; + +function int add(int a, int b) +{ + return a + b; +} + +function void init(int pin) +{ + if (pin < 12) + { + return; + } + + /*if (pin > 15) + { + return; + }*/ + + var RCC_Type RCC; + RCC = cast(0x40023800); + + // Enable the clock to port D: + RCC->AHB1ENR = RCC->AHB1ENR | (1 << 3); + // Memory mapped control registers: + var GPIO_Type GPIOD; + GPIOD = cast(0x40020C00); + + // PD13 == output (01) + GPIOD->MODER = (1 << (pin << 1)); + GPIOD->ODR = (1 << pin); +} + + +function void main() +{ + // Vary between 12 and 15: + init(13); + + var int a; + a = 0 + while (a < 1000) + { + a = a + 1; + } + + while(true) {} +} + diff -r c9781c73e7e2 -r 05184b95fa16 test/c3examples/cast.c3 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/c3examples/cast.c3 Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,18 @@ + +/* + Demo of how to type cast +*/ + +package castdemo; + +function int testcast() +{ + var int a; + var int* b; + a = 3; + + b = cast(a); + + return 0; +} + diff -r c9781c73e7e2 -r 05184b95fa16 test/c3examples/comments.c3 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/c3examples/comments.c3 Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,14 @@ + +/* + block + comment +*/ + +// fjd jjd- +package comments; // hjfkds + +function int tst() +{ + return 0; +} + diff -r c9781c73e7e2 -r 05184b95fa16 test/c3examples/functions.c3 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/c3examples/functions.c3 Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,27 @@ + +/* + Demo of function usage +*/ + +package functiondemo; + +function void main() +{ + var int a, b, c; + a = 3; + b = a; + a =3; + b = fib(a + 9); + sum(a, b); +} + +function int fib(int x) +{ + return fib(x - 1) * x; +} + +function int sum(int a, int b) +{ + return a + b; +} + diff -r c9781c73e7e2 -r 05184b95fa16 test/c3examples/stm32f4xx.c3 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/c3examples/stm32f4xx.c3 Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,31 @@ + +package stm32f4xx; + +type struct { + int MODER; + int OTYPER; + int OSPEEDR; + int PUPDR; + int IDR; + int ODR; +}* GPIO_Type; + +type struct { + int CR; + int PLLCFGR; + int CFGR; + int CIR; + int AHB1RSTR; + int AHB2RSTR; + int AHB3RSTR; + int reserved0; + int APB1RSTR; + int APB2RSTR; + int reserved1a, reserved1b; + int AHB1ENR; + int AHB2ENR; + int AHB3ENR; + int reserved2; + int APB1ENR, APB2ENR; +}* RCC_Type; + diff -r c9781c73e7e2 -r 05184b95fa16 test/c3examples/types.c3 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/c3examples/types.c3 Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,40 @@ + +/* + Demo of how to define types +*/ + +package typedemo; + +type int A; +type int B; +type struct { + int x, y; + A z; +} C; +type struct { + C x; + B y; + int z; +} D; + +type D* E; + +function int testcast() +{ + var A a; + var B b; + a = 3; + b = a; + var C c; + c.x = a; + c.z = c.y; + var D d; + var E e; + var D* e2; + e = &d; + e2 = e; + e2->x.x = 22; + + return 0; +} + diff -r c9781c73e7e2 -r 05184b95fa16 test/runtests.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtests.sh Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,16 @@ +#!/usr/bin/bash + +export PYTHONPATH=$PYTHONPATH:../python + +if [ $1 == "loop" ]; then + DIR=.. + while :; do + python -m unittest + echo "Awaiting changes in $DIR" + inotifywait -r -e modify $DIR + done +else + python -m unittest +fi + + diff -r c9781c73e7e2 -r 05184b95fa16 test/testasm.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testasm.py Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,318 @@ +#!/usr/bin/python + +import unittest, cProfile +from ppci import CompilerError +from asmnodes import AInstruction, ABinop, AUnop, ASymbol, ALabel, ANumber +from asm import tokenize, Assembler +import msp430 +import cortexm3 as arm +import outstream +from target import Label + +class AssemblerLexingCase(unittest.TestCase): + """ Tests the assemblers lexer """ + + def testLex0(self): + """ Check if the lexer is OK """ + asmline, toks = 'mov rax, rbx ', ['ID', 'ID', ',', 'ID'] + self.assertSequenceEqual([tok.typ for tok in tokenize(asmline)], toks) + + def testLex1(self): + """ Test if lexer correctly maps some tokens """ + asmline, toks = 'lab1: mov rax, rbx ', ['ID', ':', 'ID', 'ID', ',', 'ID'] + self.assertSequenceEqual([tok.typ for tok in tokenize(asmline)], toks) + + def testLex1(self): + """ Test if lexer correctly maps some tokens """ + asmline, toks = 'mov 3.13 0xC 13', ['ID', 'REAL', 'NUMBER', 'NUMBER'] + self.assertSequenceEqual([tok.typ for tok in tokenize(asmline)], toks) + + def testLex2(self): + """ Test if lexer fails on a token that is invalid """ + asmline = '0z4: mov rax, rbx $ ' + with self.assertRaises(CompilerError): + list(tokenize(asmline)) + +class AssemblerParsingTestCase(unittest.TestCase): + """ + Tests the assembler parts + """ + def setUp(self): + self.a = Assembler() + + def testParse(self): + asmline = 'lab1: mov rax, rbx' + self.a.parse_line(asmline) + + def expectTree(self, asmline, stack): + self.a.parse_line(asmline) + self.assertSequenceEqual(stack, self.a.stack) + + def testParse2(self): + asmline = 'a: mov rax, [rbx + 2]' + output = [] + output.append(ALabel('a')) + output.append(AInstruction('mov', [ASymbol('rax'), AUnop('[]', ASymbol('rbx') + ANumber(2))])) + self.expectTree(asmline, output) + + def testParse3(self): + # A label must be optional: + asmline = 'mov rax, 1' + output = [AInstruction('mov', [ASymbol('rax'), ANumber(1)])] + self.expectTree(asmline, output) + + def testParse4(self): + # Test 3 operands: + asmline = 'add rax, [4*rbx + 22], rcx' + ops = [] + ops.append(ASymbol('rax')) + ops.append(AUnop('[]', ANumber(4) * ASymbol('rbx') + ANumber(22))) + ops.append(ASymbol('rcx')) + output = [AInstruction('add', ops)] + self.expectTree(asmline, output) + + def testParse5(self): + # An instruction must be optional: + asmline = 'lab1:' + output = [] + output.append(ALabel('lab1')) + self.expectTree(asmline, output) + + def testParse6(self): + # A line can be empty + self.a.parse_line('') + +class AssemblerOtherTestCase(unittest.TestCase): + def testWithoutTarget(self): + a = Assembler() + with self.assertRaises(CompilerError): + a.assemble_line('') + + @unittest.skip + def testX86(self): + testsrc = """ ; tst + begin: + mov rax, rbx ; 0x48, 0x89, 0xd8 + xor rcx, rbx ; 0x48, 0x31, 0xd9 + inc rcx ; 0x48 0xff 0xc1 + """ + a = Assembler() + a.assemble(testsrc) + # Compare with nasm output: + nasmbytes = [0x48, 0x89, 0xd8, 0x48, 0x31, 0xd9, 0x48, 0xff, 0xc1] + + +class OustreamTestCase(unittest.TestCase): + def test1(self): + o = outstream.BinOutputStream() + o.selectSection('.text') + o.emit(Label('a')) + self.assertSequenceEqual(bytes(), o.Data) + + +class AsmTestCaseBase(unittest.TestCase): + def feed(self, line): + self.a.assemble(line) + + def check(self, hexstr): + self.assertSequenceEqual(bytes.fromhex(hexstr), self.o.Data) + + +class AssemblerMSP430TestCase(AsmTestCaseBase): + def setUp(self): + self.t = msp430.msp430target + self.o = outstream.BinOutputStream() + self.o.selectSection('.text') + self.a = Assembler(target=self.t, stream=self.o) + + def testMapMovInstruction(self): + i = AInstruction('mov', [ASymbol('r14'), ASymbol('r15')]) + ri = self.t.mapInstruction(i) + + def testMapRetiInstruction(self): + i = AInstruction('reti', []) + ri = self.t.mapInstruction(i) + + @unittest.skip + def testMapOperand(self): + o = ASymbol('r14') + mo = self.t.mapOperand(o) + self.assertEqual(mo, msp430.r14) + + @unittest.skip + def testMapOperandIndirection(self): + o = AUnop('[]', ASymbol('r14')) + mo = self.t.mapOperand(o) + + def testMov(self): + line1 = "mov r14, r15" + self.feed(line1) + self.check('0F4E') + + def testMov1337(self): + line1 = "mov 0x1337, r12" + self.feed(line1) + self.check('3C403713') + + def testAdd(self): + line1 = "add r15, r13" + self.feed(line1) + self.check('0D5F') + + def testReti(self): + line1 = "reti" + self.feed(line1) + self.check('0013') + + def testMSPinstructionCount(self): + """ Check that there are 27 instructions """ + self.assertEqual(27, len(self.t.instructions)) + + +class AssemblerARMTestCase(AsmTestCaseBase): + def setUp(self): + self.t = arm.armtarget + self.o = outstream.BinOutputStream() + self.o.selectSection('.text') + self.a = Assembler(target=self.t, stream=self.o) + + def testMapOperand(self): + pass + + def testMovImm8(self): + self.feed('mov r4, 100') + self.check('6424') + + @unittest.skip + def testMovExt(self): + self.feed('mov r3, sp') + self.check('') + + def testYield(self): + self.feed('yield') + self.check('10bf') + + def testPush(self): + self.feed('push {r2,r3,lr}') + self.check('0cb5') + + def testPop(self): + self.feed('pop {r4-r6, pc}') + self.check('70bd') + + def testStr5(self): + self.feed('str r4, [r1 + 0]') + self.check('0c60') + + def testLdr5(self): + self.feed('ldr r4, [r0 + 0]') + self.check('0468') + + def testLdrSpRel(self): + self.feed('ldr r0, [sp + 4]') + self.check('0198') + + def testStrSpRel(self): + self.feed('str r0, [sp + 4]') + self.check('0190') + + def testLdrPcRel(self): + self.feed('ldr r7, henkie') + self.feed('ldr r6, henkie') + self.feed('ldr r1, henkie') + self.feed('align 4') + self.feed('dcd 1') + self.feed('henkie: dcd 2') + self.check('024F024E 01490000 01000000 02000000') + + def testBranch(self): + self.feed('start: b henkie') + self.feed('beq henkie') + self.feed('bne henkie') + self.feed('henkie: b start') + self.feed('eof: b eof') + self.check('01e000d0 ffd1fbe7 fee7') + + def testConditions(self): + self.feed('blt x') + self.feed('bgt x') + self.feed('x:') + self.check('00dbffdc') + + def testBoff(self): + self.feed('b henkie') + self.feed('b henkie') + self.feed('b henkie') + self.feed('b henkie') + self.feed('b henkie') + self.feed('b henkie') + self.feed('b henkie') + self.feed('henkie:') + self.feed('b henkie') + self.feed('b henkie') + self.feed('b henkie') + self.feed('b henkie') + self.check('05e004e0 03e002e0 01e000e0 ffe7fee7 fde7fce7 fbe7') + + def testBl(self): + self.feed('bl henkie') + self.feed('bl henkie') + self.feed('henkie:') + self.feed('bl henkie') + self.feed('bl henkie') + self.check('00f0 02f8 00f0 00f8 fff7 feff fff7 fcff') + + def testCmpRegReg(self): + self.feed('cmp r0, r1') + self.check('8842') + + def testAddimm3(self): + self.feed('add r3, r5, 2') + self.feed('add r4, r1, 6') + self.check('ab1c8c1d') + + def testSubImm3(self): + self.feed('sub r3, r5, 2') + self.feed('sub r4, r1, 6') + self.check('ab1e8c1f') + + def testLeftShift(self): + self.feed('lsl r3, r5') + self.check('ab40') + + def testAddSp(self): + self.feed('add sp,sp,8') + self.feed('add sp,sp,16') + self.check('02b004b0') + + def testSubSp(self): + self.feed('sub sp,sp,32') + self.feed('sub sp,sp,4') + self.check('88b081b0') + + def testSequence1(self): + self.feed('mov r5, 3') + self.feed('add r4, r5, 0') + self.feed('loop: add r6, r4, 7') + self.feed('cmp r6, 5') + self.check('0325 2c1c e61d 052e') + + def testSequence2(self): + self.feed('henkie:') + self.feed('push {r1,r4,r5}') + self.feed('add r5, r2, r4') + self.feed('cmp r4, r2') + self.feed('ldr r0, [sp + 4]') + self.feed('str r3, [sp + 16]') + self.feed('pop {r1, r4, r5}') + self.feed('lsl r3, r4') + self.feed('cmp r3, r5') + self.feed('beq henkie') + self.feed('bne henkie') + self.feed('b henkie') + self.check('32b41519 94420198 049332bc a340ab42 f6d0f5d1 f4e7') + +if __name__ == '__main__': + #cProfile.run('unittest.main()') + unittest.main() + diff -r c9781c73e7e2 -r 05184b95fa16 test/testc3.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testc3.py Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,435 @@ +import c3 +import time, ppci, x86, ir +import unittest +import glob + +testsrc = """module test; + +/* + demo of the source that is correct :) +*/ +var int c, d; +var double e; +var int f; + +const int A = 1337; + +function void test1() +{ + var int bdd; + var int a = 10; + bdd = 20; + var int buf; + var int i; + i = 2; + var int zero = i - 2; + if (i > 1) + { + buf = b + 22 * i - 13 + (55 * 2 *9-2) / 44 - 1; + } + else + { + ;;; + } + + t2(2, 3); +} + +function int t2(int a, int b) +{ + if (a > 0) + { + a = 2 + t2(a - 1, 10); + } + + return a + b; +} + +var int a, b; + +function int t3(int aap, int blah) +{ + if (a > blah and blah < 45 + 33 or 33 > aap or 6 > 2 and true) + { + a = 2 + t2(a - 1, 0); + } + + return a + b; +} + +var int hahaa = 23 * 2; + + +""" + +class testLexer(unittest.TestCase): + def testUnexpectedCharacter(self): + snippet = """ var s \u6c34 """ + with self.assertRaises(ppci.CompilerError): + list(c3.lexer.tokenize(snippet)) + + def testBlockComment(self): + snippet = """ + /* Demo */ + var int x = 0; + """ + toks = ['var', 'ID', 'ID', '=', 'NUMBER', ';', 'END'] + self.assertSequenceEqual([tok.typ for tok in c3.lexer.tokenize(snippet)], toks) + + def testBlockCommentMultiLine(self): + snippet = """ + /* Demo + bla1 + bla2 + */ + var int x = 0; + """ + toks = ['var', 'ID', 'ID', '=', 'NUMBER', ';', 'END'] + self.assertSequenceEqual([tok.typ for tok in c3.lexer.tokenize(snippet)], toks) + +class testBuilder(unittest.TestCase): + def setUp(self): + self.diag = ppci.DiagnosticsManager() + self.builder = c3.Builder(self.diag) + self.diag.clear() + + def testSrc(self): + self.expectOK(testsrc) + + def expectErrors(self, snippet, rows): + """ Helper to test for expected errors on rows """ + ircode = self.builder.build(snippet) + actualErrors = [err.row for err in self.diag.diags] + if rows != actualErrors: + self.diag.printErrors(snippet) + self.assertSequenceEqual(rows, actualErrors) + self.assertFalse(ircode) + + def expectOK(self, snippet, pack_dir=None): + ircode = self.builder.build(snippet, pack_dir=pack_dir) + if not ircode: + self.diag.printErrors(snippet) + self.assertTrue(ircode) + return ircode + + def testPackage(self): + p1 = """module p1; + type int A; + """ + self.assertTrue(self.builder.build(p1)) + p2 = """module p2; + import p1; + var A b; + """ + self.expectOK(p2) + + def testFunctArgs(self): + snippet = """ + module testargs; + function void t2(int a, double b) + { + t2(2, 2); + t2(2); + t2(1, 1.2); + } + """ + self.expectErrors(snippet, [5, 6]) + + def testExpressions(self): + snippet = """ + module test; + function void t(int a, double b) + { + var int a2; + var bool c; + + a2 = b * a; + c = a; + c = b > 1; + } + """ + self.expectErrors(snippet, [8, 9, 10]) + + def testExpression1(self): + snippet = """ + module testexpr1; + function void t() + { + var int a, b, c; + a = 1; + b = a * 2 + a * a; + c = b * a - 3; + } + """ + self.expectOK(snippet) + + def testEmpty(self): + snippet = """ + module A + """ + self.expectErrors(snippet, [3]) + + def testEmpty2(self): + snippet = "" + self.expectErrors(snippet, [1]) + + def testRedefine(self): + snippet = """ + module test; + var int a; + var int b; + var int a; + """ + self.expectErrors(snippet, [5]) + + def testWhile(self): + snippet = """ + module tstwhile; + var int a; + function void t() + { + var int i = 0; + while (i < 1054) + { + i = i + 3; + a = a + i; + } + + while(true) + { + } + + while(false) + { + } + } + """ + self.expectOK(snippet) + + def testIf(self): + snippet = """ + module tstIFF; + function void t(int b) + { + var int a; + a = 2; + if (a > b) + { + if (a > 1337) + { + b = 2; + } + } + else + { + b = 1; + } + + return b; + } + """ + self.expectOK(snippet) + + def testTypeDef(self): + snippet = """ + module testtypedef; + type int my_int; + function void t() + { + var my_int a; + var int b; + a = 2; + b = a + 2; + } + """ + self.expectOK(snippet) + + def testLocalVariable(self): + snippet = """ + module testlocalvar; + function void t() + { + var int a, b; + a = 2; + b = a + 2; + } + """ + self.expectOK(snippet) + + def testUnknownType(self): + snippet = """module testlocalvar; + function void t() + { + var int2 a; + } + """ + self.expectErrors(snippet, [4]) + + def testStruct1(self): + snippet = """ + module teststruct1; + function void t() + { + var struct {int x, y;} a; + a.x = 2; + a.y = a.x + 2; + } + """ + self.expectOK(snippet) + + def testPointerType1(self): + snippet = """ + module testpointer1; + var int* pa; + function void t() + { + var int a; + pa = &a; + *pa = 22; + } + """ + self.expectOK(snippet) + + def testPointerType(self): + snippet = """ + module testpointer; + var int* pa, pb; + function void t(int a, double b) + { + var int a2; + a2 = a; // parameters cannot be escaped for now.. + pa = &a2; + pb = pa; + *pa = 22; + } + """ + self.expectOK(snippet) + + def testPointerTypeInCorrect(self): + snippet = """ + module testpointerincorrect; + var int* pa; + function void t(int a, double b) + { + pa = 2; // type conflict + pa = &a; + pa = &2; + &a = pa; // No valid lvalue + **pa = 22; // Cannot deref int + } + """ + self.expectErrors(snippet, [6, 9, 10]) + + def testPointerTypeIr(self): + snippet = """ + module testptr_ir; + function void t() + { + var int* a; + a = cast(40); + *a = 2; + } + """ + self.expectOK(snippet) + + def testPointerTypeIr2(self): + snippet = """ + module testptr_ir; + type struct {int x,y;}* gpio; + function void t() + { + var gpio a; + a = cast(40); + a->x = 2; + a->y = a->x - 14; + } + """ + self.expectOK(snippet) + + def testWrongCast(self): + snippet = """ + module testptr_ir; + type struct {int x,y;}* gpio; + function void t() + { + var gpio a; + *cast(*a); + } + """ + # TODO: remove the duplicate error: + self.expectErrors(snippet, [7, 7]) + + def testComplexType(self): + snippet = """ + module testpointer; + type int my_int; + + type struct { + int x, y; + } point; + + type struct { + int mem1; + int memb2; + point P1; + } my_struct; + + type my_struct* my_sptr; + var int* pa; + + function void t(int a, int b, my_sptr x) + { + var my_struct *msp; + + var my_struct u, v; + var point *pt; + + pt = &msp->P1; + msp = x; + *pa = 22 + u.mem1 * v.memb2 - u.P1.x; + x->memb2 = *pa + a * b; + + msp->P1.x = a * x->P1.y; + } + """ + self.expectOK(snippet) + + def testExamples(self): + """ Test all examples in the c3/examples directory """ + example_filenames = glob.glob('./c3/examples/*.c3') + for filename in example_filenames: + with open(filename, 'r') as f: + src = f.read() + self.expectOK(src, pack_dir='./c3/examples') + + def test2(self): + # testsrc2 is valid code: + snippet = """ + module test2; + + function void tst() + { + var int a, b; + a = 2 * 33 - 12; + b = a * 2 + 13; + a = b + a; + if (a > b and b == 3) + { + var int x = a; + x = b * 2 - a; + a = x*x; + } + else + { + a = b + a; + } + } + + """ + ircode = self.expectOK(snippet) + self.assertEqual(1, len(ircode.Functions)) + +if __name__ == '__main__': + unittest.main() + + diff -r c9781c73e7e2 -r 05184b95fa16 test/testcg.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testcg.py Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,41 @@ +import unittest +import ppci, codegen, ir +import cortexm3 as arm +import codegenarm +import outstream + +def genTestFunction(): + m = ir.Module('tst') + f = ir.Function('tst') + m.addFunction(f) + return m, f, f.entry + + +class testCodeGeneration(unittest.TestCase): + def setUp(self): + self.cg = codegen.CodeGenerator(arm.armtarget) + + def testFunction(self): + m, f, bb = genTestFunction() + bb.addInstruction(ir.Const(123)) + bb.addInstruction(ir.Jump(f.epiloog)) + m.check() + obj = self.cg.generate(m) + self.assertTrue(obj) + + +class testArmCodeGeneration(unittest.TestCase): + def testStack(self): + s = outstream.OutputStream() + cg = codegenarm.ArmCodeGenerator(s) + m, f, bb = genTestFunction() + bb.addInstruction(ir.Move(ir.Mem(ir.Const(1)), ir.Const(22))) + bb.addInstruction(ir.Jump(f.epiloog)) + m.check() + cg.generate(m) + #s.dump() + + +if __name__ == '__main__': + unittest.main() + diff -r c9781c73e7e2 -r 05184b95fa16 test/testgraph.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testgraph.py Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,81 @@ +#!/usr/bin/python + +import unittest +import graph +import interferencegraph +import flowgraph +import ir +from irmach import AbstractInstruction as AI +from target import Nop + + +class GraphTestCase(unittest.TestCase): + def testEdge(self): + g = graph.Graph() + n1 = graph.Node(g) + g.addNode(n1) + n2 = graph.Node(g) + g.addNode(n2) + g.addEdge(n1, n2) + self.assertTrue(g.hasEdge(n2, n1)) + self.assertTrue(g.hasEdge(n1, n2)) + g.delNode(n1) + g.delNode(n2) + + def testDegree(self): + g = graph.Graph() + n1 = graph.Node(g) + g.addNode(n1) + n2 = graph.Node(g) + g.addNode(n2) + n3 = graph.Node(g) + g.addNode(n3) + g.addEdge(n1, n2) + g.addEdge(n1, n3) + self.assertEqual(2, n1.Degree) + self.assertEqual(1, n2.Degree) + g.delNode(n2) + self.assertEqual(1, n1.Degree) + + +class DigraphTestCase(unittest.TestCase): + pass + + +class InterferenceGraphTestCase(unittest.TestCase): + def testNormalUse(self): + t1 = ir.Temp('t1') + t2 = ir.Temp('t2') + t3 = ir.Temp('t3') + t4 = ir.Temp('t4') + t5 = ir.Temp('t5') + t6 = ir.Temp('t6') + instrs = [] + instrs.append(AI(Nop, dst=[t1])) + instrs.append(AI(Nop, dst=[t2])) + instrs.append(AI(Nop, dst=[t3])) + cfg = flowgraph.FlowGraph(instrs) + ig = interferencegraph.InterferenceGraph(cfg) + + def testCombine(self): + t1 = ir.Temp('t1') + t2 = ir.Temp('t2') + t3 = ir.Temp('t3') + t4 = ir.Temp('t4') + instrs = [] + instrs.append(AI(Nop, dst=[t1])) + instrs.append(AI(Nop, dst=[t2])) + instrs.append(AI(Nop, dst=[t3])) + instrs.append(AI(Nop, dst=[t4], src=[t3])) + instrs.append(AI(Nop, src=[t4])) + instrs.append(AI(Nop, src=[t1])) + instrs.append(AI(Nop, src=[t2])) + cfg = flowgraph.FlowGraph(instrs) + ig = interferencegraph.InterferenceGraph(cfg) + ig.Combine(ig.getNode(t4), ig.getNode(t3)) + self.assertIs(ig.getNode(t4), ig.getNode(t3)) + + +if __name__ == '__main__': + unittest.main() + diff -r c9781c73e7e2 -r 05184b95fa16 test/testhexfile.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testhexfile.py Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,102 @@ +import unittest +import io +from hexfile import HexFile, HexFileException + + +class testHexFile(unittest.TestCase): + def saveload(self, hf): + f = io.StringIO() + hf.save(f) + hf2 = HexFile() + hf2.load(io.StringIO(f.getvalue())) + self.assertEqual(hf, hf2) + + def testSave1(self): + hf = HexFile() + hf.addRegion(0x8000, bytes.fromhex('aabbcc')) + self.saveload(hf) + + def testSave2(self): + hf = HexFile() + hf.addRegion(0x8000, bytes.fromhex('aabbcc')) + hf.addRegion(0x118000, bytes.fromhex('aabbcc')) + self.saveload(hf) + + def testSave3(self): + hf = HexFile() + hf.addRegion(0x8000, bytes.fromhex('aabbcc')) + hf.addRegion(0xFFFE, bytes.fromhex('aabbcc')) + self.saveload(hf) + + def testSave4(self): + hf = HexFile() + hf.addRegion(0xF000, bytes.fromhex('ab')*0x10000) + self.saveload(hf) + + def testSave5(self): + hf = HexFile() + hf.addRegion(0xF003, bytes.fromhex('ab')*0x10000) + self.saveload(hf) + + def testMerge(self): + hf = HexFile() + hf.addRegion(0x10, bytes.fromhex('abcdab')) + hf.addRegion(0x13, bytes.fromhex('abcdab')) + self.assertEqual(1, len(hf.regions)) + + def testOverlapped(self): + hf = HexFile() + hf.addRegion(0x10, bytes.fromhex('abcdab')) + with self.assertRaisesRegex(HexFileException, 'verlap'): + hf.addRegion(0x12, bytes.fromhex('abcdab')) + + def testEqual(self): + hf1 = HexFile() + hf2 = HexFile() + hf1.addRegion(10, bytes.fromhex('aabbcc')) + hf2.addRegion(10, bytes.fromhex('aabbcc')) + self.assertEqual(hf1, hf2) + + def testNotEqual(self): + hf1 = HexFile() + hf2 = HexFile() + hf1.addRegion(10, bytes.fromhex('aabbcc')) + hf2.addRegion(10, bytes.fromhex('aabbdc')) + self.assertNotEqual(hf1, hf2) + + def testNotEqual2(self): + hf1 = HexFile() + hf2 = HexFile() + hf1.addRegion(10, bytes.fromhex('aabbcc')) + hf2.addRegion(10, bytes.fromhex('aabbcc')) + hf2.addRegion(22, bytes.fromhex('aabbcc')) + self.assertNotEqual(hf1, hf2) + + def testLoad(self): + hf = HexFile() + dummyhex = """ + :01400000aa15 + """ + f = io.StringIO(dummyhex) + hf.load(f) + self.assertEqual(1, len(hf.regions)) + self.assertEqual(0x4000, hf.regions[0].address) + self.assertSequenceEqual(bytes.fromhex('aa'), hf.regions[0].data) + + def testIncorrectCrc(self): + hf = HexFile() + txt = ":01400000aabb" + f = io.StringIO(txt) + with self.assertRaisesRegex(HexFileException, 'crc'): + hf.load(f) + + def testIncorrectLength(self): + hf = HexFile() + txt = ":0140002200aabb" + f = io.StringIO(txt) + with self.assertRaisesRegex(HexFileException, 'count'): + hf.load(f) + +if __name__ == '__main__': + unittest.main() + diff -r c9781c73e7e2 -r 05184b95fa16 test/testir.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testir.py Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,162 @@ +import unittest, os +import sys +import c3 +import ppci +import ir, x86, transform +import optimize + + +class IrCodeTestCase(unittest.TestCase): + def setUp(self): + self.b = ir.Builder() + self.m = ir.Module('test') + self.b.setModule(self.m) + + def testBuilder(self): + f = self.b.newFunction('add') + self.b.setFunction(f) + bb = self.b.newBlock() + self.b.emit(ir.Jump(bb)) + self.b.setBlock(bb) + self.b.emit(ir.Exp(ir.Const(0))) + self.b.emit(ir.Jump(f.epiloog)) + self.m.check() + # Run interpreter: + # r = self.m.getFunction('add').call(1, 2) + #self.assertEqual(3, r) + + +class PatternMatchTestCase(unittest.TestCase): + def testSimpleTree(self): + t = ir.Term('x') + pat = ir.Binop(ir.Const(2), '+', t) + res, mp = ir.match_tree(ir.Binop(ir.Const(2), '+', 3), pat) + self.assertTrue(res) + self.assertIn(t, mp) + self.assertEqual(3, mp[t]) + + def testSimpleTree2(self): + t = ir.Term('x') + t2 = ir.Term('y') + pat = ir.Binop(ir.Const(2), '+', ir.Binop(t, '-', t2)) + res, mp = ir.match_tree(ir.Binop(ir.Const(2), '+', ir.Binop(2,'-',3)), pat) + self.assertTrue(res) + self.assertIn(t, mp) + self.assertEqual(2, mp[t]) + self.assertIn(t2, mp) + self.assertEqual(3, mp[t2]) + res, mp = ir.match_tree(ir.Const(2), pat) + self.assertFalse(res) + + +class ConstantFolderTestCase(unittest.TestCase): + def setUp(self): + self.b = ir.Builder() + self.cf = transform.ConstantFolder() + self.m = ir.Module('test') + self.b.setModule(self.m) + + def testBuilder(self): + f = self.b.newFunction('test') + self.b.setFunction(f) + bb = self.b.newBlock() + self.b.emit(ir.Jump(bb)) + self.b.setBlock(bb) + v1 = ir.Const(5) + v2 = ir.Const(7) + v3 = ir.Add(v1, v2) + self.b.emit(ir.Jump(f.epiloog)) + self.cf.run(self.m) + + def testAdd0(self): + f = self.b.newFunction('test') + self.b.setFunction(f) + self.b.setBlock(self.b.newBlock()) + v1 = ir.Const(0) + v2 = ir.Const(0) + v3 = ir.Add(v1, v2) + + +testsrc = """ +package test2; + +function void tesssst(int henkie) +{ + var int a, b, cee; + a = 2 * 33 - 12; + b = a * 2 + 13; + a = b + a; + cee = a; + cee = cee * 2 + a + cee * 2; + if (cee + a > b and b *3 - a+8*b== 3*6-b) + { + var int x = a; + x = b * 2 - a; + a = x * x * (x + 22 - a); + } + else + { + a = b + a + (a + b); + } + var int y; + y = a - b * 53; +} +""" + +testsrc2 = """ +function int add2(int x, int y) +{ + var int res; + res = x + y + 2 - 7 + 2; + //if (y < 2) + //{ + // return y - 33; + //} + + res = res + (x + 2 * y) + (x + 2 * y) + (2*8) + (2*8); + + if (x > 13) + { + while (y > 1337) + { + res = res + 2; + y = y - 12; + } + } + return res; +} + +""" + +if __name__ == '__main__': + #unittest.main() + #sys.exit() + diag = ppci.DiagnosticsManager() + builder = c3.Builder(diag) + cgenx86 = x86.X86CodeGenSimple(diag) + ir = builder.build(testsrc) + diag.printErrors(testsrc) + ir.check() + ir.dump() + optimize.optimize(ir) + print('dump IR') + print('dump IR') + print('dump IR') + print('dump IR') + ir.dump() + + # Dump a graphiz file: + with open('graaf.gv', 'w') as f: + ir.dumpgv(f) + os.system('dot -Tsvg -ograaf.svg graaf.gv') + + sys.exit() + asm = cgenx86.genBin(ir) + #for a in asm: + # print(a) + with open('out.asm', 'w') as f: + f.write('BITS 64\n') + for a in asm: + f.write(str(a) + '\n') + print(a) + diff -r c9781c73e7e2 -r 05184b95fa16 test/testparserlib.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testparserlib.py Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,61 @@ +import unittest +from parserlib import OneOrMore, Literal, Or, Sequence, Optional + +class ParserCombinatorTestCase(unittest.TestCase): + def test1(self): + #p = Parser() + # parse and interpret: + n40 = Literal('40') + plus = Literal('+') + n2 = Literal('2') + n40.ParseAction = int + plus.ParseAction = replaceWith(0) + n2.ParseAction = int + p = Sequence([n40,plus,n2]) + p.ParseAction = wordsum + + result = p.parse('40+2') + self.assertEqual(42, result[0]) + +def replaceWith(s): + def _repFunc(*args): + return s + return _repFunc + +wordsum = lambda t: sum(t) + +class WordToNumTestCase(unittest.TestCase): + def setUp(self): + numWords = OneOrMore() + def makeLit(s, val): + ret = Literal(s) + ret.ParseAction = replaceWith(val) + return ret + unitDefs = [('zero', 0), ('three', 3), ('one', 1)] + units = Or( [makeLit(s, v) for s, v in unitDefs] ) + tensDefs = [('twenty', 20)] + tens = Or( [makeLit(s, v) for s, v in tensDefs] ) + + numPart = Sequence([Optional(tens), units]) + numPart.ParseAction = wordsum + self.p = numPart + + def check(self, i, o): + result = self.p.parse(i)[0] + self.assertEqual(o, result) + + def test0(self): + self.check('zero', 0) + + def test23(self): + self.check('twentythree', 23) + + @unittest.skip + def test321(self): + # TODO + self.check('three hundred and twenty one', 321) + + +if __name__ == '__main__': + unittest.main() + diff -r c9781c73e7e2 -r 05184b95fa16 test/testpyy.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testpyy.py Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,220 @@ +import unittest, pprint +from pyyacc import Grammar, Item, ParserGenerationException, ParserException, EPS, EOF +from ppci import Token + +def genTokens(lst): + for t in lst: + yield Token(t, t) + +class testLR(unittest.TestCase): + """ Test basic LR(1) parser generator constructs """ + def testSimpleGrammar(self): + # 1. define a simple grammar: + g = Grammar(['identifier', '(', ')', '+', '*']) + g.add_production('input', ['expression']) + g.add_production('expression', ['term']) + g.add_production('expression', ['expression', '+', 'term']) + g.add_production('term', ['factor']) + g.add_production('term', ['term', '*', 'factor']) + g.add_production('factor', ['(', 'expression', ')']) + g.add_production('factor', ['identifier']) + g.start_symbol = 'input' + # 2. define input: + tokens = genTokens(['identifier', '+', 'identifier', '+', 'identifier']) + # 3. build parser: + p = g.genParser() + # 4. feed input: + p.parse(tokens) + def testReduceReduceConflict(self): + """ Check if a reduce-reduce conflict is detected """ + # Define a grammar with an obvious reduce-reduce conflict: + g = Grammar(['id']) + g.add_production('goal', ['a']) + g.add_production('a', ['b']) + g.add_production('a', ['c']) + g.add_production('b', ['id']) + g.add_production('c', ['id']) + g.start_symbol = 'goal' + with self.assertRaises(ParserGenerationException): + p = g.genParser() + def testShiftReduceConflict(self): + """ Must be handled automatically by doing shift """ + g = Grammar([EOF, 'if', 'then', 'else', 'ass']) + # Ambiguous grammar: + g.add_production('if_stmt', ['if', 'then', 'stmt']) + g.add_production('if_stmt', ['if', 'then', 'stmt', 'else', 'stmt']) + g.add_production('stmt', ['if_stmt']) + g.add_production('stmt', ['ass']) + g.start_symbol = 'stmt' + p = g.genParser() + # Ambiguous program: + tokens = genTokens(['if', 'then','if', 'then', 'ass', 'else', 'ass']) + p.parse(tokens) + + def testUndefinedTerminal(self): + """ Test correct behavior when a terminal is undefined """ + g = Grammar(['b']) + g.add_production('goal', ['a']) + g.add_production('a', ['b']) + g.add_production('a', ['c']) + g.start_symbol = 'goal' + with self.assertRaises(ParserGenerationException): + g.genParser() + def testRedefineTerminal(self): + """ Test correct behavior when a terminal is redefined """ + g = Grammar([EOF, 'b', 'c']) + g.add_production('goal', ['a']) + with self.assertRaises(ParserGenerationException): + g.add_production('b', ['c']) # Not allowed + g.add_production('a', ['c']) + g.start_symbol = 'goal' + g.genParser() + def testEmpty(self): + """ Test empty token stream """ + g = Grammar([',']) + g.add_production('input', [',']) + g.start_symbol = 'input' + p = g.genParser() + tokens = genTokens([]) + with self.assertRaises(ParserException): + p.parse(tokens) + + def testEps(self): + """ Test epsilon terminal """ + g = Grammar(['a', 'b']) + g.add_production('input', ['optional_a', 'b']) + g.add_production('optional_a', ['a']) + g.add_production('optional_a', []) + g.start_symbol = 'input' + p = g.genParser() + tokens = genTokens(['b']) + p.parse(tokens) + + def testEps2(self): + g = Grammar(['id', ':']) + g.add_production('input', ['opt_lab', 'ins', 'op1']) + g.add_production('input', ['ins', 'op1']) + g.add_production('opt_lab', ['id', ':']) + g.add_production('ins', ['id']) + g.add_production('op1', ['id']) + g.start_symbol = 'input' + p = g.genParser() + tokens = genTokens(['id', ':', 'id', 'id']) # i.e. "lab_0: inc rax" + p.parse(tokens) + tokens = genTokens(['id', 'id']) # i.e. "inc rax" + p.parse(tokens) + + def test_cb(self): + """ Test callback of one rule and order or parameters """ + self.cb_called = False + def cb(a, c, b): + self.cb_called = True + self.assertEqual(a, 'a') + self.assertEqual(b, 'b') + self.assertEqual(c, 'c') + g = Grammar(['a', 'b', 'c']) + g.add_production('goal', ['a', 'c', 'b'], cb) + g.start_symbol = 'goal' + p = g.genParser() + tokens = genTokens(['a', 'c', 'b']) + p.parse(tokens) + self.assertTrue(self.cb_called) + + +class testExpressionGrammar(unittest.TestCase): + def setUp(self): + g = Grammar(['EOF', 'identifier', '(', ')', '+', '*', 'num']) + g.add_production('input', ['expression']) + g.add_production('expression', ['term']) + g.add_production('expression', ['expression', '+', 'term']) + g.add_production('term', ['factor']) + g.add_production('term', ['term', '*', 'factor']) + g.add_production('factor', ['(', 'expression', ')']) + g.add_production('factor', ['identifier']) + g.add_production('factor', ['num']) + g.start_symbol = 'input' + self.g = g + + def testFirstSimpleGrammar(self): + # 1. define a simple grammar: + first = self.g.calcFirstSets() + self.assertEqual(first['input'], {'identifier', '(', 'num'}) + self.assertEqual(first['term'], {'identifier', '(', 'num'}) + + def testCanonical(self): + s0 = self.g.initialItemSet() + s, gt = self.g.genCanonicalSet(s0) + # Must result in 12 sets: + self.assertEqual(len(s), 24) + +class testPG(unittest.TestCase): + """ Tests several parts of the parser generator """ + def setUp(self): + g = Grammar(['(', ')']) + g.add_production('goal', ['list']) + g.add_production('list', ['list', 'pair']) + g.add_production('list', ['pair']) + g.add_production('pair', ['(', 'pair', ')']) + g.add_production('pair', ['(', ')']) + g.start_symbol = 'goal' + self.g = g + + def testFirstSet(self): + for a in ['(', ')', EOF, 'EPS']: + self.assertEqual(self.g.first[a], {a}) + for nt in ['list', 'pair', 'goal']: + self.assertEqual(self.g.first[nt], {'('}) + + def testInitItemSet(self): + p0, p1, p2, p3, p4 = self.g.productions + s0 = self.g.initialItemSet() + self.assertEqual(len(s0), 9) # 9 with the goal rule included! + self.assertIn(Item(p0, 0, EOF), s0) + self.assertIn(Item(p1, 0, EOF), s0) + self.assertIn(Item(p1, 0, '('), s0) + self.assertIn(Item(p2, 0, EOF), s0) + self.assertIn(Item(p2, 0, '('), s0) + self.assertIn(Item(p3, 0, EOF), s0) + self.assertIn(Item(p3, 0, '('), s0) + self.assertIn(Item(p4, 0, EOF), s0) + self.assertIn(Item(p4, 0, '('), s0) + + def testCanonical(self): + s0 = self.g.initialItemSet() + s, gt = self.g.genCanonicalSet(s0) + # Must result in 12 sets: + self.assertEqual(len(s), 12) + + def testClosure(self): + p0, p1, p2, p3, p4 = self.g.productions + s0 = set() + s0.add(Item(p0, 0, EOF)) + self.assertEqual(len(s0), 1) # 1 rule + self.assertIn(Item(p0, 0, EOF), s0) + + # Invoke closure on set: + s0 = self.g.closure(s0) + self.assertIn(Item(p0, 0, EOF), s0) + self.assertIn(Item(p1, 0, EOF), s0) + self.assertIn(Item(p1, 0, '('), s0) + self.assertIn(Item(p2, 0, EOF), s0) + self.assertIn(Item(p2, 0, '('), s0) + self.assertIn(Item(p3, 0, EOF), s0) + self.assertIn(Item(p3, 0, '('), s0) + self.assertIn(Item(p4, 0, EOF), s0) + self.assertIn(Item(p4, 0, '('), s0) + + def testParser(self): + tokens = ['(', '(', ')', ')', '(', ')'] + # 3. build parser: + p = self.g.genParser() + self.assertEqual(len(p.goto_table), 5) + self.assertEqual(len(p.action_table), 19) + + # 4. feed input: + p.parse(genTokens(tokens)) + +if __name__ == '__main__': + unittest.main() + + diff -r c9781c73e7e2 -r 05184b95fa16 test/testregalloc.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testregalloc.py Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,61 @@ +import unittest +import os +import sys +from irmach import AbstractInstruction as makeIns, Frame +import registerallocator +import ir +from target import Nop + + +class RegAllocTestCase(unittest.TestCase): + def setUp(self): + self.ra = registerallocator.RegisterAllocator() + + def testRegAlloc(self): + f = Frame('tst') + f.regs = [1,2,3,4,5,6] # for test use numbers! + f.tempMap = {} + t1 = ir.Temp('t1') + t2 = ir.Temp('t2') + t3 = ir.Temp('t3') + t4 = ir.Temp('t4') + t5 = ir.Temp('t5') + f.instructions.append(makeIns(Nop, dst=[t1])) + f.instructions.append(makeIns(Nop, dst=[t2])) + f.instructions.append(makeIns(Nop, dst=[t3])) + f.instructions.append(makeIns(Nop, dst=[t4], src=[t1, t2])) + f.instructions.append(makeIns(Nop, dst=[t5], src=[t4, t3])) + f.instructions.append(makeIns(Nop, src=[t5])) + self.ra.allocFrame(f) + self.conflict(t1, t2) + self.conflict(t2, t3) + + def conflict(self, ta, tb): + self.assertNotEqual(self.ra.Node(ta).color, self.ra.Node(tb).color) + + def testRegCoalesc(self): + f = Frame('tst') + f.regs = [1,2,3,4,5,6] # for test use numbers! + f.tempMap = {} + t1 = ir.Temp('t1') + t2 = ir.Temp('t2') + t3 = ir.Temp('t3') + t4 = ir.Temp('t4') + t5 = ir.Temp('t5') + t6 = ir.Temp('t6') + f.instructions.append(makeIns(Nop, dst=[t1])) + f.instructions.append(makeIns(Nop, dst=[t2])) + f.instructions.append(makeIns(Nop, dst=[t3])) + f.instructions.append(makeIns(Nop, dst=[t4], src=[t2, t1])) + f.instructions.append(makeIns(Nop, dst=[t5], src=[t3])) + f.instructions.append(makeIns(Nop, dst=[t5], src=[t4, t5])) + f.instructions.append(makeIns(Nop, dst=[t6], src=[t5])) + f.instructions.append(makeIns(Nop, src=[t6])) + self.ra.allocFrame(f) + self.conflict(t1, t2) + self.conflict(t2, t3) + self.conflict(t1, t3) + +if __name__ == '__main__': + unittest.main() + diff -r c9781c73e7e2 -r 05184b95fa16 test/testx86asm.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testx86asm.py Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,130 @@ +#!/usr/bin/python + +import unittest + + +class AssemblerTestCase(unittest.TestCase): + """ + test methods start with 'test*' + Checks several assembly constructs agains their bytecodes + """ + def setUp(self): + self.skipTest('not implemented yet') + self.assembler = Assembler('x86-64') + + def tstAssembler(self): + """ Check all kind of assembler cases """ + assert(assembler.shortjump(5) == [0xeb, 0x5]) + assert(assembler.shortjump(-2) == [0xeb, 0xfc]) + assert(assembler.shortjump(10,'GE') == [0x7d, 0xa]) + assert(assembler.nearjump(5) == [0xe9, 0x5,0x0,0x0,0x0]) + assert(assembler.nearjump(-2) == [0xe9, 0xf9, 0xff,0xff,0xff]) + assert(assembler.nearjump(10,'LE') == [0x0f, 0x8e, 0xa,0x0,0x0,0x0]) + + def testCall(self): + assert(assembler.call('r10') == [0x41, 0xff, 0xd2]) + assert(assembler.call('rcx') == [0xff, 0xd1]) + def testXOR(self): + assert(assembler.xorreg64('rax', 'rax') == [0x48, 0x31, 0xc0]) + assert(assembler.xorreg64('r9', 'r8') == [0x4d, 0x31, 0xc1]) + assert(assembler.xorreg64('rbx', 'r11') == [0x4c, 0x31, 0xdb]) + + def testINC(self): + assert(assembler.increg64('r11') == [0x49, 0xff, 0xc3]) + assert(assembler.increg64('rcx') == [0x48, 0xff, 0xc1]) + + def testPush(self): + assert(assembler.push('rbp') == [0x55]) + assert(assembler.push('rbx') == [0x53]) + assert(assembler.push('r12') == [0x41, 0x54]) + def testPop(self): + assert(assembler.pop('rbx') == [0x5b]) + assert(assembler.pop('rbp') == [0x5d]) + assert(assembler.pop('r12') == [0x41, 0x5c]) + + def testAsmLoads(self): + # TODO constant add testcases + assert(assembler.mov('rbx', 'r14') == [0x4c, 0x89, 0xf3]) + assert(assembler.mov('r12', 'r8') == [0x4d, 0x89, 0xc4]) + assert(assembler.mov('rdi', 'rsp') == [0x48, 0x89, 0xe7]) + + def testAsmMemLoads(self): + assert(assembler.mov('rax', ['r8','r15',0x11]) == [0x4b,0x8b,0x44,0x38,0x11]) + assert(assembler.mov('r13', ['rbp','rcx',0x23]) == [0x4c,0x8b,0x6c,0xd,0x23]) + + assert(assembler.mov('r9', ['rbp',-0x33]) == [0x4c,0x8b,0x4d,0xcd]) + #assert(assembler.movreg64('rbx', ['rax']) == [0x48, 0x8b,0x18]) + + assert(assembler.mov('rax', [0xb000]) == [0x48,0x8b,0x4,0x25,0x0,0xb0,0x0,0x0]) + assert(assembler.mov('r11', [0xa0]) == [0x4c,0x8b,0x1c,0x25,0xa0,0x0,0x0,0x0]) + + assert(assembler.mov('r11', ['RIP', 0xf]) == [0x4c,0x8b,0x1d,0x0f,0x0,0x0,0x0]) + + def testAsmMemStores(self): + assert(assembler.mov(['rbp', 0x13],'rbx') == [0x48,0x89,0x5d,0x13]) + assert(assembler.mov(['r12', 0x12],'r9') == [0x4d,0x89,0x4c,0x24,0x12]) + assert(assembler.mov(['rcx', 0x11],'r14') == [0x4c,0x89,0x71,0x11]) + + + assert(assembler.mov([0xab], 'rbx') == [0x48,0x89,0x1c,0x25,0xab,0x0,0x0,0x0]) + assert(assembler.mov([0xcd], 'r13') == [0x4c,0x89,0x2c,0x25,0xcd,0x0,0x0,0x0]) + + assert(assembler.mov(['RIP', 0xf], 'r9') == [0x4c,0x89,0x0d,0x0f,0x0,0x0,0x0]) + + def testAsmMOV8(self): + assert(assembler.mov(['rbp', -8], 'al') == [0x88, 0x45, 0xf8]) + assert(assembler.mov(['r11', 9], 'cl') == [0x41, 0x88, 0x4b, 0x09]) + + assert(assembler.mov(['rbx'], 'al') == [0x88, 0x03]) + assert(assembler.mov(['r11'], 'dl') == [0x41, 0x88, 0x13]) + + def testAsmLea(self): + assert(assembler.leareg64('r11', ['RIP', 0xf]) == [0x4c,0x8d,0x1d,0x0f,0x0,0x0,0x0]) + assert(assembler.leareg64('rsi', ['RIP', 0x7]) == [0x48,0x8d,0x35,0x07,0x0,0x0,0x0]) + + assert(assembler.leareg64('rcx', ['rbp', -8]) == [0x48,0x8d,0x4d,0xf8]) + + def testAssemblerCMP(self): + assert(assembler.cmpreg64('rdi', 'r13') == [0x4c, 0x39, 0xef]) + assert(assembler.cmpreg64('rbx', 'r14') == [0x4c, 0x39, 0xf3]) + assert(assembler.cmpreg64('r12', 'r9') == [0x4d, 0x39, 0xcc]) + + assert(assembler.cmpreg64('rdi', 1) == [0x48, 0x83, 0xff, 0x01]) + assert(assembler.cmpreg64('r11', 2) == [0x49, 0x83, 0xfb, 0x02]) + def testAssemblerADD(self): + assert(assembler.addreg64('rbx', 'r13') == [0x4c, 0x01, 0xeb]) + assert(assembler.addreg64('rax', 'rbx') == [0x48, 0x01, 0xd8]) + assert(assembler.addreg64('r12', 'r13') == [0x4d, 0x01, 0xec]) + + assert(assembler.addreg64('rbx', 0x13) == [0x48, 0x83, 0xc3, 0x13]) + assert(assembler.addreg64('r11', 0x1234567) == [0x49, 0x81, 0xc3, 0x67, 0x45,0x23,0x1]) + assert(assembler.addreg64('rsp', 0x33) == [0x48, 0x83, 0xc4, 0x33]) + + def testAssemblerSUB(self): + assert(assembler.subreg64('rdx', 'r14') == [0x4c, 0x29, 0xf2]) + assert(assembler.subreg64('r15', 'rbx') == [0x49, 0x29, 0xdf]) + assert(assembler.subreg64('r8', 'r9') == [0x4d, 0x29, 0xc8]) + + assert(assembler.subreg64('rsp', 0x123456) == [0x48, 0x81, 0xec, 0x56,0x34,0x12,0x0]) + assert(assembler.subreg64('rsp', 0x12) == [0x48, 0x83, 0xec, 0x12]) + + def testAssemblerIDIV(self): + assert(assembler.idivreg64('r11') == [0x49, 0xf7, 0xfb]) + assert(assembler.idivreg64('rcx') == [0x48, 0xf7, 0xf9]) + assert(assembler.idivreg64('rsp') == [0x48, 0xf7, 0xfc]) + + def testAssemblerIMUL(self): + assert(assembler.imulreg64_rax('rdi') == [0x48, 0xf7, 0xef]) + assert(assembler.imulreg64_rax('r10') == [0x49, 0xf7, 0xea]) + assert(assembler.imulreg64_rax('rdx') == [0x48, 0xf7, 0xea]) + + assert(assembler.imulreg64('r11', 'rdi') == [0x4c, 0xf, 0xaf, 0xdf]) + assert(assembler.imulreg64('r12', 'rbx') == [0x4c, 0xf, 0xaf, 0xe3]) + # nasm generates this machine code: 0x4d, 0x6b, 0xff, 0xee + # This also works: 4D0FAFFE (another variant?? ) + assert(assembler.imulreg64('r15', 'r14') == [0x4d, 0x0f, 0xaf, 0xfe]) + + +if __name__ == '__main__': + unittest.main() + diff -r c9781c73e7e2 -r 05184b95fa16 test/testzcc.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testzcc.py Fri Nov 15 13:43:22 2013 +0100 @@ -0,0 +1,34 @@ +import unittest +import glob +import zcc +import outstream +import ppci + +class ZccTestCase(unittest.TestCase): + """ Tests the compiler driver """ + + def do(self, fn): + """ Compile blink.c3 """ + args = zcc.parser.parse_args([fn, '--package_dir', './c3examples']) + zcc.main(args) + + def testExamples(self): + """ Test all examples in the c3/examples directory """ + example_filenames = glob.glob('./c3examples/*.c3') + for filename in example_filenames: + self.do(filename) + + def testSectionAddress(self): + src = "module tst; function void t2() {var int t3; t3 = 2;}" + diag = ppci.DiagnosticsManager() + outs = outstream.TextOutputStream() + self.assertTrue(zcc.zcc(src, outs, diag)) + code = outs.getSection('code') + self.assertEqual(0x08000000, code.address) + data = outs.getSection('data') + self.assertEqual(0x20000000, data.address) + + +if __name__ == '__main__': + unittest.main() +