/// <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); } }