public CodePiece GenerateCode(CodeGenEnvironment env, int methOffsetX, int methOffsetY) { CodePiece p = new CodePiece(); // Generate Space for Variables p.AppendBottom(CodePieceStore.CreateVariableSpace(Variables, methOffsetX, methOffsetY, CGO, env.MaxVarDeclarationWidth)); //TODO auto calc max width (by option) - not simply use constant - use two generator runs // Generate Initialization of Variables CodePiece pVi = GenerateCode_VariableIntialization(env); pVi.SetTag(0, 0, new MethodEntryFullInitializationTag(this)); //v<-- Entry Point p.AppendBottom(pVi); // Generate Initialization of Parameters p.AppendBottom(GenerateCode_ParameterIntialization(env)); // Generate Statements p.AppendBottom(GenerateCode_Body(env)); return(p); }
private CodePiece GenerateCode(int estimatedWidth, string initialDisp) { // v {TEMP..} // 0 v{STACKFLOODER} < // {++++++++++++} | // v < // ############### // ############### // ## ## // ## {DISPLAY} ## // ## ## // ############### // ############### | // v < // :# $ {GLOBALVAR} # // !# $ {GLOBALVAR} ! // ## $ // ># $ {METHOD} // |# $ {++++++} // # $ {++++++} // ##$ // #>$ {METHOD} // #|$ {++++++} // # $ {++++++} // # $ {METHOD} // # $ {++++++} ResetBeforeCodeGen(); List <Tuple <MathExt.Point, CodePiece> > methPieces = new List <Tuple <MathExt.Point, CodePiece> >(); CodeGenEnvironment env = new CodeGenEnvironment(); env.MaxVarDeclarationWidth = MathExt.Max(estimatedWidth - 4 - CodeGenConstants.LANE_VERTICAL_MARGIN - 2, CodeGenConstants.MinVarDeclarationWidth, DisplayWidth, CGO.DefaultVarDeclarationWidth); CodePiece p = new CodePiece(); int maxReturnValWidth = GetMaxReturnValueWidth(); int methOffsetX = 4 + CodeGenConstants.LANE_VERTICAL_MARGIN; #region Generate Top Lane CodePiece pTopLane = new CodePiece(); pTopLane[0, 0] = BCHelper.PCDown; pTopLane[CodeGenConstants.TMP_FIELDPOS_IO_ARR.X, CodeGenConstants.TMP_FIELDPOS_IO_ARR.Y] = BCHelper.Chr(CGO.DefaultTempSymbol, new TemporaryCodeFieldTag()); env.TMP_FIELD_IO_ARR = CodeGenConstants.TMP_FIELDPOS_IO_ARR; pTopLane[CodeGenConstants.TMP_FIELDPOS_OUT_ARR.X, CodeGenConstants.TMP_FIELDPOS_OUT_ARR.Y] = BCHelper.Chr(CGO.DefaultTempSymbol, new TemporaryCodeFieldTag()); env.TMP_FIELD_OUT_ARR = CodeGenConstants.TMP_FIELDPOS_OUT_ARR; pTopLane[CodeGenConstants.TMP_FIELDPOS_JMP_ADDR.X, CodeGenConstants.TMP_FIELDPOS_JMP_ADDR.Y] = BCHelper.Chr(CGO.DefaultTempSymbol, new TemporaryCodeFieldTag()); env.TMP_FIELD_JMP_ADDR = CodeGenConstants.TMP_FIELDPOS_JMP_ADDR; pTopLane[CodeGenConstants.TMP_FIELDPOS_GENERAL.X, CodeGenConstants.TMP_FIELDPOS_GENERAL.Y] = BCHelper.Chr(CGO.DefaultTempSymbol, new TemporaryCodeFieldTag()); env.TMP_FIELD_GENERAL = CodeGenConstants.TMP_FIELDPOS_GENERAL; int tempDeclHeight = 0; if (maxReturnValWidth < (CodeGenConstants.TOP_COMMENT_X - CodeGenConstants.TMP_ARRFIELDPOS_RETURNVAL_TL.X - 3)) { // Single line env.TMP_ARRFIELD_RETURNVAL = new VarDeclarationPosition(CodeGenConstants.TMP_ARRFIELDPOS_RETURNVAL_TL, maxReturnValWidth, 1, maxReturnValWidth); pTopLane.Fill( env.TMP_ARRFIELD_RETURNVAL.X, env.TMP_ARRFIELD_RETURNVAL.Y, env.TMP_ARRFIELD_RETURNVAL.X + maxReturnValWidth, env.TMP_ARRFIELD_RETURNVAL.Y + 1, BCHelper.Chr(CGO.DefaultResultTempSymbol), new TemporaryResultCodeFieldTag(maxReturnValWidth)); tempDeclHeight = 1; } else { // Multiline (or at least in its own seperate row) var space = CodePieceStore.CreateVariableSpace( maxReturnValWidth, CGO, env.MaxVarDeclarationWidth, BCHelper.Chr(CGO.DefaultResultTempSymbol), new TemporaryResultCodeFieldTag(maxReturnValWidth)); env.TMP_ARRFIELD_RETURNVAL = space.Item2 + new MathExt.Point(1, 1); pTopLane.SetAt(1, 1, space.Item1); tempDeclHeight = 1 + space.Item1.Height; } pTopLane.SetText(CodeGenConstants.TOP_COMMENT_X, 0, "// generated by BefunGen v" + CodeGenConstants.BEFUNGEN_VERSION); pTopLane.CreateColWw(0, 1, tempDeclHeight); pTopLane[0, tempDeclHeight] = BCHelper.Digit0; pTopLane[2, tempDeclHeight] = BCHelper.PCDown; CodePiece pFlooder = CodePieceStore.BooleanStackFlooder(); pTopLane.SetAt(3, tempDeclHeight, pFlooder); CodePiece displayValue = GenerateCode_DisplayValue(initialDisp); CodePiece pDisplay = GenerateCode_Display(displayValue); DisplayOffsetX = 3; DisplayOffsetY = 2 + tempDeclHeight; pTopLane.SetAt(DisplayOffsetX, DisplayOffsetY, pDisplay); int topLaneBottomRow = 2 + tempDeclHeight + pDisplay.Height; DisplayOffsetX += CGO.DisplayBorderThickness; DisplayOffsetY += CGO.DisplayBorderThickness; pTopLane[0, topLaneBottomRow] = BCHelper.PCDown; pTopLane[1, topLaneBottomRow] = BCHelper.Walkway; pTopLane.FillColWw(0, tempDeclHeight + 1, topLaneBottomRow); pTopLane.FillColWw(2, tempDeclHeight + 1, topLaneBottomRow + 1); p.SetAt(0, 0, pTopLane); #endregion int laneStartY = p.MaxY; int methOffsetY = p.MaxY; // +3 For the MinY=3 of VerticalLaneTurnout_Dec #region Insert VariableSpace CodePiece pVars = CodePieceStore.CreateVariableSpace(Variables, methOffsetX, methOffsetY, CGO, env.MaxVarDeclarationWidth); p.SetAt(methOffsetX, methOffsetY, pVars); #endregion methOffsetY += Math.Max(0, pVars.Height - 3); // -3 For the MinY=3 of VerticalLaneTurnout_Dec methOffsetY += 3; // +3 For the MinY=3 of VerticalLaneTurnout_Dec #region Insert Methods for (int i = 0; i < MethodList.Count; i++) { Method m = MethodList[i]; CodePiece pMethod = m.GenerateCode(env, methOffsetX, methOffsetY); if (p.HasActiveTag(typeof(MethodEntryFullInitializationTag))) // Force MethodEntry_FullIntialization Distance (at least so that lanes can be generated) { int pLast = p.FindAllActiveCodeTags(typeof(MethodEntryFullInitializationTag)).Last().Y; int pNext = pMethod.FindAllActiveCodeTags(typeof(MethodEntryFullInitializationTag)).First().Y + (methOffsetY - pMethod.MinY); int overflow = (pNext - pLast) - CodePieceStore.VerticalLaneTurnout_Dec(false).Height; if (overflow < 0) { methOffsetY -= overflow; } } int mx = methOffsetX - pMethod.MinX; int my = methOffsetY - pMethod.MinY; methPieces.Add(Tuple.Create(new MathExt.Point(mx, my), pMethod)); p.SetAt(mx, my, pMethod); methOffsetY += pMethod.Height + CodeGenConstants.VERTICAL_METHOD_DISTANCE; } #endregion int highwayX = p.MaxX; #region Generate Lane Chooser p.FillRowWw(tempDeclHeight, 3 + pFlooder.Width, highwayX); p.FillRowWw(topLaneBottomRow, 3, highwayX); p[highwayX, tempDeclHeight] = BCHelper.PCLeft; p[highwayX, topLaneBottomRow - 1] = BCHelper.IfVertical; p[highwayX, topLaneBottomRow + 0] = BCHelper.PCLeft; p[highwayX, topLaneBottomRow + 1] = BCHelper.PCJump; p[highwayX, topLaneBottomRow + 2] = BCHelper.Not; p.FillColWw(highwayX, tempDeclHeight + 1, topLaneBottomRow - 1); #endregion #region Generate Lanes (Left Lane && Right Lane) List <TagLocation> methodEntries = p.FindAllActiveCodeTags(typeof(MethodEntryFullInitializationTag)) // Left Lane .OrderBy(tp => tp.Y) .ToList(); List <TagLocation> codeEntries = p.FindAllActiveCodeTags(typeof(MethodCallHorizontalReEntryTag)) // Right Lane .OrderBy(tp => tp.Y) .ToList(); int last; bool first; //######### LEFT LANE ######### first = true; last = laneStartY; foreach (TagLocation methodEntry in methodEntries) { CodePiece pTurnout = CodePieceStore.VerticalLaneTurnout_Dec(first); p.FillColWw(0, last, methodEntry.Y + pTurnout.MinY); p.SetAt(0, methodEntry.Y, pTurnout); p.FillRowWw(methodEntry.Y, 4, methodEntry.X); last = methodEntry.Y + pTurnout.MaxY; first = false; } //p.FillColWW(0, last, p.MaxY); //######### RIGHT LANE ######### first = true; last = laneStartY; foreach (TagLocation codeEntry in codeEntries) { CodePiece pTurnout = CodePieceStore.VerticalLaneTurnout_Test(); p.FillColWw(2, last, codeEntry.Y + pTurnout.MinY); p.SetAt(2, codeEntry.Y, pTurnout); p.CreateRowWw(codeEntry.Y, 4, codeEntry.X); last = codeEntry.Y + pTurnout.MaxY; first = false; } //p.FillColWW(2, last, p.MaxY); //######### MIDDLE LANE ######### p.Fill(1, laneStartY, 2, p.MaxY, BCHelper.PCJump); //######### POP LANE ######### p.Fill(3, laneStartY, 4, p.MaxY, BCHelper.StackPop); #endregion #region Generate Highway (Path on right side of code) List <TagLocation> codeExits = p.FindAllActiveCodeTags(typeof(MethodCallHorizontalExitTag)) .OrderBy(tp => tp.Y) .ToList(); first = true; last = topLaneBottomRow + 3; foreach (TagLocation exit in codeExits) { p.FillColWw(highwayX, last, exit.Y); p[highwayX, exit.Y] = BCHelper.PCUp; p.CreateRowWw(exit.Y, exit.X + 1, highwayX); last = exit.Y + 1; exit.Tag.Deactivate(); first = false; } #endregion return(p); }