File indexing completed on 2024-07-14 05:32:54

0001 /***************************************************************************
0002  *   Copyright (C) 2003-2004 by David Saxton                               *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #ifndef FLOWCODE_H
0012 #define FLOWCODE_H
0013 
0014 #include "language.h"
0015 
0016 #include <QList>
0017 #include <QObject>
0018 #include <QPointer>
0019 #include <QString>
0020 #include <QStringList>
0021 
0022 class CNItem;
0023 class FlowPart;
0024 class Item;
0025 class MicroSettings;
0026 
0027 typedef QList<FlowPart *> FlowPartList;
0028 typedef QList<QPointer<Item>> ItemList;
0029 
0030 /**
0031 "FlowCode" can possibly be considered a misnomer, as the output is actually Microbe.
0032 However, the function of this class is to take a set of FlowParts, and generate the
0033 basic from the code that they create. The 3 simple steps for usage of this function:
0034 (1) Create an instance of this class, giving the Start point and setings
0035 (2) Add all the subroutines present using addSubroutine()
0036 (3) Call generateMicrobe() to get the Microbe code.
0037 @author David Saxton
0038 */
0039 class FlowCode : public Language
0040 {
0041 public:
0042     FlowCode(ProcessChain *processChain);
0043 
0044     void processInput(ProcessOptions options) override;
0045     ProcessOptions::ProcessPath::Path outputPath(ProcessOptions::ProcessPath::Path inputPath) const override;
0046 
0047     /**
0048      * You must set the start part
0049      */
0050     void setStartPart(FlowPart *startPart);
0051     ~FlowCode() override;
0052     /**
0053      * You must add all top level subroutines using this function
0054      */
0055     void addSubroutine(FlowPart *part);
0056     /**
0057      * Adds code at the current insertion point
0058      */
0059     void addCode(const QString &code);
0060     /**
0061      * Adds a code branch to the current insertion point. This will stop when the level gets
0062      * below the original starting level (so for insertion of the contents of a for loop,
0063      * insertion will stop at the end of that for loop).
0064      * @param flowPart The next FlowPart to get code from
0065      */
0066     void addCodeBranch(FlowPart *flowPart);
0067     /**
0068      * Designates a FlowPart as a stopping part (i.e. will refuse requests to addCodeBranch
0069      * for that FlowPart until removeStopPart is called
0070      */
0071     void addStopPart(FlowPart *part);
0072     /**
0073      * Undesignates a FlowPart as a stopping part
0074      */
0075     void removeStopPart(FlowPart *part);
0076     /**
0077      * Generates and returns the microbe code
0078      */
0079     QString generateMicrobe(const ItemList &itemList, MicroSettings *settings);
0080     /**
0081      * Returns true if the FlowPart is a valid one for adding a branch
0082      */
0083     bool isValidBranch(FlowPart *flowPart);
0084     /**
0085      * Generates a nice label name from the string, e.g. genLabel("callsub")
0086      * returns "__label_callsub".
0087      */
0088     static QString genLabel(const QString &id);
0089 
0090 protected:
0091     /**
0092      * Performs indenting, removal of unnecessary labels, etc.
0093      */
0094     void tidyCode();
0095 
0096     QStringList m_gotos;  // Gotos used
0097     QStringList m_labels; // Labels used
0098     FlowPartList m_subroutines;
0099     FlowPartList m_addedParts;
0100     FlowPartList m_stopParts;
0101     FlowPart *p_startPart;
0102     QString m_code;
0103     int m_curLevel;
0104 };
0105 
0106 #endif