parser.cxx

changeset 37
c349dca807f9
parent 36
a8838b5f1213
child 38
e4bbd540663b
equal deleted inserted replaced
36:a8838b5f1213 37:c349dca807f9
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());
373 printf ("done\n"); 412 printf ("done\n");
374 413
375 retbuf->Merge (rb); 414 retbuf->Merge (rb);
376 retbuf->Merge (lb); 415 retbuf->Merge (lb);
377 416
378 long dh = DataHeaderByOperator (var, oper); 417 long dh = DataHeaderByOperator (NULL, oper);
379 retbuf->Write<word> (dh); 418 retbuf->Write<word> (dh);
380 419
381 printf ("expression complete\n"); 420 printf ("expression complete\n");
382 return retbuf; 421 return retbuf;
383 } 422 }
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 }

mercurial