# HG changeset patch # User Windel Bouwman # Date 1375122193 -7200 # Node ID 6ed3d3a82a63902330a5fb21fcfe6d908e97914b # Parent f5fba5b554d7f526ae0705b58cd873a4a3242b3c Added another c3 example. First import attempt diff -r f5fba5b554d7 -r 6ed3d3a82a63 python/c3/analyse.py --- a/python/c3/analyse.py Sun Jul 28 19:07:51 2013 +0200 +++ b/python/c3/analyse.py Mon Jul 29 20:23:13 2013 +0200 @@ -12,13 +12,24 @@ def __init__(self, diag): self.diag = diag - def analyzePackage(self, pkg): + def analyzePackage(self, pkg, packageProvider): self.ok = True visitor = Visitor() # Prepare top level scope: self.scopeStack = [topScope] + modScope = Scope(self.CurrentScope) + self.scopeStack.append(modScope) visitor.visit(pkg, self.enterScope, self.quitScope) del self.scopeStack + + # Handle imports: + for i in pkg.imports: + ip = packageProvider.getPackage(i) + if not ip: + self.error('Cannot import {}'.format(i)) + continue + for x in ip.declarations: + modScope.addSymbol(x) visitor.visit(pkg, self.findRefs) visitor.visit(pkg, self.sanity) return self.ok @@ -28,31 +39,29 @@ self.diag.error(msg, loc) @property - def currentScope(self): + def CurrentScope(self): return self.scopeStack[-1] # Scope creation: def addSymbol(self, sym): - if self.currentScope.hasSymbol(sym.name): + if self.CurrentScope.hasSymbol(sym.name): self.error('Redefinition of {0}'.format(sym.name), sym.loc) else: - self.currentScope.addSymbol(sym) + self.CurrentScope.addSymbol(sym) def enterScope(self, sym): # Distribute the scope: - sym.scope = self.currentScope + sym.scope = self.CurrentScope # Add symbols to current scope: - if isinstance(sym, Symbol): - self.addSymbol(sym) - if isinstance(sym, DefinedType): + if isinstance(sym, Symbol) or isinstance(sym, DefinedType): self.addSymbol(sym) # Create subscope: if type(sym) in [Package, Function]: - newScope = Scope(self.currentScope) + newScope = Scope(self.CurrentScope) self.scopeStack.append(newScope) - sym.innerScope = self.currentScope + sym.innerScope = self.CurrentScope def quitScope(self, sym): # Pop out of scope: diff -r f5fba5b554d7 -r 6ed3d3a82a63 python/c3/astnodes.py --- a/python/c3/astnodes.py Sun Jul 28 19:07:51 2013 +0200 +++ b/python/c3/astnodes.py Mon Jul 29 20:23:13 2013 +0200 @@ -16,6 +16,7 @@ self.name = name self.loc = loc self.declarations = [] + self.imports = [] def __repr__(self): return 'PACKAGE {}'.format(self.name) diff -r f5fba5b554d7 -r 6ed3d3a82a63 python/c3/builder.py --- a/python/c3/builder.py Sun Jul 28 19:07:51 2013 +0200 +++ b/python/c3/builder.py Mon Jul 29 20:23:13 2013 +0200 @@ -1,6 +1,7 @@ import ppci from . import Parser, TypeChecker, Analyzer, CodeGenerator from . astprinter import AstPrinter +import glob class Builder: """ @@ -13,19 +14,43 @@ self.tc = TypeChecker(diag) self.al = Analyzer(diag) self.cg = CodeGenerator() - def build(self, src): - """ Create IR-code from sources """ + self.packages = {} + + def getPackage(self, pname): + """ package provider for use when analyzing """ + if pname in self.packages: + return self.packages[pname] + else: + # Try to lookup package from file + fns = glob.glob('./*/{}.c3'.format(pname)) + if fns: + with open(fns[0]) as f: + src = f.read() + self.build(src) + if pname in self.packages: + return self.packages[pname] + + def parse(self, src): pkg = self.parser.parseSource(src) if not pkg: return - self.pkg = pkg + # TODO: merge the two below? #AstPrinter().printAst(pkg) - if not self.al.analyzePackage(pkg): + if not self.al.analyzePackage(pkg, self): return if not self.tc.checkPackage(pkg): return + # Store for later use: + self.packages[pkg.name] = pkg + return pkg + + def build(self, src): + """ Create IR-code from sources """ + pkg = self.parse(src) + # Only return ircode when everything is OK - return self.cg.gencode(pkg) + if pkg: + return self.cg.gencode(pkg) diff -r f5fba5b554d7 -r 6ed3d3a82a63 python/c3/examples/functions.c3 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/c3/examples/functions.c3 Mon Jul 29 20:23:13 2013 +0200 @@ -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 f5fba5b554d7 -r 6ed3d3a82a63 python/c3/parser.py --- a/python/c3/parser.py Sun Jul 28 19:07:51 2013 +0200 +++ b/python/c3/parser.py Mon Jul 29 20:23:13 2013 +0200 @@ -51,9 +51,11 @@ def addDeclaration(self, decl): self.currentPart.declarations.append(decl) - def parseUses(self): - # TODO: parse uses - pass + def parseImport(self): + self.Consume('import') + name = self.Consume('ID').val + self.mod.imports.append(name) + self.Consume(';') def parsePackage(self): self.Consume('package') @@ -61,22 +63,23 @@ self.Consume(';') self.mod = astnodes.Package(name.val, name.loc) self.currentPart = self.mod - self.parseUses() while self.Peak != 'END': self.parseTopLevel() self.Consume('END') def parseTopLevel(self): - if self.Peak == 'function': - self.parseFunctionDef() - elif self.Peak == 'var': - self.parseVarDef() - elif self.Peak == 'const': - self.parseConstDef() - elif self.Peak == 'type': - self.parseTypeDef() - else: - self.Error('Expected function, var, const or type') + if self.Peak == 'function': + self.parseFunctionDef() + elif self.Peak == 'var': + self.parseVarDef() + elif self.Peak == 'const': + self.parseConstDef() + elif self.Peak == 'type': + self.parseTypeDef() + elif self.Peak == 'import': + self.parseImport() + else: + self.Error('Expected function, var, const or type') def parseDesignator(self): """ A designator designates an object """ diff -r f5fba5b554d7 -r 6ed3d3a82a63 python/cortexm3.py --- a/python/cortexm3.py Sun Jul 28 19:07:51 2013 +0200 +++ b/python/cortexm3.py Mon Jul 29 20:23:13 2013 +0200 @@ -487,6 +487,20 @@ h = (0b11100 << 11) | imm11 # | 1 # 1 to enable thumb mode return u16(h) +@armtarget.instruction +class bl_ins(jumpBase_ins): + mnemonic = 'BL' + def encode(self): + imm32 = wrap_negative(self.offset >> 1, 32) + imm11 = imm32 & 0x7FF + imm10 = (imm32 >> 11) & 0x3FF + j1 = 1 # TODO: what do these mean? + j2 = 1 + s = (imm32 >> 24) & 0x1 + h1 = (0b11110 << 11) | (s << 10) | imm10 + h2 = (0b1101 << 12) | (j1 << 13) | (j2 << 11) | imm11 + return u16(h1) + u16(h2) + class cond_base_ins(jumpBase_ins): def encode(self): imm8 = wrap_negative(self.offset >> 1, 8) diff -r f5fba5b554d7 -r 6ed3d3a82a63 python/hexfile.py --- a/python/hexfile.py Sun Jul 28 19:07:51 2013 +0200 +++ b/python/hexfile.py Mon Jul 29 20:23:13 2013 +0200 @@ -102,10 +102,6 @@ def check(self): self.regions.sort(key=lambda r: r.address) - if len(self.regions) > 1: - for r1, r2 in zip(self.regions[:-1], self.regions[1:]): - if r1.EndAddress > r2.address: - raise HexFileException('Overlapping regions') change = True while change and len(self.regions) > 1: change = False @@ -114,6 +110,8 @@ r1.addData(r2.data) self.regions.remove(r2) change = True + elif r1.EndAddress > r2.address: + raise HexFileException('Overlapping regions') def merge(self, other): for r in other.regions: diff -r f5fba5b554d7 -r 6ed3d3a82a63 python/ide.py --- a/python/ide.py Sun Jul 28 19:07:51 2013 +0200 +++ b/python/ide.py Mon Jul 29 20:23:13 2013 +0200 @@ -257,15 +257,14 @@ return self.diag.clear() self.buildOutput.append('Starting parse') - ir = self.c3front.build(ce.Source) + pkg = self.c3front.parse(ce.Source) # Set errors: for err in self.diag.diags: self.buildOutput.append(str(err)) self.builderrors.setErrorList(self.diag.diags) ce.setErrors(self.diag.diags) - ast = self.c3front.pkg - self.astViewer.setAst(ast) + self.astViewer.setAst(pkg) self.buildOutput.append("Done!") def buildFile(self): diff -r f5fba5b554d7 -r 6ed3d3a82a63 python/ppci/errors.py --- a/python/ppci/errors.py Sun Jul 28 19:07:51 2013 +0200 +++ b/python/ppci/errors.py Mon Jul 29 20:23:13 2013 +0200 @@ -14,7 +14,7 @@ self.row = loc.row self.col = loc.col else: - self.row = self.col = None + self.row = self.col = 0 def __repr__(self): if self.row: @@ -23,11 +23,11 @@ return 'Compilererror: "{0}"'.format(self.msg) def printError(source, e): - def printLine(row, txt): + def printLine(row, txt): print(str(row)+':'+txt) - if e.loc.row == 0: - print('Error: {0}'.format(e.msg)) - else: + if e.row == 0: + print('Error: {0}'.format(e.msg)) + else: lines = source.split('\n') ro, co = e.row, e.col prerow = ro - 2 diff -r f5fba5b554d7 -r 6ed3d3a82a63 python/stm32f4/blink.c3 --- a/python/stm32f4/blink.c3 Sun Jul 28 19:07:51 2013 +0200 +++ b/python/stm32f4/blink.c3 Mon Jul 29 20:23:13 2013 +0200 @@ -6,34 +6,7 @@ package blink; -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; - +import stm32f4xx; // Functions: function void main() diff -r f5fba5b554d7 -r 6ed3d3a82a63 python/stm32f4/burn.c3 --- a/python/stm32f4/burn.c3 Sun Jul 28 19:07:51 2013 +0200 +++ b/python/stm32f4/burn.c3 Mon Jul 29 20:23:13 2013 +0200 @@ -6,48 +6,25 @@ */ -package blink; +package burn; -type struct { - int MODER; - int OTYPER; - int OSPEEDR; - int PUPDR; - int IDR; - int ODR; -}* GPIO_Type; +import stm32f4xx; -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; +function void init() +{ +} - -// Functions: function void main() { - // Memory mapped control registers: - var GPIO_Type GPIOD; - GPIOD = cast(0x40020C00); + //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; diff -r f5fba5b554d7 -r 6ed3d3a82a63 python/stm32f4/stm32f4xx.c3 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/stm32f4/stm32f4xx.c3 Mon Jul 29 20:23:13 2013 +0200 @@ -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 f5fba5b554d7 -r 6ed3d3a82a63 python/testasm.py --- a/python/testasm.py Sun Jul 28 19:07:51 2013 +0200 +++ b/python/testasm.py Mon Jul 29 20:23:13 2013 +0200 @@ -243,6 +243,14 @@ 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') diff -r f5fba5b554d7 -r 6ed3d3a82a63 python/testc3.py --- a/python/testc3.py Sun Jul 28 19:07:51 2013 +0200 +++ b/python/testc3.py Mon Jul 29 20:23:13 2013 +0200 @@ -122,6 +122,17 @@ self.assertSequenceEqual(expected_ins, actual_ins) return ircode + def testPackage(self): + p1 = """package p1; + type int A; + """ + p2 = """package p2; + import p1; + var A b; + """ + self.assertTrue(self.builder.build(p1)) + self.expectOK(p2) + def testFunctArgs(self): snippet = """ package testargs; diff -r f5fba5b554d7 -r 6ed3d3a82a63 python/testhexfile.py --- a/python/testhexfile.py Sun Jul 28 19:07:51 2013 +0200 +++ b/python/testhexfile.py Mon Jul 29 20:23:13 2013 +0200 @@ -30,12 +30,12 @@ def testSave4(self): hf = HexFile() - hf.addRegion(0xF000, bytes.fromhex('ab')*0x20000) + hf.addRegion(0xF000, bytes.fromhex('ab')*0x10000) self.saveload(hf) def testSave5(self): hf = HexFile() - hf.addRegion(0xF003, bytes.fromhex('ab')*0x20000) + hf.addRegion(0xF003, bytes.fromhex('ab')*0x10000) self.saveload(hf) def testMerge(self):