Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }