File indexing completed on 2024-12-01 08:18:03

0001 /***************************************************************************
0002  *   Copyright (C) 2004-2005 by Daniel Clarke                              *
0003  *   daniel.jc@gmail.com                                                   *
0004  *                                     *
0005  *   24-04-2007                                                            *
0006  *   Modified to add pic 16f877,16f627 and 16f628              *
0007  *   by george john george@space-kerala.org                    *
0008  *   supported by SPACE www.space-kerala.org                   *
0009  *                                                                         *
0010  *   This program is free software; you can redistribute it and/or modify  *
0011  *   it under the terms of the GNU General Public License as published by  *
0012  *   the Free Software Foundation; either version 2 of the License, or     *
0013  *   (at your option) any later version.                                   *
0014  *                                                                         *
0015  *   This program is distributed in the hope that it will be useful,       *
0016  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0018  *   GNU General Public License for more details.                          *
0019  *                                                                         *
0020  *   You should have received a copy of the GNU General Public License     *
0021  *   along with this program; if not, write to the                         *
0022  *   Free Software Foundation, Inc.,                                       *
0023  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
0024  ***************************************************************************/
0025 
0026 #ifndef MICROBE_H
0027 #define MICROBE_H
0028 
0029 #include <instruction.h>
0030 #include <variable.h>
0031 // #include <pic14.h>
0032 
0033 #include <QMap>
0034 #include <QString>
0035 #include <QStringList>
0036 
0037 class QString;
0038 class BTreeBase;
0039 class BTreeNode;
0040 class Code;
0041 class PIC14;
0042 class PortPin;
0043 
0044 typedef QList<PortPin> PortPinList;
0045 
0046 typedef QList<Variable> VariableList;
0047 typedef QMap<QString,QString> AliasMap;
0048 
0049 enum ExprType
0050 {
0051     unset       = 1,
0052     working     = 2,
0053     number      = 3,
0054     variable    = 4,
0055     extpin      = 5,
0056     keypad      = 6
0057 };
0058 
0059 
0060 class SourceLineMicrobe;
0061 typedef QList<SourceLineMicrobe> SourceLineList;
0062 /**
0063 Represents a source line, with the convention of line number starting at zero.
0064 @author David Saxton
0065 */
0066 class SourceLineMicrobe
0067 {
0068     public:
0069         /**
0070          * The QList template requires a default constructor - calling this
0071          * though creates an invalid SourceLineMicrobe with line() returning -1. So
0072          * this constructor should never be used.
0073          */
0074         SourceLineMicrobe();
0075         SourceLineMicrobe( const QString & text, const QString & url, int line );
0076         
0077         QString text() const { return m_text; }
0078         QString url() const { return m_url; }
0079         int line() const { return m_line; }
0080         
0081         /**
0082          * Extracts the text from each SourceLineMicrobe and adds it to the
0083          * returned QStringList.
0084          */
0085         static QStringList toStringList( const SourceLineList & lines );
0086         
0087     protected:
0088         QString m_text;
0089         QString m_url;
0090         int m_line;
0091 };
0092 
0093 
0094     
0095 /**
0096 @author Daniel Clarke
0097 @author David Saxton
0098 */
0099 class MicrobeApp
0100 {
0101     public:
0102         MicrobeApp();
0103         ~MicrobeApp();
0104         
0105         enum MistakeType
0106         {
0107             UnknownStatement = 1,
0108             InvalidPort = 2,
0109             UnassignedPin = 3, // pin identifier without an "= something"
0110             NonHighLowPinState = 4,
0111             UnassignedPort = 5, // port identifier without an "= something"
0112             UnexpectedStatementBeforeBracket = 6,
0113             MismatchedBrackets = 7,
0114             InvalidEquals = 8,
0115             ReservedKeyword = 9,
0116             ConsecutiveOperators = 10,
0117             MissingOperator = 11,
0118             UnknownVariable = 12,
0119             UnopenableInclude = 16,
0120             DivisionByZero = 17,
0121             NumberTooBig = 18,
0122             NonConstantStep = 19,
0123             NonConstantDelay = 20,
0124             HighLowExpected = 21,
0125             InvalidComparison = 22,
0126             SubBeforeEnd = 23,
0127             LabelExpected = 24,
0128             TooManyTokens = 25,
0129             FixedStringExpected = 26,
0130             PinListExpected = 27,
0131             AliasRedefined = 28,
0132             InvalidInterrupt = 29,
0133             InterruptRedefined = 30,
0134             InterruptBeforeEnd = 31,
0135             ReadOnlyVariable = 32,
0136             WriteOnlyVariable = 33,
0137             InvalidPinMapSize = 34,
0138             VariableRedefined = 35,
0139             InvalidVariableName = 36,
0140             VariableExpected = 40,
0141             NameExpected = 41
0142         };
0143     
0144         /**
0145          * Returns a list of errors occurred during compilation, intended for
0146          * outputting to stderr.
0147          */
0148         QString errorReport() const { return m_errorReport; }
0149         /**
0150          * Call this to compile the given code. This serves as the top level of
0151          * recursion as it performs initialisation of things, to recurse at
0152          * levels use parseUsingChild(), or create your own Parser.
0153          * @param url is used for reporting errors
0154          */
0155         QString compile( const QString & url, bool optimize );
0156         /**
0157          * Adds the given compiler error at the file line number to the
0158          * compilation report.
0159          */
0160         void compileError( MistakeType type, const QString & context, const SourceLineMicrobe & sourceLine );
0161         /**
0162          * This is for generating unique numbers for computer generated labels.
0163          */
0164         QString uniqueLabel() { return QString("__%1").arg(m_uniqueLabel++); }
0165         /**
0166          * If alias is an alias for something then it returns that something,
0167          * otherwise it just returns alias (which in that case is not an alias!)
0168          */
0169         QString alias( const QString & alias ) const;
0170         /**
0171          * Aliases the name to the dest.
0172          */
0173         void addAlias( const QString & name, const QString & dest );
0174         /**
0175          * Tell MicrobeApp that a minimum of the given delay routine needs to be
0176          * created.
0177          * @see PIC14::DelaySubroutine
0178          * @param routine - DelaySubroutine enum, higher is more priority
0179          */
0180         void addDelayRoutineWanted( unsigned routine );
0181         /**
0182          * Makes a new PIC assembly object, based on the PIC string that the
0183          * user has given in the source.
0184          */
0185         PIC14 * makePic();
0186         /**
0187          * Add the interrupt as being used, i.e. make sure there is one and only
0188          * one occurance of its name in m_usedInterrupts.
0189          */ 
0190         void setInterruptUsed( const QString & interruptName );
0191         /**
0192          * @returns whether the given interrupt has already been used.
0193          */
0194         bool isInterruptUsed( const QString & interruptName );
0195         /**
0196          * @returns whether the variable name is valid.
0197          */
0198         static bool isValidVariableName( const QString & variableName );
0199         /**
0200          * Appends the given variable name to the variable list.
0201          */
0202         void addVariable( const Variable & variable );
0203         /**
0204          * @returns the variable with the given name, or one of invalidType if
0205          * no such variable exists.
0206          */
0207         Variable variable( const QString & variableName ) const;
0208         /**
0209          * @returns whether the variable has been declared yet.
0210          */
0211         bool isVariableKnown( const QString & variableName ) const;
0212         /**
0213          * This is used as a temporary variable while evaluating an expression.
0214          */
0215         QString dest() const;
0216         void incDest();
0217         void decDest();
0218         void resetDest();
0219     
0220     protected:
0221         /**
0222          * Strips comments from m_program, simplifies the white space in each line,
0223          * puts braces on separate lines, and then removes any blank lines.
0224          */
0225         void simplifyProgram();
0226     
0227         QStringList m_usedInterrupts;
0228         SourceLineList m_program;
0229         QString m_errorReport;
0230         int m_uniqueLabel;
0231         VariableList m_variables;
0232         int m_dest;
0233         unsigned m_maxDelaySubroutine;
0234     
0235         /**
0236          * Keeps a list of aliases that have been created which maps the key as
0237          * the alias text to the data which is the thing being aliased, so that
0238          * something can be  aliased to two different things. e.g. 
0239          * alias ken bob
0240          * alias mary bob
0241          */
0242         QMap<QString,QString> m_aliasList;
0243         /**
0244          * Once the child parser has found it, this is set to the pic type
0245          * string found in the source file. The pic type directive must be
0246          * the first thing in the microbe program, before even includes.
0247          * @see PIC14::Type
0248          */
0249         int m_picType;
0250 };
0251 
0252 
0253 #endif
0254