//-----------------------------------------------------------
        private Type Visit(Identifier node, Table table)
        {
            GlobalSymbolTable gstable = table as GlobalSymbolTable;
            LocalSymbolTable  lstable = table as LocalSymbolTable;

            var symbolName = node.AnchorToken.Lexeme;

            if (table is GlobalSymbolTable)
            {
                if (gstable.Contains(symbolName))
                {
                    return(gstable[symbolName].TheType);
                }
                throw new SemanticError("Undeclared variable: " + symbolName, node.AnchorToken);
            }
            else if (table is LocalSymbolTable)
            {
                if (lstable.Contains(symbolName))
                {
                    return(lstable[symbolName].LocalType);
                }
                if (GSTable.Contains(symbolName))
                {
                    return(GSTable[symbolName].TheType);
                }
                throw new SemanticError("Undeclared variable: " + symbolName, node.AnchorToken);
            }
            else
            {
                throw new TypeAccessException("Expecting either a GlobalSymbolTable or a LocalSymboltable");
            }
        }
        //-----------------------------------------------------------
        private Type Visit(ProcedureDeclaration node, Table table)
        {
            GlobalSymbolTable gstable = table as GlobalSymbolTable;

            if (table == null)
            {
                throw new TypeAccessException("Expecting a GlobalSymbolTable");
            }

            var procedureName = node.AnchorToken.Lexeme;

            if (gstable.Contains(procedureName))
            {
                throw new SemanticError("Duplicated procedure: " + procedureName, node.AnchorToken);
            }

            if (node[1] is SimpleType || node[1] is ListType)
            {
                GPTable[procedureName] = new GlobalProcedure(false, Visit((dynamic)node[1], table));
                var i = 0;
                foreach (var n in node)
                {
                    if (i != 1)
                    {
                        Visit((dynamic)n, GPTable[procedureName].LocalSymbols);
                    }
                    i++;
                }
            }
            else
            {
                GPTable[procedureName] = new GlobalProcedure(false);
                VisitChildren(node, GPTable[procedureName].LocalSymbols);
            }

            return(Type.VOID);
        }