src/parser.cc

changeset 87
8f65914e7046
parent 86
43fe4be38a58
equal deleted inserted replaced
86:43fe4be38a58 87:8f65914e7046
51 51
52 // ============================================================================ 52 // ============================================================================
53 // 53 //
54 void botscript_parser::check_toplevel() 54 void botscript_parser::check_toplevel()
55 { 55 {
56 if (m_current_mode != MODE_TOPLEVEL) 56 if (m_current_mode != e_top_level_mode)
57 error ("%1-statements may only be defined at top level!", token_string()); 57 error ("%1-statements may only be defined at top level!", token_string());
58 } 58 }
59 59
60 // ============================================================================ 60 // ============================================================================
61 // 61 //
62 void botscript_parser::check_not_toplevel() 62 void botscript_parser::check_not_toplevel()
63 { 63 {
64 if (m_current_mode == MODE_TOPLEVEL) 64 if (m_current_mode == e_top_level_mode)
65 error ("%1-statements must not be defined at top level!", token_string()); 65 error ("%1-statements must not be defined at top level!", token_string());
66 } 66 }
67 67
68 // ============================================================================ 68 // ============================================================================
69 // 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
72 void botscript_parser::parse_botscript (string file_name) 72 void botscript_parser::parse_botscript (string file_name)
73 { 73 {
74 // Lex and preprocess the file 74 // Lex and preprocess the file
75 m_lx->process_file (file_name); 75 m_lx->process_file (file_name);
76 76
77 m_current_mode = MODE_TOPLEVEL; 77 m_current_mode = e_top_level_mode;
78 m_num_states = 0; 78 m_num_states = 0;
79 m_num_events = 0; 79 m_num_events = 0;
80 m_scope_cursor = 0; 80 m_scope_cursor = 0;
81 m_state_spawn_defined = false; 81 m_state_spawn_defined = false;
82 m_got_main_loop = false; 82 m_got_main_loop = false;
218 } 218 }
219 } 219 }
220 220
221 // =============================================================================== 221 // ===============================================================================
222 // Script file ended. Do some last checks and write the last things to main buffer 222 // Script file ended. Do some last checks and write the last things to main buffer
223 if (m_current_mode != MODE_TOPLEVEL) 223 if (m_current_mode != e_top_level_mode)
224 error ("script did not end at top level; a `}` is missing somewhere"); 224 error ("script did not end at top level; a `}` is missing somewhere");
225 225
226 // stateSpawn must be defined! 226 // stateSpawn must be defined!
227 if (!m_state_spawn_defined) 227 if (!m_state_spawn_defined)
228 error ("script must have a state named `stateSpawn`!"); 228 error ("script must have a state named `stateSpawn`!");
291 291
292 if (!e) 292 if (!e)
293 error ("bad event, got `%1`\n", token_string()); 293 error ("bad event, got `%1`\n", token_string());
294 294
295 m_lx->must_get_next (tk_brace_start); 295 m_lx->must_get_next (tk_brace_start);
296 m_current_mode = MODE_EVENT; 296 m_current_mode = e_event_mode;
297 buffer()->write_dword (dh_event); 297 buffer()->write_dword (dh_event);
298 buffer()->write_dword (e->number); 298 buffer()->write_dword (e->number);
299 m_num_events++; 299 m_num_events++;
300 } 300 }
301 301
304 void botscript_parser::parse_mainloop() 304 void botscript_parser::parse_mainloop()
305 { 305 {
306 check_toplevel(); 306 check_toplevel();
307 m_lx->must_get_next (tk_brace_start); 307 m_lx->must_get_next (tk_brace_start);
308 308
309 m_current_mode = MODE_MAINLOOP; 309 m_current_mode = e_main_loop_mode;
310 m_main_loop_buffer->write_dword (dh_main_loop); 310 m_main_loop_buffer->write_dword (dh_main_loop);
311 } 311 }
312 312
313 // ============================================================================ 313 // ============================================================================
314 // 314 //
316 { 316 {
317 check_toplevel(); 317 check_toplevel();
318 bool onenter = (token_is (tk_onenter)); 318 bool onenter = (token_is (tk_onenter));
319 m_lx->must_get_next (tk_brace_start); 319 m_lx->must_get_next (tk_brace_start);
320 320
321 m_current_mode = onenter ? MODE_ONENTER : MODE_ONEXIT; 321 m_current_mode = onenter ? e_onenter_mode : e_onexit_mode;
322 buffer()->write_dword (onenter ? dh_on_enter : dh_on_exit); 322 buffer()->write_dword (onenter ? dh_on_enter : dh_on_exit);
323 } 323 }
324 324
325 // ============================================================================ 325 // ============================================================================
326 // 326 //
327 void botscript_parser::parse_variable_declaration() 327 void botscript_parser::parse_variable_declaration()
328 { 328 {
329 // For now, only globals are supported 329 // For now, only globals are supported
330 if (m_current_mode != MODE_TOPLEVEL || m_current_state.is_empty() == false) 330 if (m_current_mode != e_top_level_mode || m_current_state.is_empty() == false)
331 error ("variables must only be global for now"); 331 error ("variables must only be global for now");
332 332
333 type_e type = (token_is (tk_int)) ? TYPE_INT : 333 type_e type = (token_is (tk_int)) ? e_int_type :
334 (token_is (tk_str)) ? TYPE_STRING : 334 (token_is (tk_str)) ? e_string_type :
335 TYPE_BOOL; 335 e_bool_type;
336 336
337 m_lx->must_get_next(); 337 m_lx->must_get_next();
338 string varname = token_string(); 338 string varname = token_string();
339 339
340 // Var name must not be a number 340 // Var name must not be a number
384 // Condition 384 // Condition
385 m_lx->must_get_next (tk_paren_start); 385 m_lx->must_get_next (tk_paren_start);
386 386
387 // Read the expression and write it. 387 // Read the expression and write it.
388 m_lx->must_get_next(); 388 m_lx->must_get_next();
389 data_buffer* c = parse_expression (TYPE_INT); 389 data_buffer* c = parse_expression (e_int_type);
390 buffer()->merge_and_destroy (c); 390 buffer()->merge_and_destroy (c);
391 391
392 m_lx->must_get_next (tk_paren_end); 392 m_lx->must_get_next (tk_paren_end);
393 m_lx->must_get_next (tk_brace_start); 393 m_lx->must_get_next (tk_brace_start);
394 394
450 byte_mark* mark2 = buffer()->add_mark (""); // end 450 byte_mark* mark2 = buffer()->add_mark (""); // end
451 451
452 // Condition 452 // Condition
453 m_lx->must_get_next (tk_paren_start); 453 m_lx->must_get_next (tk_paren_start);
454 m_lx->must_get_next(); 454 m_lx->must_get_next();
455 data_buffer* expr = parse_expression (TYPE_INT); 455 data_buffer* expr = parse_expression (e_int_type);
456 m_lx->must_get_next (tk_paren_end); 456 m_lx->must_get_next (tk_paren_end);
457 m_lx->must_get_next (tk_brace_start); 457 m_lx->must_get_next (tk_brace_start);
458 458
459 // write condition 459 // write condition
460 buffer()->merge_and_destroy (expr); 460 buffer()->merge_and_destroy (expr);
486 486
487 m_lx->must_get_next (tk_semicolon); 487 m_lx->must_get_next (tk_semicolon);
488 488
489 // Condition 489 // Condition
490 m_lx->must_get_next(); 490 m_lx->must_get_next();
491 data_buffer* cond = parse_expression (TYPE_INT); 491 data_buffer* cond = parse_expression (e_int_type);
492 492
493 if (!cond) 493 if (!cond)
494 error ("bad statement for condition of for"); 494 error ("bad statement for condition of for");
495 495
496 m_lx->must_get_next (tk_semicolon); 496 m_lx->must_get_next (tk_semicolon);
554 554
555 check_not_toplevel(); 555 check_not_toplevel();
556 push_scope(); 556 push_scope();
557 m_lx->must_get_next (tk_paren_start); 557 m_lx->must_get_next (tk_paren_start);
558 m_lx->must_get_next(); 558 m_lx->must_get_next();
559 buffer()->merge_and_destroy (parse_expression (TYPE_INT)); 559 buffer()->merge_and_destroy (parse_expression (e_int_type));
560 m_lx->must_get_next (tk_paren_end); 560 m_lx->must_get_next (tk_paren_end);
561 m_lx->must_get_next (tk_brace_start); 561 m_lx->must_get_next (tk_brace_start);
562 SCOPE (0).type = e_switch_scope; 562 SCOPE (0).type = e_switch_scope;
563 SCOPE (0).mark1 = buffer()->add_mark (""); // end mark 563 SCOPE (0).mark1 = buffer()->add_mark (""); // end mark
564 SCOPE (0).buffer1 = null; // default header 564 SCOPE (0).buffer1 = null; // default header
716 break; 716 break;
717 717
718 case e_for_scope: 718 case e_for_scope:
719 // write the incrementor at the end of the loop block 719 // write the incrementor at the end of the loop block
720 buffer()->merge_and_destroy (SCOPE (0).buffer1); 720 buffer()->merge_and_destroy (SCOPE (0).buffer1);
721
722 // fall-thru
723 case e_while_scope: 721 case e_while_scope:
724 // write down the instruction to go back to the start of the loop 722 // write down the instruction to go back to the start of the loop
725 buffer()->write_dword (dh_goto); 723 buffer()->write_dword (dh_goto);
726 buffer()->add_reference (SCOPE (0).mark1); 724 buffer()->add_reference (SCOPE (0).mark1);
727 725
732 case e_do_scope: 730 case e_do_scope:
733 { 731 {
734 m_lx->must_get_next (tk_while); 732 m_lx->must_get_next (tk_while);
735 m_lx->must_get_next (tk_paren_start); 733 m_lx->must_get_next (tk_paren_start);
736 m_lx->must_get_next(); 734 m_lx->must_get_next();
737 data_buffer* expr = parse_expression (TYPE_INT); 735 data_buffer* expr = parse_expression (e_int_type);
738 m_lx->must_get_next (tk_paren_end); 736 m_lx->must_get_next (tk_paren_end);
739 m_lx->must_get_next (tk_semicolon); 737 m_lx->must_get_next (tk_semicolon);
740 738
741 // If the condition runs true, go back to the start. 739 // If the condition runs true, go back to the start.
742 buffer()->merge_and_destroy (expr); 740 buffer()->merge_and_destroy (expr);
789 // Descend down the stack 787 // Descend down the stack
790 m_scope_cursor--; 788 m_scope_cursor--;
791 return; 789 return;
792 } 790 }
793 791
794 int dataheader = (m_current_mode == MODE_EVENT) ? dh_end_event : 792 int dataheader = (m_current_mode == e_event_mode) ? dh_end_event :
795 (m_current_mode == MODE_MAINLOOP) ? dh_end_main_loop : 793 (m_current_mode == e_main_loop_mode) ? dh_end_main_loop :
796 (m_current_mode == MODE_ONENTER) ? dh_end_on_enter : 794 (m_current_mode == e_onenter_mode) ? dh_end_on_enter :
797 (m_current_mode == MODE_ONEXIT) ? dh_end_on_exit : -1; 795 (m_current_mode == e_onexit_mode) ? dh_end_on_exit : -1;
798 796
799 if (dataheader == -1) 797 if (dataheader == -1)
800 error ("unexpected `}`"); 798 error ("unexpected `}`");
801 799
802 // Data header must be written before mode is changed because 800 // Data header must be written before mode is changed because
803 // onenter and mainloop go into special buffers, and we want 801 // onenter and mainloop go into special buffers, and we want
804 // the closing data headers into said buffers too. 802 // the closing data headers into said buffers too.
805 buffer()->write_dword (dataheader); 803 buffer()->write_dword (dataheader);
806 m_current_mode = MODE_TOPLEVEL; 804 m_current_mode = e_top_level_mode;
807 m_lx->get_next (tk_semicolon); 805 m_lx->get_next (tk_semicolon);
808 } 806 }
809 807
810 // ============================================================================ 808 // ============================================================================
811 // 809 //
814 constant_info info; 812 constant_info info;
815 813
816 // Get the type 814 // Get the type
817 m_lx->must_get_next(); 815 m_lx->must_get_next();
818 string typestring = token_string(); 816 string typestring = token_string();
819 info.type = GetTypeByName (typestring); 817 info.type = get_type_by_name (typestring);
820 818
821 if (info.type == TYPE_UNKNOWN || info.type == TYPE_VOID) 819 if (info.type == e_unknown_type || info.type == e_void_type)
822 error ("unknown type `%1` for constant", typestring); 820 error ("unknown type `%1` for constant", typestring);
823 821
824 m_lx->must_get_next(); 822 m_lx->must_get_next();
825 info.name = token_string(); 823 info.name = token_string();
826 824
827 m_lx->must_get_next (tk_assign); 825 m_lx->must_get_next (tk_assign);
828 826
829 switch (info.type) 827 switch (info.type)
830 { 828 {
831 case TYPE_BOOL: 829 case e_bool_type:
832 case TYPE_INT: 830 case e_int_type:
833 { 831 {
834 m_lx->must_get_next (tk_number); 832 m_lx->must_get_next (tk_number);
835 } break; 833 } break;
836 834
837 case TYPE_STRING: 835 case e_string_type:
838 { 836 {
839 m_lx->must_get_next (tk_string); 837 m_lx->must_get_next (tk_string);
840 } break; 838 } break;
841 839
842 case TYPE_UNKNOWN: 840 case e_unknown_type:
843 case TYPE_VOID: 841 case e_void_type:
844 break; 842 break;
845 } 843 }
846 844
847 info.val = m_lx->get_token()->text; 845 info.val = m_lx->get_token()->text;
848 m_constants << info; 846 m_constants << info;
921 919
922 m_lx->must_get_next (tk_colon); 920 m_lx->must_get_next (tk_colon);
923 921
924 // Return value 922 // Return value
925 m_lx->must_get_any_of ({tk_int, tk_void, tk_bool, tk_str}); 923 m_lx->must_get_any_of ({tk_int, tk_void, tk_bool, tk_str});
926 comm->returnvalue = GetTypeByName (m_lx->get_token()->text); // TODO 924 comm->returnvalue = get_type_by_name (m_lx->get_token()->text); // TODO
927 assert (comm->returnvalue != -1); 925 assert (comm->returnvalue != -1);
928 926
929 m_lx->must_get_next (tk_colon); 927 m_lx->must_get_next (tk_colon);
930 928
931 // Num args 929 // Num args
944 while (curarg < comm->maxargs) 942 while (curarg < comm->maxargs)
945 { 943 {
946 command_argument arg; 944 command_argument arg;
947 m_lx->must_get_next (tk_colon); 945 m_lx->must_get_next (tk_colon);
948 m_lx->must_get_any_of ({tk_int, tk_bool, tk_str}); 946 m_lx->must_get_any_of ({tk_int, tk_bool, tk_str});
949 type_e type = GetTypeByName (m_lx->get_token()->text); 947 type_e type = get_type_by_name (m_lx->get_token()->text);
950 assert (type != -1 && type != TYPE_VOID); 948 assert (type != -1 && type != e_void_type);
951 arg.type = type; 949 arg.type = type;
952 950
953 m_lx->must_get_next (tk_paren_start); 951 m_lx->must_get_next (tk_paren_start);
954 m_lx->must_get_next (tk_symbol); 952 m_lx->must_get_next (tk_symbol);
955 arg.name = m_lx->get_token()->text; 953 arg.name = m_lx->get_token()->text;
959 { 957 {
960 m_lx->must_get_next (tk_assign); 958 m_lx->must_get_next (tk_assign);
961 959
962 switch (type) 960 switch (type)
963 { 961 {
964 case TYPE_INT: 962 case e_int_type:
965 case TYPE_BOOL: 963 case e_bool_type:
966 m_lx->must_get_next (tk_number); 964 m_lx->must_get_next (tk_number);
967 break; 965 break;
968 966
969 case TYPE_STRING: 967 case e_string_type:
970 m_lx->must_get_next (tk_string); 968 m_lx->must_get_next (tk_string);
971 break; 969 break;
972 970
973 case TYPE_UNKNOWN: 971 case e_unknown_type:
974 case TYPE_VOID: 972 case e_void_type:
975 break; 973 break;
976 } 974 }
977 975
978 arg.defvalue = m_lx->get_token()->text.to_long(); 976 arg.defvalue = m_lx->get_token()->text.to_long();
979 } 977 }
991 // Parses a command call 989 // Parses a command call
992 data_buffer* botscript_parser::parse_command (command_info* comm) 990 data_buffer* botscript_parser::parse_command (command_info* comm)
993 { 991 {
994 data_buffer* r = new data_buffer (64); 992 data_buffer* r = new data_buffer (64);
995 993
996 if (m_current_mode == MODE_TOPLEVEL) 994 if (m_current_mode == e_top_level_mode)
997 error ("command call at top level"); 995 error ("command call at top level");
998 996
999 m_lx->must_get_next (tk_paren_start); 997 m_lx->must_get_next (tk_paren_start);
1000 m_lx->must_get_next(); 998 m_lx->must_get_next();
1001 999
1347 else if (constant_info* constant = find_constant (token_string())) 1345 else if (constant_info* constant = find_constant (token_string()))
1348 { 1346 {
1349 // Type check 1347 // Type check
1350 if (reqtype != constant->type) 1348 if (reqtype != constant->type)
1351 error ("constant `%1` is %2, expression requires %3\n", 1349 error ("constant `%1` is %2, expression requires %3\n",
1352 constant->name, GetTypeName (constant->type), 1350 constant->name, get_type_name (constant->type),
1353 GetTypeName (reqtype)); 1351 get_type_name (reqtype));
1354 1352
1355 switch (constant->type) 1353 switch (constant->type)
1356 { 1354 {
1357 case TYPE_BOOL: 1355 case e_bool_type:
1358 case TYPE_INT: 1356 case e_int_type:
1359 b->write_dword (dh_push_number); 1357 b->write_dword (dh_push_number);
1360 b->write_dword (atoi (constant->val)); 1358 b->write_dword (atoi (constant->val));
1361 break; 1359 break;
1362 1360
1363 case TYPE_STRING: 1361 case e_string_type:
1364 b->write_string_index (constant->val); 1362 b->write_string_index (constant->val);
1365 break; 1363 break;
1366 1364
1367 case TYPE_VOID: 1365 case e_void_type:
1368 case TYPE_UNKNOWN: 1366 case e_unknown_type:
1369 break; 1367 break;
1370 } 1368 }
1371 } 1369 }
1372 else if ((g = find_global_variable (token_string()))) 1370 else if ((g = find_global_variable (token_string())))
1373 { 1371 {
1378 else 1376 else
1379 { 1377 {
1380 // If nothing else, check for literal 1378 // If nothing else, check for literal
1381 switch (reqtype) 1379 switch (reqtype)
1382 { 1380 {
1383 case TYPE_VOID: 1381 case e_void_type:
1384 case TYPE_UNKNOWN: 1382 case e_unknown_type:
1385 error ("unknown identifier `%1` (expected keyword, function or variable)", token_string()); 1383 error ("unknown identifier `%1` (expected keyword, function or variable)", token_string());
1386 break; 1384 break;
1387 1385
1388 case TYPE_BOOL: 1386 case e_bool_type:
1389 case TYPE_INT: 1387 case e_int_type:
1390 { 1388 {
1391 m_lx->must_be (tk_number); 1389 m_lx->must_be (tk_number);
1392 1390
1393 // All values are written unsigned - thus we need to write the value's 1391 // All values are written unsigned - thus we need to write the value's
1394 // absolute value, followed by an unary minus for negatives. 1392 // absolute value, followed by an unary minus for negatives.
1401 b->write_dword (dh_unary_minus); 1399 b->write_dword (dh_unary_minus);
1402 1400
1403 break; 1401 break;
1404 } 1402 }
1405 1403
1406 case TYPE_STRING: 1404 case e_string_type:
1407 // PushToStringTable either returns the string index of the 1405 // PushToStringTable either returns the string index of the
1408 // string if it finds it in the table, or writes it to the 1406 // string if it finds it in the table, or writes it to the
1409 // table and returns it index if it doesn't find it there. 1407 // table and returns it index if it doesn't find it there.
1410 m_lx->must_be (tk_string); 1408 m_lx->must_be (tk_string);
1411 b->write_string_index (token_string()); 1409 b->write_string_index (token_string());
1432 int oper = parse_operator(); 1430 int oper = parse_operator();
1433 1431
1434 if (!is_assignment_operator (oper)) 1432 if (!is_assignment_operator (oper))
1435 error ("expected assignment operator"); 1433 error ("expected assignment operator");
1436 1434
1437 if (m_current_mode == MODE_TOPLEVEL) 1435 if (m_current_mode == e_top_level_mode)
1438 error ("can't alter variables at top level"); 1436 error ("can't alter variables at top level");
1439 1437
1440 // Parse the right operand 1438 // Parse the right operand
1441 m_lx->must_get_next(); 1439 m_lx->must_get_next();
1442 data_buffer* retbuf = new data_buffer; 1440 data_buffer* retbuf = new data_buffer;
1568 data_buffer* botscript_parser::buffer() 1566 data_buffer* botscript_parser::buffer()
1569 { 1567 {
1570 if (m_switch_buffer != null) 1568 if (m_switch_buffer != null)
1571 return m_switch_buffer; 1569 return m_switch_buffer;
1572 1570
1573 if (m_current_mode == MODE_MAINLOOP) 1571 if (m_current_mode == e_main_loop_mode)
1574 return m_main_loop_buffer; 1572 return m_main_loop_buffer;
1575 1573
1576 if (m_current_mode == MODE_ONENTER) 1574 if (m_current_mode == e_onenter_mode)
1577 return m_on_enter_buffer; 1575 return m_on_enter_buffer;
1578 1576
1579 return m_main_buffer; 1577 return m_main_buffer;
1580 } 1578 }
1581 1579
1628 // Write the compiled bytecode to a file 1626 // Write the compiled bytecode to a file
1629 // 1627 //
1630 void botscript_parser::write_to_file (string outfile) 1628 void botscript_parser::write_to_file (string outfile)
1631 { 1629 {
1632 FILE* fp = fopen (outfile, "w"); 1630 FILE* fp = fopen (outfile, "w");
1633 CHECK_FILE (fp, outfile, "writing"); 1631
1632 if (fp == null)
1633 error ("couldn't open %1 for writing: %2", outfile, strerror (errno));
1634 1634
1635 // First, resolve references 1635 // First, resolve references
1636 for (int u = 0; u < MAX_MARKS; u++) 1636 for (mark_reference* ref : m_main_buffer->get_refs())
1637 { 1637 {
1638 mark_reference* ref = m_main_buffer->get_refs()[u];
1639
1640 if (!ref)
1641 continue;
1642
1643 // Substitute the placeholder with the mark position 1638 // Substitute the placeholder with the mark position
1644 generic_union<word> uni; 1639 for (int v = 0; v < 4; v++)
1645 uni.as_word = static_cast<word> (ref->target->pos); 1640 m_main_buffer->get_buffer()[ref->pos + v] = ((ref->target->pos) << (8 * v)) & 0xFF;
1646 1641
1647 for (int v = 0; v < (int) sizeof (word); v++) 1642 print ("reference at %1 resolved to mark at %2\n", ref->pos, ref->target->pos);
1648 memset (m_main_buffer->get_buffer() + ref->pos + v, uni.as_bytes[v], 1);
1649
1650 /*
1651 printf ("reference %u at %d resolved to %u at %d\n",
1652 u, ref->pos, ref->num, MainBuffer->marks[ref->num]->pos);
1653 */
1654 } 1643 }
1655 1644
1656 // Then, dump the main buffer to the file 1645 // Then, dump the main buffer to the file
1657 fwrite (m_main_buffer->get_buffer(), 1, m_main_buffer->get_write_size(), fp); 1646 fwrite (m_main_buffer->get_buffer(), 1, m_main_buffer->get_write_size(), fp);
1658 print ("-- %1 byte%s1 written to %2\n", m_main_buffer->get_write_size(), outfile); 1647 print ("-- %1 byte%s1 written to %2\n", m_main_buffer->get_write_size(), outfile);

mercurial