# HG changeset patch # User Windel Bouwman # Date 1373521350 -7200 # Node ID 1c7364bd74c7fa360ab36d0b354e898461e8cc18 # Parent 5af52987f5bd96288d92e90bc764416db43a4a0b Fixed pointer deref diff -r 5af52987f5bd -r 1c7364bd74c7 python/asmnodes.py --- a/python/asmnodes.py Tue Jul 09 17:59:15 2013 +0200 +++ b/python/asmnodes.py Thu Jul 11 07:42:30 2013 +0200 @@ -11,6 +11,12 @@ def __repr__(self): return '{0}:'.format(self.name) +class AComment(ANode): + def __init__(self, name): + self.txt = name + def __repr__(self): + return '; {}'.format(self.txt) + class AInstruction(ANode): def __init__(self, mnemonic, operands): self.mnemonic = mnemonic diff -r 5af52987f5bd -r 1c7364bd74c7 python/c3/analyse.py --- a/python/c3/analyse.py Tue Jul 09 17:59:15 2013 +0200 +++ b/python/c3/analyse.py Thu Jul 11 07:42:30 2013 +0200 @@ -44,6 +44,8 @@ # Add symbols to current scope: if isinstance(sym, Symbol): self.addSymbol(sym) + if isinstance(sym, DefinedType): + self.addSymbol(sym) # Create subscope: if type(sym) in [Package, Function]: @@ -78,8 +80,11 @@ return t elif type(t) is Designator: return self.resolveDesignator(t, scope) + elif isinstance(t, Type): + # Already resolved?? + return t else: - print('ERR resolve type!') + raise Exception('Error resolving type {} {}'.format(t, type(t))) def findRefs(self, sym): if type(sym) in [Variable, Constant]: diff -r 5af52987f5bd -r 1c7364bd74c7 python/c3/astnodes.py --- a/python/c3/astnodes.py Tue Jul 09 17:59:15 2013 +0200 +++ b/python/c3/astnodes.py Thu Jul 11 07:42:30 2013 +0200 @@ -59,6 +59,7 @@ class PointerType(Type): def __init__(self, ptype): + assert isinstance(ptype, Type) or isinstance(ptype, Designator) self.ptype = ptype def __repr__(self): return '({}*)'.format(self.ptype) @@ -66,13 +67,26 @@ class StructureType(Type): def __init__(self, mems): self.mems = mems + def hasField(self, name): + for fn, ft in self.mems: + if name == fn: + return True + return False + def fieldType(self, name): + for fn, ft in self.mems: + if name == fn: + return ft + raise Exception() + class DefinedType(Type): - def __init__(self, name, typ): - self.name = name - self.typ = typ - def __repr__(self): - return 'Named type {0} of type {1}'.format(self.name, self.typ) + def __init__(self, name, typ, loc): + assert isinstance(name, str) + self.name = name + self.typ = typ + self.loc = loc + def __repr__(self): + return 'Named type {0} of type {1}'.format(self.name, self.typ) class TypeCast(Node): def __init__(self, to_type, x): @@ -109,7 +123,7 @@ self.isReadOnly = False self.isParameter = False def __repr__(self): - return 'Var {}'.format(self.name) + return 'Var {} [{}]'.format(self.name, self.typ) # Procedure types class Function(Symbol): @@ -126,6 +140,24 @@ class Expression(Node): pass +class Deref(Expression): + def __init__(self, ptr, loc): + assert isinstance(ptr, Expression) + self.ptr = ptr + self.loc = loc + def __repr__(self): + return 'DEREF {}'.format(self.ptr) + +class FieldRef(Expression): + def __init__(self, base, field, loc): + assert isinstance(base, Expression) + assert isinstance(field, str) + self.base = base + self.field = field + self.loc = loc + def __repr__(self): + return 'FIELD {}.{}'.format(self.base, self.field) + class Unop(Expression): def __init__(self, op, a, loc): assert isinstance(a, Expression) diff -r 5af52987f5bd -r 1c7364bd74c7 python/c3/builder.py --- a/python/c3/builder.py Tue Jul 09 17:59:15 2013 +0200 +++ b/python/c3/builder.py Thu Jul 11 07:42:30 2013 +0200 @@ -1,5 +1,6 @@ import ppci from . import Parser, TypeChecker, Analyzer, CodeGenerator +from . astprinter import AstPrinter class Builder: """ @@ -19,6 +20,7 @@ return self.pkg = pkg # TODO: merge the two below? + #AstPrinter().printAst(pkg) if not self.al.analyzePackage(pkg): return if not self.tc.checkPackage(pkg): diff -r 5af52987f5bd -r 1c7364bd74c7 python/c3/codegenerator.py --- a/python/c3/codegenerator.py Tue Jul 09 17:59:15 2013 +0200 +++ b/python/c3/codegenerator.py Thu Jul 11 07:42:30 2013 +0200 @@ -124,7 +124,7 @@ else: print('Unknown cond', expr) def genExprCode(self, expr): - if type(expr) is astnodes.Binop: + if type(expr) is astnodes.Binop: ra = self.genExprCode(expr.a) rb = self.genExprCode(expr.b) ops = ['+', '-', '*', '/', '|', '&'] @@ -140,37 +140,38 @@ tmp = self.builder.newTmp() # TODO return tmp - elif type(expr) is astnodes.Unop: - ra = self.genExprCode(expr.a) - if expr.op == '&': - # Address of operator - tmp = self.builder.newTmp('addr') + elif type(expr) is astnodes.Unop: + ra = self.genExprCode(expr.a) + if expr.op == '&': + # Address of operator + tmp = self.builder.newTmp('addr') + return tmp + #self.builder.addIns(ins) + else: + raise Exception('Unknown {0}'.format(expr)) + elif type(expr) is astnodes.Constant: + tmp = self.builder.newTmp() + # TODO return tmp - #self.builder.addIns(ins) - elif expr.op == '*': + elif type(expr) is astnodes.VariableUse: + tmp = self.builder.newTmp() + loc = self.varMap[expr.target] + i = ir.Load(loc, tmp) + self.builder.addIns(i) + return tmp + elif type(expr) is astnodes.Deref: # dereference pointer type: + addr = self.genExprCode(expr.ptr) tmp = self.builder.newTmp('deref') - ins = ir.Load(ra, tmp) + ins = ir.Load(addr, tmp) self.builder.addIns(ins) return tmp - else: - print('Unknown {0}'.format(expr)) - elif type(expr) is astnodes.Constant: - tmp = self.builder.newTmp() - # TODO - return tmp - elif type(expr) is astnodes.VariableUse: - tmp = self.builder.newTmp() - loc = self.varMap[expr.target] - i = ir.Load(loc, tmp) - self.builder.addIns(i) - return tmp - elif type(expr) is astnodes.Literal: - tmp = self.builder.newTmp() - ins = ir.ImmLoad(tmp, expr.val) - self.builder.addIns(ins) - return tmp - elif type(expr) is astnodes.TypeCast: + elif type(expr) is astnodes.Literal: + tmp = self.builder.newTmp() + ins = ir.ImmLoad(tmp, expr.val) + self.builder.addIns(ins) + return tmp + elif type(expr) is astnodes.TypeCast: ar = self.genExprCode(expr.a) if isinstance(expr.to_type, astnodes.PointerType): if expr.a.typ is intType: @@ -179,7 +180,7 @@ return ar else: raise Exception() - elif type(expr) is astnodes.FunctionCall: + elif type(expr) is astnodes.FunctionCall: tmp = self.builder.newTmp("res") args = [] for arg in expr.args: @@ -189,6 +190,6 @@ ins = ir.Call(fn, args, tmp) self.builder.addIns(ins) return tmp - else: + else: raise CompilerError('Unknown expr {}'.format(expr)) diff -r 5af52987f5bd -r 1c7364bd74c7 python/c3/lexer.py --- a/python/c3/lexer.py Tue Jul 09 17:59:15 2013 +0200 +++ b/python/c3/lexer.py Thu Jul 11 07:42:30 2013 +0200 @@ -29,7 +29,7 @@ ('COMMENTS', r'//.*'), ('LONGCOMMENTBEGIN', r'\/\*'), ('LONGCOMMENTEND', r'\*\/'), - ('LEESTEKEN', r'==|[\.,=:;\-+*\[\]/\(\)]|>=|<=|<>|>|<|{|}|&|\^|\|'), + ('LEESTEKEN', r'==|->|[\.,=:;\-+*\[\]/\(\)]|>=|<=|<>|>|<|{|}|&|\^|\|'), ('STRING', r"'.*?'") ] tok_re = '|'.join('(?P<%s>%s)' % pair for pair in tok_spec) diff -r 5af52987f5bd -r 1c7364bd74c7 python/c3/parser.py --- a/python/c3/parser.py Tue Jul 09 17:59:15 2013 +0200 +++ b/python/c3/parser.py Thu Jul 11 07:42:30 2013 +0200 @@ -75,10 +75,9 @@ self.Error('Expected function, var, const or type') def parseDesignator(self): - """ A designator designates an object """ - name = self.Consume('ID') - d = astnodes.Designator(name.val, name.loc) - return d + """ A designator designates an object """ + name = self.Consume('ID') + return astnodes.Designator(name.val, name.loc) # Type system def parseTypeSpec(self): @@ -109,9 +108,9 @@ self.Consume('type') newtype = self.parseTypeSpec() typename = self.Consume('ID') - # TODO: action here :) self.Consume(';') - return astnodes.DefinedType(typename, newtype) + df = astnodes.DefinedType(typename.val, newtype, typename.loc) + self.addDeclaration(df) # Variable declarations: def parseVarDef(self): @@ -319,7 +318,10 @@ if self.Peak in ['&', '*']: op = self.Consume(self.Peak) ce = self.CastExpression() - return astnodes.Unop(op.typ, ce, op.loc) + if op.val == '*': + return astnodes.Deref(ce, op.loc) + else: + return astnodes.Unop(op.typ, ce, op.loc) else: return self.PostFixExpression() @@ -337,8 +339,15 @@ args.append(self.Expression()) self.Consume(')') pfe = astnodes.FunctionCall(pfe, args, pfe.loc) + elif self.hasConsumed('->'): + field = self.Consume('ID') + pfe = astnodes.Deref(pfe, pfe.loc) + pfe = astnodes.FieldRef(pfe, field.val, field.loc) + elif self.hasConsumed('.'): + field = self.Consume('ID') + pfe = astnodes.FieldRef(pfe, field.val, field.loc) else: - rrrr + raise Exception() return pfe def PrimaryExpression(self): diff -r 5af52987f5bd -r 1c7364bd74c7 python/c3/typecheck.py --- a/python/c3/typecheck.py Tue Jul 09 17:59:15 2013 +0200 +++ b/python/c3/typecheck.py Thu Jul 11 07:42:30 2013 +0200 @@ -34,19 +34,19 @@ return self.ok def check2(self, sym): - if type(sym) in [IfStatement, WhileStatement]: - if not equalTypes(sym.condition.typ, boolType): - self.error('Condition must be of type {0}'.format(boolType), sym.condition.loc) - elif type(sym) is Assignment: + if type(sym) in [IfStatement, WhileStatement]: + if not equalTypes(sym.condition.typ, boolType): + self.error('Condition must be of type {0}'.format(boolType), sym.condition.loc) + elif type(sym) is Assignment: if not equalTypes(sym.lval.typ, sym.rval.typ): self.error('Cannot assign {0} to {1}'.format(sym.rval.typ, sym.lval.typ), sym.loc) if not sym.lval.lvalue: self.error('No valid lvalue {}'.format(sym.lval), sym.lval.loc) #if sym.rval.lvalue: # self.error('Right hand side must be an rvalue', sym.rval.loc) - elif type(sym) is ReturnStatement: - pass - elif type(sym) is FunctionCall: + elif type(sym) is ReturnStatement: + pass + elif type(sym) is FunctionCall: if sym.proc: # Check arguments: ngiv = len(sym.args) @@ -62,13 +62,14 @@ sym.typ = sym.proc.typ.returntype else: sym.typ = intType - elif type(sym) is VariableUse: + elif type(sym) is VariableUse: sym.lvalue = True - if sym.target: + if type(sym.target) is Variable: sym.typ = sym.target.typ else: + print('warning {} has no target, defaulting to int'.format(sym)) sym.typ = intType - elif type(sym) is Literal: + elif type(sym) is Literal: sym.lvalue = False if type(sym.val) is int: sym.typ = intType @@ -77,22 +78,35 @@ elif type(sym.val) is bool: sym.typ = boolType else: - self.error('Unknown literal type', sym.loc) - elif type(sym) is Unop: + raise Exception('Unknown literal type'.format(sym.val)) + elif type(sym) is Unop: if sym.op == '&': sym.typ = PointerType(sym.a.typ) sym.lvalue = False - elif sym.op == '*': - # pointer deref - sym.lvalue = True - if type(sym.a.typ) is PointerType: - sym.typ = sym.a.typ.ptype + else: + raise Exception('Unknown unop {0}'.format(sym.op)) + elif type(sym) is Deref: + # pointer deref + sym.lvalue = True + # check if the to be dereferenced variable is a pointer type: + if type(sym.ptr.typ) is PointerType: + sym.typ = sym.ptr.typ.ptype + else: + self.error('Cannot dereference non-pointer type {}'.format(sym.ptr.typ), sym.loc) + sym.typ = intType + elif type(sym) is FieldRef: + basetype = sym.base.typ + sym.lvalue = True + if type(basetype) is StructureType: + if basetype.hasField(sym.field): + sym.typ = basetype.fieldType(sym.field) else: + self.error('{} does not contain field {}'.format(basetype, symfield), sym.loc) sym.typ = intType - self.error('Cannot dereference non-pointer type {}'.format(sym.a.typ), sym.loc) else: - print('unknown unop', sym.op) - elif type(sym) is Binop: + self.error('Cannot select field {} of non-structure type {}'.format(sym.field, basetype), sym.loc) + sym.typ = intType + elif type(sym) is Binop: sym.lvalue = False if sym.op in ['+', '-', '*', '/']: if equalTypes(sym.a.typ, sym.b.typ): @@ -104,11 +118,11 @@ else: # assume void here? TODO: throw exception! sym.typ = intType - self.error('Types unequal', sym.loc) + self.error('Types unequal {} != {}'.format(sym.a.typ, sym.b.typ), sym.loc) elif sym.op in ['>', '<', '==', '<=', '>=']: sym.typ = boolType if not equalTypes(sym.a.typ, sym.b.typ): - self.error('Types unequal', sym.loc) + self.error('Types unequal {} != {}'.format(sym.a.typ, sym.b.typ), sym.loc) elif sym.op in ['or', 'and']: sym.typ = boolType if not equalTypes(sym.a.typ, boolType): @@ -117,24 +131,24 @@ self.error('Must be {0}'.format(boolType), sym.b.loc) elif sym.op in ['|', '&']: sym.typ = intType + raise Exception('Not implemented') # TODO: elaborate? else: - sym.typ = voidType - print('unknown binop', sym.op) - elif type(sym) is Variable: + raise Exception('Unknown binop {0}'.format(sym.op)) + elif type(sym) is Variable: # check initial value type: # TODO pass - elif type(sym) is TypeCast: + elif type(sym) is TypeCast: if canCast(sym.a.typ, sym.to_type): sym.typ = sym.to_type else: self.error('Cannot cast {} to {}'.format(sym.a.typ, sym.to_type)) - elif type(sym) is Constant: - if not equalTypes(sym.typ, sym.value.typ): - self.error('Cannot assign {0} to {1}'.format(sym.value.typ, sym.typ), sym.loc) - elif type(sym) in [EmptyStatement, CompoundStatement, Package, Function, FunctionType, ExpressionStatement]: + elif type(sym) is Constant: + if not equalTypes(sym.typ, sym.value.typ): + self.error('Cannot assign {0} to {1}'.format(sym.value.typ, sym.typ), sym.loc) + elif type(sym) in [EmptyStatement, CompoundStatement, Package, Function, FunctionType, ExpressionStatement, DefinedType]: pass - else: + else: raise Exception('Unknown type check {0}'.format(sym)) diff -r 5af52987f5bd -r 1c7364bd74c7 python/c3/visitor.py --- a/python/c3/visitor.py Tue Jul 09 17:59:15 2013 +0200 +++ b/python/c3/visitor.py Thu Jul 11 07:42:30 2013 +0200 @@ -47,9 +47,13 @@ self.do(node.ex) elif type(node) is TypeCast: self.do(node.a) + elif type(node) is FieldRef: + self.do(node.base) + elif type(node) is Deref: + self.do(node.ptr) elif type(node) is Constant: self.do(node.value) - elif type(node) in [EmptyStatement, VariableUse, Variable, Literal, FunctionType]: + elif type(node) in [EmptyStatement, VariableUse, Variable, Literal, FunctionType, DefinedType]: # Those nodes do not have child nodes. pass elif type(node) is WhileStatement: diff -r 5af52987f5bd -r 1c7364bd74c7 python/codegenarm.py --- a/python/codegenarm.py Tue Jul 09 17:59:15 2013 +0200 +++ b/python/codegenarm.py Thu Jul 11 07:42:30 2013 +0200 @@ -1,5 +1,5 @@ import ir -from asmnodes import ALabel +from asmnodes import ALabel, AComment import cortexm3 as arm from ppci import CompilerError @@ -47,6 +47,7 @@ self.emit(arm.dcd_ins(v)) self.outs.align(4) + # Helper functions: def getStack(self, v): off = self.stack_frame.index(v) return off * 4 @@ -56,43 +57,53 @@ def getGlobal(self, r, g): _global_address = g.name + '__global' self.emit(arm.ldr_pcrel(r, ALabel(_global_address))) + def loadStack(self, reg, val): + self.emit(arm.ldr_sprel(reg, arm.MemSpRel(self.getStack(val)))) + def comment(self, txt): + self.emit(AComment(txt)) def generateInstruction(self, ins): if type(ins) is ir.Branch: tgt = ALabel(ins.target.name) self.emit(arm.jmp_ins(tgt)) elif type(ins) is ir.ImmLoad: + self.comment(str(ins)) lname = ins.target.name + '_ivalue' self.emit(arm.ldr_pcrel(arm.r0, ALabel(lname))) self.imms.append((lname, ins.value)) - self.emit(arm.str_sprel(arm.r0, arm.MemoryOp(arm.sp, self.addStack(ins.target)))) + self.emit(arm.str_sprel(arm.r0, arm.MemSpRel(self.addStack(ins.target)))) elif type(ins) is ir.Store: + self.comment(str(ins)) # Load value in r0: - self.emit(arm.ldr_sprel(arm.r0, arm.MemoryOp(arm.sp, self.getStack(ins.value)))) + self.loadStack(arm.r0, ins.value) # store in memory: self.getGlobal(arm.r1, ins.location) - self.emit(arm.storeimm5_ins(arm.r0, arm.MemoryOp(arm.r1, 0))) + self.emit(arm.storeimm5_ins(arm.r0, arm.MemR8Rel(arm.r1, 0))) elif type(ins) is ir.Load: + self.comment(str(ins)) self.getGlobal(arm.r0, ins.location) - self.emit(arm.loadimm5_ins(arm.r0, arm.MemoryOp(arm.r0, 0))) + self.emit(arm.loadimm5_ins(arm.r0, arm.MemR8Rel(arm.r0, 0))) # Store value on stack: - self.emit(arm.str_sprel(arm.r0, arm.MemoryOp(arm.sp, self.addStack(ins.value)))) + self.emit(arm.str_sprel(arm.r0, arm.MemSpRel(self.addStack(ins.value)))) elif type(ins) is ir.BinaryOperator: + self.comment(str(ins)) # Load operands: - self.emit(arm.ldr_sprel(arm.r0, arm.MemoryOp(arm.sp, self.getStack(ins.value1)))) - self.emit(arm.ldr_sprel(arm.r1, arm.MemoryOp(arm.sp, self.getStack(ins.value2)))) + self.loadStack(arm.r0, ins.value1) + self.loadStack(arm.r1, ins.value2) # do operation: if ins.operation == '+': self.emit(arm.addregs_ins(arm.r0, arm.r0, arm.r1)) else: print('operation not implemented', ins.operation) # Store value back: - self.emit(arm.str_sprel(arm.r0, arm.MemoryOp(arm.sp, self.addStack(ins.result)))) + self.emit(arm.str_sprel(arm.r0, arm.MemSpRel(self.addStack(ins.result)))) elif type(ins) is ir.Return: + self.comment(str(ins)) self.emit(arm.pop_ins(arm.RegisterSet({arm.r4, arm.r5, arm.r6, arm.r7, arm.pc}))) elif type(ins) is ir.ConditionalBranch: - self.emit(arm.ldr_sprel(arm.r0, arm.MemoryOp(arm.sp, self.getStack(ins.a)))) - self.emit(arm.ldr_sprel(arm.r1, arm.MemoryOp(arm.sp, self.getStack(ins.b)))) + self.comment(str(ins)) + self.loadStack(arm.r0, ins.a) + self.loadStack(arm.r1, ins.b) self.emit(arm.cmp_ins(arm.r1, arm.r0)) tgt_yes = ALabel(ins.lab1.name) if ins.cond == '==': diff -r 5af52987f5bd -r 1c7364bd74c7 python/cortexm3.py --- a/python/cortexm3.py Tue Jul 09 17:59:15 2013 +0200 +++ b/python/cortexm3.py Thu Jul 11 07:42:30 2013 +0200 @@ -101,7 +101,7 @@ class MemPcRel(MemRegXRel): regname = 'PC' -class MemoryOpReg8Imm5: +class MemR8Rel: def __init__(self, basereg, offset): assert type(basereg) is ArmReg self.basereg = basereg @@ -212,19 +212,19 @@ class LS_imm5_base(ArmInstruction): """ ??? Rt, [Rn, imm5] """ - operands = (Reg8Op, MemoryOpReg8Imm5) + operands = (Reg8Op, MemR8Rel) def __init__(self, rt, memop): assert memop.offset % 4 == 0 self.imm5 = memop.offset >> 2 self.rn = memop.basereg.num - self.rt = rt.num + self.rt = rt self.memloc = memop assert self.rn < 8 - assert self.rt < 8 + assert self.rt.num < 8 def encode(self): Rn = self.rn - Rt = self.rt + Rt = self.rt.num imm5 = self.imm5 h = (self.opcode << 11) | (imm5 << 6) | (Rn << 3) | Rt @@ -252,7 +252,6 @@ rt = self.rt.num assert rt < 8 imm8 = self.offset >> 2 - print(imm8) assert imm8 < 256 h = (self.opcode << 8) | (rt << 8) | imm8 return u16(h) diff -r 5af52987f5bd -r 1c7364bd74c7 python/outstream.py --- a/python/outstream.py Tue Jul 09 17:59:15 2013 +0200 +++ b/python/outstream.py Thu Jul 11 07:42:30 2013 +0200 @@ -1,5 +1,5 @@ import binascii -from asmnodes import ALabel +from asmnodes import ALabel, AComment """ The output stream is a stream of instructions that can be output to a file or binary or hexfile. @@ -13,6 +13,7 @@ def __init__(self): self.sections = {} self.currentSection = None + def emit(self, item): self.sections[self.currentSection].append(item) @@ -36,7 +37,7 @@ address = 0x0 for i in self.sections[s]: i.address = address - if type(i) is ALabel: + if type(i) in [ALabel, AComment]: continue if type(i) is Alignment: while (address % i.align) != 0: @@ -53,7 +54,7 @@ def dumpSection(self, s): print('.section '+s) for i in self.sections[s]: - if type(i) is ALabel: + if type(i) in [ALabel, AComment]: print(i) elif type(i) is Alignment: pass diff -r 5af52987f5bd -r 1c7364bd74c7 python/ppci/errors.py --- a/python/ppci/errors.py Tue Jul 09 17:59:15 2013 +0200 +++ b/python/ppci/errors.py Thu Jul 11 07:42:30 2013 +0200 @@ -48,21 +48,24 @@ printLine(r, lines[r-1]) class DiagnosticsManager: - def __init__(self): + def __init__(self): self.diags = [] - def addDiag(self, d): + def addDiag(self, d): self.diags.append(d) - def error(self, msg, loc): + def error(self, msg, loc): self.addDiag(CompilerError(msg, loc)) - def clear(self): + def clear(self): del self.diags[:] - def printErrors(self, src): - if len(self.diags) > 0: - print('{0} Errors'.format(len(self.diags))) - for d in self.diags: - printError(src, d) + def printErrors(self, src): + if len(self.diags) > 0: + print('==============') + print('{0} Errors'.format(len(self.diags))) + for d in self.diags: + print('==============') + printError(src, d) + print('==============') diff -r 5af52987f5bd -r 1c7364bd74c7 python/testc3.py --- a/python/testc3.py Tue Jul 09 17:59:15 2013 +0200 +++ b/python/testc3.py Thu Jul 11 07:42:30 2013 +0200 @@ -205,14 +205,43 @@ } """ 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 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; + var int* pa, pb; function void t(int a, double b) { pa = &a; + pb = pa; *pa = 22; } """ @@ -234,7 +263,6 @@ """ self.expectErrors(snippet, [6, 9, 9, 10, 11]) - @unittest.skip def testComplexType(self): snippet = """ package testpointer; @@ -251,16 +279,21 @@ } my_struct; type my_struct* my_sptr; + var int* pa; function void t(int a, double b, my_sptr x) { var my_struct *msp; + var my_struct u, v; + var point *pt; + + pt = &msp->P1; msp = x; - *pa = 22; + *pa = 22 + u.mem1 * v.memb2 - u.P1.x; x->memb2 = *pa + a * b; - mxp->P1.x = a * x->P1.y; + msp->P1.x = a * x->P1.y; } """ self.expectOK(snippet) diff -r 5af52987f5bd -r 1c7364bd74c7 python/transform.py --- a/python/transform.py Tue Jul 09 17:59:15 2013 +0200 +++ b/python/transform.py Thu Jul 11 07:42:30 2013 +0200 @@ -89,15 +89,12 @@ # find predecessors of this block and replace this block reference with the jumped reference. ins = bb.LastInstruction if type(ins) is Branch: - print('Removing block {}'.format(bb)) - #print(ins, bb.Predecessors) preds = bb.Predecessors if bb in preds: # Do not remove if preceeded by itself pass else: for pred in bb.Predecessors: - print('predecessor: {}'.format(pred)) pred.LastInstruction.changeTarget(bb, ins.target) f.removeBasicBlock(bb)