diff --git a/gds/elements.py b/gds/elements.py index ab65758..0652d5b 100644 --- a/gds/elements.py +++ b/gds/elements.py @@ -72,4 +72,18 @@ class SRef(Element): # tree parent = None +class ARef(Element): + position = (0,0) + + # positions of last instance in X and Y direction + bounds = [(0,0), (0,0)] + # number of instances in X and Y direction + size = (0,0) + + structure = "" + + transformation = Transformation() + + # tree + parent = None diff --git a/gds/library.py b/gds/library.py index 93a7c51..28c0f39 100644 --- a/gds/library.py +++ b/gds/library.py @@ -38,8 +38,8 @@ class Library(object): for key, value in self.structures.items(): - for element in value.references: - if isinstance(element, SRef) and isinstance(element.structure, str): + for element in value.references: + if isinstance(element.structure, str): # try to resolve link try: ref = self.structures[element.structure] diff --git a/gds/parser.py b/gds/parser.py index 0d2556c..9c1ff18 100644 --- a/gds/parser.py +++ b/gds/parser.py @@ -18,6 +18,8 @@ class errors(Enum): EXPECTED_STRING = "textelement is missing text" EXPECTED_BOXTYPE = "expected BOXTYPE" EXPECTED_SNAME = "expected SNAME" + EXPECTED_COLROW = "expected COLROW" + AREF_MISSING_POINTS = "aref needs three points" INVALID_PATHTYPE = "pathtype must be in range [0,2]" class Warnings(Enum): @@ -142,6 +144,8 @@ class Parser(Reader): self.parse_text() elif self.token.ident == Records.SREF: self.parse_sref() + elif self.token.ident == Records.AREF: + self.parse_aref() else: self.skip(self.token.len) @@ -162,7 +166,6 @@ class Parser(Reader): element.plex = self.read_int() self.next_token(True) - def parse_boundary(self): element = Boundary() if not self.next_token(): @@ -367,13 +370,50 @@ class Parser(Reader): if self.token.ident != Records.XY: raise ParserError(errors.EXPECTED_POINT) - element.point = self.read_coord() + element.position = self.read_coord() self.skip(self.token.len - 8) if not self.next_token() or self.token.ident != Records.ENDEL: raise ParserError(errors.EXPECTED_ENDEL) self.structure.references.append(element) + + def parse_aref(self): + element = ARef() + element.parent = self.structure + + if not self.next_token(): + raise ParserError(errors.EXPECTED_SNAME) + + self.parse_element(element) + + if self.token.ident != Records.SNAME: + raise ParserError(errors.EXPECTED_SNAME) + + element.structure = self.read_ascii(self.token.len) + + self.next_token(True) + self.parse_strans(element.transformation) + + if self.token.ident != Records.COLROW: + raise ParserError(errors.EXPECTED_COLROW) + + element.size = (self.read_short(), self.read_short()) + + if not self.next_token() or self.token.ident != Records.XY: + raise ParserError(errors.EXPECTED_POINT) + + if self.token.len != 3*8: + raise ParserError(errors.AREF_MISSING_POINTS) + + element.position = self.read_coord() + element.bounds[0] = self.read_coord() + element.bounds[1] = self.read_coord() + + if not self.next_token() or self.token.ident != Records.ENDEL: + raise ParserError(errors.EXPECTED_ENDEL) + + self.structure.references.append(element) def parse_file(file, progress_func=None): parser = Parser(file, progress_callback=progress_func)