class Token: def __init__(self, type, value, pos, rawValue=None): self.type = type self.value = value self.pos = pos if rawValue is None: rawValue = value self.rawValue = rawValue def __str__(self): return "{" + str(self.type.name) + ", '" + str(self.value) + "', " + str(self.pos) + "}" def __repr__(self): return self.__str__() class TokenList: def __init__(self, tokens, lines): self.tokens = tokens self.cursor = 0 self.snap = 0 self.lines = lines def append(self, token): self.tokens.append(token) def __getitem__(self, index): return self.tokens[index] def current(self): if self.cursor >= len(self.tokens): raise RuntimeError(f"Cursor points to not existing token! Cursor = {self.cursor}, len = {len(self.tokens)}") return self.tokens[self.cursor] def currentPos(self): #TODO maybe change raw pos (position) tuple to some class with method "nextCol()", "nextRow()" etc. return self.current().pos if self.hasCurrent() else (self.tokens[-1].pos[0], self.tokens[-1].pos[1]+1) if len(self.tokens) > 0 else None def isCurrent(self, type): return self.hasCurrent() and self.current().type == type def next(self, number=1): return self.tokens[self.cursor + number] def prev(self, number=1): return self.tokens[self.cursor - number] def hasMore(self, count=1): return self.cursor + count < len(self.tokens) def hasCurrent(self): return self.cursor < len(self.tokens) def ahead(self): self.cursor += 1 def snapshot(self): return self.cursor def reset(self, snap): self.cursor = snap def currentToEndOfLine(self): return self.lines[self.current().pos[0]][self.current().pos[1]:] def __str__(self): return f"[Current({self.cursor}): {self.current() if self.hasCurrent() else 'out of tokens'}\n{', '.join([str(token) for token in self.tokens])}]" def __repr__(self): return self.__str__()