62 int g_CurMode = MODE_TOPLEVEL; |
62 int g_CurMode = MODE_TOPLEVEL; |
63 str g_CurState = ""; |
63 str g_CurState = ""; |
64 bool g_stateSpawnDefined = false; |
64 bool g_stateSpawnDefined = false; |
65 bool g_GotMainLoop = false; |
65 bool g_GotMainLoop = false; |
66 unsigned int g_BlockStackCursor = 0; |
66 unsigned int g_BlockStackCursor = 0; |
|
67 DataBuffer* g_IfExpression = NULL; |
67 |
68 |
68 // ============================================================================ |
69 // ============================================================================ |
69 // Main parser code. Begins read of the script file, checks the syntax of it |
70 // Main parser code. Begins read of the script file, checks the syntax of it |
70 // and writes the data to the object file via ObjWriter - which also takes care |
71 // and writes the data to the object file via ObjWriter - which also takes care |
71 // of necessary buffering so stuff is written in the correct order. |
72 // of necessary buffering so stuff is written in the correct order. |
72 void ScriptReader::BeginParse (ObjWriter* w) { |
73 void ScriptReader::BeginParse (ObjWriter* w) { |
73 g_BlockStackCursor = 0; |
|
74 while (Next()) { |
74 while (Next()) { |
75 if (!token.icompare ("state")) { |
75 if (!token.icompare ("state")) { |
76 MUST_TOPLEVEL |
76 MUST_TOPLEVEL |
77 |
77 |
78 MustString (); |
78 MustString (); |
204 // If |
204 // If |
205 if (!token.icompare ("if")) { |
205 if (!token.icompare ("if")) { |
206 // Condition |
206 // Condition |
207 MustNext ("("); |
207 MustNext ("("); |
208 |
208 |
209 // Read the expression and write it. |
209 // Read the expression and write it. Store it to memory too for else statements. |
210 MustNext (); |
210 MustNext (); |
211 DataBuffer* c = ParseExpression (TYPE_INT); |
211 DataBuffer* c = ParseExpression (TYPE_INT); |
212 w->WriteBuffer (c); |
212 w->WriteBuffer (c); |
213 |
213 |
214 MustNext (")"); |
214 MustNext (")"); |
215 MustNext ("{"); |
215 MustNext ("{"); |
216 |
216 |
217 // Add a mark - to here temporarily - and add a reference to it. |
|
218 // Upon a closing brace, the mark will be adjusted. |
|
219 unsigned int marknum = w->AddMark (MARKTYPE_IF, ""); |
|
220 |
|
221 // Use DH_IFNOTGOTO - if the expression is not true, we goto the mark |
217 // Use DH_IFNOTGOTO - if the expression is not true, we goto the mark |
222 // we just defined - and this mark will be at the end of the block. |
218 // we just defined - and this mark will be at the end of the block. |
223 w->Write<word> (DH_IFNOTGOTO); |
219 AddBlockMark (w, DH_IFNOTGOTO); |
224 w->AddReference (marknum); |
|
225 |
|
226 // Store it in the block stack |
|
227 g_BlockStackCursor++; |
|
228 blockstack[g_BlockStackCursor] = marknum; |
|
229 continue; |
220 continue; |
230 } |
221 } |
231 |
222 |
232 if (!token.compare ("}")) { |
223 if (!token.compare ("}")) { |
233 // Closing brace |
224 // Closing brace |
561 retbuf->Write<word> (dh); |
552 retbuf->Write<word> (dh); |
562 retbuf->Write<word> (var->index); |
553 retbuf->Write<word> (var->index); |
563 |
554 |
564 return retbuf; |
555 return retbuf; |
565 } |
556 } |
|
557 |
|
558 void ScriptReader::AddBlockMark (ObjWriter* w, word dataheader) { |
|
559 // Add a mark - to here temporarily - and add a reference to it. |
|
560 // Upon a closing brace, the mark will be adjusted. |
|
561 unsigned int marknum = w->AddMark (MARKTYPE_IF, ""); |
|
562 |
|
563 // Write the header and store reference to the mark |
|
564 w->Write<word> (dataheader); |
|
565 w->AddReference (marknum); |
|
566 |
|
567 // Store it in the block stack |
|
568 g_BlockStackCursor++; |
|
569 blockstack[g_BlockStackCursor] = marknum; |
|
570 } |