/// <summary>
        /// Generates the code for a function, with its subfunctions and variables
        /// </summary>
        /// <param name="mainDiagram">Main function for code generation</param>
        /// <param name="functions">Subfunctions</param>
        /// <param name="variables">Variables</param>
        /// <param name="asmPath">Path of the resulting asm file</param>
        public static void GenerateCode(Diagram mainDiagram, List <Diagram> functions, List <Variable> variables, string asmPath)
        {
            StreamWriter writer = new StreamWriter(asmPath, false);

            AsmGenerator.RestoreLabelCounter();
            AsmGenerator.WriteHead(writer);
            if (variables.Count > 0)
            {
                AsmGenerator.WriteVariables(writer, variables);
            }
            AsmGenerator.WriteVectors(writer);
            AsmGenerator.WriteConfiguration(writer);
            //the program variables are initialized
            if (variables.Count > 0)
            {
                AsmGenerator.WriteInitVariables(writer, variables);
            }
            // the main function is encoded
            AsmGenerator.GenerateDiagramCode(writer, mainDiagram);
            //the functions are encoded
            foreach (Diagram diagram in functions)
            {
                AsmGenerator.GenerateDiagramCode(writer, diagram);
            }
            AsmGenerator.WriteEndDirective(writer);
            writer.Close();
        }
        /// <summary>
        /// Generate the code for a diagram
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="diagram">Diagram for the generation</param>
        /// <param name="subrutine">Indicates whether it is a subroutine or not.True for subroutine</param>
        private static void GenerateDiagramCode(StreamWriter writer, Diagram diagram)
        {
            Queue <Element> falseBranch = new Queue <Element>();
            Hashtable       labelElements = new Hashtable();
            List <Element>  elementsCodified = new List <Element>();
            bool            endElement = false, forceLoopEnd = false;
            Element         presentElement = AsmGenerator.GetNextElement(diagram.Start);
            string          label;

            if (diagram.IsFunction)
            {
                AsmGenerator.WriteLabel(writer, diagram.Name);
            }

            while (presentElement != null)
            {
                if (elementsCodified.Contains(presentElement))
                {
                    AsmGenerator.WriteUnconditionalJump(writer, (string)labelElements[presentElement]);
                    if (falseBranch.Count != 0)
                    {
                        presentElement = falseBranch.Dequeue();
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }
                if (presentElement is Finish)
                {
                    if (diagram.IsFunction)
                    {
                        AsmGenerator.WriteSubrutineEnd(writer);
                    }
                    else
                    if (!endElement)
                    {
                        AsmGenerator.WriteEndLoop(writer);
                        endElement = true;
                    }
                    else
                    {
                        AsmGenerator.WriteUnconditionalJump(writer, "loopEnd");
                    }
                    if (falseBranch.Count != 0)
                    {
                        presentElement = falseBranch.Dequeue();
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    if (labelElements.ContainsKey(presentElement))
                    {
                        AsmGenerator.WriteLabel(writer, (string)labelElements[presentElement]);
                    }
                    else if (presentElement.MoreThan1Prev)
                    {
                        label = AsmGenerator.GenerateLabel();
                        labelElements.Add(presentElement, label);
                        AsmGenerator.WriteLabel(writer, label);
                    }
                    if (presentElement is Module)
                    {
                        ((Module)presentElement).WriteCode(writer);
                        elementsCodified.Add(presentElement);
                        presentElement = AsmGenerator.GetNextElement(presentElement);
                    }
                    else if (presentElement is Conditional)
                    {
                        Element elementNextFalse = AsmGenerator.GetNextElement((Conditional)presentElement, false);
                        if (labelElements.ContainsKey(elementNextFalse))
                        {
                            label = (string)labelElements[elementNextFalse];
                            ((Conditional)presentElement).WriteCode(writer, AsmGenerator.GetUnconditionalJump(label));
                            elementsCodified.Add(presentElement);
                            presentElement = AsmGenerator.GetNextElement((Conditional)presentElement, true);
                        }
                        else if (elementNextFalse is Finish)
                        {
                            if (diagram.IsFunction)
                            {
                                ((Conditional)presentElement).WriteCode(writer, AsmGenerator.GetSubrutineEnd());
                                elementsCodified.Add(presentElement);
                                presentElement = AsmGenerator.GetNextElement((Conditional)presentElement, true);
                            }
                            else
                            {
                                ((Conditional)presentElement).WriteCode(writer, AsmGenerator.GetUnconditionalJump("loopEnd"));
                                elementsCodified.Add(presentElement);
                                presentElement = AsmGenerator.GetNextElement((Conditional)presentElement, true);
                                forceLoopEnd   = true;
                            }
                        }
                        else
                        {
                            label = AsmGenerator.GenerateLabel();
                            labelElements.Add(elementNextFalse, label);
                            falseBranch.Enqueue(elementNextFalse);
                            ((Conditional)presentElement).WriteCode(writer, AsmGenerator.GetUnconditionalJump(label));
                            elementsCodified.Add(presentElement);
                            presentElement = AsmGenerator.GetNextElement((Conditional)presentElement, true);
                        }
                    }
                }
            }
            if ((forceLoopEnd) && (!endElement))
            {
                AsmGenerator.WriteEndLoop(writer);
            }
        }