parser.cxx

changeset 56
384c5605bda9
parent 55
173956c1ac27
child 57
96f60ca748a0
equal deleted inserted replaced
55:173956c1ac27 56:384c5605bda9
55 ParserError ("%s-statements may only be defined at top level!", token.chars()); 55 ParserError ("%s-statements may only be defined at top level!", token.chars());
56 56
57 #define MUST_NOT_TOPLEVEL if (g_CurMode == MODE_TOPLEVEL) \ 57 #define MUST_NOT_TOPLEVEL if (g_CurMode == MODE_TOPLEVEL) \
58 ParserError ("%s-statements may not be defined at top level!", token.chars()); 58 ParserError ("%s-statements may not be defined at top level!", token.chars());
59 59
60 #define SCOPE(n) blockstack[g_BlockStackCursor - n]
61
60 int g_NumStates = 0; 62 int g_NumStates = 0;
61 int g_NumEvents = 0; 63 int g_NumEvents = 0;
62 int g_CurMode = MODE_TOPLEVEL; 64 int g_CurMode = MODE_TOPLEVEL;
63 str g_CurState = ""; 65 str g_CurState = "";
64 bool g_stateSpawnDefined = false; 66 bool g_stateSpawnDefined = false;
69 // ============================================================================ 71 // ============================================================================
70 // Main parser code. Begins read of the script file, checks the syntax of it 72 // Main parser code. Begins read of the script file, checks the syntax of it
71 // and writes the data to the object file via ObjWriter - which also takes care 73 // and writes the data to the object file via ObjWriter - which also takes care
72 // of necessary buffering so stuff is written in the correct order. 74 // of necessary buffering so stuff is written in the correct order.
73 void ScriptReader::ParseBotScript (ObjWriter* w) { 75 void ScriptReader::ParseBotScript (ObjWriter* w) {
76 // Zero the entire block stack first
77 for (int i = 0; i < MAX_STRUCTSTACK; i++)
78 memset (&blockstack[i], 0, sizeof (BlockInformation));
79
74 while (Next()) { 80 while (Next()) {
75 // ============================================================ 81 // ============================================================
76 if (!token.compare ("state")) { 82 if (!token.compare ("state")) {
77 MUST_TOPLEVEL 83 MUST_TOPLEVEL
78 84
205 211
206 // Condition 212 // Condition
207 MustNext ("("); 213 MustNext ("(");
208 214
209 // Read the expression and write it. 215 // Read the expression and write it.
210 // TODO: This should be storing it into a variable first, so
211 // that else statements would be possible!
212 MustNext (); 216 MustNext ();
213 DataBuffer* c = ParseExpression (TYPE_INT); 217 DataBuffer* c = ParseExpression (TYPE_INT);
214 w->WriteBuffer (c); 218 w->WriteBuffer (c);
215 219
216 MustNext (")"); 220 MustNext (")");
224 // we just defined - and this mark will be at the end of the block. 228 // we just defined - and this mark will be at the end of the block.
225 w->Write<word> (DH_IFNOTGOTO); 229 w->Write<word> (DH_IFNOTGOTO);
226 w->AddReference (marknum); 230 w->AddReference (marknum);
227 231
228 // Store it in the block stack 232 // Store it in the block stack
229 blockstack[g_BlockStackCursor].mark1 = marknum; 233 SCOPE(0).mark1 = marknum;
230 blockstack[g_BlockStackCursor].type = BLOCKTYPE_IF; 234 SCOPE(0).type = BLOCKTYPE_IF;
235 continue;
236 }
237
238 if (!token.compare ("else")) {
239 MUST_NOT_TOPLEVEL
240 MustNext ("{");
241
242 // Don't use PushBlockStack as that will reset the scope.
243 g_BlockStackCursor++;
244 if (g_BlockStackCursor >= MAX_STRUCTSTACK)
245 ParserError ("too deep scope");
246
247 if (SCOPE(0).type != BLOCKTYPE_IF)
248 ParserError ("else without preceding if");
249
250 // Write down to jump to the end of the else statement
251 // Otherwise we have fall-throughs
252 SCOPE(0).mark2 = w->AddMark ("");
253
254 // Instruction to jump to the end after if block is complete
255 w->Write (DH_GOTO);
256 w->AddReference (SCOPE(0).mark2);
257
258 // Move the ifnot mark here and set type to else
259 w->MoveMark (SCOPE(0).mark1);
260 SCOPE(0).type = BLOCKTYPE_ELSE;
231 continue; 261 continue;
232 } 262 }
233 263
234 // ============================================================ 264 // ============================================================
235 // While 265 // While
257 // Instruction to go to the end if it fails 287 // Instruction to go to the end if it fails
258 w->Write<word> (DH_IFNOTGOTO); 288 w->Write<word> (DH_IFNOTGOTO);
259 w->AddReference (mark2); 289 w->AddReference (mark2);
260 290
261 // Store the needed stuff 291 // Store the needed stuff
262 blockstack[g_BlockStackCursor].mark1 = mark1; 292 SCOPE(0).mark1 = mark1;
263 blockstack[g_BlockStackCursor].mark2 = mark2; 293 SCOPE(0).mark2 = mark2;
264 blockstack[g_BlockStackCursor].type = BLOCKTYPE_WHILE; 294 SCOPE(0).type = BLOCKTYPE_WHILE;
265 continue; 295 continue;
266 } 296 }
267 297
268 // ============================================================ 298 // ============================================================
269 // For loop 299 // For loop
299 w->WriteBuffer (cond); 329 w->WriteBuffer (cond);
300 w->Write<word> (DH_IFNOTGOTO); 330 w->Write<word> (DH_IFNOTGOTO);
301 w->AddReference (mark2); 331 w->AddReference (mark2);
302 332
303 // Store the marks and incrementor 333 // Store the marks and incrementor
304 blockstack[g_BlockStackCursor].mark1 = mark1; 334 SCOPE(0).mark1 = mark1;
305 blockstack[g_BlockStackCursor].mark2 = mark2; 335 SCOPE(0).mark2 = mark2;
306 blockstack[g_BlockStackCursor].buffer1 = incr; 336 SCOPE(0).buffer1 = incr;
307 blockstack[g_BlockStackCursor].type = BLOCKTYPE_FOR; 337 SCOPE(0).type = BLOCKTYPE_FOR;
308 continue; 338 continue;
309 } 339 }
310 340
311 // ============================================================ 341 // ============================================================
312 // Do/while loop 342 // Do/while loop
313 if (!token.compare ("do")) { 343 if (!token.compare ("do")) {
314 MUST_NOT_TOPLEVEL 344 MUST_NOT_TOPLEVEL
315 PushBlockStack (); 345 PushBlockStack ();
316 MustNext ("{"); 346 MustNext ("{");
317 blockstack[g_BlockStackCursor].mark1 = w->AddMark (""); 347 SCOPE(0).mark1 = w->AddMark ("");
318 blockstack[g_BlockStackCursor].type = BLOCKTYPE_DO; 348 SCOPE(0).type = BLOCKTYPE_DO;
319 continue; 349 continue;
320 } 350 }
321 351
322 // ============================================================ 352 // ============================================================
323 // Switch 353 // Switch
340 MustNext ("("); 370 MustNext ("(");
341 MustNext (); 371 MustNext ();
342 w->WriteBuffer (ParseExpression (TYPE_INT)); 372 w->WriteBuffer (ParseExpression (TYPE_INT));
343 MustNext (")"); 373 MustNext (")");
344 MustNext ("{"); 374 MustNext ("{");
345 blockstack[g_BlockStackCursor].type = BLOCKTYPE_SWITCH; 375 SCOPE(0).type = BLOCKTYPE_SWITCH;
346 blockstack[g_BlockStackCursor].mark1 = w->AddMark (""); // end mark 376 SCOPE(0).mark1 = w->AddMark (""); // end mark
347 blockstack[g_BlockStackCursor].buffer1 = NULL; // default header 377 SCOPE(0).buffer1 = NULL; // default header
348 continue; 378 continue;
349 } 379 }
350 380
351 // ============================================================ 381 // ============================================================
352 if (!token.compare ("case")) { 382 if (!token.compare ("case")) {
353 // case is only allowed inside switch 383 // case is only allowed inside switch
354 BlockInformation* info = &blockstack[g_BlockStackCursor]; 384 if (SCOPE(0).type != BLOCKTYPE_SWITCH)
355 if (info->type != BLOCKTYPE_SWITCH)
356 ParserError ("case label outside switch"); 385 ParserError ("case label outside switch");
357 386
358 // Get the literal (Zandronum does not support expressions here) 387 // Get the literal (Zandronum does not support expressions here)
359 MustNumber (); 388 MustNumber ();
360 int num = atoi (token.chars ()); 389 int num = atoi (token.chars ());
361 MustNext (":"); 390 MustNext (":");
362 391
363 for (int i = 0; i < MAX_CASE; i++) 392 for (int i = 0; i < MAX_CASE; i++)
364 if (info->casenumbers[i] == num) 393 if (SCOPE(0).casenumbers[i] == num)
365 ParserError ("multiple case %d labels in one switch", num); 394 ParserError ("multiple case %d labels in one switch", num);
366 395
367 // Write down the expression and case-go-to. This builds 396 // Write down the expression and case-go-to. This builds
368 // the case tree. The closing event will write the actual 397 // the case tree. The closing event will write the actual
369 // blocks and move the marks appropriately. 398 // blocks and move the marks appropriately.
374 // we want it all under the switch, not into the case-buffers. 403 // we want it all under the switch, not into the case-buffers.
375 w->SwitchBuffer = NULL; 404 w->SwitchBuffer = NULL;
376 w->Write<word> (DH_CASEGOTO); 405 w->Write<word> (DH_CASEGOTO);
377 w->Write<word> (num); 406 w->Write<word> (num);
378 AddSwitchCase (w, NULL); 407 AddSwitchCase (w, NULL);
379 info->casenumbers[info->casecursor] = num; 408 SCOPE(0).casenumbers[SCOPE(0).casecursor] = num;
380 continue; 409 continue;
381 } 410 }
382 411
383 if (!token.compare ("default")) { 412 if (!token.compare ("default")) {
384 BlockInformation* info = &blockstack[g_BlockStackCursor]; 413 if (SCOPE(0).type != BLOCKTYPE_SWITCH)
385 if (info->type != BLOCKTYPE_SWITCH)
386 ParserError ("default label outside switch"); 414 ParserError ("default label outside switch");
387 415
388 if (info->buffer1) 416 if (SCOPE(0).buffer1)
389 ParserError ("multiple default labels in one switch"); 417 ParserError ("multiple default labels in one switch");
390 418
391 MustNext (":"); 419 MustNext (":");
392 420
393 // The default header is buffered into buffer1, since 421 // The default header is buffered into buffer1, since
396 // Since the expression is pushed into the switch 424 // Since the expression is pushed into the switch
397 // and is only popped when case succeeds, we have 425 // and is only popped when case succeeds, we have
398 // to pop it with DH_DROP manually if we end up in 426 // to pop it with DH_DROP manually if we end up in
399 // a default. 427 // a default.
400 DataBuffer* b = new DataBuffer; 428 DataBuffer* b = new DataBuffer;
401 info->buffer1 = b; 429 SCOPE(0).buffer1 = b;
402 b->Write<word> (DH_DROP); 430 b->Write<word> (DH_DROP);
403 b->Write<word> (DH_GOTO); 431 b->Write<word> (DH_GOTO);
404 AddSwitchCase (w, b); 432 AddSwitchCase (w, b);
405 continue; 433 continue;
406 } 434 }
409 // Break statement. 437 // Break statement.
410 if (!token.compare ("break")) { 438 if (!token.compare ("break")) {
411 if (!g_BlockStackCursor) 439 if (!g_BlockStackCursor)
412 ParserError ("unexpected `break`"); 440 ParserError ("unexpected `break`");
413 441
414 BlockInformation* info = &blockstack[g_BlockStackCursor];
415
416 w->Write<word> (DH_GOTO); 442 w->Write<word> (DH_GOTO);
417 443
418 // switch and if use mark1 for the closing point, 444 // switch and if use mark1 for the closing point,
419 // for and while use mark2. 445 // for and while use mark2.
420 switch (info->type) { 446 switch (SCOPE(0).type) {
421 case BLOCKTYPE_IF: 447 case BLOCKTYPE_IF:
422 case BLOCKTYPE_SWITCH: 448 case BLOCKTYPE_SWITCH:
423 w->AddReference (info->mark1); 449 w->AddReference (SCOPE(0).mark1);
424 break; 450 break;
425 case BLOCKTYPE_FOR: 451 case BLOCKTYPE_FOR:
426 case BLOCKTYPE_WHILE: 452 case BLOCKTYPE_WHILE:
427 w->AddReference (info->mark2); 453 w->AddReference (SCOPE(0).mark2);
428 break; 454 break;
429 default: 455 default:
430 ParserError ("unexpected `break`"); 456 ParserError ("unexpected `break`");
431 break; 457 break;
432 } 458 }
456 if (!token.compare ("}")) { 482 if (!token.compare ("}")) {
457 // Closing brace 483 // Closing brace
458 484
459 // If we're in the block stack, we're descending down from it now 485 // If we're in the block stack, we're descending down from it now
460 if (g_BlockStackCursor > 0) { 486 if (g_BlockStackCursor > 0) {
461 BlockInformation* info = &blockstack[g_BlockStackCursor]; 487 switch (SCOPE(0).type) {
462 switch (info->type) {
463 case BLOCKTYPE_IF: 488 case BLOCKTYPE_IF:
464 // Adjust the closing mark. 489 // Adjust the closing mark.
465 w->MoveMark (info->mark1); 490 w->MoveMark (SCOPE(0).mark1);
491 break;
492 case BLOCKTYPE_ELSE:
493 // else instead uses mark1 for itself (so if expression
494 // fails, jump to else), mark2 means end of else
495 w->MoveMark (SCOPE(0).mark2);
466 break; 496 break;
467 case BLOCKTYPE_FOR: 497 case BLOCKTYPE_FOR:
468 // Write the incrementor at the end of the loop block 498 // Write the incrementor at the end of the loop block
469 w->WriteBuffer (info->buffer1); 499 w->WriteBuffer (SCOPE(0).buffer1);
470 // fall-thru 500 // fall-thru
471 case BLOCKTYPE_WHILE: 501 case BLOCKTYPE_WHILE:
472 // Write down the instruction to go back to the start of the loop 502 // Write down the instruction to go back to the start of the loop
473 w->Write (DH_GOTO); 503 w->Write (DH_GOTO);
474 w->AddReference (info->mark1); 504 w->AddReference (SCOPE(0).mark1);
475 505
476 // Move the closing mark here since we're at the end of the while loop 506 // Move the closing mark here since we're at the end of the while loop
477 w->MoveMark (info->mark2); 507 w->MoveMark (SCOPE(0).mark2);
478 break; 508 break;
479 case BLOCKTYPE_DO: { 509 case BLOCKTYPE_DO: {
480 MustNext ("while"); 510 MustNext ("while");
481 MustNext ("("); 511 MustNext ("(");
482 MustNext (); 512 MustNext ();
485 MustNext (";"); 515 MustNext (";");
486 516
487 // If the condition runs true, go back to the start. 517 // If the condition runs true, go back to the start.
488 w->WriteBuffer (expr); 518 w->WriteBuffer (expr);
489 w->Write<long> (DH_IFGOTO); 519 w->Write<long> (DH_IFGOTO);
490 w->AddReference (info->mark1); 520 w->AddReference (SCOPE(0).mark1);
491 break; 521 break;
492 } 522 }
493 case BLOCKTYPE_SWITCH: { 523 case BLOCKTYPE_SWITCH: {
494 // Switch closes. Move down to the record buffer of 524 // Switch closes. Move down to the record buffer of
495 // the lower block. 525 // the lower block.
496 BlockInformation* previnfo = &blockstack[g_BlockStackCursor - 1]; 526 if (SCOPE(1).casecursor != -1)
497 if (previnfo->casecursor != -1) 527 w->SwitchBuffer = SCOPE(1).casebuffers[SCOPE(1).casecursor];
498 w->SwitchBuffer = previnfo->casebuffers[previnfo->casecursor];
499 else 528 else
500 w->SwitchBuffer = NULL; 529 w->SwitchBuffer = NULL;
501 530
502 // If there was a default in the switch, write its header down now. 531 // If there was a default in the switch, write its header down now.
503 // If not, write instruction to jump to the end of switch after 532 // If not, write instruction to jump to the end of switch after
504 // the headers (thus won't fall-through if no case matched) 533 // the headers (thus won't fall-through if no case matched)
505 if (info->buffer1) 534 if (SCOPE(0).buffer1)
506 w->WriteBuffer (info->buffer1); 535 w->WriteBuffer (SCOPE(0).buffer1);
507 else { 536 else {
508 w->Write<word> (DH_DROP); 537 w->Write<word> (DH_DROP);
509 w->Write<word> (DH_GOTO); 538 w->Write<word> (DH_GOTO);
510 w->AddReference (info->mark1); 539 w->AddReference (SCOPE(0).mark1);
511 } 540 }
512 541
513 // Go through all of the buffers we 542 // Go through all of the buffers we
514 // recorded down and write them. 543 // recorded down and write them.
515 for (unsigned int u = 0; u < MAX_CASE; u++) { 544 for (unsigned int u = 0; u < MAX_CASE; u++) {
516 if (!info->casebuffers[u]) 545 if (!SCOPE(0).casebuffers[u])
517 continue; 546 continue;
518 547
519 w->MoveMark (info->casemarks[u]); 548 w->MoveMark (SCOPE(0).casemarks[u]);
520 w->WriteBuffer (info->casebuffers[u]); 549 w->WriteBuffer (SCOPE(0).casebuffers[u]);
521 } 550 }
522 551
523 // Move the closing mark here 552 // Move the closing mark here
524 w->MoveMark (info->mark1); 553 w->MoveMark (SCOPE(0).mark1);
525 } 554 }
526 } 555 }
527 556
528 // Descend down the stack 557 // Descend down the stack
529 g_BlockStackCursor--; 558 g_BlockStackCursor--;
711 740
712 // Parse the right operand, 741 // Parse the right operand,
713 MustNext (); 742 MustNext ();
714 DataBuffer* rb = ParseExprValue (reqtype); 743 DataBuffer* rb = ParseExprValue (reqtype);
715 744
716 // Ternary operator requires - naturally - a third operator
717 if (oper == OPER_TERNARY) { 745 if (oper == OPER_TERNARY) {
746 // Ternary operator requires - naturally - a third operand.
718 MustNext (":"); 747 MustNext (":");
719 MustNext (); 748 MustNext ();
720 DataBuffer* tb = ParseExprValue (reqtype); 749 DataBuffer* tb = ParseExprValue (reqtype);
721 750
722 // It also is handled differently: there isn't a dataheader for ternary 751 // It also is handled differently: there isn't a dataheader for ternary
950 return retbuf; 979 return retbuf;
951 } 980 }
952 981
953 void ScriptReader::PushBlockStack () { 982 void ScriptReader::PushBlockStack () {
954 g_BlockStackCursor++; 983 g_BlockStackCursor++;
955 BlockInformation* info = &blockstack[g_BlockStackCursor]; 984 if (g_BlockStackCursor >= MAX_STRUCTSTACK)
985 ParserError ("too deep scope");
986
987 BlockInformation* info = &SCOPE(0);
956 info->type = 0; 988 info->type = 0;
957 info->mark1 = 0; 989 info->mark1 = 0;
958 info->mark2 = 0; 990 info->mark2 = 0;
959 info->buffer1 = NULL; 991 info->buffer1 = NULL;
960 info->casecursor = -1; 992 info->casecursor = -1;
976 DataBuffer* b = ParseExpression (TYPE_VOID); 1008 DataBuffer* b = ParseExpression (TYPE_VOID);
977 return b; 1009 return b;
978 } 1010 }
979 1011
980 void ScriptReader::AddSwitchCase (ObjWriter* w, DataBuffer* b) { 1012 void ScriptReader::AddSwitchCase (ObjWriter* w, DataBuffer* b) {
981 BlockInformation* info = &blockstack[g_BlockStackCursor]; 1013 BlockInformation* info = &SCOPE(0);
982 1014
983 info->casecursor++; 1015 info->casecursor++;
984 if (info->casecursor >= MAX_CASE) 1016 if (info->casecursor >= MAX_CASE)
985 ParserError ("too many cases in one switch"); 1017 ParserError ("too many cases in one switch");
986 1018

mercurial