summaryrefslogtreecommitdiffstats
path: root/microbe/microbe.h
blob: 59d0bb94f613dee7aff9bf7e3b818bb2c614acbd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
/***************************************************************************
 *   Copyright (C) 2004-2005 by Daniel Clarke                              *
 *   [email protected]                                                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
 ***************************************************************************/

#ifndef MICROBE_H
#define MICROBE_H

#include <instruction.h>
#include <variable.h>
// #include <pic14.h>

#include <tqmap.h>
#include <tqstring.h>
#include <tqstringlist.h>

class TQString;
class BTreeBase;
class BTreeNode;
class Code;
class PIC14;
class PortPin;

typedef TQValueList<PortPin> PortPinList;

typedef TQValueList<Variable> VariableList;
typedef TQMap<TQString,TQString> AliasMap;

enum ExprType
{
	unset		= 1,
	working		= 2,
	number		= 3,
	variable	= 4,
	extpin		= 5,
	keypad		= 6,
};


class SourceLine;
typedef TQValueList<SourceLine> SourceLineList;
/**
Represents a source line, with the convention of line number starting at zero.
@author David Saxton
*/
class SourceLine
{
	public:
		/**
		 * The TQValueList template requires a default constructor - calling this
		 * though creates an invalid SourceLine with line() returning -1. So
		 * this constructor should never be used.
		 */
		SourceLine();
		SourceLine( const TQString & text, const TQString & url, int line );
		
		TQString text() const { return m_text; }
		TQString url() const { return m_url; }
		int line() const { return m_line; }
		
		/**
		 * Extracts the text from each SourceLine and adds it to the
		 * returned TQStringList.
		 */
		static TQStringList toStringList( const SourceLineList & lines );
		
	protected:
		TQString m_text;
		TQString m_url;
		int m_line;
};


	
/**
@author Daniel Clarke
@author David Saxton
*/
class Microbe
{
	public:
		Microbe();
		~Microbe();
		
		enum MistakeType
		{
			UnknownStatement = 1,
			InvalidPort = 2,
			UnassignedPin = 3, // pin identifier without an "= something"
			NonHighLowPinState = 4,
			UnassignedPort = 5, // port identifier without an "= something"
			UnexpectedStatementBeforeBracket = 6,
			MismatchedBrackets = 7,
			InvalidEquals = 8,
			ReservedKeyword = 9,
			ConsecutiveOperators = 10,
			MissingOperator = 11,
			UnknownVariable = 12,
			UnopenableInclude = 16,
			DivisionByZero = 17,
			NumberTooBig = 18,
			NonConstantStep = 19,
			NonConstantDelay = 20,
			HighLowExpected = 21,
			InvalidComparison = 22,
			SubBeforeEnd = 23,
			LabelExpected = 24,
			TooManyTokens = 25,
			FixedStringExpected = 26,
			PinListExpected = 27,
			AliasRedefined = 28,
			InvalidInterrupt = 29,
			InterruptRedefined = 30,
			InterruptBeforeEnd = 31,
			ReadOnlyVariable = 32,
			WriteOnlyVariable = 33,
			InvalidPinMapSize = 34,
			VariableRedefined = 35,
			InvalidVariableName = 36,
			VariableExpected = 40,
			NameExpected = 41
		};
	
		/**
		 * Returns a list of errors occured during compilation, intended for
		 * outputting to stderr.
		 */
		TQString errorReport() const { return m_errorReport; }
		/**
		 * Call this to compile the given code. This serves as the top level of
		 * recursion as it performs initialisation of things, to recurse at
		 * levels use parseUsingChild(), or create your own Parser.
		 * @param url is used for reporting errors
		 */
		TQString compile( const TQString & url, bool showSource, bool optimize );
		/**
		 * Adds the given compiler error at the file line number to the
		 * compilation report.
		 */
		void compileError( MistakeType type, const TQString & context, const SourceLine & sourceLine );
		/**
		 * This is for generating unique numbers for computer generated labels.
		 */
		TQString uniqueLabel() { return TQString("__%1").arg(m_uniqueLabel++); }
		/**
		 * If alias is an alias for something then it returns that something,
		 * otherwise it just returns alias (which in that case is not an alias!)
		 */
		TQString alias( const TQString & alias ) const;
		/**
		 * Aliases the name to the dest.
		 */
		void addAlias( const TQString & name, const TQString & dest );
		/**
		 * Tell Microbe that a minimum of the given delay routine needs to be
		 * created.
		 * @see PIC14::DelaySubroutine
		 * @param routine - DelaySubroutine enum, higher is more priority
		 */
		void addDelayRoutineWanted( unsigned routine );
		/**
		 * Makes a new PIC assembly object, based on the PIC string that the
		 * user has given in the source.
		 */
		PIC14 * makePic();
		/**
		 * Add the interrupt as being used, i.e. make sure there is one and only
		 * one occurance of its name in m_usedInterrupts.
		 */ 
		void setInterruptUsed( const TQString & interruptName );
		/**
		 * @returns whether the given interrupt has already been used.
		 */
		bool isInterruptUsed( const TQString & interruptName );
		/**
		 * @returns whether the variable name is valid.
		 */
		static bool isValidVariableName( const TQString & variableName );
		/**
		 * Appends the given variable name to the variable list.
		 */
		void addVariable( const Variable & variable );
		/**
		 * @returns the variable with the given name, or one of invalidType if
		 * no such variable exists.
		 */
		Variable variable( const TQString & variableName ) const;
		/**
		 * @returns whether the variable has been declared yet.
		 */
		bool isVariableKnown( const TQString & variableName ) const;
		/**
		 * This is used as a temporary variable while evaluating an expression.
		 */
		TQString dest() const;
		void incDest();
		void decDest();
		void resetDest();
	
	protected:
		/**
		 * Strips comments from m_program, simplifies the white space in each line,
		 * puts braces on separate lines, and then removes any blank lines.
		 */
		void simplifyProgram();
	
		TQStringList m_usedInterrupts;
		SourceLineList m_program;
		TQString m_errorReport;
		int m_uniqueLabel;
		VariableList m_variables;
		int m_dest;
		unsigned m_maxDelaySubroutine;
	
		/**
		 * Keeps a list of aliases that have been created which maps the key as
		 * the alias text to the data which is the thing being aliased, so that
		 * something can be  aliased to two different things. e.g. 
		 * alias ken bob
		 * alias mary bob
		 */
		TQMap<TQString,TQString> m_aliasList;
		/**
		 * Once the child parser has found it, this is set to the pic type
		 * string found in the source file. The pic type directive must be
		 * the first thing in the microbe program, before even includes.
		 * @see PIC14::Type
		 */
		int m_picType;
};


#endif