//-----------------------------------------------------------
        public Type VisitFirst(Subroutine node)
        {
            var subrName = node[0].AnchorToken.Lexeme;

            GlobalTable.Add(subrName, new SymbolTable());

            currentProgUnit = subrName;
            var subrTable = GlobalTable[currentProgUnit];

            foreach (var arg in node[1])
            {
                var argName = arg.AnchorToken.Lexeme;
                subrTable[argName] = new FunctionSymbolEntry(Type.NONE, true);
            }
            VisitFirst((DeclarationList)node[2]);
            return(Type.VOID);
        }
        //-----------------------------------------------------------
        public Type VisitFirst(Function node)
        {
            var funcType = node[0];
            var funcName = node[1].AnchorToken.Lexeme;

            GlobalTable.Add(funcName, new SymbolTable());

            currentProgUnit = funcName;
            var funcTable = GlobalTable[currentProgUnit];

            foreach (var arg in node[2])
            {
                var argName = arg.AnchorToken.Lexeme;
                funcTable[argName] = new FunctionSymbolEntry(Type.NONE, true);
            }

            VisitFirst((DeclarationList)node[3]);
            return(typeMapper[funcType.AnchorToken.Category]);
        }
        //-----------------------------------------------------------
        public Type VisitFirst(Declaration node)
        {
            var funcTable = GlobalTable[currentProgUnit];

            foreach (var decl in node)
            {
                var variableName = decl.AnchorToken.Lexeme;
                if (!funcTable.Contains(variableName))
                {
                    funcTable[variableName] =
                        new FunctionSymbolEntry(
                            typeMapper[node.AnchorToken.Category]);
                }
                else
                {
                    funcTable[variableName].SymbolType =
                        typeMapper[node.AnchorToken.Category];
                }

                if (decl.HasChildren())
                {
                    var declArray = decl[0];
                    if (declArray.NodeChildrenCount() > 2)
                    {
                        throw new SemanticError(
                                  "An array can have 2 dimensions at most: "
                                  + variableName,
                                  decl.AnchorToken);
                    }

                    for (int i = 0; i < declArray.NodeChildrenCount(); i++)
                    {
                        funcTable[variableName].Params
                        .Add(declArray[i].AnchorToken.Lexeme);
                    }
                }
            }
            return(Type.VOID);
        }