src/Parser.h

changeset 119
bdf8d46c145f
parent 118
e3361cf7cbf4
child 120
5ea0faefa82a
equal deleted inserted replaced
118:e3361cf7cbf4 119:bdf8d46c145f
1 /*
2 Copyright 2012-2014 Santeri Piippo
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 2. Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 3. The name of the author may not be used to endorse or promote products
15 derived from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifndef BOTC_PARSER_H
30 #define BOTC_PARSER_H
31
32 #include <stdio.h>
33 #include "Main.h"
34 #include "Commands.h"
35 #include "LexerScanner.h"
36 #include "Tokens.h"
37
38 class DataBuffer;
39 class Lexer;
40 class Variable;
41
42 // ============================================================================
43 // Mark types
44 //
45 named_enum MarkType
46 {
47 MARK_Label,
48 MARK_If,
49 MARK_Internal, // internal structures
50 };
51
52 // ============================================================================
53 // Scope types
54 //
55 named_enum ScopeType
56 {
57 SCOPE_Unknown,
58 SCOPE_If,
59 SCOPE_While,
60 SCOPE_For,
61 SCOPE_Do,
62 SCOPE_Switch,
63 SCOPE_Else,
64 };
65
66 named_enum AssignmentOperator
67 {
68 ASSIGNOP_Assign,
69 ASSIGNOP_Add,
70 ASSIGNOP_Subtract,
71 ASSIGNOP_Multiply,
72 ASSIGNOP_Divide,
73 ASSIGNOP_Modulus,
74 ASSIGNOP_Increase,
75 ASSIGNOP_Decrease,
76 };
77
78 named_enum Writability
79 {
80 WRITE_Mutable, // normal read-many-write-many variable
81 WRITE_Const, // write-once const variable
82 WRITE_Constexpr, // const variable whose value is known to compiler
83 };
84
85 // =============================================================================
86 //
87 // Parser mode: where is the parser at?
88 //
89 named_enum ParserMode
90 {
91 PARSERMODE_TopLevel, // at top level
92 PARSERMODE_Event, // inside event definition
93 PARSERMODE_MainLoop, // inside mainloop
94 PARSERMODE_Onenter, // inside onenter
95 PARSERMODE_Onexit, // inside onexit
96 };
97
98 // ============================================================================
99 //
100 struct Variable
101 {
102 String name;
103 String statename;
104 DataType type;
105 int index;
106 Writability writelevel;
107 int value;
108 String origin;
109 bool isarray;
110
111 inline bool IsGlobal() const
112 {
113 return statename.isEmpty();
114 }
115 };
116
117 // ============================================================================
118 //
119 struct CaseInfo
120 {
121 ByteMark* mark;
122 int number;
123 DataBuffer* data;
124 };
125
126 // ============================================================================
127 //
128 // Meta-data about scopes
129 //
130 struct ScopeInfo
131 {
132 ByteMark* mark1;
133 ByteMark* mark2;
134 ScopeType type;
135 DataBuffer* buffer1;
136 int globalVarIndexBase;
137 int globalArrayIndexBase;
138 int localVarIndexBase;
139
140 // switch-related stuff
141 List<CaseInfo>::Iterator casecursor;
142 List<CaseInfo> cases;
143 List<Variable*> localVariables;
144 List<Variable*> globalVariables;
145 List<Variable*> globalArrays;
146 };
147
148 // ============================================================================
149 //
150 class BotscriptParser
151 {
152 PROPERTY (public, bool, isReadOnly, setReadOnly, STOCK_WRITE)
153
154 public:
155 enum EReset
156 {
157 eNoReset,
158 SCOPE_Reset,
159 };
160
161 BotscriptParser();
162 ~BotscriptParser();
163 void parseBotscript (String fileName);
164 DataBuffer* parseCommand (CommandInfo* comm);
165 DataBuffer* parseAssignment (Variable* var);
166 AssignmentOperator parseAssignmentOperator();
167 String parseFloat();
168 void pushScope (EReset reset = SCOPE_Reset);
169 DataBuffer* parseStatement();
170 void addSwitchCase (DataBuffer* b);
171 void checkToplevel();
172 void checkNotToplevel();
173 bool tokenIs (ETokenType a);
174 String getTokenString();
175 String describePosition() const;
176 void writeToFile (String outfile);
177 Variable* findVariable (const String& name);
178 bool isInGlobalState() const;
179 void suggestHighestVarIndex (bool global, int index);
180 int getHighestVarIndex (bool global);
181
182 inline ScopeInfo& scope (int offset)
183 {
184 return m_scopeStack[m_scopeCursor - offset];
185 }
186
187 inline int numEvents() const
188 {
189 return m_numEvents;
190 }
191
192 inline int numStates() const
193 {
194 return m_numStates;
195 }
196
197 private:
198 // The main buffer - the contents of this is what we
199 // write to file after parsing is complete
200 DataBuffer* m_mainBuffer;
201
202 // onenter buffer - the contents of the onenter {} block
203 // is buffered here and is merged further at the end of state
204 DataBuffer* m_onenterBuffer;
205
206 // Mainloop buffer - the contents of the mainloop {} block
207 // is buffered here and is merged further at the end of state
208 DataBuffer* m_mainLoopBuffer;
209
210 // Switch buffer - switch case data is recorded to this
211 // buffer initially, instead of into main buffer.
212 DataBuffer* m_switchBuffer;
213
214 Lexer* m_lexer;
215 int m_numStates;
216 int m_numEvents;
217 ParserMode m_currentMode;
218 String m_currentState;
219 bool m_isStateSpawnDefined;
220 bool m_gotMainLoop;
221 int m_scopeCursor;
222 bool m_isElseAllowed;
223 int m_highestGlobalVarIndex;
224 int m_highestStateVarIndex;
225 int m_numWrittenBytes;
226 List<ScopeInfo> m_scopeStack;
227 int m_zandronumVersion;
228 bool m_defaultZandronumVersion;
229
230 DataBuffer* currentBuffer();
231 void parseStateBlock();
232 void parseEventBlock();
233 void parseMainloop();
234 void parseOnEnterExit();
235 void parseVar();
236 void parseGoto();
237 void parseIf();
238 void parseElse();
239 void parseWhileBlock();
240 void parseForBlock();
241 void parseDoBlock();
242 void parseSwitchBlock();
243 void parseSwitchCase();
244 void parseSwitchDefault();
245 void parseBreak();
246 void parseContinue();
247 void parseBlockEnd();
248 void parseLabel();
249 void parseEventdef();
250 void parseFuncdef();
251 void parseUsing();
252 void writeMemberBuffers();
253 void writeStringTable();
254 DataBuffer* parseExpression (DataType reqtype, bool fromhere = false);
255 DataHeader getAssigmentDataHeader (AssignmentOperator op, Variable* var);
256 };
257
258 #endif // BOTC_PARSER_H

mercurial