src/parser.cc

changeset 77
ad17801b1a36
parent 75
bf8c57437231
child 82
841562f5a32f
equal deleted inserted replaced
76:c8058716070a 77:ad17801b1a36
40 #define SCOPE(n) scopestack[g_ScopeCursor - n] 40 #define SCOPE(n) scopestack[g_ScopeCursor - n]
41 41
42 // TODO: make these static 42 // TODO: make these static
43 int g_NumStates = 0; 43 int g_NumStates = 0;
44 int g_NumEvents = 0; 44 int g_NumEvents = 0;
45 parsermode_e g_CurMode = MODE_TOPLEVEL; 45 parsermode_e g_current_mode = MODE_TOPLEVEL;
46 string g_CurState = ""; 46 string g_CurState = "";
47 bool g_stateSpawnDefined = false; 47 bool g_stateSpawnDefined = false;
48 bool g_GotMainLoop = false; 48 bool g_GotMainLoop = false;
49 int g_ScopeCursor = 0; 49 int g_ScopeCursor = 0;
50 data_buffer* g_IfExpression = null; 50 data_buffer* g_IfExpression = null;
51 bool g_CanElse = false; 51 bool g_CanElse = false;
52 static string* g_undefined_labels[MAX_MARKS]; // TODO: make a list 52 static string* g_undefined_labels[MAX_MARKS]; // TODO: make a list
53 list<constant_info> g_ConstInfo; 53 list<constant_info> g_ConstInfo;
54 54
55 static botscript_parser* g_current_parser = null;
56
57 // ============================================================================ 55 // ============================================================================
58 // 56 //
59 botscript_parser::botscript_parser() : 57 botscript_parser::botscript_parser() :
60 m_lx (new lexer) {} 58 m_lx (new lexer) {}
61 59
68 66
69 // ============================================================================ 67 // ============================================================================
70 // 68 //
71 void botscript_parser::check_toplevel() 69 void botscript_parser::check_toplevel()
72 { 70 {
73 if (g_CurMode != MODE_TOPLEVEL) 71 if (g_current_mode != MODE_TOPLEVEL)
74 error ("%1-statements may only be defined at top level!", token_string().chars()); 72 error ("%1-statements may only be defined at top level!", token_string());
75 } 73 }
76 74
77 // ============================================================================ 75 // ============================================================================
78 // 76 //
79 void botscript_parser::check_not_toplevel() 77 void botscript_parser::check_not_toplevel()
80 { 78 {
81 if (g_CurMode == MODE_TOPLEVEL) 79 if (g_current_mode == MODE_TOPLEVEL)
82 error ("%1-statements must not be defined at top level!", token_string().chars()); 80 error ("%1-statements must not be defined at top level!", token_string());
83 } 81 }
84 82
85 // ============================================================================ 83 // ============================================================================
86 // Main parser code. Begins read of the script file, checks the syntax of it 84 // Main parser code. Begins read of the script file, checks the syntax of it
87 // and writes the data to the object file via Objwriter - which also takes care 85 // and writes the data to the object file via Objwriter - which also takes care
209 m_lx->must_get_next (tk_semicolon); 207 m_lx->must_get_next (tk_semicolon);
210 continue; 208 continue;
211 } 209 }
212 210
213 // If nothing else, parse it as a statement 211 // If nothing else, parse it as a statement
214 data_buffer* b = parse_statement (w); 212 data_buffer* b = parse_statement();
215 213
216 if (!b) 214 if (!b)
217 error ("unknown token `%1`", token_string()); 215 error ("unknown token `%1`", token_string());
218 216
219 m_writer->write_buffer (b); 217 m_writer->write_buffer (b);
223 } 221 }
224 } 222 }
225 223
226 // =============================================================================== 224 // ===============================================================================
227 // Script file ended. Do some last checks and write the last things to main buffer 225 // Script file ended. Do some last checks and write the last things to main buffer
228 if (g_CurMode != MODE_TOPLEVEL) 226 if (g_current_mode != MODE_TOPLEVEL)
229 error ("script did not end at top level; a `}` is missing somewhere"); 227 error ("script did not end at top level; a `}` is missing somewhere");
230 228
231 // stateSpawn must be defined! 229 // stateSpawn must be defined!
232 if (!g_stateSpawnDefined) 230 if (!g_stateSpawnDefined)
233 error ("script must have a state named `stateSpawn`!"); 231 error ("script must have a state named `stateSpawn`!");
234 232
235 for (int i = 0; i < MAX_MARKS; i++) 233 for (int i = 0; i < MAX_MARKS; i++)
236 if (g_undefined_labels[i]) 234 if (g_undefined_labels[i])
237 error ("label `%s` is referenced via `goto` but isn't defined\n", g_undefined_labels[i]->chars()); 235 error ("label `%1` is referenced via `goto` but isn't defined\n", g_undefined_labels[i]);
238 236
239 // Dump the last state's onenter and mainloop 237 // Dump the last state's onenter and mainloop
240 m_writer->write_member_buffers(); 238 m_writer->write_member_buffers();
241 239
242 // String table 240 // String table
289 287
290 if (!e) 288 if (!e)
291 error ("bad event, got `%1`\n", token_string()); 289 error ("bad event, got `%1`\n", token_string());
292 290
293 m_lx->must_get_next (tk_brace_start); 291 m_lx->must_get_next (tk_brace_start);
294 g_CurMode = MODE_EVENT; 292 g_current_mode = MODE_EVENT;
295 m_writer->write (dh_event); 293 m_writer->write (dh_event);
296 m_writer->write (e->number); 294 m_writer->write (e->number);
297 g_NumEvents++; 295 g_NumEvents++;
298 } 296 }
299 297
303 { 301 {
304 check_toplevel(); 302 check_toplevel();
305 m_lx->must_get_next (tk_brace_start); 303 m_lx->must_get_next (tk_brace_start);
306 304
307 // Mode must be set before dataheader is written here! 305 // Mode must be set before dataheader is written here!
308 g_CurMode = MODE_MAINLOOP; 306 g_current_mode = MODE_MAINLOOP;
309 m_writer->write (dh_main_loop); 307 m_writer->write (dh_main_loop);
310 } 308 }
311 309
312 // ============================================================================ 310 // ============================================================================
313 // 311 //
317 bool onenter = (token_is (tk_onenter)); 315 bool onenter = (token_is (tk_onenter));
318 m_lx->must_get_next (tk_brace_start); 316 m_lx->must_get_next (tk_brace_start);
319 317
320 // Mode must be set before dataheader is written here, 318 // Mode must be set before dataheader is written here,
321 // because onenter goes to a separate buffer. 319 // because onenter goes to a separate buffer.
322 g_CurMode = onenter ? MODE_ONENTER : MODE_ONEXIT; 320 g_current_mode = onenter ? MODE_ONENTER : MODE_ONEXIT;
323 m_writer->write (onenter ? dh_on_enter : dh_on_exit); 321 m_writer->write (onenter ? dh_on_enter : dh_on_exit);
324 } 322 }
325 323
326 // ============================================================================ 324 // ============================================================================
327 // 325 //
328 void botscript_parser::parse_variable_declaration() 326 void botscript_parser::parse_variable_declaration()
329 { 327 {
330 // For now, only globals are supported 328 // For now, only globals are supported
331 if (g_CurMode != MODE_TOPLEVEL || g_CurState.is_empty() == false) 329 if (g_current_mode != MODE_TOPLEVEL || g_CurState.is_empty() == false)
332 error ("variables must only be global for now"); 330 error ("variables must only be global for now");
333 331
334 type_e type = (token_is (tk_int)) ? TYPE_INT : 332 type_e type = (token_is (tk_int)) ? TYPE_INT :
335 (token_is (tk_str)) ? TYPE_STRING : 333 (token_is (tk_str)) ? TYPE_STRING :
336 TYPE_BOOL; 334 TYPE_BOOL;
369 367
370 // Add a reference to the mark. 368 // Add a reference to the mark.
371 m_writer->write (dh_goto); 369 m_writer->write (dh_goto);
372 m_writer->add_reference (m); 370 m_writer->add_reference (m);
373 m_lx->must_get_next (tk_semicolon); 371 m_lx->must_get_next (tk_semicolon);
374 continue;
375 } 372 }
376 373
377 // ============================================================================ 374 // ============================================================================
378 // 375 //
379 void botscript_parser::parse_if() 376 void botscript_parser::parse_if()
477 push_scope(); 474 push_scope();
478 475
479 // Initializer 476 // Initializer
480 m_lx->must_get_next (tk_paren_start); 477 m_lx->must_get_next (tk_paren_start);
481 m_lx->must_get_next(); 478 m_lx->must_get_next();
482 data_buffer* init = parse_statement (w); 479 data_buffer* init = parse_statement();
483 480
484 if (!init) 481 if (!init)
485 error ("bad statement for initializer of for"); 482 error ("bad statement for initializer of for");
486 483
487 m_lx->must_get_next (tk_semicolon); 484 m_lx->must_get_next (tk_semicolon);
495 492
496 m_lx->must_get_next (tk_semicolon); 493 m_lx->must_get_next (tk_semicolon);
497 494
498 // Incrementor 495 // Incrementor
499 m_lx->must_get_next(); 496 m_lx->must_get_next();
500 data_buffer* incr = parse_statement (w); 497 data_buffer* incr = parse_statement();
501 498
502 if (!incr) 499 if (!incr)
503 error ("bad statement for incrementor of for"); 500 error ("bad statement for incrementor of for");
504 501
505 m_lx->must_get_next (tk_paren_end); 502 m_lx->must_get_next (tk_paren_end);
590 // null the switch buffer for the case-go-to statement, 587 // null the switch buffer for the case-go-to statement,
591 // we want it all under the switch, not into the case-buffers. 588 // we want it all under the switch, not into the case-buffers.
592 m_writer->SwitchBuffer = null; 589 m_writer->SwitchBuffer = null;
593 m_writer->write (dh_case_goto); 590 m_writer->write (dh_case_goto);
594 m_writer->write (num); 591 m_writer->write (num);
595 add_switch_case (m_writer, null); 592 add_switch_case (null);
596 SCOPE (0).casenumbers[SCOPE (0).casecursor] = num; 593 SCOPE (0).casenumbers[SCOPE (0).casecursor] = num;
597 } 594 }
598 595
599 // ============================================================================ 596 // ============================================================================
600 // 597 //
617 // a default. 614 // a default.
618 data_buffer* b = new data_buffer; 615 data_buffer* b = new data_buffer;
619 SCOPE (0).buffer1 = b; 616 SCOPE (0).buffer1 = b;
620 b->write (dh_drop); 617 b->write (dh_drop);
621 b->write (dh_goto); 618 b->write (dh_goto);
622 add_switch_case (m_writer, b); 619 add_switch_case (b);
623 } 620 }
624 621
625 // ============================================================================ 622 // ============================================================================
626 // 623 //
627 void botscript_parser::parse_break() 624 void botscript_parser::parse_break()
784 break; 781 break;
785 } 782 }
786 783
787 // Descend down the stack 784 // Descend down the stack
788 g_ScopeCursor--; 785 g_ScopeCursor--;
789 continue; 786 return;
790 } 787 }
791 788
792 int dataheader = (g_CurMode == MODE_EVENT) ? dh_end_event : 789 int dataheader = (g_current_mode == MODE_EVENT) ? dh_end_event :
793 (g_CurMode == MODE_MAINLOOP) ? dh_end_main_loop : 790 (g_current_mode == MODE_MAINLOOP) ? dh_end_main_loop :
794 (g_CurMode == MODE_ONENTER) ? dh_end_on_enter : 791 (g_current_mode == MODE_ONENTER) ? dh_end_on_enter :
795 (g_CurMode == MODE_ONEXIT) ? dh_end_on_exit : -1; 792 (g_current_mode == MODE_ONEXIT) ? dh_end_on_exit : -1;
796 793
797 if (dataheader == -1) 794 if (dataheader == -1)
798 error ("unexpected `}`"); 795 error ("unexpected `}`");
799 796
800 // Data header must be written before mode is changed because 797 // Data header must be written before mode is changed because
801 // onenter and mainloop go into special buffers, and we want 798 // onenter and mainloop go into special buffers, and we want
802 // the closing data headers into said buffers too. 799 // the closing data headers into said buffers too.
803 m_writer->write (dataheader); 800 m_writer->write (dataheader);
804 g_CurMode = MODE_TOPLEVEL; 801 g_current_mode = MODE_TOPLEVEL;
805 m_lx->get_next (tk_semicolon); 802 m_lx->get_next (tk_semicolon);
806 } 803 }
807 804
808 // ============================================================================ 805 // ============================================================================
809 // 806 //
855 check_not_toplevel(); 852 check_not_toplevel();
856 string label_name = token_string(); 853 string label_name = token_string();
857 854
858 // want no conflicts.. 855 // want no conflicts..
859 if (find_command_by_name (label_name)) 856 if (find_command_by_name (label_name))
860 error ("label name `%s` conflicts with command name\n", label_name); 857 error ("label name `%1` conflicts with command name\n", label_name);
861 858
862 if (find_global_variable (label_name)) 859 if (find_global_variable (label_name))
863 error ("label name `%s` conflicts with variable\n", label_name); 860 error ("label name `%1` conflicts with variable\n", label_name);
864 861
865 // See if a mark already exists for this label 862 // See if a mark already exists for this label
866 int mark = -1; 863 int mark = -1;
867 864
868 for (int i = 0; i < MAX_MARKS; i++) 865 for (int i = 0; i < MAX_MARKS; i++)
889 // Parses a command call 886 // Parses a command call
890 data_buffer* botscript_parser::ParseCommand (command_info* comm) 887 data_buffer* botscript_parser::ParseCommand (command_info* comm)
891 { 888 {
892 data_buffer* r = new data_buffer (64); 889 data_buffer* r = new data_buffer (64);
893 890
894 if (g_CurMode == MODE_TOPLEVEL) 891 if (g_current_mode == MODE_TOPLEVEL)
895 error ("command call at top level"); 892 error ("command call at top level");
896 893
897 m_lx->must_get_next (tk_paren_start); 894 m_lx->must_get_next (tk_paren_start);
898 m_lx->must_get_next(); 895 m_lx->must_get_next();
899 896
902 while (1) 899 while (1)
903 { 900 {
904 if (token_is (tk_paren_end)) 901 if (token_is (tk_paren_end))
905 { 902 {
906 if (curarg < comm->numargs) 903 if (curarg < comm->numargs)
907 error ("too few arguments passed to %s\n\tprototype: %s", 904 error ("too few arguments passed to %1\n\tprototype: %2",
908 comm->name.chars(), get_command_signature (comm).chars()); 905 comm->name, get_command_signature (comm));
909 906
910 break; 907 break;
911 curarg++; 908 curarg++;
912 } 909 }
913 910
914 if (curarg >= comm->maxargs) 911 if (curarg >= comm->maxargs)
915 error ("too many arguments passed to %s\n\tprototype: %s", 912 error ("too many arguments passed to %1\n\tprototype: %2",
916 comm->name.chars(), get_command_signature (comm).chars()); 913 comm->name, get_command_signature (comm));
917 914
918 r->merge (parse_expression (comm->args[curarg].type)); 915 r->merge (parse_expression (comm->args[curarg].type));
919 m_lx->must_get_next(); 916 m_lx->must_get_next();
920 917
921 if (curarg < comm->numargs - 1) 918 if (curarg < comm->numargs - 1)
956 return r; 953 return r;
957 } 954 }
958 955
959 // ============================================================================ 956 // ============================================================================
960 // Is the given operator an assignment operator? 957 // Is the given operator an assignment operator?
958 //
961 static bool is_assignment_operator (int oper) 959 static bool is_assignment_operator (int oper)
962 { 960 {
963 switch (oper) 961 switch (oper)
964 { 962 {
965 case OPER_ASSIGNADD: 963 case OPER_ASSIGNADD:
976 return false; 974 return false;
977 } 975 }
978 976
979 // ============================================================================ 977 // ============================================================================
980 // Finds an operator's corresponding dataheader 978 // Finds an operator's corresponding dataheader
979 //
981 static word get_data_header_by_operator (script_variable* var, int oper) 980 static word get_data_header_by_operator (script_variable* var, int oper)
982 { 981 {
983 if (is_assignment_operator (oper)) 982 if (is_assignment_operator (oper))
984 { 983 {
985 if (!var) 984 if (!var)
1002 } 1001 }
1003 } 1002 }
1004 1003
1005 switch (oper) 1004 switch (oper)
1006 { 1005 {
1007 case OPER_ADD: return dh_add; 1006 case OPER_ADD: return dh_add;
1008 case OPER_SUBTRACT: return dh_subtract; 1007 case OPER_SUBTRACT: return dh_subtract;
1009 case OPER_MULTIPLY: return dh_multiply; 1008 case OPER_MULTIPLY: return dh_multiply;
1010 case OPER_DIVIDE: return dh_divide; 1009 case OPER_DIVIDE: return dh_divide;
1011 case OPER_MODULUS: return dh_modulus; 1010 case OPER_MODULUS: return dh_modulus;
1012 case OPER_EQUALS: return dh_equals; 1011 case OPER_EQUALS: return dh_equals;
1013 case OPER_NOTEQUALS: return dh_not_equals; 1012 case OPER_NOTEQUALS: return dh_not_equals;
1014 case OPER_LESSTHAN: return dh_less_than; 1013 case OPER_LESSTHAN: return dh_less_than;
1015 case OPER_GREATERTHAN: return dh_greater_than; 1014 case OPER_GREATERTHAN: return dh_greater_than;
1016 case OPER_LESSTHANEQUALS: return dh_at_most; 1015 case OPER_LESSTHANEQUALS: return dh_at_most;
1017 case OPER_GREATERTHANEQUALS: return dh_at_least; 1016 case OPER_GREATERTHANEQUALS: return dh_at_least;
1018 case OPER_LEFTSHIFT: return dh_left_shift; 1017 case OPER_LEFTSHIFT: return dh_left_shift;
1019 case OPER_RIGHTSHIFT: return dh_right_shift; 1018 case OPER_RIGHTSHIFT: return dh_right_shift;
1020 case OPER_OR: return dh_or_logical; 1019 case OPER_OR: return dh_or_logical;
1021 case OPER_AND: return dh_and_logical; 1020 case OPER_AND: return dh_and_logical;
1022 case OPER_BITWISEOR: return dh_or_bitwise; 1021 case OPER_BITWISEOR: return dh_or_bitwise;
1023 case OPER_BITWISEEOR: return dh_eor_bitwise; 1022 case OPER_BITWISEEOR: return dh_eor_bitwise;
1024 case OPER_BITWISEAND: return dh_and_bitwise; 1023 case OPER_BITWISEAND: return dh_and_bitwise;
1025 } 1024 }
1026 1025
1027 error ("DataHeaderByOperator: couldn't find dataheader for operator %d!\n", oper); 1026 error ("DataHeaderByOperator: couldn't find dataheader for operator %d!\n", oper);
1028 return 0; 1027 return 0;
1029 } 1028 }
1030 1029
1031 // ============================================================================ 1030 // ============================================================================
1032 // Parses an expression, potentially recursively 1031 // Parses an expression, potentially recursively
1032 //
1033 data_buffer* botscript_parser::parse_expression (type_e reqtype) 1033 data_buffer* botscript_parser::parse_expression (type_e reqtype)
1034 { 1034 {
1035 data_buffer* retbuf = new data_buffer (64); 1035 data_buffer* retbuf = new data_buffer (64);
1036 1036
1037 // Parse first operand 1037 // Parse first operand
1085 return retbuf; 1085 return retbuf;
1086 } 1086 }
1087 1087
1088 // ============================================================================ 1088 // ============================================================================
1089 // Parses an operator string. Returns the operator number code. 1089 // Parses an operator string. Returns the operator number code.
1090 //
1090 #define ISNEXT(C) (m_lx->peek_next_string (peek ? 1 : 0) == C) 1091 #define ISNEXT(C) (m_lx->peek_next_string (peek ? 1 : 0) == C)
1092
1091 int botscript_parser::parse_operator (bool peek) 1093 int botscript_parser::parse_operator (bool peek)
1092 { 1094 {
1093 string oper; 1095 string oper;
1094 1096
1095 if (peek) 1097 if (peek)
1161 1163
1162 return o; 1164 return o;
1163 } 1165 }
1164 1166
1165 // ============================================================================ 1167 // ============================================================================
1168 //
1166 string botscript_parser::parse_float() 1169 string botscript_parser::parse_float()
1167 { 1170 {
1168 m_lx->must_be (tk_number); 1171 m_lx->must_be (tk_number);
1169 string floatstring = token_string(); 1172 string floatstring = token_string();
1170 lexer::token tok; 1173 lexer::token tok;
1183 1186
1184 // ============================================================================ 1187 // ============================================================================
1185 // Parses a value in the expression and returns the data needed to push 1188 // Parses a value in the expression and returns the data needed to push
1186 // it, contained in a data buffer. A value can be either a variable, a command, 1189 // it, contained in a data buffer. A value can be either a variable, a command,
1187 // a literal or an expression. 1190 // a literal or an expression.
1191 //
1188 data_buffer* botscript_parser::parse_expr_value (type_e reqtype) 1192 data_buffer* botscript_parser::parse_expr_value (type_e reqtype)
1189 { 1193 {
1190 data_buffer* b = new data_buffer (16); 1194 data_buffer* b = new data_buffer (16);
1191 script_variable* g; 1195 script_variable* g;
1192 1196
1207 1211
1208 if (!constant || constant->type != TYPE_STRING) 1212 if (!constant || constant->type != TYPE_STRING)
1209 error ("strlen only works with const str"); 1213 error ("strlen only works with const str");
1210 1214
1211 if (reqtype != TYPE_INT) 1215 if (reqtype != TYPE_INT)
1212 error ("strlen returns int but %s is expected\n", GetTypeName (reqtype).c_str()); 1216 error ("strlen returns int but %1 is expected\n", GetTypeName (reqtype));
1213 1217
1214 b->write (dh_push_number); 1218 b->write (dh_push_number);
1215 b->write (constant->val.len()); 1219 b->write (constant->val.len());
1216 1220
1217 m_lx->must_get_next (tk_paren_end); 1221 m_lx->must_get_next (tk_paren_end);
1229 { 1233 {
1230 delete b; 1234 delete b;
1231 1235
1232 // Command 1236 // Command
1233 if (reqtype && comm->returnvalue != reqtype) 1237 if (reqtype && comm->returnvalue != reqtype)
1234 error ("%s returns an incompatible data type", comm->name.chars()); 1238 error ("%1 returns an incompatible data type", comm->name);
1235 1239
1236 b = ParseCommand (comm); 1240 b = ParseCommand (comm);
1237 } 1241 }
1238 else if (constant_info* constant = find_constant (token_string())) 1242 else if (constant_info* constant = find_constant (token_string()))
1239 { 1243 {
1240 // Type check 1244 // Type check
1241 if (reqtype != constant->type) 1245 if (reqtype != constant->type)
1242 error ("constant `%s` is %s, expression requires %s\n", 1246 error ("constant `%1` is %2, expression requires %3\n",
1243 constant->name.c_str(), GetTypeName (constant->type).c_str(), 1247 constant->name, GetTypeName (constant->type),
1244 GetTypeName (reqtype).c_str()); 1248 GetTypeName (reqtype));
1245 1249
1246 switch (constant->type) 1250 switch (constant->type)
1247 { 1251 {
1248 case TYPE_BOOL: 1252 case TYPE_BOOL:
1249 case TYPE_INT: 1253 case TYPE_INT:
1313 1317
1314 // ============================================================================ 1318 // ============================================================================
1315 // Parses an assignment. An assignment starts with a variable name, followed 1319 // Parses an assignment. An assignment starts with a variable name, followed
1316 // by an assignment operator, followed by an expression value. Expects current 1320 // by an assignment operator, followed by an expression value. Expects current
1317 // token to be the name of the variable, and expects the variable to be given. 1321 // token to be the name of the variable, and expects the variable to be given.
1318 data_buffer* botscript_parser::ParseAssignment (script_variable* var) 1322 //
1323 data_buffer* botscript_parser::parse_assignment (script_variable* var)
1319 { 1324 {
1320 bool global = !var->statename.len(); 1325 bool global = !var->statename.len();
1321 1326
1322 // Get an operator 1327 // Get an operator
1323 m_lx->must_get_next(); 1328 m_lx->must_get_next();
1324 int oper = parse_operator(); 1329 int oper = parse_operator();
1325 1330
1326 if (!is_assignment_operator (oper)) 1331 if (!is_assignment_operator (oper))
1327 error ("expected assignment operator"); 1332 error ("expected assignment operator");
1328 1333
1329 if (g_CurMode == MODE_TOPLEVEL) 1334 if (g_current_mode == MODE_TOPLEVEL)
1330 error ("can't alter variables at top level"); 1335 error ("can't alter variables at top level");
1331 1336
1332 // Parse the right operand 1337 // Parse the right operand
1333 m_lx->must_get_next(); 1338 m_lx->must_get_next();
1334 data_buffer* retbuf = new data_buffer; 1339 data_buffer* retbuf = new data_buffer;
1355 } 1360 }
1356 1361
1357 return retbuf; 1362 return retbuf;
1358 } 1363 }
1359 1364
1365 // ============================================================================
1366 //
1360 void botscript_parser::push_scope() 1367 void botscript_parser::push_scope()
1361 { 1368 {
1362 g_ScopeCursor++; 1369 g_ScopeCursor++;
1363 1370
1364 if (g_ScopeCursor >= MAX_SCOPE) 1371 if (g_ScopeCursor >= MAX_SCOPE)
1377 info->casebuffers[i] = null; 1384 info->casebuffers[i] = null;
1378 info->casenumbers[i] = -1; 1385 info->casenumbers[i] = -1;
1379 } 1386 }
1380 } 1387 }
1381 1388
1382 data_buffer* botscript_parser::parse_statement (object_writer* w) 1389 // ============================================================================
1390 //
1391 data_buffer* botscript_parser::parse_statement()
1383 { 1392 {
1384 if (find_constant (token_string())) // There should not be constants here. 1393 if (find_constant (token_string())) // There should not be constants here.
1385 error ("invalid use for constant\n"); 1394 error ("invalid use for constant\n");
1386 1395
1387 // If it's a variable, expect assignment. 1396 // If it's a variable, expect assignment.
1388 if (script_variable* var = find_global_variable (token_string())) 1397 if (script_variable* var = find_global_variable (token_string()))
1389 return ParseAssignment (var); 1398 return parse_assignment (var);
1390 1399
1391 return null; 1400 return null;
1392 } 1401 }
1393 1402
1394 void botscript_parser::add_switch_case (object_writer* w, data_buffer* b) 1403 // ============================================================================
1404 //
1405 void botscript_parser::add_switch_case (data_buffer* b)
1395 { 1406 {
1396 ScopeInfo* info = &SCOPE (0); 1407 ScopeInfo* info = &SCOPE (0);
1397 1408
1398 info->casecursor++; 1409 info->casecursor++;
1399 1410

mercurial