src/Parser.cc

changeset 115
9be16e1c1e44
parent 114
6cbeb9f8350f
child 116
56ff19947607
equal deleted inserted replaced
114:6cbeb9f8350f 115:9be16e1c1e44
33 #include "Containers.h" 33 #include "Containers.h"
34 #include "Lexer.h" 34 #include "Lexer.h"
35 #include "DataBuffer.h" 35 #include "DataBuffer.h"
36 #include "Expression.h" 36 #include "Expression.h"
37 37
38 #define SCOPE(n) (mScopeStack[mScopeCursor - n]) 38 #define SCOPE(n) (m_scopeStack[m_scopeCursor - n])
39 39
40 // ============================================================================ 40 // ============================================================================
41 // 41 //
42 BotscriptParser::BotscriptParser() : 42 BotscriptParser::BotscriptParser() :
43 mIsReadOnly (false), 43 m_isReadOnly (false),
44 mMainBuffer (new DataBuffer), 44 m_mainBuffer (new DataBuffer),
45 mOnEnterBuffer (new DataBuffer), 45 m_onenterBuffer (new DataBuffer),
46 mMainLoopBuffer (new DataBuffer), 46 m_mainLoopBuffer (new DataBuffer),
47 mLexer (new Lexer), 47 m_lexer (new Lexer),
48 mNumStates (0), 48 m_numStates (0),
49 mNumEvents (0), 49 m_numEvents (0),
50 mCurrentMode (PARSERMODE_TopLevel), 50 m_currentMode (PARSERMODE_TopLevel),
51 mStateSpawnDefined (false), 51 m_isStateSpawnDefined (false),
52 mGotMainLoop (false), 52 m_gotMainLoop (false),
53 mScopeCursor (-1), 53 m_scopeCursor (-1),
54 mCanElse (false), 54 m_isElseAllowed (false),
55 mHighestGlobalVarIndex (0), 55 m_highestGlobalVarIndex (0),
56 mHighestStateVarIndex (0) {} 56 m_highestStateVarIndex (0) {}
57 57
58 // ============================================================================ 58 // ============================================================================
59 // 59 //
60 BotscriptParser::~BotscriptParser() 60 BotscriptParser::~BotscriptParser()
61 { 61 {
62 delete mLexer; 62 delete m_lexer;
63 } 63 }
64 64
65 // ============================================================================ 65 // ============================================================================
66 // 66 //
67 void BotscriptParser::CheckToplevel() 67 void BotscriptParser::checkToplevel()
68 { 68 {
69 if (mCurrentMode != PARSERMODE_TopLevel) 69 if (m_currentMode != PARSERMODE_TopLevel)
70 Error ("%1-statements may only be defined at top level!", GetTokenString()); 70 error ("%1-statements may only be defined at top level!", getTokenString());
71 } 71 }
72 72
73 // ============================================================================ 73 // ============================================================================
74 // 74 //
75 void BotscriptParser::CheckNotToplevel() 75 void BotscriptParser::checkNotToplevel()
76 { 76 {
77 if (mCurrentMode == PARSERMODE_TopLevel) 77 if (m_currentMode == PARSERMODE_TopLevel)
78 Error ("%1-statements must not be defined at top level!", GetTokenString()); 78 error ("%1-statements must not be defined at top level!", getTokenString());
79 } 79 }
80 80
81 // ============================================================================ 81 // ============================================================================
82 // 82 //
83 // Main compiler code. Begins read of the script file, checks the syntax of it 83 // Main compiler code. Begins read of the script file, checks the syntax of it
84 // and writes the data to the object file via Objwriter - which also takes care 84 // and writes the data to the object file via Objwriter - which also takes care
85 // of necessary buffering so stuff is written in the correct order. 85 // of necessary buffering so stuff is written in the correct order.
86 // 86 //
87 void BotscriptParser::ParseBotscript (String fileName) 87 void BotscriptParser::parseBotscript (String fileName)
88 { 88 {
89 // Lex and preprocess the file 89 // Lex and preprocess the file
90 mLexer->ProcessFile (fileName); 90 m_lexer->processFile (fileName);
91 PushScope(); 91 pushScope();
92 92
93 while (mLexer->Next()) 93 while (m_lexer->next())
94 { 94 {
95 // Check if else is potentically valid 95 // Check if else is potentically valid
96 if (TokenIs (TK_Else) && mCanElse == false) 96 if (tokenIs (TK_Else) && m_isElseAllowed == false)
97 Error ("else without preceding if"); 97 error ("else without preceding if");
98 98
99 if (TokenIs (TK_Else) == false) 99 if (tokenIs (TK_Else) == false)
100 mCanElse = false; 100 m_isElseAllowed = false;
101 101
102 switch (mLexer->Token()->type) 102 switch (m_lexer->token()->type)
103 { 103 {
104 case TK_State: 104 case TK_State:
105 ParseStateBlock(); 105 parseStateBlock();
106 break; 106 break;
107 107
108 case TK_Event: 108 case TK_Event:
109 ParseEventBlock(); 109 parseEventBlock();
110 break; 110 break;
111 111
112 case TK_Mainloop: 112 case TK_Mainloop:
113 ParseMainloop(); 113 parseMainloop();
114 break; 114 break;
115 115
116 case TK_Onenter: 116 case TK_Onenter:
117 case TK_Onexit: 117 case TK_Onexit:
118 ParseOnEnterExit(); 118 parseOnEnterExit();
119 break; 119 break;
120 120
121 case TK_Var: 121 case TK_Var:
122 ParseVar(); 122 parseVar();
123 break; 123 break;
124 124
125 case TK_If: 125 case TK_If:
126 ParseIf(); 126 parseIf();
127 break; 127 break;
128 128
129 case TK_Else: 129 case TK_Else:
130 ParseElse(); 130 parseElse();
131 break; 131 break;
132 132
133 case TK_While: 133 case TK_While:
134 ParseWhileBlock(); 134 parseWhileBlock();
135 break; 135 break;
136 136
137 case TK_For: 137 case TK_For:
138 ParseForBlock(); 138 parseForBlock();
139 break; 139 break;
140 140
141 case TK_Do: 141 case TK_Do:
142 ParseDoBlock(); 142 parseDoBlock();
143 break; 143 break;
144 144
145 case TK_Switch: 145 case TK_Switch:
146 ParseSwitchBlock(); 146 parseSwitchBlock();
147 break; 147 break;
148 148
149 case TK_Case: 149 case TK_Case:
150 ParseSwitchCase(); 150 parseSwitchCase();
151 break; 151 break;
152 152
153 case TK_Default: 153 case TK_Default:
154 ParseSwitchDefault(); 154 parseSwitchDefault();
155 break; 155 break;
156 156
157 case TK_Break: 157 case TK_Break:
158 ParseBreak(); 158 parseBreak();
159 break; 159 break;
160 160
161 case TK_Continue: 161 case TK_Continue:
162 ParseContinue(); 162 parseContinue();
163 break; 163 break;
164 164
165 case TK_BraceEnd: 165 case TK_BraceEnd:
166 ParseBlockEnd(); 166 parseBlockEnd();
167 break; 167 break;
168 168
169 case TK_Eventdef: 169 case TK_Eventdef:
170 ParseEventdef(); 170 parseEventdef();
171 break; 171 break;
172 172
173 case TK_Funcdef: 173 case TK_Funcdef:
174 ParseFuncdef(); 174 parseFuncdef();
175 break; 175 break;
176 176
177 case TK_Semicolon: 177 case TK_Semicolon:
178 break; 178 break;
179 179
180 default: 180 default:
181 { 181 {
182 // Check if it's a command 182 // Check if it's a command
183 CommandInfo* comm = FindCommandByName (GetTokenString()); 183 CommandInfo* comm = findCommandByName (getTokenString());
184 184
185 if (comm) 185 if (comm)
186 { 186 {
187 buffer()->MergeAndDestroy (ParseCommand (comm)); 187 currentBuffer()->mergeAndDestroy (parseCommand (comm));
188 mLexer->MustGetNext (TK_Semicolon); 188 m_lexer->mustGetNext (TK_Semicolon);
189 continue; 189 continue;
190 } 190 }
191 191
192 // If nothing else, parse it as a statement 192 // If nothing else, parse it as a statement
193 mLexer->Skip (-1); 193 m_lexer->skip (-1);
194 DataBuffer* b = ParseStatement(); 194 DataBuffer* b = parseStatement();
195 195
196 if (b == false) 196 if (b == false)
197 { 197 {
198 mLexer->Next(); 198 m_lexer->next();
199 Error ("unknown token `%1`", GetTokenString()); 199 error ("unknown token `%1`", getTokenString());
200 } 200 }
201 201
202 buffer()->MergeAndDestroy (b); 202 currentBuffer()->mergeAndDestroy (b);
203 mLexer->MustGetNext (TK_Semicolon); 203 m_lexer->mustGetNext (TK_Semicolon);
204 break; 204 break;
205 } 205 }
206 } 206 }
207 } 207 }
208 208
209 // =============================================================================== 209 // ===============================================================================
210 // Script file ended. Do some last checks and write the last things to main buffer 210 // Script file ended. Do some last checks and write the last things to main buffer
211 if (mCurrentMode != PARSERMODE_TopLevel) 211 if (m_currentMode != PARSERMODE_TopLevel)
212 Error ("script did not end at top level; a `}` is missing somewhere"); 212 error ("script did not end at top level; a `}` is missing somewhere");
213 213
214 if (IsReadOnly() == false) 214 if (isReadOnly() == false)
215 { 215 {
216 // stateSpawn must be defined! 216 // stateSpawn must be defined!
217 if (mStateSpawnDefined == false) 217 if (m_isStateSpawnDefined == false)
218 Error ("script must have a state named `stateSpawn`!"); 218 error ("script must have a state named `stateSpawn`!");
219 219
220 // Dump the last state's onenter and mainloop 220 // Dump the last state's onenter and mainloop
221 writeMemberBuffers(); 221 writeMemberBuffers();
222 222
223 // String table 223 // String table
224 WriteStringTable(); 224 writeStringTable();
225 } 225 }
226 } 226 }
227 227
228 // ============================================================================ 228 // ============================================================================
229 // 229 //
230 void BotscriptParser::ParseStateBlock() 230 void BotscriptParser::parseStateBlock()
231 { 231 {
232 CheckToplevel(); 232 checkToplevel();
233 mLexer->MustGetNext (TK_String); 233 m_lexer->mustGetNext (TK_String);
234 String statename = GetTokenString(); 234 String statename = getTokenString();
235 235
236 // State name must be a word. 236 // State name must be a word.
237 if (statename.FirstIndexOf (" ") != -1) 237 if (statename.firstIndexOf (" ") != -1)
238 Error ("state name must be a single word, got `%1`", statename); 238 error ("state name must be a single word, got `%1`", statename);
239 239
240 // stateSpawn is special - it *must* be defined. If we 240 // stateSpawn is special - it *must* be defined. If we
241 // encountered it, then mark down that we have it. 241 // encountered it, then mark down that we have it.
242 if (statename.ToLowercase() == "statespawn") 242 if (statename.toLowercase() == "statespawn")
243 mStateSpawnDefined = true; 243 m_isStateSpawnDefined = true;
244 244
245 // Must end in a colon 245 // Must end in a colon
246 mLexer->MustGetNext (TK_Colon); 246 m_lexer->mustGetNext (TK_Colon);
247 247
248 // write the previous state's onenter and 248 // write the previous state's onenter and
249 // mainloop buffers to file now 249 // mainloop buffers to file now
250 if (mCurrentState.IsEmpty() == false) 250 if (m_currentState.isEmpty() == false)
251 writeMemberBuffers(); 251 writeMemberBuffers();
252 252
253 buffer()->WriteDWord (DH_StateName); 253 currentBuffer()->writeDWord (DH_StateName);
254 buffer()->WriteString (statename); 254 currentBuffer()->writeString (statename);
255 buffer()->WriteDWord (DH_StateIndex); 255 currentBuffer()->writeDWord (DH_StateIndex);
256 buffer()->WriteDWord (mNumStates); 256 currentBuffer()->writeDWord (m_numStates);
257 257
258 mNumStates++; 258 m_numStates++;
259 mCurrentState = statename; 259 m_currentState = statename;
260 mGotMainLoop = false; 260 m_gotMainLoop = false;
261 } 261 }
262 262
263 // ============================================================================ 263 // ============================================================================
264 // 264 //
265 void BotscriptParser::ParseEventBlock() 265 void BotscriptParser::parseEventBlock()
266 { 266 {
267 CheckToplevel(); 267 checkToplevel();
268 mLexer->MustGetNext (TK_String); 268 m_lexer->mustGetNext (TK_String);
269 269
270 EventDefinition* e = FindEventByName (GetTokenString()); 270 EventDefinition* e = findEventByName (getTokenString());
271 271
272 if (e == null) 272 if (e == null)
273 Error ("bad event, got `%1`\n", GetTokenString()); 273 error ("bad event, got `%1`\n", getTokenString());
274 274
275 mLexer->MustGetNext (TK_BraceStart); 275 m_lexer->mustGetNext (TK_BraceStart);
276 mCurrentMode = PARSERMODE_Event; 276 m_currentMode = PARSERMODE_Event;
277 buffer()->WriteDWord (DH_Event); 277 currentBuffer()->writeDWord (DH_Event);
278 buffer()->WriteDWord (e->number); 278 currentBuffer()->writeDWord (e->number);
279 mNumEvents++; 279 m_numEvents++;
280 } 280 }
281 281
282 // ============================================================================ 282 // ============================================================================
283 // 283 //
284 void BotscriptParser::ParseMainloop() 284 void BotscriptParser::parseMainloop()
285 { 285 {
286 CheckToplevel(); 286 checkToplevel();
287 mLexer->MustGetNext (TK_BraceStart); 287 m_lexer->mustGetNext (TK_BraceStart);
288 288
289 mCurrentMode = PARSERMODE_MainLoop; 289 m_currentMode = PARSERMODE_MainLoop;
290 mMainLoopBuffer->WriteDWord (DH_MainLoop); 290 m_mainLoopBuffer->writeDWord (DH_MainLoop);
291 } 291 }
292 292
293 // ============================================================================ 293 // ============================================================================
294 // 294 //
295 void BotscriptParser::ParseOnEnterExit() 295 void BotscriptParser::parseOnEnterExit()
296 { 296 {
297 CheckToplevel(); 297 checkToplevel();
298 bool onenter = (TokenIs (TK_Onenter)); 298 bool onenter = (tokenIs (TK_Onenter));
299 mLexer->MustGetNext (TK_BraceStart); 299 m_lexer->mustGetNext (TK_BraceStart);
300 300
301 mCurrentMode = onenter ? PARSERMODE_Onenter : PARSERMODE_Onexit; 301 m_currentMode = onenter ? PARSERMODE_Onenter : PARSERMODE_Onexit;
302 buffer()->WriteDWord (onenter ? DH_OnEnter : DH_OnExit); 302 currentBuffer()->writeDWord (onenter ? DH_OnEnter : DH_OnExit);
303 } 303 }
304 304
305 // ============================================================================ 305 // ============================================================================
306 // 306 //
307 void BotscriptParser::ParseVar() 307 void BotscriptParser::parseVar()
308 { 308 {
309 Variable* var = new Variable; 309 Variable* var = new Variable;
310 var->origin = mLexer->DescribeCurrentPosition(); 310 var->origin = m_lexer->describeCurrentPosition();
311 var->isarray = false; 311 var->isarray = false;
312 const bool isconst = mLexer->Next (TK_Const); 312 const bool isconst = m_lexer->next (TK_Const);
313 mLexer->MustGetAnyOf ({TK_Int,TK_Str,TK_Void}); 313 m_lexer->mustGetAnyOf ({TK_Int,TK_Str,TK_Void});
314 314
315 DataType vartype = (TokenIs (TK_Int)) ? TYPE_Int : 315 DataType vartype = (tokenIs (TK_Int)) ? TYPE_Int :
316 (TokenIs (TK_Str)) ? TYPE_String : 316 (tokenIs (TK_Str)) ? TYPE_String :
317 TYPE_Bool; 317 TYPE_Bool;
318 318
319 mLexer->MustGetNext (TK_DollarSign); 319 m_lexer->mustGetNext (TK_DollarSign);
320 mLexer->MustGetNext (TK_Symbol); 320 m_lexer->mustGetNext (TK_Symbol);
321 String name = GetTokenString(); 321 String name = getTokenString();
322 322
323 if (mLexer->Next (TK_BracketStart)) 323 if (m_lexer->next (TK_BracketStart))
324 { 324 {
325 mLexer->MustGetNext (TK_BracketEnd); 325 m_lexer->mustGetNext (TK_BracketEnd);
326 var->isarray = true; 326 var->isarray = true;
327 327
328 if (isconst) 328 if (isconst)
329 Error ("arrays cannot be const"); 329 error ("arrays cannot be const");
330 } 330 }
331 331
332 for (Variable* var : SCOPE(0).globalVariables + SCOPE(0).localVariables) 332 for (Variable* var : SCOPE(0).globalVariables + SCOPE(0).localVariables)
333 { 333 {
334 if (var->name == name) 334 if (var->name == name)
335 Error ("Variable $%1 is already declared on this scope; declared at %2", 335 error ("Variable $%1 is already declared on this scope; declared at %2",
336 var->name, var->origin); 336 var->name, var->origin);
337 } 337 }
338 338
339 var->name = name; 339 var->name = name;
340 var->statename = ""; 340 var->statename = "";
344 { 344 {
345 var->writelevel = WRITE_Mutable; 345 var->writelevel = WRITE_Mutable;
346 } 346 }
347 else 347 else
348 { 348 {
349 mLexer->MustGetNext (TK_Assign); 349 m_lexer->mustGetNext (TK_Assign);
350 Expression expr (this, mLexer, vartype); 350 Expression expr (this, m_lexer, vartype);
351 351
352 // If the expression was constexpr, we know its value and thus 352 // If the expression was constexpr, we know its value and thus
353 // can store it in the variable. 353 // can store it in the variable.
354 if (expr.Result()->IsConstexpr()) 354 if (expr.getResult()->isConstexpr())
355 { 355 {
356 var->writelevel = WRITE_Constexpr; 356 var->writelevel = WRITE_Constexpr;
357 var->value = expr.Result()->Value(); 357 var->value = expr.getResult()->value();
358 } 358 }
359 else 359 else
360 { 360 {
361 // TODO: might need a VM-wise oninit for this... 361 // TODO: might need a VM-wise oninit for this...
362 Error ("const variables must be constexpr"); 362 error ("const variables must be constexpr");
363 } 363 }
364 } 364 }
365 365
366 // Assign an index for the variable if it is not constexpr. Constexpr 366 // Assign an index for the variable if it is not constexpr. Constexpr
367 // variables can simply be substituted out for their value when used 367 // variables can simply be substituted out for their value when used
368 // so they need no index. 368 // so they need no index.
369 if (var->writelevel != WRITE_Constexpr) 369 if (var->writelevel != WRITE_Constexpr)
370 { 370 {
371 bool isglobal = IsInGlobalState(); 371 bool isglobal = isInGlobalState();
372 var->index = isglobal ? SCOPE(0).globalVarIndexBase++ : SCOPE(0).localVarIndexBase++; 372 var->index = isglobal ? SCOPE(0).globalVarIndexBase++ : SCOPE(0).localVarIndexBase++;
373 373
374 if ((isglobal == true && var->index >= gMaxGlobalVars) || 374 if ((isglobal == true && var->index >= gMaxGlobalVars) ||
375 (isglobal == false && var->index >= gMaxStateVars)) 375 (isglobal == false && var->index >= gMaxStateVars))
376 { 376 {
377 Error ("too many %1 variables", isglobal ? "global" : "state-local"); 377 error ("too many %1 variables", isglobal ? "global" : "state-local");
378 } 378 }
379 } 379 }
380 380
381 if (IsInGlobalState()) 381 if (isInGlobalState())
382 SCOPE(0).globalVariables << var; 382 SCOPE(0).globalVariables << var;
383 else 383 else
384 SCOPE(0).localVariables << var; 384 SCOPE(0).localVariables << var;
385 385
386 SuggestHighestVarIndex (IsInGlobalState(), var->index); 386 suggestHighestVarIndex (isInGlobalState(), var->index);
387 mLexer->MustGetNext (TK_Semicolon); 387 m_lexer->mustGetNext (TK_Semicolon);
388 Print ("Declared %3 variable #%1 $%2\n", var->index, var->name, IsInGlobalState() ? "global" : "state-local"); 388 print ("Declared %3 variable #%1 $%2\n", var->index, var->name, isInGlobalState() ? "global" : "state-local");
389 } 389 }
390 390
391 // ============================================================================ 391 // ============================================================================
392 // 392 //
393 void BotscriptParser::ParseIf() 393 void BotscriptParser::parseIf()
394 { 394 {
395 CheckNotToplevel(); 395 checkNotToplevel();
396 PushScope(); 396 pushScope();
397 397
398 // Condition 398 // Condition
399 mLexer->MustGetNext (TK_ParenStart); 399 m_lexer->mustGetNext (TK_ParenStart);
400 400
401 // Read the expression and write it. 401 // Read the expression and write it.
402 DataBuffer* c = ParseExpression (TYPE_Int); 402 DataBuffer* c = parseExpression (TYPE_Int);
403 buffer()->MergeAndDestroy (c); 403 currentBuffer()->mergeAndDestroy (c);
404 404
405 mLexer->MustGetNext (TK_ParenEnd); 405 m_lexer->mustGetNext (TK_ParenEnd);
406 mLexer->MustGetNext (TK_BraceStart); 406 m_lexer->mustGetNext (TK_BraceStart);
407 407
408 // Add a mark - to here temporarily - and add a reference to it. 408 // Add a mark - to here temporarily - and add a reference to it.
409 // Upon a closing brace, the mark will be adjusted. 409 // Upon a closing brace, the mark will be adjusted.
410 ByteMark* mark = buffer()->AddMark (""); 410 ByteMark* mark = currentBuffer()->addMark ("");
411 411
412 // Use DH_IfNotGoto - if the expression is not true, we goto the mark 412 // Use DH_IfNotGoto - if the expression is not true, we goto the mark
413 // we just defined - and this mark will be at the end of the scope block. 413 // we just defined - and this mark will be at the end of the scope block.
414 buffer()->WriteDWord (DH_IfNotGoto); 414 currentBuffer()->writeDWord (DH_IfNotGoto);
415 buffer()->AddReference (mark); 415 currentBuffer()->addReference (mark);
416 416
417 // Store it 417 // Store it
418 SCOPE (0).mark1 = mark; 418 SCOPE (0).mark1 = mark;
419 SCOPE (0).type = SCOPE_If; 419 SCOPE (0).type = SCOPE_If;
420 } 420 }
421 421
422 // ============================================================================ 422 // ============================================================================
423 // 423 //
424 void BotscriptParser::ParseElse() 424 void BotscriptParser::parseElse()
425 { 425 {
426 CheckNotToplevel(); 426 checkNotToplevel();
427 mLexer->MustGetNext (TK_BraceStart); 427 m_lexer->mustGetNext (TK_BraceStart);
428 PushScope (eNoReset); 428 pushScope (eNoReset);
429 429
430 if (SCOPE (0).type != SCOPE_If) 430 if (SCOPE (0).type != SCOPE_If)
431 Error ("else without preceding if"); 431 error ("else without preceding if");
432 432
433 // write down to jump to the end of the else statement 433 // write down to jump to the end of the else statement
434 // Otherwise we have fall-throughs 434 // Otherwise we have fall-throughs
435 SCOPE (0).mark2 = buffer()->AddMark (""); 435 SCOPE (0).mark2 = currentBuffer()->addMark ("");
436 436
437 // Instruction to jump to the end after if block is complete 437 // Instruction to jump to the end after if block is complete
438 buffer()->WriteDWord (DH_Goto); 438 currentBuffer()->writeDWord (DH_Goto);
439 buffer()->AddReference (SCOPE (0).mark2); 439 currentBuffer()->addReference (SCOPE (0).mark2);
440 440
441 // Move the ifnot mark here and set type to else 441 // Move the ifnot mark here and set type to else
442 buffer()->AdjustMark (SCOPE (0).mark1); 442 currentBuffer()->adjustMark (SCOPE (0).mark1);
443 SCOPE (0).type = SCOPE_Else; 443 SCOPE (0).type = SCOPE_Else;
444 } 444 }
445 445
446 // ============================================================================ 446 // ============================================================================
447 // 447 //
448 void BotscriptParser::ParseWhileBlock() 448 void BotscriptParser::parseWhileBlock()
449 { 449 {
450 CheckNotToplevel(); 450 checkNotToplevel();
451 PushScope(); 451 pushScope();
452 452
453 // While loops need two marks - one at the start of the loop and one at the 453 // While loops need two marks - one at the start of the loop and one at the
454 // end. The condition is checked at the very start of the loop, if it fails, 454 // end. The condition is checked at the very start of the loop, if it fails,
455 // we use goto to skip to the end of the loop. At the end, we loop back to 455 // we use goto to skip to the end of the loop. At the end, we loop back to
456 // the beginning with a go-to statement. 456 // the beginning with a go-to statement.
457 ByteMark* mark1 = buffer()->AddMark (""); // start 457 ByteMark* mark1 = currentBuffer()->addMark (""); // start
458 ByteMark* mark2 = buffer()->AddMark (""); // end 458 ByteMark* mark2 = currentBuffer()->addMark (""); // end
459 459
460 // Condition 460 // Condition
461 mLexer->MustGetNext (TK_ParenStart); 461 m_lexer->mustGetNext (TK_ParenStart);
462 DataBuffer* expr = ParseExpression (TYPE_Int); 462 DataBuffer* expr = parseExpression (TYPE_Int);
463 mLexer->MustGetNext (TK_ParenEnd); 463 m_lexer->mustGetNext (TK_ParenEnd);
464 mLexer->MustGetNext (TK_BraceStart); 464 m_lexer->mustGetNext (TK_BraceStart);
465 465
466 // write condition 466 // write condition
467 buffer()->MergeAndDestroy (expr); 467 currentBuffer()->mergeAndDestroy (expr);
468 468
469 // Instruction to go to the end if it fails 469 // Instruction to go to the end if it fails
470 buffer()->WriteDWord (DH_IfNotGoto); 470 currentBuffer()->writeDWord (DH_IfNotGoto);
471 buffer()->AddReference (mark2); 471 currentBuffer()->addReference (mark2);
472 472
473 // Store the needed stuff 473 // Store the needed stuff
474 SCOPE (0).mark1 = mark1; 474 SCOPE (0).mark1 = mark1;
475 SCOPE (0).mark2 = mark2; 475 SCOPE (0).mark2 = mark2;
476 SCOPE (0).type = SCOPE_While; 476 SCOPE (0).type = SCOPE_While;
477 } 477 }
478 478
479 // ============================================================================ 479 // ============================================================================
480 // 480 //
481 void BotscriptParser::ParseForBlock() 481 void BotscriptParser::parseForBlock()
482 { 482 {
483 CheckNotToplevel(); 483 checkNotToplevel();
484 PushScope(); 484 pushScope();
485 485
486 // Initializer 486 // Initializer
487 mLexer->MustGetNext (TK_ParenStart); 487 m_lexer->mustGetNext (TK_ParenStart);
488 DataBuffer* init = ParseStatement(); 488 DataBuffer* init = parseStatement();
489 489
490 if (init == null) 490 if (init == null)
491 Error ("bad statement for initializer of for"); 491 error ("bad statement for initializer of for");
492 492
493 mLexer->MustGetNext (TK_Semicolon); 493 m_lexer->mustGetNext (TK_Semicolon);
494 494
495 // Condition 495 // Condition
496 DataBuffer* cond = ParseExpression (TYPE_Int); 496 DataBuffer* cond = parseExpression (TYPE_Int);
497 497
498 if (cond == null) 498 if (cond == null)
499 Error ("bad statement for condition of for"); 499 error ("bad statement for condition of for");
500 500
501 mLexer->MustGetNext (TK_Semicolon); 501 m_lexer->mustGetNext (TK_Semicolon);
502 502
503 // Incrementor 503 // Incrementor
504 DataBuffer* incr = ParseStatement(); 504 DataBuffer* incr = parseStatement();
505 505
506 if (incr == null) 506 if (incr == null)
507 Error ("bad statement for incrementor of for"); 507 error ("bad statement for incrementor of for");
508 508
509 mLexer->MustGetNext (TK_ParenEnd); 509 m_lexer->mustGetNext (TK_ParenEnd);
510 mLexer->MustGetNext (TK_BraceStart); 510 m_lexer->mustGetNext (TK_BraceStart);
511 511
512 // First, write out the initializer 512 // First, write out the initializer
513 buffer()->MergeAndDestroy (init); 513 currentBuffer()->mergeAndDestroy (init);
514 514
515 // Init two marks 515 // Init two marks
516 ByteMark* mark1 = buffer()->AddMark (""); 516 ByteMark* mark1 = currentBuffer()->addMark ("");
517 ByteMark* mark2 = buffer()->AddMark (""); 517 ByteMark* mark2 = currentBuffer()->addMark ("");
518 518
519 // Add the condition 519 // Add the condition
520 buffer()->MergeAndDestroy (cond); 520 currentBuffer()->mergeAndDestroy (cond);
521 buffer()->WriteDWord (DH_IfNotGoto); 521 currentBuffer()->writeDWord (DH_IfNotGoto);
522 buffer()->AddReference (mark2); 522 currentBuffer()->addReference (mark2);
523 523
524 // Store the marks and incrementor 524 // Store the marks and incrementor
525 SCOPE (0).mark1 = mark1; 525 SCOPE (0).mark1 = mark1;
526 SCOPE (0).mark2 = mark2; 526 SCOPE (0).mark2 = mark2;
527 SCOPE (0).buffer1 = incr; 527 SCOPE (0).buffer1 = incr;
528 SCOPE (0).type = SCOPE_For; 528 SCOPE (0).type = SCOPE_For;
529 } 529 }
530 530
531 // ============================================================================ 531 // ============================================================================
532 // 532 //
533 void BotscriptParser::ParseDoBlock() 533 void BotscriptParser::parseDoBlock()
534 { 534 {
535 CheckNotToplevel(); 535 checkNotToplevel();
536 PushScope(); 536 pushScope();
537 mLexer->MustGetNext (TK_BraceStart); 537 m_lexer->mustGetNext (TK_BraceStart);
538 SCOPE (0).mark1 = buffer()->AddMark (""); 538 SCOPE (0).mark1 = currentBuffer()->addMark ("");
539 SCOPE (0).type = SCOPE_Do; 539 SCOPE (0).type = SCOPE_Do;
540 } 540 }
541 541
542 // ============================================================================ 542 // ============================================================================
543 // 543 //
544 void BotscriptParser::ParseSwitchBlock() 544 void BotscriptParser::parseSwitchBlock()
545 { 545 {
546 // This gets a bit tricky. switch is structured in the 546 // This gets a bit tricky. switch is structured in the
547 // bytecode followingly: 547 // bytecode followingly:
548 // 548 //
549 // (expression) 549 // (expression)
554 // casemark1: ... 554 // casemark1: ...
555 // casemark2: ... 555 // casemark2: ...
556 // casemark3: ... 556 // casemark3: ...
557 // mark1: // end mark 557 // mark1: // end mark
558 558
559 CheckNotToplevel(); 559 checkNotToplevel();
560 PushScope(); 560 pushScope();
561 mLexer->MustGetNext (TK_ParenStart); 561 m_lexer->mustGetNext (TK_ParenStart);
562 buffer()->MergeAndDestroy (ParseExpression (TYPE_Int)); 562 currentBuffer()->mergeAndDestroy (parseExpression (TYPE_Int));
563 mLexer->MustGetNext (TK_ParenEnd); 563 m_lexer->mustGetNext (TK_ParenEnd);
564 mLexer->MustGetNext (TK_BraceStart); 564 m_lexer->mustGetNext (TK_BraceStart);
565 SCOPE (0).type = SCOPE_Switch; 565 SCOPE (0).type = SCOPE_Switch;
566 SCOPE (0).mark1 = buffer()->AddMark (""); // end mark 566 SCOPE (0).mark1 = currentBuffer()->addMark (""); // end mark
567 SCOPE (0).buffer1 = null; // default header 567 SCOPE (0).buffer1 = null; // default header
568 } 568 }
569 569
570 // ============================================================================ 570 // ============================================================================
571 // 571 //
572 void BotscriptParser::ParseSwitchCase() 572 void BotscriptParser::parseSwitchCase()
573 { 573 {
574 // case is only allowed inside switch 574 // case is only allowed inside switch
575 if (SCOPE (0).type != SCOPE_Switch) 575 if (SCOPE (0).type != SCOPE_Switch)
576 Error ("case label outside switch"); 576 error ("case label outside switch");
577 577
578 // Get a literal value for the case block. Zandronum does not support 578 // Get a literal value for the case block. Zandronum does not support
579 // expressions here. 579 // expressions here.
580 mLexer->MustGetNext (TK_Number); 580 m_lexer->mustGetNext (TK_Number);
581 int num = mLexer->Token()->text.ToLong(); 581 int num = m_lexer->token()->text.toLong();
582 mLexer->MustGetNext (TK_Colon); 582 m_lexer->mustGetNext (TK_Colon);
583 583
584 for (const CaseInfo& info : SCOPE(0).cases) 584 for (const CaseInfo& info : SCOPE(0).cases)
585 if (info.number == num) 585 if (info.number == num)
586 Error ("multiple case %1 labels in one switch", num); 586 error ("multiple case %1 labels in one switch", num);
587 587
588 // Write down the expression and case-go-to. This builds 588 // Write down the expression and case-go-to. This builds
589 // the case tree. The closing event will write the actual 589 // the case tree. The closing event will write the actual
590 // blocks and move the marks appropriately. 590 // blocks and move the marks appropriately.
591 // 591 //
593 // for the case block that this heralds, and takes care 593 // for the case block that this heralds, and takes care
594 // of buffering setup and stuff like that. 594 // of buffering setup and stuff like that.
595 // 595 //
596 // We null the switch buffer for the case-go-to statement as 596 // We null the switch buffer for the case-go-to statement as
597 // we want it all under the switch, not into the case-buffers. 597 // we want it all under the switch, not into the case-buffers.
598 mSwitchBuffer = null; 598 m_switchBuffer = null;
599 buffer()->WriteDWord (DH_CaseGoto); 599 currentBuffer()->writeDWord (DH_CaseGoto);
600 buffer()->WriteDWord (num); 600 currentBuffer()->writeDWord (num);
601 AddSwitchCase (null); 601 addSwitchCase (null);
602 SCOPE (0).casecursor->number = num; 602 SCOPE (0).casecursor->number = num;
603 } 603 }
604 604
605 // ============================================================================ 605 // ============================================================================
606 // 606 //
607 void BotscriptParser::ParseSwitchDefault() 607 void BotscriptParser::parseSwitchDefault()
608 { 608 {
609 if (SCOPE (0).type != SCOPE_Switch) 609 if (SCOPE (0).type != SCOPE_Switch)
610 Error ("default label outside switch"); 610 error ("default label outside switch");
611 611
612 if (SCOPE (0).buffer1 != null) 612 if (SCOPE (0).buffer1 != null)
613 Error ("multiple default labels in one switch"); 613 error ("multiple default labels in one switch");
614 614
615 mLexer->MustGetNext (TK_Colon); 615 m_lexer->mustGetNext (TK_Colon);
616 616
617 // The default header is buffered into buffer1, since 617 // The default header is buffered into buffer1, since
618 // it has to be the last of the case headers 618 // it has to be the last of the case headers
619 // 619 //
620 // Since the expression is pushed into the switch 620 // Since the expression is pushed into the switch
621 // and is only popped when case succeeds, we have 621 // and is only popped when case succeeds, we have
622 // to pop it with DH_Drop manually if we end up in 622 // to pop it with DH_Drop manually if we end up in
623 // a default. 623 // a default.
624 DataBuffer* buf = new DataBuffer; 624 DataBuffer* buf = new DataBuffer;
625 SCOPE (0).buffer1 = buf; 625 SCOPE (0).buffer1 = buf;
626 buf->WriteDWord (DH_Drop); 626 buf->writeDWord (DH_Drop);
627 buf->WriteDWord (DH_Goto); 627 buf->writeDWord (DH_Goto);
628 AddSwitchCase (buf); 628 addSwitchCase (buf);
629 } 629 }
630 630
631 // ============================================================================ 631 // ============================================================================
632 // 632 //
633 void BotscriptParser::ParseBreak() 633 void BotscriptParser::parseBreak()
634 { 634 {
635 if (mScopeCursor == 0) 635 if (m_scopeCursor == 0)
636 Error ("unexpected `break`"); 636 error ("unexpected `break`");
637 637
638 buffer()->WriteDWord (DH_Goto); 638 currentBuffer()->writeDWord (DH_Goto);
639 639
640 // switch and if use mark1 for the closing point, 640 // switch and if use mark1 for the closing point,
641 // for and while use mark2. 641 // for and while use mark2.
642 switch (SCOPE (0).type) 642 switch (SCOPE (0).type)
643 { 643 {
644 case SCOPE_If: 644 case SCOPE_If:
645 case SCOPE_Switch: 645 case SCOPE_Switch:
646 { 646 {
647 buffer()->AddReference (SCOPE (0).mark1); 647 currentBuffer()->addReference (SCOPE (0).mark1);
648 } break; 648 } break;
649 649
650 case SCOPE_For: 650 case SCOPE_For:
651 case SCOPE_While: 651 case SCOPE_While:
652 { 652 {
653 buffer()->AddReference (SCOPE (0).mark2); 653 currentBuffer()->addReference (SCOPE (0).mark2);
654 } break; 654 } break;
655 655
656 default: 656 default:
657 { 657 {
658 Error ("unexpected `break`"); 658 error ("unexpected `break`");
659 } break; 659 } break;
660 } 660 }
661 661
662 mLexer->MustGetNext (TK_Semicolon); 662 m_lexer->mustGetNext (TK_Semicolon);
663 } 663 }
664 664
665 // ============================================================================ 665 // ============================================================================
666 // 666 //
667 void BotscriptParser::ParseContinue() 667 void BotscriptParser::parseContinue()
668 { 668 {
669 mLexer->MustGetNext (TK_Semicolon); 669 m_lexer->mustGetNext (TK_Semicolon);
670 670
671 int curs; 671 int curs;
672 bool found = false; 672 bool found = false;
673 673
674 // Fall through the scope until we find a loop block 674 // Fall through the scope until we find a loop block
675 for (curs = mScopeCursor; curs > 0 && !found; curs--) 675 for (curs = m_scopeCursor; curs > 0 && !found; curs--)
676 { 676 {
677 switch (mScopeStack[curs].type) 677 switch (m_scopeStack[curs].type)
678 { 678 {
679 case SCOPE_For: 679 case SCOPE_For:
680 case SCOPE_While: 680 case SCOPE_While:
681 case SCOPE_Do: 681 case SCOPE_Do:
682 { 682 {
683 buffer()->WriteDWord (DH_Goto); 683 currentBuffer()->writeDWord (DH_Goto);
684 buffer()->AddReference (mScopeStack[curs].mark1); 684 currentBuffer()->addReference (m_scopeStack[curs].mark1);
685 found = true; 685 found = true;
686 } break; 686 } break;
687 687
688 default: 688 default:
689 break; 689 break;
690 } 690 }
691 } 691 }
692 692
693 // No loop blocks 693 // No loop blocks
694 if (found == false) 694 if (found == false)
695 Error ("`continue`-statement not inside a loop"); 695 error ("`continue`-statement not inside a loop");
696 } 696 }
697 697
698 // ============================================================================ 698 // ============================================================================
699 // 699 //
700 void BotscriptParser::ParseBlockEnd() 700 void BotscriptParser::parseBlockEnd()
701 { 701 {
702 // Closing brace 702 // Closing brace
703 // If we're in the block stack, we're descending down from it now 703 // If we're in the block stack, we're descending down from it now
704 if (mScopeCursor > 0) 704 if (m_scopeCursor > 0)
705 { 705 {
706 switch (SCOPE (0).type) 706 switch (SCOPE (0).type)
707 { 707 {
708 case SCOPE_If: 708 case SCOPE_If:
709 { 709 {
710 // Adjust the closing mark. 710 // Adjust the closing mark.
711 buffer()->AdjustMark (SCOPE (0).mark1); 711 currentBuffer()->adjustMark (SCOPE (0).mark1);
712 712
713 // We're returning from `if`, thus `else` follow 713 // We're returning from `if`, thus `else` follow
714 mCanElse = true; 714 m_isElseAllowed = true;
715 break; 715 break;
716 } 716 }
717 717
718 case SCOPE_Else: 718 case SCOPE_Else:
719 { 719 {
720 // else instead uses mark1 for itself (so if expression 720 // else instead uses mark1 for itself (so if expression
721 // fails, jump to else), mark2 means end of else 721 // fails, jump to else), mark2 means end of else
722 buffer()->AdjustMark (SCOPE (0).mark2); 722 currentBuffer()->adjustMark (SCOPE (0).mark2);
723 break; 723 break;
724 } 724 }
725 725
726 case SCOPE_For: 726 case SCOPE_For:
727 { // write the incrementor at the end of the loop block 727 { // write the incrementor at the end of the loop block
728 buffer()->MergeAndDestroy (SCOPE (0).buffer1); 728 currentBuffer()->mergeAndDestroy (SCOPE (0).buffer1);
729 } 729 }
730 case SCOPE_While: 730 case SCOPE_While:
731 { // write down the instruction to go back to the start of the loop 731 { // write down the instruction to go back to the start of the loop
732 buffer()->WriteDWord (DH_Goto); 732 currentBuffer()->writeDWord (DH_Goto);
733 buffer()->AddReference (SCOPE (0).mark1); 733 currentBuffer()->addReference (SCOPE (0).mark1);
734 734
735 // Move the closing mark here since we're at the end of the while loop 735 // Move the closing mark here since we're at the end of the while loop
736 buffer()->AdjustMark (SCOPE (0).mark2); 736 currentBuffer()->adjustMark (SCOPE (0).mark2);
737 break; 737 break;
738 } 738 }
739 739
740 case SCOPE_Do: 740 case SCOPE_Do:
741 { 741 {
742 mLexer->MustGetNext (TK_While); 742 m_lexer->mustGetNext (TK_While);
743 mLexer->MustGetNext (TK_ParenStart); 743 m_lexer->mustGetNext (TK_ParenStart);
744 DataBuffer* expr = ParseExpression (TYPE_Int); 744 DataBuffer* expr = parseExpression (TYPE_Int);
745 mLexer->MustGetNext (TK_ParenEnd); 745 m_lexer->mustGetNext (TK_ParenEnd);
746 mLexer->MustGetNext (TK_Semicolon); 746 m_lexer->mustGetNext (TK_Semicolon);
747 747
748 // If the condition runs true, go back to the start. 748 // If the condition runs true, go back to the start.
749 buffer()->MergeAndDestroy (expr); 749 currentBuffer()->mergeAndDestroy (expr);
750 buffer()->WriteDWord (DH_IfGoto); 750 currentBuffer()->writeDWord (DH_IfGoto);
751 buffer()->AddReference (SCOPE (0).mark1); 751 currentBuffer()->addReference (SCOPE (0).mark1);
752 break; 752 break;
753 } 753 }
754 754
755 case SCOPE_Switch: 755 case SCOPE_Switch:
756 { 756 {
757 // Switch closes. Move down to the record buffer of 757 // Switch closes. Move down to the record buffer of
758 // the lower block. 758 // the lower block.
759 if (SCOPE (1).casecursor != SCOPE (1).cases.begin() - 1) 759 if (SCOPE (1).casecursor != SCOPE (1).cases.begin() - 1)
760 mSwitchBuffer = SCOPE (1).casecursor->data; 760 m_switchBuffer = SCOPE (1).casecursor->data;
761 else 761 else
762 mSwitchBuffer = null; 762 m_switchBuffer = null;
763 763
764 // If there was a default in the switch, write its header down now. 764 // If there was a default in the switch, write its header down now.
765 // If not, write instruction to jump to the end of switch after 765 // If not, write instruction to jump to the end of switch after
766 // the headers (thus won't fall-through if no case matched) 766 // the headers (thus won't fall-through if no case matched)
767 if (SCOPE (0).buffer1) 767 if (SCOPE (0).buffer1)
768 buffer()->MergeAndDestroy (SCOPE (0).buffer1); 768 currentBuffer()->mergeAndDestroy (SCOPE (0).buffer1);
769 else 769 else
770 { 770 {
771 buffer()->WriteDWord (DH_Drop); 771 currentBuffer()->writeDWord (DH_Drop);
772 buffer()->WriteDWord (DH_Goto); 772 currentBuffer()->writeDWord (DH_Goto);
773 buffer()->AddReference (SCOPE (0).mark1); 773 currentBuffer()->addReference (SCOPE (0).mark1);
774 } 774 }
775 775
776 // Go through all of the buffers we 776 // Go through all of the buffers we
777 // recorded down and write them. 777 // recorded down and write them.
778 for (CaseInfo& info : SCOPE (0).cases) 778 for (CaseInfo& info : SCOPE (0).cases)
779 { 779 {
780 buffer()->AdjustMark (info.mark); 780 currentBuffer()->adjustMark (info.mark);
781 buffer()->MergeAndDestroy (info.data); 781 currentBuffer()->mergeAndDestroy (info.data);
782 } 782 }
783 783
784 // Move the closing mark here 784 // Move the closing mark here
785 buffer()->AdjustMark (SCOPE (0).mark1); 785 currentBuffer()->adjustMark (SCOPE (0).mark1);
786 break; 786 break;
787 } 787 }
788 788
789 case SCOPE_Unknown: 789 case SCOPE_Unknown:
790 break; 790 break;
791 } 791 }
792 792
793 // Descend down the stack 793 // Descend down the stack
794 mScopeCursor--; 794 m_scopeCursor--;
795 return; 795 return;
796 } 796 }
797 797
798 int dataheader = (mCurrentMode == PARSERMODE_Event) ? DH_EndEvent : 798 int dataheader = (m_currentMode == PARSERMODE_Event) ? DH_EndEvent :
799 (mCurrentMode == PARSERMODE_MainLoop) ? DH_EndMainLoop : 799 (m_currentMode == PARSERMODE_MainLoop) ? DH_EndMainLoop :
800 (mCurrentMode == PARSERMODE_Onenter) ? DH_EndOnEnter : 800 (m_currentMode == PARSERMODE_Onenter) ? DH_EndOnEnter :
801 (mCurrentMode == PARSERMODE_Onexit) ? DH_EndOnExit : -1; 801 (m_currentMode == PARSERMODE_Onexit) ? DH_EndOnExit : -1;
802 802
803 if (dataheader == -1) 803 if (dataheader == -1)
804 Error ("unexpected `}`"); 804 error ("unexpected `}`");
805 805
806 // Data header must be written before mode is changed because 806 // Data header must be written before mode is changed because
807 // onenter and mainloop go into special buffers, and we want 807 // onenter and mainloop go into special buffers, and we want
808 // the closing data headers into said buffers too. 808 // the closing data headers into said buffers too.
809 buffer()->WriteDWord (dataheader); 809 currentBuffer()->writeDWord (dataheader);
810 mCurrentMode = PARSERMODE_TopLevel; 810 m_currentMode = PARSERMODE_TopLevel;
811 mLexer->Next (TK_Semicolon); 811 m_lexer->next (TK_Semicolon);
812 } 812 }
813 813
814 // ============================================================================= 814 // =============================================================================
815 // 815 //
816 void BotscriptParser::ParseEventdef() 816 void BotscriptParser::parseEventdef()
817 { 817 {
818 EventDefinition* e = new EventDefinition; 818 EventDefinition* e = new EventDefinition;
819 819
820 mLexer->MustGetNext (TK_Number); 820 m_lexer->mustGetNext (TK_Number);
821 e->number = GetTokenString().ToLong(); 821 e->number = getTokenString().toLong();
822 mLexer->MustGetNext (TK_Colon); 822 m_lexer->mustGetNext (TK_Colon);
823 mLexer->MustGetNext (TK_Symbol); 823 m_lexer->mustGetNext (TK_Symbol);
824 e->name = mLexer->Token()->text; 824 e->name = m_lexer->token()->text;
825 mLexer->MustGetNext (TK_ParenStart); 825 m_lexer->mustGetNext (TK_ParenStart);
826 mLexer->MustGetNext (TK_ParenEnd); 826 m_lexer->mustGetNext (TK_ParenEnd);
827 mLexer->MustGetNext (TK_Semicolon); 827 m_lexer->mustGetNext (TK_Semicolon);
828 AddEvent (e); 828 addEvent (e);
829 } 829 }
830 830
831 // ============================================================================= 831 // =============================================================================
832 // 832 //
833 void BotscriptParser::ParseFuncdef() 833 void BotscriptParser::parseFuncdef()
834 { 834 {
835 CommandInfo* comm = new CommandInfo; 835 CommandInfo* comm = new CommandInfo;
836 comm->origin = mLexer->DescribeCurrentPosition(); 836 comm->origin = m_lexer->describeCurrentPosition();
837 837
838 // Return value 838 // Return value
839 mLexer->MustGetAnyOf ({TK_Int,TK_Void,TK_Bool,TK_Str}); 839 m_lexer->mustGetAnyOf ({TK_Int,TK_Void,TK_Bool,TK_Str});
840 comm->returnvalue = GetTypeByName (mLexer->Token()->text); // TODO 840 comm->returnvalue = getTypeByName (m_lexer->token()->text); // TODO
841 assert (comm->returnvalue != -1); 841 assert (comm->returnvalue != -1);
842 842
843 // Number 843 // Number
844 mLexer->MustGetNext (TK_Number); 844 m_lexer->mustGetNext (TK_Number);
845 comm->number = mLexer->Token()->text.ToLong(); 845 comm->number = m_lexer->token()->text.toLong();
846 mLexer->MustGetNext (TK_Colon); 846 m_lexer->mustGetNext (TK_Colon);
847 847
848 // Name 848 // Name
849 mLexer->MustGetNext (TK_Symbol); 849 m_lexer->mustGetNext (TK_Symbol);
850 comm->name = mLexer->Token()->text; 850 comm->name = m_lexer->token()->text;
851 851
852 // Arguments 852 // Arguments
853 mLexer->MustGetNext (TK_ParenStart); 853 m_lexer->mustGetNext (TK_ParenStart);
854 comm->minargs = 0; 854 comm->minargs = 0;
855 855
856 while (mLexer->PeekNextType (TK_ParenEnd) == false) 856 while (m_lexer->peekNextType (TK_ParenEnd) == false)
857 { 857 {
858 if (comm->args.IsEmpty() == false) 858 if (comm->args.isEmpty() == false)
859 mLexer->MustGetNext (TK_Comma); 859 m_lexer->mustGetNext (TK_Comma);
860 860
861 CommandArgument arg; 861 CommandArgument arg;
862 mLexer->MustGetAnyOf ({TK_Int,TK_Bool,TK_Str}); 862 m_lexer->mustGetAnyOf ({TK_Int,TK_Bool,TK_Str});
863 DataType type = GetTypeByName (mLexer->Token()->text); // TODO 863 DataType type = getTypeByName (m_lexer->token()->text); // TODO
864 assert (type != -1 && type != TYPE_Void); 864 assert (type != -1 && type != TYPE_Void);
865 arg.type = type; 865 arg.type = type;
866 866
867 mLexer->MustGetNext (TK_Symbol); 867 m_lexer->mustGetNext (TK_Symbol);
868 arg.name = mLexer->Token()->text; 868 arg.name = m_lexer->token()->text;
869 869
870 // If this is an optional parameter, we need the default value. 870 // If this is an optional parameter, we need the default value.
871 if (comm->minargs < comm->args.Size() || mLexer->PeekNextType (TK_Assign)) 871 if (comm->minargs < comm->args.size() || m_lexer->peekNextType (TK_Assign))
872 { 872 {
873 mLexer->MustGetNext (TK_Assign); 873 m_lexer->mustGetNext (TK_Assign);
874 874
875 switch (type) 875 switch (type)
876 { 876 {
877 case TYPE_Int: 877 case TYPE_Int:
878 case TYPE_Bool: 878 case TYPE_Bool:
879 mLexer->MustGetNext (TK_Number); 879 m_lexer->mustGetNext (TK_Number);
880 break; 880 break;
881 881
882 case TYPE_String: 882 case TYPE_String:
883 Error ("string arguments cannot have default values"); 883 error ("string arguments cannot have default values");
884 884
885 case TYPE_Unknown: 885 case TYPE_Unknown:
886 case TYPE_Void: 886 case TYPE_Void:
887 break; 887 break;
888 } 888 }
889 889
890 arg.defvalue = mLexer->Token()->text.ToLong(); 890 arg.defvalue = m_lexer->token()->text.toLong();
891 } 891 }
892 else 892 else
893 comm->minargs++; 893 comm->minargs++;
894 894
895 comm->args << arg; 895 comm->args << arg;
896 } 896 }
897 897
898 mLexer->MustGetNext (TK_ParenEnd); 898 m_lexer->mustGetNext (TK_ParenEnd);
899 mLexer->MustGetNext (TK_Semicolon); 899 m_lexer->mustGetNext (TK_Semicolon);
900 AddCommandDefinition (comm); 900 addCommandDefinition (comm);
901 } 901 }
902 902
903 // ============================================================================ 903 // ============================================================================
904 // Parses a command call 904 // Parses a command call
905 DataBuffer* BotscriptParser::ParseCommand (CommandInfo* comm) 905 DataBuffer* BotscriptParser::parseCommand (CommandInfo* comm)
906 { 906 {
907 DataBuffer* r = new DataBuffer (64); 907 DataBuffer* r = new DataBuffer (64);
908 908
909 if (mCurrentMode == PARSERMODE_TopLevel && comm->returnvalue == TYPE_Void) 909 if (m_currentMode == PARSERMODE_TopLevel && comm->returnvalue == TYPE_Void)
910 Error ("command call at top level"); 910 error ("command call at top level");
911 911
912 mLexer->MustGetNext (TK_ParenStart); 912 m_lexer->mustGetNext (TK_ParenStart);
913 mLexer->MustGetNext (TK_Any); 913 m_lexer->mustGetNext (TK_Any);
914 914
915 int curarg = 0; 915 int curarg = 0;
916 916
917 for (;;) 917 for (;;)
918 { 918 {
919 if (TokenIs (TK_ParenEnd)) 919 if (tokenIs (TK_ParenEnd))
920 { 920 {
921 if (curarg < comm->minargs) 921 if (curarg < comm->minargs)
922 Error ("too few arguments passed to %1\n\tusage is: %2", 922 error ("too few arguments passed to %1\n\tusage is: %2",
923 comm->name, comm->GetSignature()); 923 comm->name, comm->signature());
924 924
925 break; 925 break;
926 } 926 }
927 927
928 if (curarg >= comm->args.Size()) 928 if (curarg >= comm->args.size())
929 Error ("too many arguments (%3) passed to %1\n\tusage is: %2", 929 error ("too many arguments (%3) passed to %1\n\tusage is: %2",
930 comm->name, comm->GetSignature()); 930 comm->name, comm->signature());
931 931
932 r->MergeAndDestroy (ParseExpression (comm->args[curarg].type, true)); 932 r->mergeAndDestroy (parseExpression (comm->args[curarg].type, true));
933 mLexer->MustGetNext (TK_Any); 933 m_lexer->mustGetNext (TK_Any);
934 934
935 if (curarg < comm->minargs - 1) 935 if (curarg < comm->minargs - 1)
936 { 936 {
937 mLexer->TokenMustBe (TK_Comma); 937 m_lexer->tokenMustBe (TK_Comma);
938 mLexer->MustGetNext (TK_Any); 938 m_lexer->mustGetNext (TK_Any);
939 } 939 }
940 else if (curarg < comm->args.Size() - 1) 940 else if (curarg < comm->args.size() - 1)
941 { 941 {
942 // Can continue, but can terminate as well. 942 // Can continue, but can terminate as well.
943 if (TokenIs (TK_ParenEnd)) 943 if (tokenIs (TK_ParenEnd))
944 { 944 {
945 curarg++; 945 curarg++;
946 break; 946 break;
947 } 947 }
948 else 948 else
949 { 949 {
950 mLexer->TokenMustBe (TK_Comma); 950 m_lexer->tokenMustBe (TK_Comma);
951 mLexer->MustGetNext (TK_Any); 951 m_lexer->mustGetNext (TK_Any);
952 } 952 }
953 } 953 }
954 954
955 curarg++; 955 curarg++;
956 } 956 }
957 957
958 // If the script skipped any optional arguments, fill in defaults. 958 // If the script skipped any optional arguments, fill in defaults.
959 while (curarg < comm->args.Size()) 959 while (curarg < comm->args.size())
960 { 960 {
961 r->WriteDWord (DH_PushNumber); 961 r->writeDWord (DH_PushNumber);
962 r->WriteDWord (comm->args[curarg].defvalue); 962 r->writeDWord (comm->args[curarg].defvalue);
963 curarg++; 963 curarg++;
964 } 964 }
965 965
966 r->WriteDWord (DH_Command); 966 r->writeDWord (DH_Command);
967 r->WriteDWord (comm->number); 967 r->writeDWord (comm->number);
968 r->WriteDWord (comm->args.Size()); 968 r->writeDWord (comm->args.size());
969 969
970 return r; 970 return r;
971 } 971 }
972 972
973 // ============================================================================ 973 // ============================================================================
974 // 974 //
975 String BotscriptParser::ParseFloat() 975 String BotscriptParser::parseFloat()
976 { 976 {
977 mLexer->TokenMustBe (TK_Number); 977 m_lexer->tokenMustBe (TK_Number);
978 String floatstring = GetTokenString(); 978 String floatstring = getTokenString();
979 Lexer::TokenInfo tok; 979 Lexer::TokenInfo tok;
980 980
981 // Go after the decimal point 981 // Go after the decimal point
982 if (mLexer->PeekNext (&tok) && tok.type ==TK_Dot) 982 if (m_lexer->peekNext (&tok) && tok.type ==TK_Dot)
983 { 983 {
984 mLexer->Skip(); 984 m_lexer->skip();
985 mLexer->MustGetNext (TK_Number); 985 m_lexer->mustGetNext (TK_Number);
986 floatstring += "."; 986 floatstring += ".";
987 floatstring += GetTokenString(); 987 floatstring += getTokenString();
988 } 988 }
989 989
990 return floatstring; 990 return floatstring;
991 } 991 }
992 992
993 // ============================================================================ 993 // ============================================================================
994 // 994 //
995 // Parses an assignment operator. 995 // Parses an assignment operator.
996 // 996 //
997 AssignmentOperator BotscriptParser::ParseAssignmentOperator() 997 AssignmentOperator BotscriptParser::parseAssignmentOperator()
998 { 998 {
999 const List<ETokenType> tokens = 999 const List<ETokenType> tokens =
1000 { 1000 {
1001 TK_Assign, 1001 TK_Assign,
1002 TK_AddAssign, 1002 TK_AddAssign,
1006 TK_ModulusAssign, 1006 TK_ModulusAssign,
1007 TK_DoublePlus, 1007 TK_DoublePlus,
1008 TK_DoubleMinus, 1008 TK_DoubleMinus,
1009 }; 1009 };
1010 1010
1011 mLexer->MustGetAnyOf (tokens); 1011 m_lexer->mustGetAnyOf (tokens);
1012 1012
1013 switch (mLexer->TokenType()) 1013 switch (m_lexer->tokenType())
1014 { 1014 {
1015 case TK_Assign: return ASSIGNOP_Assign; 1015 case TK_Assign: return ASSIGNOP_Assign;
1016 case TK_AddAssign: return ASSIGNOP_Add; 1016 case TK_AddAssign: return ASSIGNOP_Add;
1017 case TK_SubAssign: return ASSIGNOP_Subtract; 1017 case TK_SubAssign: return ASSIGNOP_Subtract;
1018 case TK_MultiplyAssign: return ASSIGNOP_Multiply; 1018 case TK_MultiplyAssign: return ASSIGNOP_Multiply;
1047 { ASSIGNOP_Modulus, DH_ModLocalVar, DH_ModGlobalVar, DH_ModGlobalArray }, 1047 { ASSIGNOP_Modulus, DH_ModLocalVar, DH_ModGlobalVar, DH_ModGlobalArray },
1048 { ASSIGNOP_Increase, DH_IncreaseLocalVar, DH_IncreaseGlobalVar, DH_IncreaseGlobalArray }, 1048 { ASSIGNOP_Increase, DH_IncreaseLocalVar, DH_IncreaseGlobalVar, DH_IncreaseGlobalArray },
1049 { ASSIGNOP_Decrease, DH_DecreaseLocalVar, DH_DecreaseGlobalVar, DH_DecreaseGlobalArray }, 1049 { ASSIGNOP_Decrease, DH_DecreaseLocalVar, DH_DecreaseGlobalVar, DH_DecreaseGlobalArray },
1050 }; 1050 };
1051 1051
1052 DataHeader BotscriptParser::GetAssigmentDataHeader (AssignmentOperator op, Variable* var) 1052 DataHeader BotscriptParser::getAssigmentDataHeader (AssignmentOperator op, Variable* var)
1053 { 1053 {
1054 for (const auto& a : gAssignmentDataHeaders) 1054 for (const auto& a : gAssignmentDataHeaders)
1055 { 1055 {
1056 if (a.op != op) 1056 if (a.op != op)
1057 continue; 1057 continue;
1063 return a.global; 1063 return a.global;
1064 1064
1065 return a.local; 1065 return a.local;
1066 } 1066 }
1067 1067
1068 Error ("WTF: couldn't find data header for operator #%1", op); 1068 error ("WTF: couldn't find data header for operator #%1", op);
1069 return (DataHeader) 0; 1069 return (DataHeader) 0;
1070 } 1070 }
1071 1071
1072 // ============================================================================ 1072 // ============================================================================
1073 // 1073 //
1074 // Parses an assignment. An assignment starts with a variable name, followed 1074 // Parses an assignment. An assignment starts with a variable name, followed
1075 // by an assignment operator, followed by an expression value. Expects current 1075 // by an assignment operator, followed by an expression value. Expects current
1076 // token to be the name of the variable, and expects the variable to be given. 1076 // token to be the name of the variable, and expects the variable to be given.
1077 // 1077 //
1078 DataBuffer* BotscriptParser::ParseAssignment (Variable* var) 1078 DataBuffer* BotscriptParser::parseAssignment (Variable* var)
1079 { 1079 {
1080 DataBuffer* retbuf = new DataBuffer; 1080 DataBuffer* retbuf = new DataBuffer;
1081 DataBuffer* arrayindex = null; 1081 DataBuffer* arrayindex = null;
1082 1082
1083 if (var->writelevel != WRITE_Mutable) 1083 if (var->writelevel != WRITE_Mutable)
1084 Error ("cannot alter read-only variable $%1", var->name); 1084 error ("cannot alter read-only variable $%1", var->name);
1085 1085
1086 if (var->isarray) 1086 if (var->isarray)
1087 { 1087 {
1088 mLexer->MustGetNext (TK_BracketStart); 1088 m_lexer->mustGetNext (TK_BracketStart);
1089 Expression expr (this, mLexer, TYPE_Int); 1089 Expression expr (this, m_lexer, TYPE_Int);
1090 expr.Result()->ConvertToBuffer(); 1090 expr.getResult()->convertToBuffer();
1091 arrayindex = expr.Result()->Buffer()->Clone(); 1091 arrayindex = expr.getResult()->buffer()->clone();
1092 mLexer->MustGetNext (TK_BracketEnd); 1092 m_lexer->mustGetNext (TK_BracketEnd);
1093 } 1093 }
1094 1094
1095 // Get an operator 1095 // Get an operator
1096 AssignmentOperator oper = ParseAssignmentOperator(); 1096 AssignmentOperator oper = parseAssignmentOperator();
1097 1097
1098 if (mCurrentMode == PARSERMODE_TopLevel) 1098 if (m_currentMode == PARSERMODE_TopLevel)
1099 Error ("can't alter variables at top level"); 1099 error ("can't alter variables at top level");
1100 1100
1101 if (var->isarray) 1101 if (var->isarray)
1102 retbuf->MergeAndDestroy (arrayindex); 1102 retbuf->mergeAndDestroy (arrayindex);
1103 1103
1104 // Parse the right operand 1104 // Parse the right operand
1105 if (oper != ASSIGNOP_Increase && oper != ASSIGNOP_Decrease) 1105 if (oper != ASSIGNOP_Increase && oper != ASSIGNOP_Decrease)
1106 { 1106 {
1107 DataBuffer* expr = ParseExpression (var->type); 1107 DataBuffer* expr = parseExpression (var->type);
1108 retbuf->MergeAndDestroy (expr); 1108 retbuf->mergeAndDestroy (expr);
1109 } 1109 }
1110 1110
1111 #if 0 1111 #if 0
1112 // <<= and >>= do not have data headers. Solution: expand them. 1112 // <<= and >>= do not have data headers. Solution: expand them.
1113 // a <<= b -> a = a << b 1113 // a <<= b -> a = a << b
1118 retbuf->WriteDWord ((oper == OPER_ASSIGNLEFTSHIFT) ? DH_LeftShift : DH_RightShift); 1118 retbuf->WriteDWord ((oper == OPER_ASSIGNLEFTSHIFT) ? DH_LeftShift : DH_RightShift);
1119 retbuf->WriteDWord (var->IsGlobal() ? DH_AssignGlobalVar : DH_AssignLocalVar); 1119 retbuf->WriteDWord (var->IsGlobal() ? DH_AssignGlobalVar : DH_AssignLocalVar);
1120 retbuf->WriteDWord (var->index); 1120 retbuf->WriteDWord (var->index);
1121 #endif 1121 #endif
1122 1122
1123 DataHeader dh = GetAssigmentDataHeader (oper, var); 1123 DataHeader dh = getAssigmentDataHeader (oper, var);
1124 retbuf->WriteDWord (dh); 1124 retbuf->writeDWord (dh);
1125 retbuf->WriteDWord (var->index); 1125 retbuf->writeDWord (var->index);
1126 return retbuf; 1126 return retbuf;
1127 } 1127 }
1128 1128
1129 // ============================================================================ 1129 // ============================================================================
1130 // 1130 //
1131 void BotscriptParser::PushScope (EReset reset) 1131 void BotscriptParser::pushScope (EReset reset)
1132 { 1132 {
1133 mScopeCursor++; 1133 m_scopeCursor++;
1134 1134
1135 if (mScopeStack.Size() < mScopeCursor + 1) 1135 if (m_scopeStack.size() < m_scopeCursor + 1)
1136 { 1136 {
1137 ScopeInfo newscope; 1137 ScopeInfo newscope;
1138 mScopeStack << newscope; 1138 m_scopeStack << newscope;
1139 reset = SCOPE_Reset; 1139 reset = SCOPE_Reset;
1140 } 1140 }
1141 1141
1142 if (reset == SCOPE_Reset) 1142 if (reset == SCOPE_Reset)
1143 { 1143 {
1144 ScopeInfo* info = &SCOPE (0); 1144 ScopeInfo* info = &SCOPE (0);
1145 info->type = SCOPE_Unknown; 1145 info->type = SCOPE_Unknown;
1146 info->mark1 = null; 1146 info->mark1 = null;
1147 info->mark2 = null; 1147 info->mark2 = null;
1148 info->buffer1 = null; 1148 info->buffer1 = null;
1149 info->cases.Clear(); 1149 info->cases.clear();
1150 info->casecursor = info->cases.begin() - 1; 1150 info->casecursor = info->cases.begin() - 1;
1151 } 1151 }
1152 1152
1153 // Reset variable stuff in any case 1153 // Reset variable stuff in any case
1154 SCOPE(0).globalVarIndexBase = (mScopeCursor == 0) ? 0 : SCOPE(1).globalVarIndexBase; 1154 SCOPE(0).globalVarIndexBase = (m_scopeCursor == 0) ? 0 : SCOPE(1).globalVarIndexBase;
1155 SCOPE(0).localVarIndexBase = (mScopeCursor == 0) ? 0 : SCOPE(1).localVarIndexBase; 1155 SCOPE(0).localVarIndexBase = (m_scopeCursor == 0) ? 0 : SCOPE(1).localVarIndexBase;
1156 1156
1157 for (Variable* var : SCOPE(0).globalVariables + SCOPE(0).localVariables) 1157 for (Variable* var : SCOPE(0).globalVariables + SCOPE(0).localVariables)
1158 delete var; 1158 delete var;
1159 1159
1160 SCOPE(0).localVariables.Clear(); 1160 SCOPE(0).localVariables.clear();
1161 SCOPE(0).globalVariables.Clear(); 1161 SCOPE(0).globalVariables.clear();
1162 } 1162 }
1163 1163
1164 // ============================================================================ 1164 // ============================================================================
1165 // 1165 //
1166 DataBuffer* BotscriptParser::ParseExpression (DataType reqtype, bool fromhere) 1166 DataBuffer* BotscriptParser::parseExpression (DataType reqtype, bool fromhere)
1167 { 1167 {
1168 // hehe 1168 // hehe
1169 if (fromhere == true) 1169 if (fromhere == true)
1170 mLexer->Skip (-1); 1170 m_lexer->skip (-1);
1171 1171
1172 Expression expr (this, mLexer, reqtype); 1172 Expression expr (this, m_lexer, reqtype);
1173 expr.Result()->ConvertToBuffer(); 1173 expr.getResult()->convertToBuffer();
1174 1174
1175 // The buffer will be destroyed once the function ends so we need to 1175 // The buffer will be destroyed once the function ends so we need to
1176 // clone it now. 1176 // clone it now.
1177 return expr.Result()->Buffer()->Clone(); 1177 return expr.getResult()->buffer()->clone();
1178 } 1178 }
1179 1179
1180 // ============================================================================ 1180 // ============================================================================
1181 // 1181 //
1182 DataBuffer* BotscriptParser::ParseStatement() 1182 DataBuffer* BotscriptParser::parseStatement()
1183 { 1183 {
1184 // If it's a variable, expect assignment. 1184 // If it's a variable, expect assignment.
1185 if (mLexer->Next (TK_DollarSign)) 1185 if (m_lexer->next (TK_DollarSign))
1186 { 1186 {
1187 mLexer->MustGetNext (TK_Symbol); 1187 m_lexer->mustGetNext (TK_Symbol);
1188 Variable* var = FindVariable (GetTokenString()); 1188 Variable* var = findVariable (getTokenString());
1189 1189
1190 if (var == null) 1190 if (var == null)
1191 Error ("unknown variable $%1", var->name); 1191 error ("unknown variable $%1", var->name);
1192 1192
1193 return ParseAssignment (var); 1193 return parseAssignment (var);
1194 } 1194 }
1195 1195
1196 return null; 1196 return null;
1197 } 1197 }
1198 1198
1199 // ============================================================================ 1199 // ============================================================================
1200 // 1200 //
1201 void BotscriptParser::AddSwitchCase (DataBuffer* casebuffer) 1201 void BotscriptParser::addSwitchCase (DataBuffer* casebuffer)
1202 { 1202 {
1203 ScopeInfo* info = &SCOPE (0); 1203 ScopeInfo* info = &SCOPE (0);
1204 CaseInfo casedata; 1204 CaseInfo casedata;
1205 1205
1206 // Init a mark for the case buffer 1206 // Init a mark for the case buffer
1207 ByteMark* casemark = buffer()->AddMark (""); 1207 ByteMark* casemark = currentBuffer()->addMark ("");
1208 casedata.mark = casemark; 1208 casedata.mark = casemark;
1209 1209
1210 // Add a reference to the mark. "case" and "default" both 1210 // Add a reference to the mark. "case" and "default" both
1211 // add the necessary bytecode before the reference. 1211 // add the necessary bytecode before the reference.
1212 if (casebuffer != null) 1212 if (casebuffer != null)
1213 casebuffer->AddReference (casemark); 1213 casebuffer->addReference (casemark);
1214 else 1214 else
1215 buffer()->AddReference (casemark); 1215 currentBuffer()->addReference (casemark);
1216 1216
1217 // Init a buffer for the case block and tell the object 1217 // Init a buffer for the case block and tell the object
1218 // writer to record all written data to it. 1218 // writer to record all written data to it.
1219 casedata.data = mSwitchBuffer = new DataBuffer; 1219 casedata.data = m_switchBuffer = new DataBuffer;
1220 SCOPE(0).cases << casedata; 1220 SCOPE(0).cases << casedata;
1221 info->casecursor++; 1221 info->casecursor++;
1222 } 1222 }
1223 1223
1224 // ============================================================================ 1224 // ============================================================================
1225 // 1225 //
1226 bool BotscriptParser::TokenIs (ETokenType a) 1226 bool BotscriptParser::tokenIs (ETokenType a)
1227 { 1227 {
1228 return (mLexer->TokenType() == a); 1228 return (m_lexer->tokenType() == a);
1229 } 1229 }
1230 1230
1231 // ============================================================================ 1231 // ============================================================================
1232 // 1232 //
1233 String BotscriptParser::GetTokenString() 1233 String BotscriptParser::getTokenString()
1234 { 1234 {
1235 return mLexer->Token()->text; 1235 return m_lexer->token()->text;
1236 } 1236 }
1237 1237
1238 // ============================================================================ 1238 // ============================================================================
1239 // 1239 //
1240 String BotscriptParser::DescribePosition() const 1240 String BotscriptParser::describePosition() const
1241 { 1241 {
1242 Lexer::TokenInfo* tok = mLexer->Token(); 1242 Lexer::TokenInfo* tok = m_lexer->token();
1243 return tok->file + ":" + String (tok->line) + ":" + String (tok->column); 1243 return tok->file + ":" + String (tok->line) + ":" + String (tok->column);
1244 } 1244 }
1245 1245
1246 // ============================================================================ 1246 // ============================================================================
1247 // 1247 //
1248 DataBuffer* BotscriptParser::buffer() 1248 DataBuffer* BotscriptParser::currentBuffer()
1249 { 1249 {
1250 if (mSwitchBuffer != null) 1250 if (m_switchBuffer != null)
1251 return mSwitchBuffer; 1251 return m_switchBuffer;
1252 1252
1253 if (mCurrentMode == PARSERMODE_MainLoop) 1253 if (m_currentMode == PARSERMODE_MainLoop)
1254 return mMainLoopBuffer; 1254 return m_mainLoopBuffer;
1255 1255
1256 if (mCurrentMode == PARSERMODE_Onenter) 1256 if (m_currentMode == PARSERMODE_Onenter)
1257 return mOnEnterBuffer; 1257 return m_onenterBuffer;
1258 1258
1259 return mMainBuffer; 1259 return m_mainBuffer;
1260 } 1260 }
1261 1261
1262 // ============================================================================ 1262 // ============================================================================
1263 // 1263 //
1264 void BotscriptParser::writeMemberBuffers() 1264 void BotscriptParser::writeMemberBuffers()
1265 { 1265 {
1266 // If there was no mainloop defined, write a dummy one now. 1266 // If there was no mainloop defined, write a dummy one now.
1267 if (mGotMainLoop == false) 1267 if (m_gotMainLoop == false)
1268 { 1268 {
1269 mMainLoopBuffer->WriteDWord (DH_MainLoop); 1269 m_mainLoopBuffer->writeDWord (DH_MainLoop);
1270 mMainLoopBuffer->WriteDWord (DH_EndMainLoop); 1270 m_mainLoopBuffer->writeDWord (DH_EndMainLoop);
1271 } 1271 }
1272 1272
1273 // Write the onenter and mainloop buffers, in that order in particular. 1273 // Write the onenter and mainloop buffers, in that order in particular.
1274 for (DataBuffer** bufp : List<DataBuffer**> ({&mOnEnterBuffer, &mMainLoopBuffer})) 1274 for (DataBuffer** bufp : List<DataBuffer**> ({&m_onenterBuffer, &m_mainLoopBuffer}))
1275 { 1275 {
1276 buffer()->MergeAndDestroy (*bufp); 1276 currentBuffer()->mergeAndDestroy (*bufp);
1277 1277
1278 // Clear the buffer afterwards for potential next state 1278 // Clear the buffer afterwards for potential next state
1279 *bufp = new DataBuffer; 1279 *bufp = new DataBuffer;
1280 } 1280 }
1281 1281
1282 // Next state definitely has no mainloop yet 1282 // Next state definitely has no mainloop yet
1283 mGotMainLoop = false; 1283 m_gotMainLoop = false;
1284 } 1284 }
1285 1285
1286 // ============================================================================ 1286 // ============================================================================
1287 // 1287 //
1288 // Write string table 1288 // Write string table
1289 // 1289 //
1290 void BotscriptParser::WriteStringTable() 1290 void BotscriptParser::writeStringTable()
1291 { 1291 {
1292 int stringcount = CountStringsInTable(); 1292 int stringcount = countStringsInTable();
1293 1293
1294 if (stringcount == 0) 1294 if (stringcount == 0)
1295 return; 1295 return;
1296 1296
1297 // Write header 1297 // Write header
1298 mMainBuffer->WriteDWord (DH_StringList); 1298 m_mainBuffer->writeDWord (DH_StringList);
1299 mMainBuffer->WriteDWord (stringcount); 1299 m_mainBuffer->writeDWord (stringcount);
1300 1300
1301 // Write all strings 1301 // Write all strings
1302 for (int i = 0; i < stringcount; i++) 1302 for (int i = 0; i < stringcount; i++)
1303 mMainBuffer->WriteString (GetStringTable()[i]); 1303 m_mainBuffer->writeString (getStringTable()[i]);
1304 } 1304 }
1305 1305
1306 // ============================================================================ 1306 // ============================================================================
1307 // 1307 //
1308 // Write the compiled bytecode to a file 1308 // Write the compiled bytecode to a file
1309 // 1309 //
1310 void BotscriptParser::WriteToFile (String outfile) 1310 void BotscriptParser::writeToFile (String outfile)
1311 { 1311 {
1312 FILE* fp = fopen (outfile, "wb"); 1312 FILE* fp = fopen (outfile, "wb");
1313 1313
1314 if (fp == null) 1314 if (fp == null)
1315 Error ("couldn't open %1 for writing: %2", outfile, strerror (errno)); 1315 error ("couldn't open %1 for writing: %2", outfile, strerror (errno));
1316 1316
1317 // First, resolve references 1317 // First, resolve references
1318 for (MarkReference* ref : mMainBuffer->References()) 1318 for (MarkReference* ref : m_mainBuffer->references())
1319 for (int i = 0; i < 4; ++i) 1319 for (int i = 0; i < 4; ++i)
1320 mMainBuffer->Buffer()[ref->pos + i] = (ref->target->pos >> (8 * i)) & 0xFF; 1320 m_mainBuffer->buffer()[ref->pos + i] = (ref->target->pos >> (8 * i)) & 0xFF;
1321 1321
1322 // Then, dump the main buffer to the file 1322 // Then, dump the main buffer to the file
1323 fwrite (mMainBuffer->Buffer(), 1, mMainBuffer->WrittenSize(), fp); 1323 fwrite (m_mainBuffer->buffer(), 1, m_mainBuffer->writtenSize(), fp);
1324 Print ("-- %1 byte%s1 written to %2\n", mMainBuffer->WrittenSize(), outfile); 1324 print ("-- %1 byte%s1 written to %2\n", m_mainBuffer->writtenSize(), outfile);
1325 fclose (fp); 1325 fclose (fp);
1326 } 1326 }
1327 1327
1328 // ============================================================================ 1328 // ============================================================================
1329 // 1329 //
1330 // Attempt to find the variable by the given name. Looks from current scope 1330 // Attempt to find the variable by the given name. Looks from current scope
1331 // downwards. 1331 // downwards.
1332 // 1332 //
1333 Variable* BotscriptParser::FindVariable (const String& name) 1333 Variable* BotscriptParser::findVariable (const String& name)
1334 { 1334 {
1335 for (int i = mScopeCursor; i >= 0; --i) 1335 for (int i = m_scopeCursor; i >= 0; --i)
1336 { 1336 {
1337 for (Variable* var : mScopeStack[i].globalVariables + mScopeStack[i].localVariables) 1337 for (Variable* var : m_scopeStack[i].globalVariables + m_scopeStack[i].localVariables)
1338 { 1338 {
1339 if (var->name == name) 1339 if (var->name == name)
1340 return var; 1340 return var;
1341 } 1341 }
1342 } 1342 }
1346 1346
1347 // ============================================================================ 1347 // ============================================================================
1348 // 1348 //
1349 // Is the parser currently in global state (i.e. not in any specific state)? 1349 // Is the parser currently in global state (i.e. not in any specific state)?
1350 // 1350 //
1351 bool BotscriptParser::IsInGlobalState() const 1351 bool BotscriptParser::isInGlobalState() const
1352 { 1352 {
1353 return mCurrentState.IsEmpty(); 1353 return m_currentState.isEmpty();
1354 } 1354 }
1355 1355
1356 // ============================================================================ 1356 // ============================================================================
1357 // 1357 //
1358 void BotscriptParser::SuggestHighestVarIndex (bool global, int index) 1358 void BotscriptParser::suggestHighestVarIndex (bool global, int index)
1359 { 1359 {
1360 if (global) 1360 if (global)
1361 mHighestGlobalVarIndex = max (mHighestGlobalVarIndex, index); 1361 m_highestGlobalVarIndex = max (m_highestGlobalVarIndex, index);
1362 else 1362 else
1363 mHighestStateVarIndex = max (mHighestStateVarIndex, index); 1363 m_highestStateVarIndex = max (m_highestStateVarIndex, index);
1364 } 1364 }
1365 1365
1366 // ============================================================================ 1366 // ============================================================================
1367 // 1367 //
1368 int BotscriptParser::GetHighestVarIndex (bool global) 1368 int BotscriptParser::getHighestVarIndex (bool global)
1369 { 1369 {
1370 if (global) 1370 if (global)
1371 return mHighestGlobalVarIndex; 1371 return m_highestGlobalVarIndex;
1372 1372
1373 return mHighestStateVarIndex; 1373 return m_highestStateVarIndex;
1374 } 1374 }

mercurial