src/Parser.cc

changeset 97
49e38433b9fd
parent 92
3a00d396bce2
child 98
ea02b78a737a
equal deleted inserted replaced
96:3384d7aa036a 97:49e38433b9fd
80 mOnEnterBuffer = new DataBuffer; 80 mOnEnterBuffer = new DataBuffer;
81 mMainLoopBuffer = new DataBuffer; 81 mMainLoopBuffer = new DataBuffer;
82 mCurrentMode = ETopLevelMode; 82 mCurrentMode = ETopLevelMode;
83 mNumStates = 0; 83 mNumStates = 0;
84 mNumEvents = 0; 84 mNumEvents = 0;
85 mScopeCursor = 0; 85 mScopeCursor = -1;
86 mStateSpawnDefined = false; 86 mStateSpawnDefined = false;
87 mGotMainLoop = false; 87 mGotMainLoop = false;
88 mIfExpression = null; 88 mIfExpression = null;
89 mCanElse = false; 89 mCanElse = false;
90 90 PushScope();
91 // Zero the entire block stack first
92 // TODO: this shouldn't be necessary
93 for (int i = 0; i < MAX_SCOPE; i++)
94 ZERO (mScopeStack[i]);
95 91
96 while (mLexer->GetNext()) 92 while (mLexer->GetNext())
97 { 93 {
98 // Check if else is potentically valid 94 // Check if else is potentically valid
99 if (TokenIs (tkElse) && mCanElse == false) 95 if (TokenIs (tkElse) && mCanElse == false)
417 // 413 //
418 void BotscriptParser::ParseElse() 414 void BotscriptParser::ParseElse()
419 { 415 {
420 CheckNotToplevel(); 416 CheckNotToplevel();
421 mLexer->MustGetNext (tkBraceStart); 417 mLexer->MustGetNext (tkBraceStart);
422 418 PushScope (eNoReset);
423 // Don't use PushScope as it resets the scope
424 mScopeCursor++;
425
426 if (mScopeCursor >= MAX_SCOPE)
427 Error ("too deep scope");
428 419
429 if (SCOPE (0).type != eIfScope) 420 if (SCOPE (0).type != eIfScope)
430 Error ("else without preceding if"); 421 Error ("else without preceding if");
431 422
432 // write down to jump to the end of the else statement 423 // write down to jump to the end of the else statement
574 { 565 {
575 // case is only allowed inside switch 566 // case is only allowed inside switch
576 if (SCOPE (0).type != eSwitchScope) 567 if (SCOPE (0).type != eSwitchScope)
577 Error ("case label outside switch"); 568 Error ("case label outside switch");
578 569
579 // Get the literal (Zandronum does not support expressions here) 570 // Get a literal value for the case block. Zandronum does not support
571 // expressions here.
580 mLexer->MustGetNext (tkNumber); 572 mLexer->MustGetNext (tkNumber);
581 int num = mLexer->GetToken()->text.ToLong(); 573 int num = mLexer->GetToken()->text.ToLong();
582 mLexer->MustGetNext (tkColon); 574 mLexer->MustGetNext (tkColon);
583 575
584 for (int i = 0; i < MAX_CASE; i++) 576 for (const CaseInfo& info : SCOPE(0).cases)
585 if (SCOPE (0).casenumbers[i] == num) 577 if (info.number == num)
586 Error ("multiple case %d labels in one switch", num); 578 Error ("multiple case %1 labels in one switch", num);
587 579
588 // Write down the expression and case-go-to. This builds 580 // Write down the expression and case-go-to. This builds
589 // the case tree. The closing event will write the actual 581 // the case tree. The closing event will write the actual
590 // blocks and move the marks appropriately. 582 // blocks and move the marks appropriately.
591 // 583 //
597 // we want it all under the switch, not into the case-buffers. 589 // we want it all under the switch, not into the case-buffers.
598 mSwitchBuffer = null; 590 mSwitchBuffer = null;
599 buffer()->WriteDWord (dhCaseGoto); 591 buffer()->WriteDWord (dhCaseGoto);
600 buffer()->WriteDWord (num); 592 buffer()->WriteDWord (num);
601 AddSwitchCase (null); 593 AddSwitchCase (null);
602 SCOPE (0).casenumbers[SCOPE (0).casecursor] = num; 594 SCOPE (0).casecursor->number = num;
603 } 595 }
604 596
605 // ============================================================================ 597 // ============================================================================
606 // 598 //
607 void BotscriptParser::ParseSwitchDefault() 599 void BotscriptParser::ParseSwitchDefault()
608 { 600 {
609 if (SCOPE (0).type != eSwitchScope) 601 if (SCOPE (0).type != eSwitchScope)
610 Error ("default label outside switch"); 602 Error ("default label outside switch");
611 603
612 if (SCOPE (0).buffer1) 604 if (SCOPE (0).buffer1 != null)
613 Error ("multiple default labels in one switch"); 605 Error ("multiple default labels in one switch");
614 606
615 mLexer->MustGetNext (tkColon); 607 mLexer->MustGetNext (tkColon);
616 608
617 // The default header is buffered into buffer1, since 609 // The default header is buffered into buffer1, since
619 // 611 //
620 // Since the expression is pushed into the switch 612 // Since the expression is pushed into the switch
621 // and is only popped when case succeeds, we have 613 // and is only popped when case succeeds, we have
622 // to pop it with dhDrop manually if we end up in 614 // to pop it with dhDrop manually if we end up in
623 // a default. 615 // a default.
624 DataBuffer* b = new DataBuffer; 616 DataBuffer* buf = new DataBuffer;
625 SCOPE (0).buffer1 = b; 617 SCOPE (0).buffer1 = buf;
626 b->WriteDWord (dhDrop); 618 buf->WriteDWord (dhDrop);
627 b->WriteDWord (dhGoto); 619 buf->WriteDWord (dhGoto);
628 AddSwitchCase (b); 620 AddSwitchCase (buf);
629 } 621 }
630 622
631 // ============================================================================ 623 // ============================================================================
632 // 624 //
633 void BotscriptParser::ParseBreak() 625 void BotscriptParser::ParseBreak()
748 740
749 case eSwitchScope: 741 case eSwitchScope:
750 { 742 {
751 // Switch closes. Move down to the record buffer of 743 // Switch closes. Move down to the record buffer of
752 // the lower block. 744 // the lower block.
753 if (SCOPE (1).casecursor != -1) 745 if (SCOPE (1).casecursor != SCOPE (1).cases.begin() - 1)
754 mSwitchBuffer = SCOPE (1).casebuffers[SCOPE (1).casecursor]; 746 mSwitchBuffer = SCOPE (1).casecursor->data;
755 else 747 else
756 mSwitchBuffer = null; 748 mSwitchBuffer = null;
757 749
758 // If there was a default in the switch, write its header down now. 750 // If there was a default in the switch, write its header down now.
759 // If not, write instruction to jump to the end of switch after 751 // If not, write instruction to jump to the end of switch after
767 buffer()->AddReference (SCOPE (0).mark1); 759 buffer()->AddReference (SCOPE (0).mark1);
768 } 760 }
769 761
770 // Go through all of the buffers we 762 // Go through all of the buffers we
771 // recorded down and write them. 763 // recorded down and write them.
772 for (int u = 0; u < MAX_CASE; u++) 764 for (CaseInfo& info : SCOPE (0).cases)
773 { 765 {
774 if (SCOPE (0).casebuffers[u] == null) 766 buffer()->AdjustMark (info.mark);
775 continue; 767 buffer()->MergeAndDestroy (info.data);
776
777 buffer()->AdjustMark (SCOPE (0).casemarks[u]);
778 buffer()->MergeAndDestroy (SCOPE (0).casebuffers[u]);
779 } 768 }
780 769
781 // Move the closing mark here 770 // Move the closing mark here
782 buffer()->AdjustMark (SCOPE (0).mark1); 771 buffer()->AdjustMark (SCOPE (0).mark1);
783 break; 772 break;
1184 return retbuf; 1173 return retbuf;
1185 } 1174 }
1186 1175
1187 // ============================================================================ 1176 // ============================================================================
1188 // 1177 //
1189 void BotscriptParser::PushScope() 1178 void BotscriptParser::PushScope (EReset reset)
1190 { 1179 {
1191 mScopeCursor++; 1180 mScopeCursor++;
1192 1181
1193 if (mScopeCursor >= MAX_SCOPE) 1182 Print ("%1 <-> %2\n", mScopeStack.Size(), mScopeCursor + 1);
1194 Error ("too deep scope"); 1183
1195 1184 if (mScopeStack.Size() < mScopeCursor + 1)
1196 ScopeInfo* info = &SCOPE (0); 1185 {
1197 info->type = eUnknownScope; 1186 Print ("Adding a scope\n");
1198 info->mark1 = null; 1187 ScopeInfo newscope;
1199 info->mark2 = null; 1188 mScopeStack << newscope;
1200 info->buffer1 = null; 1189 reset = eResetScope;
1201 info->casecursor = -1; 1190 }
1202 1191
1203 for (int i = 0; i < MAX_CASE; i++) 1192 if (reset == eResetScope)
1204 { 1193 {
1205 info->casemarks[i] = null; 1194 ScopeInfo* info = &SCOPE (0);
1206 info->casebuffers[i] = null; 1195 info->type = eUnknownScope;
1207 info->casenumbers[i] = -1; 1196 info->mark1 = null;
1197 info->mark2 = null;
1198 info->buffer1 = null;
1199 info->cases.Clear();
1200 info->casecursor = info->cases.begin() - 1;
1208 } 1201 }
1209 } 1202 }
1210 1203
1211 // ============================================================================ 1204 // ============================================================================
1212 // 1205 //
1238 return null; 1231 return null;
1239 } 1232 }
1240 1233
1241 // ============================================================================ 1234 // ============================================================================
1242 // 1235 //
1243 void BotscriptParser::AddSwitchCase (DataBuffer* b) 1236 void BotscriptParser::AddSwitchCase (DataBuffer* casebuffer)
1244 { 1237 {
1245 ScopeInfo* info = &SCOPE (0); 1238 ScopeInfo* info = &SCOPE (0);
1246 1239 CaseInfo casedata;
1247 info->casecursor++;
1248
1249 if (info->casecursor >= MAX_CASE)
1250 Error ("too many cases in one switch");
1251 1240
1252 // Init a mark for the case buffer 1241 // Init a mark for the case buffer
1253 ByteMark* casemark = buffer()->AddMark (""); 1242 ByteMark* casemark = buffer()->AddMark ("");
1254 info->casemarks[info->casecursor] = casemark; 1243 casedata.mark = casemark;
1255 1244
1256 // Add a reference to the mark. "case" and "default" both 1245 // Add a reference to the mark. "case" and "default" both
1257 // add the necessary bytecode before the reference. 1246 // add the necessary bytecode before the reference.
1258 if (b) 1247 if (casebuffer != null)
1259 b->AddReference (casemark); 1248 casebuffer->AddReference (casemark);
1260 else 1249 else
1261 buffer()->AddReference (casemark); 1250 buffer()->AddReference (casemark);
1262 1251
1263 // Init a buffer for the case block and tell the object 1252 // Init a buffer for the case block and tell the object
1264 // writer to record all written data to it. 1253 // writer to record all written data to it.
1265 info->casebuffers[info->casecursor] = mSwitchBuffer = new DataBuffer; 1254 casedata.data = mSwitchBuffer = new DataBuffer;
1255 SCOPE(0).cases << casedata;
1256 info->casecursor++;
1266 } 1257 }
1267 1258
1268 // ============================================================================ 1259 // ============================================================================
1269 // 1260 //
1270 ConstantInfo* BotscriptParser::FindConstant (const String& tok) 1261 ConstantInfo* BotscriptParser::FindConstant (const String& tok)
1371 1362
1372 // First, resolve references 1363 // First, resolve references
1373 for (MarkReference* ref : mMainBuffer->GetReferences()) 1364 for (MarkReference* ref : mMainBuffer->GetReferences())
1374 { 1365 {
1375 // Substitute the placeholder with the mark position 1366 // Substitute the placeholder with the mark position
1376 for (int v = 0; v < 4; v++) 1367 for (int i = 0; i < 4; ++i)
1377 mMainBuffer->GetBuffer()[ref->pos + v] = ((ref->target->pos) << (8 * v)) & 0xFF; 1368 mMainBuffer->GetBuffer()[ref->pos + i] = (ref->target->pos >> (8 * i)) & 0xFF;
1378 1369
1379 Print ("reference at %1 resolved to mark at %2\n", ref->pos, ref->target->pos); 1370 Print ("reference at %1 resolved to mark at %2\n", ref->pos, ref->target->pos);
1380 } 1371 }
1381 1372
1382 // Then, dump the main buffer to the file 1373 // Then, dump the main buffer to the file

mercurial