Mercurial > lcfOS
changeset 226:240111e0456f
Work on named types
author | Windel Bouwman |
---|---|
date | Fri, 12 Jul 2013 17:25:31 +0200 |
parents | 1c7364bd74c7 |
children | 82dfe6a32717 |
files | python/c3/analyse.py python/c3/astnodes.py python/c3/builder.py python/c3/parser.py python/c3/typecheck.py |
diffstat | 5 files changed, 51 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- a/python/c3/analyse.py Thu Jul 11 07:42:30 2013 +0200 +++ b/python/c3/analyse.py Fri Jul 12 17:25:31 2013 +0200 @@ -78,8 +78,13 @@ if type(t) is PointerType: t.ptype = self.resolveType(t.ptype, scope) return t + elif type(t) is StructureType: + for mem in t.mems: + mem.typ = self.resolveType(mem.typ, scope) + return t elif type(t) is Designator: - return self.resolveDesignator(t, scope) + t = self.resolveDesignator(t, scope) + return self.resolveType(t) elif isinstance(t, Type): # Already resolved?? return t @@ -101,6 +106,8 @@ ft = sym.typ ft.returntype = self.resolveType(ft.returntype, sym.scope) ft.parametertypes = [self.resolveType(pt, sym.scope) for pt in ft.parametertypes] + elif type(sym) is DefinedType: + sym.typ = self.resolveType(sym.typ, sym.scope) def sanity(self, sym): if type(sym) is FunctionType:
--- a/python/c3/astnodes.py Thu Jul 11 07:42:30 2013 +0200 +++ b/python/c3/astnodes.py Fri Jul 12 17:25:31 2013 +0200 @@ -67,13 +67,15 @@ class StructureType(Type): def __init__(self, mems): self.mems = mems + for ft, fn in mems: + assert type(fn) is str def hasField(self, name): - for fn, ft in self.mems: + for ft, fn in self.mems: if name == fn: return True return False def fieldType(self, name): - for fn, ft in self.mems: + for ft, fn in self.mems: if name == fn: return ft raise Exception()
--- a/python/c3/builder.py Thu Jul 11 07:42:30 2013 +0200 +++ b/python/c3/builder.py Fri Jul 12 17:25:31 2013 +0200 @@ -8,25 +8,24 @@ Reports errors to the diagnostics system """ def __init__(self, diag): - self.diag = diag - self.parser = Parser(diag) - self.tc = TypeChecker(diag) - self.al = Analyzer(diag) - self.cg = CodeGenerator() + self.diag = diag + self.parser = Parser(diag) + self.tc = TypeChecker(diag) + self.al = Analyzer(diag) + self.cg = CodeGenerator() def build(self, src): - """ Create IR-code from sources """ - pkg = self.parser.parseSource(src) - if not pkg: + """ Create IR-code from sources """ + 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): + self.pkg = pkg + # TODO: merge the two below? + #AstPrinter().printAst(pkg) + if not self.al.analyzePackage(pkg): return - if not self.tc.checkPackage(pkg): + if not self.tc.checkPackage(pkg): return - # Only return ircode when everything is OK - ircode = self.cg.gencode(pkg) - return ircode + # Only return ircode when everything is OK + return self.cg.gencode(pkg)
--- a/python/c3/parser.py Thu Jul 11 07:42:30 2013 +0200 +++ b/python/c3/parser.py Fri Jul 12 17:25:31 2013 +0200 @@ -89,10 +89,10 @@ mems = [] while self.Peak != '}': mem_t = self.parseTypeSpec() - mem_n = self.Consume('ID') + mem_n = self.Consume('ID').val mems.append((mem_t, mem_n)) while self.hasConsumed(','): - mem_n = self.Consume('ID') + mem_n = self.Consume('ID').val mems.append((mem_t, mem_n)) self.Consume(';') self.Consume('}')
--- a/python/c3/typecheck.py Thu Jul 11 07:42:30 2013 +0200 +++ b/python/c3/typecheck.py Fri Jul 12 17:25:31 2013 +0200 @@ -3,13 +3,19 @@ from .visitor import Visitor def equalTypes(a, b): - """ Compare types a and b for equality. Not equal until proven otherwise. """ - if type(a) is type(b): - if type(a) is BaseType: - return a.name == b.name - elif type(a) is PointerType: - return equalTypes(a.ptype, b.ptype) - return False + """ Compare types a and b for equality. Not equal until proven otherwise. """ + # Recurse into named types: + if type(a) is DefinedType: + return equalTypes(a.typ, b) + if type(b) is DefinedType: + return equalTypes(a, b.typ) + # Compare for structural equivalence: + if type(a) is type(b): + if type(a) is BaseType: + return a.name == b.name + elif type(a) is PointerType: + return equalTypes(a.ptype, b.ptype) + return False def canCast(fromT, toT): if isinstance(fromT, PointerType) and isinstance(toT, PointerType): @@ -89,19 +95,24 @@ # 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 + ptype = sym.ptr.typ + if type(ptype) is DefinedType: + ptype = ptype.typ + if type(ptype) is PointerType: + sym.typ = ptype.ptype else: - self.error('Cannot dereference non-pointer type {}'.format(sym.ptr.typ), sym.loc) + self.error('Cannot dereference non-pointer type {}'.format(ptype), sym.loc) sym.typ = intType elif type(sym) is FieldRef: basetype = sym.base.typ sym.lvalue = True + if type(basetype) is DefinedType: + basetype = basetype.typ 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) + self.error('{} does not contain field {}'.format(basetype, sym.field), sym.loc) sym.typ = intType else: self.error('Cannot select field {} of non-structure type {}'.format(sym.field, basetype), sym.loc)