import types_mv


class Symbol(object):
    def __init__(self, name, type=types_mv.Element(), is_global=False, node=None, params=None):
        self.name = name
        self.type = type
        self.is_global = is_global
        self.node = node
        self.params = params

    def is_func(self):
        return self.params is not None

    def signature(self):
        if self.is_func():
            params = ", ".join([str(t) for t in self.params])
            return "{} function {}({})".format(str(self.type),
                                               self.name, params)
        else:
            return self.name

class SymbolTable(object):
    def __init__(self):
        self.stacks = []

    def open_scope(self):
        self.stacks.append({})

    def close_scope(self):
        self.stacks.pop()

    def add(self, symbol):
        if symbol.name in self.stacks[-1]:
            raise Exception("Redefinition of symbol " + str(symbol))
        else:
            self.stacks[-1][symbol.name] = symbol

    def get(self, name):
        for frame in reversed(self.stacks):
            try:
                return frame[name]
            except KeyError:
                # Not in this scope, so keep going
                pass
        raise KeyError("Undefined symbol: " + name)