def check_iterator(self, iterator):
     _, iter_symbol, iter_lineno = iterator
     if iter_symbol in self.scope:
         raise_error(
             msg=
             "trying to set previously declared variable '{0}' as iterator".
             format(iter_symbol),
             lineno=iter_lineno)
         raise CompilerError()
 def check_initialized(self, var):
     if is_int(var):
         _, symbol, lineno = var
         if not self.initialized.get(symbol, False):
             raise_error(
                 "Usage of uninitialized variable '{symbol}'".format(
                     symbol=symbol), lineno)
     elif is_array(var):
         # Cannot check int tab initialization
         pass
 def check_int(self, variable):
     _, symbol, lineno = variable
     if '#'.join([symbol, '0']) in self.scope:
         raise_error(
             msg="Usage of array variable '{symbol}' without specifing index"
             .format(symbol=symbol),
             lineno=lineno)
     if symbol not in self.scope:
         raise_error(
             msg="Variable '{symbol}' not declared".format(symbol=symbol),
             lineno=lineno)
 def check_scope(self, operand):
     if is_number(operand):
         pass
     elif is_int(operand):
         if operand[1] not in self.scope:
             raise_error(msg="Undeclared variable {}".format(operand[1]),
                         lineno=operand[2])
     elif is_array(operand):
         if is_number(operand[2]):
             self.check_inttab(operand)
     else:
         raise CompilerError("Unexpected operand")
    def check_inttab(self, variable):
        _, symbol, index, lineno = variable

        arr_start = '#'.join([symbol, '0'])

        if arr_start not in self.scope:
            raise_error("Usage of undeclared array {}".format(symbol), lineno)
        if is_number(index):
            self.check_inttab_index(variable)
        elif is_int(index):
            self.check_variable(index)
        else:
            raise CompilerError("Unexpected array index")
    def check_assign(self, cmd):
        _, target, expression = cmd
        self.check_scope(target)

        if is_int(target):
            _, symbol, lineno = target
            if symbol in self.iterators:
                raise_error(
                    "Mutation of iterator '{symbol}'".format(symbol=symbol),
                    lineno)
        elif is_array(target):
            _, symbol, index, _ = target
            symbol = '#'.join([symbol, str(index)])
        else:
            raise CompilerError("Unexpected target type")

        self.check_expression(expression)
        self.initialized[symbol] = True
    def check_for_duplicate_declarations(self, declarations):
        seen = []
        arrays = {}

        for kind, val, *details, lineno in declarations:
            if val in seen:
                raise_error(msg='double declaration of {}'.format(val),
                            lineno=lineno)
            if kind == 'int[]':
                [size] = details
                seen.append(val + '#0')
                if val in arrays.keys():
                    raise_error(
                        msg='double declaration of array {}'.format(val),
                        lineno=lineno)
                arrays[val + '#0'] = size
            else:
                seen.append(val)
        self.symbols = set(seen)
        self.scope = set(seen)
        self.arrays = arrays
 def check_inttab_index(self, variable):
     _, symbol, index, lineno = variable
     if not 0 <= index <= self.arrays[symbol + '#0'] - 1:
         raise_error("Array {} index out of range".format(symbol), lineno)