parser.cxx

changeset 39
07b7ab8080cf
parent 38
e4bbd540663b
child 40
9e4f785501db
equal deleted inserted replaced
38:e4bbd540663b 39:07b7ab8080cf
70 // 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
71 // of necessary buffering so stuff is written in the correct order. 71 // of necessary buffering so stuff is written in the correct order.
72 void ScriptReader::BeginParse (ObjWriter* w) { 72 void ScriptReader::BeginParse (ObjWriter* w) {
73 g_BlockStackCursor = 0; 73 g_BlockStackCursor = 0;
74 while (Next()) { 74 while (Next()) {
75 printf ("BeginParse: token: `%s`\n", token.chars());
76 if (!token.icompare ("state")) { 75 if (!token.icompare ("state")) {
77 MUST_TOPLEVEL 76 MUST_TOPLEVEL
78 77
79 MustString (); 78 MustString ();
80 79
209 208
210 // Read the expression and write it. 209 // Read the expression and write it.
211 MustNext (); 210 MustNext ();
212 DataBuffer* c = ParseExpression (TYPE_INT); 211 DataBuffer* c = ParseExpression (TYPE_INT);
213 w->WriteBuffer (c); 212 w->WriteBuffer (c);
214 delete c;
215 213
216 MustNext (")"); 214 MustNext (")");
217 MustNext ("{"); 215 MustNext ("{");
218 216
219 // Add a mark - to here temporarily - and add a reference to it. 217 // Add a mark - to here temporarily - and add a reference to it.
224 // we just defined - and this mark will be at the end of the block. 222 // we just defined - and this mark will be at the end of the block.
225 w->Write<word> (DH_IFNOTGOTO); 223 w->Write<word> (DH_IFNOTGOTO);
226 w->AddReference (marknum); 224 w->AddReference (marknum);
227 225
228 // Store it in the block stack 226 // Store it in the block stack
227 g_BlockStackCursor++;
229 blockstack[g_BlockStackCursor] = marknum; 228 blockstack[g_BlockStackCursor] = marknum;
230 g_BlockStackCursor++;
231 continue; 229 continue;
232 } 230 }
233 231
234 if (!token.compare ("}")) { 232 if (!token.compare ("}")) {
235 // Closing brace 233 // Closing brace
236 234
237 // If we're in the block stack, we're descending down from it now 235 // If we're in the block stack, we're descending down from it now
238 if (g_BlockStackCursor > 0) { 236 if (g_BlockStackCursor > 0) {
239 // Adjust its closing mark so that it's here. 237 // Adjust its closing mark so that it's here.
240 unsigned int marknum = blockstack[g_BlockStackCursor]; 238 unsigned int marknum = blockstack[g_BlockStackCursor];
241 if (marknum != MAX_MARKS) { 239 if (marknum != MAX_MARKS)
242 // printf ("\tblock %d stack mark moved from %d ",
243 g_BlockStackCursor, w->GetCurrentBuffer()->marks[marknum]->pos);
244 w->MoveMark (marknum); 240 w->MoveMark (marknum);
245 // printf ("to %d\n", w->GetCurrentBuffer()->marks[marknum]->pos); 241 w->AddMark (MARKTYPE_INTERNAL, "");
246 }
247
248 g_BlockStackCursor--; 242 g_BlockStackCursor--;
249 continue; 243 continue;
250 } 244 }
251 245
252 int dataheader = (g_CurMode == MODE_EVENT) ? DH_ENDEVENT : 246 int dataheader = (g_CurMode == MODE_EVENT) ? DH_ENDEVENT :
269 } 263 }
270 264
271 // If it's a variable, expect assignment. 265 // If it's a variable, expect assignment.
272 if (ScriptVar* var = FindGlobalVariable (token)) { 266 if (ScriptVar* var = FindGlobalVariable (token)) {
273 DataBuffer* b = ParseAssignment (var); 267 DataBuffer* b = ParseAssignment (var);
274 printf ("current token after assignment: `%s`\n", token.chars());
275 MustNext (";"); 268 MustNext (";");
276 w->WriteBuffer (b); 269 w->WriteBuffer (b);
277 delete b;
278 continue; 270 continue;
279 } 271 }
280 272
281 // If it's not a keyword, parse it as an expression. 273 // If it's not a keyword, parse it as an expression.
282 printf ("token length: %d, first char: %c [%d]\n", token.len(), token.chars()[0], token.chars()[0]);
283 DataBuffer* b = ParseExpression (TYPE_VOID); 274 DataBuffer* b = ParseExpression (TYPE_VOID);
284 w->WriteBuffer (b); 275 w->WriteBuffer (b);
285 delete b;
286 printf ("expression done! current token is %s\n", token.chars());
287 MustNext (";"); 276 MustNext (";");
288 } 277 }
289 278
290 if (g_CurMode != MODE_TOPLEVEL) 279 if (g_CurMode != MODE_TOPLEVEL)
291 ParserError ("script did not end at top level; did you forget a `}`?"); 280 ParserError ("script did not end at top level; did you forget a `}`?");
306 DataBuffer* ScriptReader::ParseCommand (CommandDef* comm) { 295 DataBuffer* ScriptReader::ParseCommand (CommandDef* comm) {
307 DataBuffer* r = new DataBuffer(64); 296 DataBuffer* r = new DataBuffer(64);
308 if (g_CurMode == MODE_TOPLEVEL) 297 if (g_CurMode == MODE_TOPLEVEL)
309 ParserError ("command call at top level"); 298 ParserError ("command call at top level");
310 299
311 printf ("\n\n\n=====================================\nBEGIN PARSING COMMAND\n");
312 printf ("token: %s\n", token.chars());
313 MustNext ("("); 300 MustNext ("(");
314 MustNext (); 301 MustNext ();
315 302
316 int curarg = 0; 303 int curarg = 0;
317 while (1) { 304 while (1) {
318 printf ("at argument %d\n", curarg);
319 printf ("next token: %s\n", token.chars());
320
321 if (!token.compare (")")) { 305 if (!token.compare (")")) {
322 printf ("closing command with token `%s`\n", token.chars());
323 if (curarg < comm->numargs - 1) 306 if (curarg < comm->numargs - 1)
324 ParserError ("too few arguments passed to %s\n", comm->name.chars()); 307 ParserError ("too few arguments passed to %s\n", comm->name.chars());
325 break; 308 break;
326 curarg++; 309 curarg++;
327 } 310 }
329 if (curarg >= comm->maxargs) 312 if (curarg >= comm->maxargs)
330 ParserError ("too many arguments passed to %s\n", comm->name.chars()); 313 ParserError ("too many arguments passed to %s\n", comm->name.chars());
331 314
332 r->Merge (ParseExpression (comm->argtypes[curarg])); 315 r->Merge (ParseExpression (comm->argtypes[curarg]));
333 MustNext (); 316 MustNext ();
334 printf ("after expression, token is `%s`\n", token.chars());
335 317
336 if (curarg < comm->numargs - 1) { 318 if (curarg < comm->numargs - 1) {
337 MustThis (","); 319 MustThis (",");
338 MustNext (); 320 MustNext ();
339 } else if (curarg < comm->maxargs - 1) { 321 } else if (curarg < comm->maxargs - 1) {
359 341
360 r->Write<word> (DH_COMMAND); 342 r->Write<word> (DH_COMMAND);
361 r->Write<word> (comm->number); 343 r->Write<word> (comm->number);
362 r->Write<word> (comm->maxargs); 344 r->Write<word> (comm->maxargs);
363 345
364 printf ("command complete\n");
365 return r; 346 return r;
366 } 347 }
367 348
368 // ============================================================================ 349 // ============================================================================
369 // Is the given operator an assignment operator? 350 // Is the given operator an assignment operator?
418 } 399 }
419 400
420 // ============================================================================ 401 // ============================================================================
421 // Parses an expression, potentially recursively 402 // Parses an expression, potentially recursively
422 DataBuffer* ScriptReader::ParseExpression (int reqtype) { 403 DataBuffer* ScriptReader::ParseExpression (int reqtype) {
423 printf ("begin parsing expression. this token is `%s`, next token is `%s`\n",
424 token.chars(), PeekNext().chars());
425 DataBuffer* retbuf = new DataBuffer (64); 404 DataBuffer* retbuf = new DataBuffer (64);
426 405
427 DataBuffer* lb = NULL; 406 DataBuffer* lb = NULL;
428 407
429 lb = ParseExprValue (reqtype); 408 lb = ParseExprValue (reqtype);
430 printf ("done\n");
431 409
432 // Get an operator 410 // Get an operator
433 printf ("parse operator at token %s\n", token.chars());
434 int oper = ParseOperator (true); 411 int oper = ParseOperator (true);
435 printf ("operator parsed: token is now %s\n", token.chars());
436 printf ("got %d\n", oper);
437 412
438 // No operator found - stop here. 413 // No operator found - stop here.
439 if (oper == -1) { 414 if (oper == -1) {
440 retbuf->Merge (lb); 415 retbuf->Merge (lb);
441 printf ("expression complete without operator, stopping at `%s`\n", token.chars());
442 return retbuf; 416 return retbuf;
443 } 417 }
444 418
445 // We peeked the operator, move forward now 419 // We peeked the operator, move forward now
446 MustNext(); 420 MustNext();
448 // Can't be an assignement operator, those belong in assignments. 422 // Can't be an assignement operator, those belong in assignments.
449 if (IsAssignmentOperator (oper)) 423 if (IsAssignmentOperator (oper))
450 ParserError ("assignment operator inside expressions"); 424 ParserError ("assignment operator inside expressions");
451 425
452 // Parse the right operand, 426 // Parse the right operand,
453 printf ("parse right operand\n");
454 MustNext (); 427 MustNext ();
455 DataBuffer* rb = ParseExprValue (reqtype); 428 DataBuffer* rb = ParseExprValue (reqtype);
456 printf ("done\n");
457 429
458 retbuf->Merge (rb); 430 retbuf->Merge (rb);
459 retbuf->Merge (lb); 431 retbuf->Merge (lb);
460 432
461 long dh = DataHeaderByOperator (NULL, oper); 433 long dh = DataHeaderByOperator (NULL, oper);
462 retbuf->Write<word> (dh); 434 retbuf->Write<word> (dh);
463
464 printf ("expression complete\n");
465 return retbuf; 435 return retbuf;
466 } 436 }
467 437
468 // ============================================================================ 438 // ============================================================================
469 // Parses an operator string. Returns the operator number code. 439 // `arses an operator string. Returns the operator number code.
470 int ScriptReader::ParseOperator (bool peek) { 440 int ScriptReader::ParseOperator (bool peek) {
471 str oper; 441 str oper;
472 if (peek) 442 if (peek)
473 oper += PeekNext (); 443 oper += PeekNext ();
474 else 444 else
475 oper += token; 445 oper += token;
476 446
477 // Check one-char operators 447 // Check one-char operators
478 bool equalsnext = !PeekNext (peek ? 1 : 0).compare ("="); 448 bool equalsnext = !PeekNext (peek ? 1 : 0).compare ("=");
479 printf ("operator one-char: %s\nequals is%s next (`%s`)\n", oper.chars(),
480 (equalsnext) ? "" : " not", PeekNext (peek ? 1 : 0).chars());
481 int o = (!oper.compare ("=") && !equalsnext) ? OPER_ASSIGN : 449 int o = (!oper.compare ("=") && !equalsnext) ? OPER_ASSIGN :
482 (!oper.compare (">") && !equalsnext) ? OPER_GREATERTHAN : 450 (!oper.compare (">") && !equalsnext) ? OPER_GREATERTHAN :
483 (!oper.compare ("<") && !equalsnext) ? OPER_LESSTHAN : 451 (!oper.compare ("<") && !equalsnext) ? OPER_LESSTHAN :
484 !oper.compare ("+") ? OPER_ADD : 452 !oper.compare ("+") ? OPER_ADD :
485 !oper.compare ("-") ? OPER_SUBTRACT : 453 !oper.compare ("-") ? OPER_SUBTRACT :
492 return o; 460 return o;
493 } 461 }
494 462
495 // Two-char operators 463 // Two-char operators
496 oper += PeekNext (peek ? 1 : 0); 464 oper += PeekNext (peek ? 1 : 0);
497
498 printf ("operator two-char: %s\n", oper.chars());
499 465
500 o = !oper.compare ("+=") ? OPER_ASSIGNADD : 466 o = !oper.compare ("+=") ? OPER_ASSIGNADD :
501 !oper.compare ("-=") ? OPER_ASSIGNSUB : 467 !oper.compare ("-=") ? OPER_ASSIGNSUB :
502 !oper.compare ("*=") ? OPER_ASSIGNMUL : 468 !oper.compare ("*=") ? OPER_ASSIGNMUL :
503 !oper.compare ("/=") ? OPER_ASSIGNDIV : 469 !oper.compare ("/=") ? OPER_ASSIGNDIV :
517 // ============================================================================ 483 // ============================================================================
518 // Parses a value in the expression and returns the data needed to push 484 // Parses a value in the expression and returns the data needed to push
519 // it, contained in a data buffer. A value can be either a variable, a command, 485 // it, contained in a data buffer. A value can be either a variable, a command,
520 // a literal or an expression. 486 // a literal or an expression.
521 DataBuffer* ScriptReader::ParseExprValue (int reqtype) { 487 DataBuffer* ScriptReader::ParseExprValue (int reqtype) {
522 printf ("parse expr value `%s` with requirement type %d\n", token.chars(), reqtype);
523 DataBuffer* b = new DataBuffer(16); 488 DataBuffer* b = new DataBuffer(16);
524 489
525 ScriptVar* g; 490 ScriptVar* g;
526 491
527 if (!token.compare ("(")) { 492 if (!token.compare ("(")) {
528 printf ("value is an expression\n");
529 // Expression 493 // Expression
530 MustNext (); 494 MustNext ();
531 DataBuffer* c = ParseExpression (reqtype); 495 DataBuffer* c = ParseExpression (reqtype);
532 b->Merge (c); 496 b->Merge (c);
533 MustNext (")"); 497 MustNext (")");
534 } else if (CommandDef* comm = FindCommand (token)) { 498 } else if (CommandDef* comm = FindCommand (token)) {
535 printf ("value is a command\n");
536 delete b; 499 delete b;
537 500
538 // Command 501 // Command
539 if (reqtype && comm->returnvalue != reqtype) 502 if (reqtype && comm->returnvalue != reqtype)
540 ParserError ("%s returns an incompatible data type", comm->name.chars()); 503 ParserError ("%s returns an incompatible data type", comm->name.chars());
541 b = ParseCommand (comm); 504 b = ParseCommand (comm);
542 } else if ((g = FindGlobalVariable (token)) && reqtype != TYPE_STRING) { 505 } else if ((g = FindGlobalVariable (token)) && reqtype != TYPE_STRING) {
543 printf ("value is a global var\n");
544 // Global variable 506 // Global variable
545 b->Write<word> (DH_PUSHGLOBALVAR); 507 b->Write<word> (DH_PUSHGLOBALVAR);
546 b->Write<word> (g->index); 508 b->Write<word> (g->index);
547 } else { 509 } else {
548 printf ("value is a literal\n");
549 // If nothing else, check for literal 510 // If nothing else, check for literal
550 switch (reqtype) { 511 switch (reqtype) {
551 case TYPE_VOID: 512 case TYPE_VOID:
552 ParserError ("bad syntax"); 513 ParserError ("bad syntax");
553 break; 514 break;
566 } 527 }
567 case TYPE_STRING: 528 case TYPE_STRING:
568 // PushToStringTable either returns the string index of the 529 // PushToStringTable either returns the string index of the
569 // string if it finds it in the table, or writes it to the 530 // string if it finds it in the table, or writes it to the
570 // table and returns it index if it doesn't find it there. 531 // table and returns it index if it doesn't find it there.
571 printf ("value is a string literal\n");
572 MustString (true); 532 MustString (true);
573 b->Write<word> (DH_PUSHSTRINGINDEX); 533 b->Write<word> (DH_PUSHSTRINGINDEX);
574 b->Write<word> (PushToStringTable (token.chars())); 534 b->Write<word> (PushToStringTable (token.chars()));
575 break; 535 break;
576 } 536 }
577 } 537 }
578 printf ("value parsed: current token is `%s`\n", token.chars());
579 538
580 return b; 539 return b;
581 } 540 }
582 541
583 // ============================================================================ 542 // ============================================================================

mercurial