package pt.up.fe.comp.utils;

import java.util.Stack;

public class SymbolTable<T> {

    public SymbolTable(boolean lazy) {
        _lazy = lazy;
        beginScope();
    }

    public void beginScope() {
        _scopes.add(new Scope<T>(_lazy));
    }

    public void endScope() {
        // do not delete "global" scope
        if (_scopes.size() > 1)
            _scopes.pop();
    }

    public void setLazy(boolean value) {
        _lazy = value;
        for (Scope<T> scp : _scopes) {
            scp.setLazy(value);
        }
    }

    public void addSymbol(String name, Class type, Producer<T> init) {
        _scopes.peek().addSymbol(name, type, init);
    }

    public boolean contains(String name) {
        return get(name) != null;
    }

    public T get(String name) {
        T value;
        for (Scope<T> scp : _scopes) {
            value = scp.getSymbol(name);
            if (value != null) return value;
        }
        return null;
    }

    public Class getType(String name) {
        Class type;
        for (Scope<T> scp : _scopes) {
            type = scp.getSymbolType(name);
            if (type != null) return type;
        }
        return null;
    }

    private Stack<Scope<T>> _scopes = new Stack<>();
    private boolean _lazy;
}

@@ -603,24 +603,57 @@
 %3CT%3E init) %7B%0A
+        if (!contains(name))%0A    
         _sco
@@ -692,16 +692,78 @@
  init);%0A
+        else throw new Error(name + %22 is already declared.%22);%0A
     %7D%0A%0A 

Add check for redeclared symbols.