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

            Type declarationType = Visit((dynamic)node[1], table);

            foreach (var n in node[0])
            {
                var symbolName = n.AnchorToken.Lexeme;
                if (table is GlobalSymbolTable)
                {
                    if (GSTable.Contains(symbolName))
                    {
                        throw new SemanticError("Duplicated symbol: " + symbolName, n.AnchorToken);
                    }
                }
                else if (table is LocalSymbolTable)
                {
                    if (lstable.Contains(symbolName))
                    {
                        throw new SemanticError("Duplicated symbol: " + symbolName, n.AnchorToken);
                    }
                }
                else
                {
                    throw new TypeAccessException("Expecting either a GlobalSymbolTable or a LocalSymboltable");
                }

                if (table is GlobalSymbolTable)
                {
                    gstable[symbolName] = new GlobalSymbol(declarationType);
                }
                else if (table is LocalSymbolTable)
                {
                    lstable[symbolName] = new LocalSymbol(declarationType);
                }
                else
                {
                    throw new TypeAccessException("Expecting either a GlobalSymbolTable or a LocalSymboltable");
                }
            }

            return(Type.VOID);
        }
        //-----------------------------------------------------------
        private Type Visit(ConstantDeclaration 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))
                {
                    throw new SemanticError("Duplicated symbol: " + symbolName, node[0].AnchorToken);
                }
            }
            else if (table is LocalSymbolTable)
            {
                if (lstable.Contains(symbolName))
                {
                    throw new SemanticError("Duplicated symbol: " + symbolName, node[0].AnchorToken);
                }
            }
            else
            {
                throw new TypeAccessException("Expecting either a GlobalSymbolTable or a LocalSymboltable");
            }

            Type nodeType = Visit((dynamic)node[0], table);

            if (node[0] is Lst)
            {
                if (node[0].Count() == 0)
                {
                    throw new SemanticError("Constant lists cannot be empty: " + symbolName, node.AnchorToken);
                }

                dynamic lst;
                if (nodeType == Type.LIST_OF_BOOLEAN)
                {
                    lst = new Boolean[node[0].Count()];
                }
                else if (nodeType == Type.LIST_OF_INTEGER)
                {
                    lst = new Int32[node[0].Count()];
                }
                else if (nodeType == Type.LIST_OF_STRING)
                {
                    lst = new String[node[0].Count()];
                }
                else
                {
                    throw new TypeAccessException("Expecting one of the following node types: LIST_OF_BOOLEAN, LIST_OF_INTEGER, LIST_OF_STRING");
                }

                int i = 0;
                foreach (var n in node[0])
                {
                    lst[i++] = n.ExtractValue();
                }
                if (table is GlobalSymbolTable)
                {
                    gstable[symbolName] = new GlobalSymbol(nodeType, lst);
                }
                else if (table is LocalSymbolTable)
                {
                    lstable[symbolName] = new LocalSymbol(nodeType, lst);
                }
                else
                {
                    throw new TypeAccessException("Expecting either a GlobalSymbolTable or a LocalSymboltable");
                }
            }
            else
            {
                if (table is GlobalSymbolTable)
                {
                    gstable[symbolName] = new GlobalSymbol(nodeType, node[0].ExtractValue());
                }
                else if (table is LocalSymbolTable)
                {
                    lstable[symbolName] = new LocalSymbol(nodeType, node[0].ExtractValue());
                }
                else
                {
                    throw new TypeAccessException("Expecting either a GlobalSymbolTable or a LocalSymboltable");
                }
            }

            return(Type.VOID);
        }