50 #include "commands.h" |
50 #include "commands.h" |
51 #include "stringtable.h" |
51 #include "stringtable.h" |
52 #include "variables.h" |
52 #include "variables.h" |
53 |
53 |
54 #define MUST_TOPLEVEL if (g_CurMode != MODE_TOPLEVEL) \ |
54 #define MUST_TOPLEVEL if (g_CurMode != MODE_TOPLEVEL) \ |
55 ParserError ("%ss may only be defined at top level!", token.chars()); |
55 ParserError ("%s-statements may only be defined at top level!", token.chars()); |
|
56 |
|
57 #define MUST_NOT_TOPLEVEL if (g_CurMode != MODE_TOPLEVEL) \ |
|
58 ParserError ("%s-statements may not be defined at top level!", token.chars()); |
56 |
59 |
57 int g_NumStates = 0; |
60 int g_NumStates = 0; |
58 int g_NumEvents = 0; |
61 int g_NumEvents = 0; |
59 int g_CurMode = MODE_TOPLEVEL; |
62 int g_CurMode = MODE_TOPLEVEL; |
60 str g_CurState = ""; |
63 str g_CurState = ""; |
61 bool g_stateSpawnDefined = false; |
64 bool g_stateSpawnDefined = false; |
62 bool g_GotMainLoop = false; |
65 bool g_GotMainLoop = false; |
|
66 int g_StructStack = 0; |
63 |
67 |
64 // ============================================================================ |
68 // ============================================================================ |
65 // Main parser code. Begins read of the script file, checks the syntax of it |
69 // Main parser code. Begins read of the script file, checks the syntax of it |
66 // and writes the data to the object file via ObjWriter - which also takes care |
70 // and writes the data to the object file via ObjWriter - which also takes care |
67 // of necessary buffering so stuff is written in the correct order. |
71 // of necessary buffering so stuff is written in the correct order. |
68 void ScriptReader::BeginParse (ObjWriter* w) { |
72 void ScriptReader::BeginParse (ObjWriter* w) { |
|
73 g_StructStack = 0; |
69 while (Next()) { |
74 while (Next()) { |
70 printf ("BeginParse: token: `%s`\n", token.chars()); |
75 printf ("BeginParse: token: `%s`\n", token.chars()); |
71 if (!token.icompare ("state")) { |
76 if (!token.icompare ("state")) { |
72 MUST_TOPLEVEL |
77 MUST_TOPLEVEL |
73 |
78 |
164 |
169 |
165 MustNext (";"); |
170 MustNext (";"); |
166 continue; |
171 continue; |
167 } |
172 } |
168 |
173 |
|
174 // Label |
|
175 if (!PeekNext().compare (":")) { |
|
176 if (IsKeyword (token)) |
|
177 ParserError ("label name `%s` conflicts with keyword\n", token.chars()); |
|
178 if (FindCommand (token)) |
|
179 ParserError ("label name `%s` conflicts with command name\n", token.chars()); |
|
180 if (FindGlobalVariable (token)) |
|
181 ParserError ("label name `%s` conflicts with variable\n", token.chars()); |
|
182 |
|
183 w->AddMark (MARKTYPE_LABEL, token); |
|
184 MustNext (":"); |
|
185 continue; |
|
186 } |
|
187 |
|
188 // Goto |
|
189 if (!token.icompare ("goto")) { |
|
190 // Get the name of the label |
|
191 MustNext (); |
|
192 |
|
193 // Find the mark this goto statement points to |
|
194 unsigned int m = w->FindMark (MARKTYPE_LABEL, token); |
|
195 if (m == MAX_MARKS) |
|
196 ParserError ("unknown label `%s`!", token.chars()); |
|
197 |
|
198 // Add a reference to the mark. |
|
199 w->Write<word> (DH_GOTO); |
|
200 w->AddReference (m); |
|
201 MustNext (";"); |
|
202 continue; |
|
203 } |
|
204 |
169 if (!token.compare ("}")) { |
205 if (!token.compare ("}")) { |
170 printf ("parse closing brace\n"); |
206 // If this was done inside the struct stack (i.e. |
|
207 // inside "if" for instance), it does not end the mode. |
|
208 if (g_StructStack > 0) { |
|
209 g_StructStack--; |
|
210 continue; |
|
211 } |
|
212 |
171 // Closing brace |
213 // Closing brace |
172 int dataheader = (g_CurMode == MODE_EVENT) ? DH_ENDEVENT : |
214 int dataheader = (g_CurMode == MODE_EVENT) ? DH_ENDEVENT : |
173 (g_CurMode == MODE_MAINLOOP) ? DH_ENDMAINLOOP : |
215 (g_CurMode == MODE_MAINLOOP) ? DH_ENDMAINLOOP : |
174 (g_CurMode == MODE_ONENTER) ? DH_ENDONENTER : |
216 (g_CurMode == MODE_ONENTER) ? DH_ENDONENTER : |
175 (g_CurMode == MODE_ONEXIT) ? DH_ENDONEXIT : -1; |
217 (g_CurMode == MODE_ONEXIT) ? DH_ENDONEXIT : -1; |
338 token.chars(), PeekNext().chars()); |
380 token.chars(), PeekNext().chars()); |
339 DataBuffer* retbuf = new DataBuffer (64); |
381 DataBuffer* retbuf = new DataBuffer (64); |
340 |
382 |
341 DataBuffer* lb = NULL; |
383 DataBuffer* lb = NULL; |
342 |
384 |
343 // If it's a variable, note it down - we need to do special checks with it later. |
|
344 ScriptVar* var = FindGlobalVariable (token); |
|
345 |
|
346 lb = ParseExprValue (reqtype); |
385 lb = ParseExprValue (reqtype); |
347 printf ("done\n"); |
386 printf ("done\n"); |
348 |
387 |
349 // Get an operator |
388 // Get an operator |
350 printf ("parse operator at token %s\n", token.chars()); |
389 printf ("parse operator at token %s\n", token.chars()); |
488 // ============================================================================ |
527 // ============================================================================ |
489 // Parses an assignment. An assignment starts with a variable name, followed |
528 // Parses an assignment. An assignment starts with a variable name, followed |
490 // by an assignment operator, followed by an expression value. Expects current |
529 // by an assignment operator, followed by an expression value. Expects current |
491 // token to be the name of the variable, and expects the variable to be given. |
530 // token to be the name of the variable, and expects the variable to be given. |
492 DataBuffer* ScriptReader::ParseAssignment (ScriptVar* var) { |
531 DataBuffer* ScriptReader::ParseAssignment (ScriptVar* var) { |
493 printf ("ASSIGNMENT: this token is `%s`, next token is `%s`\n", |
|
494 token.chars(), PeekNext().chars()); |
|
495 |
|
496 // Get an operator |
532 // Get an operator |
497 printf ("parse assignment operator at token %s\n", token.chars()); |
|
498 |
|
499 MustNext (); |
533 MustNext (); |
500 int oper = ParseOperator (); |
534 int oper = ParseOperator (); |
501 if (!IsAssignmentOperator (oper)) |
535 if (!IsAssignmentOperator (oper)) |
502 ParserError ("expected assignment operator"); |
536 ParserError ("expected assignment operator"); |
503 printf ("got %d\n", oper); |
|
504 |
537 |
505 if (g_CurMode == MODE_TOPLEVEL) // TODO: lift this restriction |
538 if (g_CurMode == MODE_TOPLEVEL) // TODO: lift this restriction |
506 ParserError ("can't alter variables at top level"); |
539 ParserError ("can't alter variables at top level"); |
507 |
540 |
508 // Parse the right operand, |
541 // Parse the right operand, |
509 printf ("parse right operand\n"); |
|
510 MustNext (); |
542 MustNext (); |
511 DataBuffer* retbuf = ParseExprValue (TYPE_INT); |
543 DataBuffer* retbuf = ParseExprValue (TYPE_INT); |
512 |
544 |
513 long dh = DataHeaderByOperator (var, oper); |
545 long dh = DataHeaderByOperator (var, oper); |
514 retbuf->Write<word> (dh); |
546 retbuf->Write<word> (dh); |
515 retbuf->Write<word> (var->index); |
547 retbuf->Write<word> (var->index); |
516 |
548 |
517 printf ("assignment complete\n"); |
|
518 return retbuf; |
549 return retbuf; |
519 } |
550 } |