Fri, 17 Jan 2014 21:39:25 +0200
- various corrections
src/main.cc | file | annotate | diff | comparison | revisions | |
src/main.h | file | annotate | diff | comparison | revisions | |
src/object_writer.cc | file | annotate | diff | comparison | revisions | |
src/parser.cc | file | annotate | diff | comparison | revisions | |
src/parser.h | file | annotate | diff | comparison | revisions |
--- a/src/main.cc Mon Jan 13 23:44:50 2014 +0200 +++ b/src/main.cc Fri Jan 17 21:39:25 2014 +0200 @@ -84,7 +84,6 @@ // I guess there should be a better way to do this. if (argc == 2 && !strcmp (argv[1], "-l")) { - command_info* comm; init_commands(); printf ("Begin list of commands:\n"); printf ("------------------------------------------------------\n");
--- a/src/main.h Mon Jan 13 23:44:50 2014 +0200 +++ b/src/main.h Fri Jan 17 21:39:25 2014 +0200 @@ -98,7 +98,7 @@ // Make the parser's variables globally available extern int g_NumStates; extern int g_NumEvents; -extern parsermode_e g_CurMode; +extern parsermode_e g_current_mode; extern string g_CurState; #ifndef __GNUC__
--- a/src/object_writer.cc Mon Jan 13 23:44:50 2014 +0200 +++ b/src/object_writer.cc Fri Jan 17 21:39:25 2014 +0200 @@ -139,8 +139,8 @@ data_buffer* object_writer::get_current_buffer() { return SwitchBuffer ? SwitchBuffer : - (g_CurMode == MODE_MAINLOOP) ? MainLoopBuffer : - (g_CurMode == MODE_ONENTER) ? OnEnterBuffer : + (g_current_mode == MODE_MAINLOOP) ? MainLoopBuffer : + (g_current_mode == MODE_ONENTER) ? OnEnterBuffer : MainBuffer; }
--- a/src/parser.cc Mon Jan 13 23:44:50 2014 +0200 +++ b/src/parser.cc Fri Jan 17 21:39:25 2014 +0200 @@ -42,7 +42,7 @@ // TODO: make these static int g_NumStates = 0; int g_NumEvents = 0; -parsermode_e g_CurMode = MODE_TOPLEVEL; +parsermode_e g_current_mode = MODE_TOPLEVEL; string g_CurState = ""; bool g_stateSpawnDefined = false; bool g_GotMainLoop = false; @@ -52,8 +52,6 @@ static string* g_undefined_labels[MAX_MARKS]; // TODO: make a list list<constant_info> g_ConstInfo; -static botscript_parser* g_current_parser = null; - // ============================================================================ // botscript_parser::botscript_parser() : @@ -70,16 +68,16 @@ // void botscript_parser::check_toplevel() { - if (g_CurMode != MODE_TOPLEVEL) - error ("%1-statements may only be defined at top level!", token_string().chars()); + if (g_current_mode != MODE_TOPLEVEL) + error ("%1-statements may only be defined at top level!", token_string()); } // ============================================================================ // void botscript_parser::check_not_toplevel() { - if (g_CurMode == MODE_TOPLEVEL) - error ("%1-statements must not be defined at top level!", token_string().chars()); + if (g_current_mode == MODE_TOPLEVEL) + error ("%1-statements must not be defined at top level!", token_string()); } // ============================================================================ @@ -211,7 +209,7 @@ } // If nothing else, parse it as a statement - data_buffer* b = parse_statement (w); + data_buffer* b = parse_statement(); if (!b) error ("unknown token `%1`", token_string()); @@ -225,7 +223,7 @@ // =============================================================================== // Script file ended. Do some last checks and write the last things to main buffer - if (g_CurMode != MODE_TOPLEVEL) + if (g_current_mode != MODE_TOPLEVEL) error ("script did not end at top level; a `}` is missing somewhere"); // stateSpawn must be defined! @@ -234,7 +232,7 @@ for (int i = 0; i < MAX_MARKS; i++) if (g_undefined_labels[i]) - error ("label `%s` is referenced via `goto` but isn't defined\n", g_undefined_labels[i]->chars()); + error ("label `%1` is referenced via `goto` but isn't defined\n", g_undefined_labels[i]); // Dump the last state's onenter and mainloop m_writer->write_member_buffers(); @@ -291,7 +289,7 @@ error ("bad event, got `%1`\n", token_string()); m_lx->must_get_next (tk_brace_start); - g_CurMode = MODE_EVENT; + g_current_mode = MODE_EVENT; m_writer->write (dh_event); m_writer->write (e->number); g_NumEvents++; @@ -305,7 +303,7 @@ m_lx->must_get_next (tk_brace_start); // Mode must be set before dataheader is written here! - g_CurMode = MODE_MAINLOOP; + g_current_mode = MODE_MAINLOOP; m_writer->write (dh_main_loop); } @@ -319,7 +317,7 @@ // Mode must be set before dataheader is written here, // because onenter goes to a separate buffer. - g_CurMode = onenter ? MODE_ONENTER : MODE_ONEXIT; + g_current_mode = onenter ? MODE_ONENTER : MODE_ONEXIT; m_writer->write (onenter ? dh_on_enter : dh_on_exit); } @@ -328,7 +326,7 @@ void botscript_parser::parse_variable_declaration() { // For now, only globals are supported - if (g_CurMode != MODE_TOPLEVEL || g_CurState.is_empty() == false) + if (g_current_mode != MODE_TOPLEVEL || g_CurState.is_empty() == false) error ("variables must only be global for now"); type_e type = (token_is (tk_int)) ? TYPE_INT : @@ -371,7 +369,6 @@ m_writer->write (dh_goto); m_writer->add_reference (m); m_lx->must_get_next (tk_semicolon); - continue; } // ============================================================================ @@ -479,7 +476,7 @@ // Initializer m_lx->must_get_next (tk_paren_start); m_lx->must_get_next(); - data_buffer* init = parse_statement (w); + data_buffer* init = parse_statement(); if (!init) error ("bad statement for initializer of for"); @@ -497,7 +494,7 @@ // Incrementor m_lx->must_get_next(); - data_buffer* incr = parse_statement (w); + data_buffer* incr = parse_statement(); if (!incr) error ("bad statement for incrementor of for"); @@ -592,7 +589,7 @@ m_writer->SwitchBuffer = null; m_writer->write (dh_case_goto); m_writer->write (num); - add_switch_case (m_writer, null); + add_switch_case (null); SCOPE (0).casenumbers[SCOPE (0).casecursor] = num; } @@ -619,7 +616,7 @@ SCOPE (0).buffer1 = b; b->write (dh_drop); b->write (dh_goto); - add_switch_case (m_writer, b); + add_switch_case (b); } // ============================================================================ @@ -786,13 +783,13 @@ // Descend down the stack g_ScopeCursor--; - continue; + return; } - int dataheader = (g_CurMode == MODE_EVENT) ? dh_end_event : - (g_CurMode == MODE_MAINLOOP) ? dh_end_main_loop : - (g_CurMode == MODE_ONENTER) ? dh_end_on_enter : - (g_CurMode == MODE_ONEXIT) ? dh_end_on_exit : -1; + int dataheader = (g_current_mode == MODE_EVENT) ? dh_end_event : + (g_current_mode == MODE_MAINLOOP) ? dh_end_main_loop : + (g_current_mode == MODE_ONENTER) ? dh_end_on_enter : + (g_current_mode == MODE_ONEXIT) ? dh_end_on_exit : -1; if (dataheader == -1) error ("unexpected `}`"); @@ -801,7 +798,7 @@ // onenter and mainloop go into special buffers, and we want // the closing data headers into said buffers too. m_writer->write (dataheader); - g_CurMode = MODE_TOPLEVEL; + g_current_mode = MODE_TOPLEVEL; m_lx->get_next (tk_semicolon); } @@ -857,10 +854,10 @@ // want no conflicts.. if (find_command_by_name (label_name)) - error ("label name `%s` conflicts with command name\n", label_name); + error ("label name `%1` conflicts with command name\n", label_name); if (find_global_variable (label_name)) - error ("label name `%s` conflicts with variable\n", label_name); + error ("label name `%1` conflicts with variable\n", label_name); // See if a mark already exists for this label int mark = -1; @@ -891,7 +888,7 @@ { data_buffer* r = new data_buffer (64); - if (g_CurMode == MODE_TOPLEVEL) + if (g_current_mode == MODE_TOPLEVEL) error ("command call at top level"); m_lx->must_get_next (tk_paren_start); @@ -904,16 +901,16 @@ if (token_is (tk_paren_end)) { if (curarg < comm->numargs) - error ("too few arguments passed to %s\n\tprototype: %s", - comm->name.chars(), get_command_signature (comm).chars()); + error ("too few arguments passed to %1\n\tprototype: %2", + comm->name, get_command_signature (comm)); break; curarg++; } if (curarg >= comm->maxargs) - error ("too many arguments passed to %s\n\tprototype: %s", - comm->name.chars(), get_command_signature (comm).chars()); + error ("too many arguments passed to %1\n\tprototype: %2", + comm->name, get_command_signature (comm)); r->merge (parse_expression (comm->args[curarg].type)); m_lx->must_get_next(); @@ -958,6 +955,7 @@ // ============================================================================ // Is the given operator an assignment operator? +// static bool is_assignment_operator (int oper) { switch (oper) @@ -978,6 +976,7 @@ // ============================================================================ // Finds an operator's corresponding dataheader +// static word get_data_header_by_operator (script_variable* var, int oper) { if (is_assignment_operator (oper)) @@ -1004,24 +1003,24 @@ switch (oper) { - case OPER_ADD: return dh_add; - case OPER_SUBTRACT: return dh_subtract; - case OPER_MULTIPLY: return dh_multiply; - case OPER_DIVIDE: return dh_divide; - case OPER_MODULUS: return dh_modulus; - case OPER_EQUALS: return dh_equals; - case OPER_NOTEQUALS: return dh_not_equals; - case OPER_LESSTHAN: return dh_less_than; - case OPER_GREATERTHAN: return dh_greater_than; - case OPER_LESSTHANEQUALS: return dh_at_most; - case OPER_GREATERTHANEQUALS: return dh_at_least; - case OPER_LEFTSHIFT: return dh_left_shift; - case OPER_RIGHTSHIFT: return dh_right_shift; - case OPER_OR: return dh_or_logical; - case OPER_AND: return dh_and_logical; - case OPER_BITWISEOR: return dh_or_bitwise; - case OPER_BITWISEEOR: return dh_eor_bitwise; - case OPER_BITWISEAND: return dh_and_bitwise; + case OPER_ADD: return dh_add; + case OPER_SUBTRACT: return dh_subtract; + case OPER_MULTIPLY: return dh_multiply; + case OPER_DIVIDE: return dh_divide; + case OPER_MODULUS: return dh_modulus; + case OPER_EQUALS: return dh_equals; + case OPER_NOTEQUALS: return dh_not_equals; + case OPER_LESSTHAN: return dh_less_than; + case OPER_GREATERTHAN: return dh_greater_than; + case OPER_LESSTHANEQUALS: return dh_at_most; + case OPER_GREATERTHANEQUALS: return dh_at_least; + case OPER_LEFTSHIFT: return dh_left_shift; + case OPER_RIGHTSHIFT: return dh_right_shift; + case OPER_OR: return dh_or_logical; + case OPER_AND: return dh_and_logical; + case OPER_BITWISEOR: return dh_or_bitwise; + case OPER_BITWISEEOR: return dh_eor_bitwise; + case OPER_BITWISEAND: return dh_and_bitwise; } error ("DataHeaderByOperator: couldn't find dataheader for operator %d!\n", oper); @@ -1030,6 +1029,7 @@ // ============================================================================ // Parses an expression, potentially recursively +// data_buffer* botscript_parser::parse_expression (type_e reqtype) { data_buffer* retbuf = new data_buffer (64); @@ -1087,7 +1087,9 @@ // ============================================================================ // Parses an operator string. Returns the operator number code. +// #define ISNEXT(C) (m_lx->peek_next_string (peek ? 1 : 0) == C) + int botscript_parser::parse_operator (bool peek) { string oper; @@ -1163,6 +1165,7 @@ } // ============================================================================ +// string botscript_parser::parse_float() { m_lx->must_be (tk_number); @@ -1185,6 +1188,7 @@ // Parses a value in the expression and returns the data needed to push // it, contained in a data buffer. A value can be either a variable, a command, // a literal or an expression. +// data_buffer* botscript_parser::parse_expr_value (type_e reqtype) { data_buffer* b = new data_buffer (16); @@ -1209,7 +1213,7 @@ error ("strlen only works with const str"); if (reqtype != TYPE_INT) - error ("strlen returns int but %s is expected\n", GetTypeName (reqtype).c_str()); + error ("strlen returns int but %1 is expected\n", GetTypeName (reqtype)); b->write (dh_push_number); b->write (constant->val.len()); @@ -1231,7 +1235,7 @@ // Command if (reqtype && comm->returnvalue != reqtype) - error ("%s returns an incompatible data type", comm->name.chars()); + error ("%1 returns an incompatible data type", comm->name); b = ParseCommand (comm); } @@ -1239,9 +1243,9 @@ { // Type check if (reqtype != constant->type) - error ("constant `%s` is %s, expression requires %s\n", - constant->name.c_str(), GetTypeName (constant->type).c_str(), - GetTypeName (reqtype).c_str()); + error ("constant `%1` is %2, expression requires %3\n", + constant->name, GetTypeName (constant->type), + GetTypeName (reqtype)); switch (constant->type) { @@ -1315,7 +1319,8 @@ // Parses an assignment. An assignment starts with a variable name, followed // by an assignment operator, followed by an expression value. Expects current // token to be the name of the variable, and expects the variable to be given. -data_buffer* botscript_parser::ParseAssignment (script_variable* var) +// +data_buffer* botscript_parser::parse_assignment (script_variable* var) { bool global = !var->statename.len(); @@ -1326,7 +1331,7 @@ if (!is_assignment_operator (oper)) error ("expected assignment operator"); - if (g_CurMode == MODE_TOPLEVEL) + if (g_current_mode == MODE_TOPLEVEL) error ("can't alter variables at top level"); // Parse the right operand @@ -1357,6 +1362,8 @@ return retbuf; } +// ============================================================================ +// void botscript_parser::push_scope() { g_ScopeCursor++; @@ -1379,19 +1386,23 @@ } } -data_buffer* botscript_parser::parse_statement (object_writer* w) +// ============================================================================ +// +data_buffer* botscript_parser::parse_statement() { if (find_constant (token_string())) // There should not be constants here. error ("invalid use for constant\n"); // If it's a variable, expect assignment. if (script_variable* var = find_global_variable (token_string())) - return ParseAssignment (var); + return parse_assignment (var); return null; } -void botscript_parser::add_switch_case (object_writer* w, data_buffer* b) +// ============================================================================ +// +void botscript_parser::add_switch_case (data_buffer* b) { ScopeInfo* info = &SCOPE (0);
--- a/src/parser.h Mon Jan 13 23:44:50 2014 +0200 +++ b/src/parser.h Fri Jan 17 21:39:25 2014 +0200 @@ -167,13 +167,13 @@ void parse_botscript (string file_name, object_writer* w); data_buffer* ParseCommand (command_info* comm); data_buffer* parse_expression (type_e reqtype); - data_buffer* ParseAssignment (script_variable* var); + data_buffer* parse_assignment (script_variable* var); int parse_operator (bool peek = false); data_buffer* parse_expr_value (type_e reqtype); string parse_float (); void push_scope (); - data_buffer* parse_statement (object_writer* w); - void add_switch_case (object_writer* w, data_buffer* b); + data_buffer* parse_statement (); + void add_switch_case (data_buffer* b); void check_toplevel(); void check_not_toplevel(); bool token_is (e_token a); @@ -183,6 +183,7 @@ private: lexer* m_lx; object_writer* m_writer; + void parse_state_block(); void parse_event_block(); void parse_mainloop(); @@ -199,7 +200,6 @@ void parse_switch_default(); void parse_break(); void parse_continue(); - void parse_continue(); void parse_block_end(); void parse_const(); void parse_label();