def visitLocation(self, ctx: decafParser.LocationContext): name = ctx.ID().getText() symbol = self.currentScope.resolve(name) if not symbol: ErrorHandler.nameError(ctx.start.line, name) self.error() return _error # Check if it is a built-in type builtIn = False if symbol.type.name in self.T.builtIn: builtIn = True if builtIn: # Declared as a variable if isinstance(symbol, symtab.VariableSymbol): if ctx.expr is not None: ErrorHandler.typeError(ctx.start.line, symbol.name, 5) self.error() if ctx.loc is not None: ErrorHandler.attributeError(ctx.start.line, symbol.name, ctx.loc.getText()) self.error() return symbol.type.name # Declared as an array elif isinstance(symbol, symtab.ArraySymbol): try: index = int(ctx.expr.getText()) except ValueError: index = None if (index is None) or (index < 0) or (index >= int( symbol.num)): ErrorHandler.arrayError(ctx.start.line, symbol.name, 2) self.error() if ctx.loc is not None: ErrorHandler.attributeError(ctx.start.line, symbol.name, ctx.loc.getText()) self.error() return symbol.type.name if not builtIn: # Save the actual scope actualScope = self.currentScope # Because it has a member, we declare the struct as the current scope self.currentScope = self.structs.get(symbol.type.name) # Visit location type = self.visit(ctx.loc) # Restore actual scope self.currentScope = actualScope # Return the type of the location return type
def visitArrayDecl(self, ctx: decafParser.ArrayDeclContext): varType = self.visit(ctx.varType()) name = ctx.ID().getText() num = ctx.NUM().getText() # <NUM> in the declaration of an array must be greater than 0. if int(num) <= 0: ErrorHandler.arrayError(ctx.start.line, name) self.error() type = self.createType(ctx.start.line, varType) symbol = symtab.ArraySymbol(name, type, num) self.defineSymbol(ctx.start.line, self.currentScope, symbol)