diff --git a/Engine/source/app/mainLoop.cpp b/Engine/source/app/mainLoop.cpp index c77c33552..5fc4aa8c0 100644 --- a/Engine/source/app/mainLoop.cpp +++ b/Engine/source/app/mainLoop.cpp @@ -45,6 +45,7 @@ #include "console/debugOutputConsumer.h" #include "console/consoleTypes.h" #include "console/engineAPI.h" +#include "console/codeInterpreter.h" #include "gfx/bitmap/gBitmap.h" #include "gfx/gFont.h" @@ -227,6 +228,9 @@ void StandardMainLoop::init() ManagedSingleton< ThreadManager >::createSingleton(); FrameAllocator::init(TORQUE_FRAME_SIZE); // See comments in torqueConfig.h + // Initialize the TorqueScript interpreter. + CodeInterpreter::init(); + // Yell if we can't initialize the network. if(!Net::init()) { diff --git a/Engine/source/console/CMDgram.y b/Engine/source/console/CMDgram.y index 5ebd9492b..6cfbf3311 100644 --- a/Engine/source/console/CMDgram.y +++ b/Engine/source/console/CMDgram.y @@ -496,9 +496,9 @@ class_name_expr assign_op_struct : opPLUSPLUS - { $$.lineNumber = $1.lineNumber; $$.token = '+'; $$.expr = FloatNode::alloc( $1.lineNumber, 1 ); } + { $$.lineNumber = $1.lineNumber; $$.token = opPLUSPLUS; $$.expr = FloatNode::alloc( $1.lineNumber, 1 ); } | opMINUSMINUS - { $$.lineNumber = $1.lineNumber; $$.token = '-'; $$.expr = FloatNode::alloc( $1.lineNumber, 1 ); } + { $$.lineNumber = $1.lineNumber; $$.token = opMINUSMINUS; $$.expr = FloatNode::alloc( $1.lineNumber, 1 ); } | opPLASN expr { $$.lineNumber = $1.lineNumber; $$.token = '+'; $$.expr = $2; } | opMIASN expr @@ -551,6 +551,8 @@ funcall_expr { $$ = FuncCallExprNode::alloc( $1.lineNumber, $3.value, $1.value, $5, false); } | expr '.' IDENT '(' expr_list_decl ')' { $1->append($5); $$ = FuncCallExprNode::alloc( $1->dbgLineNumber, $3.value, NULL, $1, true); } + | expr '(' expr_list_decl ')' + { $$ = FuncPointerCallExprNode::alloc( $1->dbgLineNumber, $1, $3); } ; assert_expr diff --git a/Engine/source/console/CMDscan.cpp b/Engine/source/console/CMDscan.cpp index 4a1c132b9..733460b09 100644 --- a/Engine/source/console/CMDscan.cpp +++ b/Engine/source/console/CMDscan.cpp @@ -20,8 +20,8 @@ /* A lexical scanner generated by flex */ /* Scanner skeleton version: - * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.85 95/04/24 10:48:47 vern Exp $ - */ +* $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.85 95/04/24 10:48:47 vern Exp $ +*/ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 @@ -49,19 +49,19 @@ /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST -#else /* ! __cplusplus */ +#else /* ! __cplusplus */ #if __STDC__ #define YY_USE_PROTOS #define YY_USE_CONST -#endif /* __STDC__ */ -#endif /* ! __cplusplus */ +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ #ifdef __TURBOC__ - #pragma warn -rch - #pragma warn -use +#pragma warn -rch +#pragma warn -use #include #include #define YY_USE_CONST @@ -85,22 +85,22 @@ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ +* integer for use as an array index. If the signed char is negative, +* we want to instead treat it as an 8-bit unsigned char, hence the +* double cast. +*/ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ +* but we do it the disgusting crufty way forced on us by the ()-less +* definition of BEGIN. +*/ #define BEGIN yy_start = 1 + 2 * /* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ +* to BEGIN to return to the state. The YYSTATE alias is for lex +* compatibility. +*/ #define YY_START ((yy_start - 1) / 2) #define YYSTATE YY_START @@ -125,419 +125,419 @@ extern FILE *yyin, *yyout; #define EOB_ACT_LAST_MATCH 2 /* The funky do-while in the following #define is used to turn the definition - * int a single C statement (which needs a semi-colon terminator). This - * avoids problems with code like: - * - * if ( condition_holds ) - * yyless( 5 ); - * else - * do_something_else(); - * - * Prior to using the do-while the compiler would get upset at the - * "else" because it interpreted the "if" statement as being all - * done when it reached the ';' after the yyless() call. - */ +* int a single C statement (which needs a semi-colon terminator). This +* avoids problems with code like: +* +* if ( condition_holds ) +* yyless( 5 ); +* else +* do_something_else(); +* +* Prior to using the do-while the compiler would get upset at the +* "else" because it interpreted the "if" statement as being all +* done when it reached the ';' after the yyless() call. +*/ /* Return all but the first 'n' matched characters back to the input stream. */ #define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - *yy_cp = yy_hold_char; \ - yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) #define unput(c) yyunput( c, yytext_ptr ) /* The following is because we cannot portably get our hands on size_t - * (without autoconf's help, which isn't available because we want - * flex-generated scanners to compile on their own). - */ +* (without autoconf's help, which isn't available because we want +* flex-generated scanners to compile on their own). +*/ typedef unsigned int yy_size_t; struct yy_buffer_state - { +{ FILE *yy_input_file; - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ + * characters. + */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ + * and can realloc() it to grow it, and should free() it to + * delete it. + */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ + * If so, '^' rules will be active on the next match, otherwise + * not. + */ int yy_at_bol; /* Whether to try to fill the input buffer when we reach the - * end of it. - */ + * end of it. + */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ #define YY_BUFFER_EOF_PENDING 2 - }; +}; static YY_BUFFER_STATE yy_current_buffer = 0; /* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - */ +* future we want to put the buffer states in a more general +* "scanner state". +*/ #define YY_CURRENT_BUFFER yy_current_buffer /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; -static int yy_n_chars; /* number of characters read into yy_ch_buf */ +static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ +static char *yy_c_buf_p = (char *)0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ -/* Flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ + /* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ static int yy_did_buffer_switch_on_eof; -void yyrestart YY_PROTO(( FILE *input_file )); +void yyrestart YY_PROTO((FILE *input_file)); -void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); -void yy_load_buffer_state YY_PROTO(( void )); -YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); -void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); -void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); -void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void yy_switch_to_buffer YY_PROTO((YY_BUFFER_STATE new_buffer)); +void yy_load_buffer_state YY_PROTO((void)); +YY_BUFFER_STATE yy_create_buffer YY_PROTO((FILE *file, int size)); +void yy_delete_buffer YY_PROTO((YY_BUFFER_STATE b)); +void yy_init_buffer YY_PROTO((YY_BUFFER_STATE b, FILE *file)); +void yy_flush_buffer YY_PROTO((YY_BUFFER_STATE b)); #define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) -YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); -YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *str )); -YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); +YY_BUFFER_STATE yy_scan_buffer YY_PROTO((char *base, yy_size_t size)); +YY_BUFFER_STATE yy_scan_string YY_PROTO((yyconst char *str)); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO((yyconst char *bytes, int len)); -static void *yy_flex_alloc YY_PROTO(( yy_size_t )); -static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); -static void yy_flex_free YY_PROTO(( void * )); +static void *yy_flex_alloc YY_PROTO((yy_size_t)); +static void *yy_flex_realloc YY_PROTO((void *, yy_size_t)); +static void yy_flex_free YY_PROTO((void *)); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_is_interactive = is_interactive; \ - } + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } #define yy_set_bol(at_bol) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_at_bol = at_bol; \ - } + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } #define YY_AT_BOL() (yy_current_buffer->yy_at_bol) typedef unsigned char YY_CHAR; -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +FILE *yyin = (FILE *)0, *yyout = (FILE *)0; typedef int yy_state_type; extern char *yytext; #define yytext_ptr yytext -static yy_state_type yy_get_previous_state YY_PROTO(( void )); -static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); -static int yy_get_next_buffer YY_PROTO(( void )); -static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); +static yy_state_type yy_get_previous_state YY_PROTO((void)); +static yy_state_type yy_try_NUL_trans YY_PROTO((yy_state_type current_state)); +static int yy_get_next_buffer YY_PROTO((void)); +static void yy_fatal_error YY_PROTO((yyconst char msg[])); /* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ +* corresponding action - sets up yytext. +*/ #define YY_DO_BEFORE_ACTION \ - yytext_ptr = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; + yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; #define YY_NUM_RULES 94 #define YY_END_OF_BUFFER 95 static yyconst short int yy_accept[224] = - { 0, - 0, 0, 95, 93, 1, 5, 4, 51, 93, 93, - 58, 57, 93, 41, 42, 45, 43, 56, 44, 50, - 46, 90, 90, 52, 53, 47, 61, 48, 38, 36, - 88, 88, 88, 88, 39, 40, 59, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, - 88, 54, 49, 55, 60, 1, 0, 9, 0, 6, - 0, 0, 17, 87, 25, 12, 26, 0, 7, 0, - 23, 16, 21, 15, 22, 31, 91, 37, 3, 24, - 0, 90, 0, 0, 14, 19, 11, 8, 10, 20, - 88, 33, 88, 88, 27, 88, 88, 88, 88, 88, +{ 0, +0, 0, 95, 93, 1, 5, 4, 51, 93, 93, +58, 57, 93, 41, 42, 45, 43, 56, 44, 50, +46, 90, 90, 52, 53, 47, 61, 48, 38, 36, +88, 88, 88, 88, 39, 40, 59, 88, 88, 88, +88, 88, 88, 88, 88, 88, 88, 88, 88, 88, +88, 54, 49, 55, 60, 1, 0, 9, 0, 6, +0, 0, 17, 87, 25, 12, 26, 0, 7, 0, +23, 16, 21, 15, 22, 31, 91, 37, 3, 24, +0, 90, 0, 0, 14, 19, 11, 8, 10, 20, +88, 33, 88, 88, 27, 88, 88, 88, 88, 88, - 88, 69, 88, 88, 88, 88, 70, 62, 88, 88, - 63, 88, 88, 88, 88, 88, 88, 28, 13, 18, - 92, 87, 0, 32, 3, 3, 91, 0, 91, 89, - 29, 30, 35, 34, 88, 88, 88, 88, 88, 88, - 88, 88, 73, 88, 88, 76, 88, 88, 88, 88, - 88, 88, 92, 0, 3, 2, 88, 88, 79, 88, - 88, 88, 66, 88, 88, 88, 88, 88, 88, 88, - 88, 85, 88, 3, 0, 88, 64, 88, 88, 88, - 86, 88, 88, 88, 88, 88, 88, 88, 68, 0, - 67, 88, 88, 88, 88, 88, 88, 88, 65, 88, +88, 69, 88, 88, 88, 88, 70, 62, 88, 88, +63, 88, 88, 88, 88, 88, 88, 28, 13, 18, +92, 87, 0, 32, 3, 3, 91, 0, 91, 89, +29, 30, 35, 34, 88, 88, 88, 88, 88, 88, +88, 88, 73, 88, 88, 76, 88, 88, 88, 88, +88, 88, 92, 0, 3, 2, 88, 88, 79, 88, +88, 88, 66, 88, 88, 88, 88, 88, 88, 88, +88, 85, 88, 3, 0, 88, 64, 88, 88, 88, +86, 88, 88, 88, 88, 88, 88, 88, 68, 0, +67, 88, 88, 88, 88, 88, 88, 88, 65, 88, - 81, 0, 88, 88, 82, 72, 88, 88, 83, 88, - 80, 0, 74, 88, 71, 75, 88, 88, 0, 78, - 84, 77, 0 - } ; +81, 0, 88, 88, 82, 72, 88, 88, 83, 88, +80, 0, 74, 88, 71, 75, 88, 88, 0, 78, +84, 77, 0 +}; static yyconst int yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 5, 6, 1, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 31, - 33, 33, 33, 33, 33, 34, 33, 35, 33, 36, - 33, 33, 37, 38, 33, 33, 33, 39, 33, 33, - 40, 41, 42, 43, 33, 1, 44, 45, 46, 47, +{ 0, +1, 1, 1, 1, 1, 1, 1, 1, 2, 3, +2, 2, 4, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 2, 5, 6, 1, 7, 8, 9, 10, 11, +12, 13, 14, 15, 16, 17, 18, 19, 20, 20, +20, 20, 20, 20, 20, 20, 20, 21, 22, 23, +24, 25, 26, 27, 28, 29, 30, 31, 32, 31, +33, 33, 33, 33, 33, 34, 33, 35, 33, 36, +33, 33, 37, 38, 33, 33, 33, 39, 33, 33, +40, 41, 42, 43, 33, 1, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 33, 53, 54, 55, 56, - 57, 58, 33, 59, 60, 61, 62, 33, 63, 39, - 33, 33, 64, 65, 66, 67, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +48, 49, 50, 51, 52, 33, 53, 54, 55, 56, +57, 58, 33, 59, 60, 61, 62, 33, 63, 39, +33, 33, 64, 65, 66, 67, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1 +}; static yyconst int yy_meta[68] = - { 0, - 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 3, 4, 4, - 5, 1, 1, 6, 1, 1, 1, 4, 4, 4, - 4, 4, 7, 7, 7, 7, 7, 7, 7, 1, - 1, 1, 1, 4, 4, 4, 4, 4, 4, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 1, 1, 1, 1 - } ; +{ 0, +1, 1, 2, 2, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 3, 4, 4, +5, 1, 1, 6, 1, 1, 1, 4, 4, 4, +4, 4, 7, 7, 7, 7, 7, 7, 7, 1, +1, 1, 1, 4, 4, 4, 4, 4, 4, 7, +7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +7, 7, 7, 1, 1, 1, 1 +}; static yyconst short int yy_base[237] = - { 0, - 0, 0, 337, 338, 334, 338, 338, 61, 63, 51, - 53, 65, 66, 338, 338, 311, 64, 338, 66, 60, - 68, 76, 80, 313, 338, 60, 309, 77, 338, 338, - 0, 298, 295, 302, 338, 338, 305, 268, 268, 54, - 61, 272, 59, 38, 62, 266, 280, 275, 62, 263, - 270, 338, 89, 338, 338, 318, 295, 338, 111, 338, - 314, 100, 338, 296, 338, 338, 338, 112, 338, 312, - 338, 338, 338, 290, 338, 338, 107, 338, 296, 338, - 110, 114, 121, 0, 338, 289, 338, 338, 338, 288, - 0, 0, 281, 281, 338, 249, 260, 247, 250, 244, +{ 0, +0, 0, 337, 338, 334, 338, 338, 61, 63, 51, +53, 65, 66, 338, 338, 311, 64, 338, 66, 60, +68, 76, 80, 313, 338, 60, 309, 77, 338, 338, +0, 298, 295, 302, 338, 338, 305, 268, 268, 54, +61, 272, 59, 38, 62, 266, 280, 275, 62, 263, +270, 338, 89, 338, 338, 318, 295, 338, 111, 338, +314, 100, 338, 296, 338, 338, 338, 112, 338, 312, +338, 338, 338, 290, 338, 338, 107, 338, 296, 338, +110, 114, 121, 0, 338, 289, 338, 338, 338, 288, +0, 0, 281, 281, 338, 249, 260, 247, 250, 244, - 255, 0, 243, 248, 242, 244, 0, 0, 244, 235, - 0, 251, 235, 239, 242, 231, 240, 338, 338, 338, - 270, 269, 268, 338, 0, 139, 119, 125, 128, 0, - 338, 338, 0, 0, 240, 243, 238, 224, 240, 239, - 234, 221, 232, 233, 230, 0, 224, 214, 225, 213, - 225, 218, 250, 249, 146, 152, 210, 215, 0, 215, - 221, 203, 0, 216, 219, 201, 201, 216, 200, 204, - 211, 0, 208, 155, 237, 193, 0, 197, 198, 197, - 0, 204, 197, 190, 197, 190, 197, 193, 0, 225, - 0, 180, 184, 179, 177, 153, 158, 151, 0, 134, +255, 0, 243, 248, 242, 244, 0, 0, 244, 235, +0, 251, 235, 239, 242, 231, 240, 338, 338, 338, +270, 269, 268, 338, 0, 139, 119, 125, 128, 0, +338, 338, 0, 0, 240, 243, 238, 224, 240, 239, +234, 221, 232, 233, 230, 0, 224, 214, 225, 213, +225, 218, 250, 249, 146, 152, 210, 215, 0, 215, +221, 203, 0, 216, 219, 201, 201, 216, 200, 204, +211, 0, 208, 155, 237, 193, 0, 197, 198, 197, +0, 204, 197, 190, 197, 190, 197, 193, 0, 225, +0, 180, 184, 179, 177, 153, 158, 151, 0, 134, - 187, 157, 143, 144, 0, 176, 123, 126, 0, 112, - 338, 160, 0, 115, 338, 0, 88, 76, 162, 0, - 0, 0, 338, 170, 174, 181, 185, 189, 193, 200, - 119, 204, 211, 218, 225, 232 - } ; +187, 157, 143, 144, 0, 176, 123, 126, 0, 112, +338, 160, 0, 115, 338, 0, 88, 76, 162, 0, +0, 0, 338, 170, 174, 181, 185, 189, 193, 200, +119, 204, 211, 218, 225, 232 +}; static yyconst short int yy_def[237] = - { 0, - 223, 1, 223, 223, 223, 223, 223, 223, 224, 225, - 225, 223, 226, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 227, 227, 227, 227, 223, 223, 223, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, - 227, 223, 223, 223, 223, 223, 223, 223, 224, 223, - 224, 228, 223, 229, 223, 223, 223, 226, 223, 226, - 223, 223, 223, 223, 223, 223, 223, 223, 230, 223, - 223, 223, 223, 231, 223, 223, 223, 223, 223, 223, - 227, 227, 227, 227, 223, 227, 227, 227, 227, 227, +{ 0, +223, 1, 223, 223, 223, 223, 223, 223, 224, 225, +225, 223, 226, 223, 223, 223, 223, 223, 223, 223, +223, 223, 223, 223, 223, 223, 223, 223, 223, 223, +227, 227, 227, 227, 223, 223, 223, 227, 227, 227, +227, 227, 227, 227, 227, 227, 227, 227, 227, 227, +227, 223, 223, 223, 223, 223, 223, 223, 224, 223, +224, 228, 223, 229, 223, 223, 223, 226, 223, 226, +223, 223, 223, 223, 223, 223, 223, 223, 230, 223, +223, 223, 223, 231, 223, 223, 223, 223, 223, 223, +227, 227, 227, 227, 223, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 223, 223, 223, - 232, 229, 229, 223, 230, 233, 223, 223, 223, 231, - 223, 223, 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 232, 232, 234, 223, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, - 227, 227, 227, 234, 223, 227, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 227, 227, 223, - 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, +227, 227, 227, 227, 227, 227, 227, 227, 227, 227, +227, 227, 227, 227, 227, 227, 227, 223, 223, 223, +232, 229, 229, 223, 230, 233, 223, 223, 223, 231, +223, 223, 227, 227, 227, 227, 227, 227, 227, 227, +227, 227, 227, 227, 227, 227, 227, 227, 227, 227, +227, 227, 232, 232, 234, 223, 227, 227, 227, 227, +227, 227, 227, 227, 227, 227, 227, 227, 227, 227, +227, 227, 227, 234, 223, 227, 227, 227, 227, 227, +227, 227, 227, 227, 227, 227, 227, 227, 227, 223, +227, 227, 227, 227, 227, 227, 227, 227, 227, 227, - 227, 235, 227, 227, 227, 227, 227, 227, 227, 227, - 223, 236, 227, 227, 223, 227, 227, 227, 236, 227, - 227, 227, 0, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223 - } ; +227, 235, 227, 227, 227, 227, 227, 227, 227, 227, +223, 236, 227, 227, 223, 227, 227, 227, 236, 227, +227, 227, 0, 223, 223, 223, 223, 223, 223, 223, +223, 223, 223, 223, 223, 223 +}; static yyconst short int yy_nxt[406] = - { 0, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 31, 31, - 31, 31, 31, 31, 32, 31, 33, 34, 31, 35, - 4, 36, 37, 38, 39, 40, 41, 42, 43, 31, - 31, 44, 31, 31, 31, 45, 46, 47, 48, 49, - 50, 31, 51, 52, 53, 54, 55, 57, 60, 62, - 62, 62, 62, 66, 63, 69, 65, 72, 77, 77, - 78, 74, 86, 87, 58, 79, 107, 73, 67, 75, - 76, 80, 81, 108, 82, 82, 81, 98, 82, 82, +{ 0, +4, 5, 6, 7, 8, 9, 10, 11, 12, 13, +14, 15, 16, 17, 18, 19, 20, 21, 22, 23, +24, 25, 26, 27, 28, 29, 30, 31, 31, 31, +31, 31, 31, 31, 32, 31, 33, 34, 31, 35, +4, 36, 37, 38, 39, 40, 41, 42, 43, 31, +31, 44, 31, 31, 31, 45, 46, 47, 48, 49, +50, 31, 51, 52, 53, 54, 55, 57, 60, 62, +62, 62, 62, 66, 63, 69, 65, 72, 77, 77, +78, 74, 86, 87, 58, 79, 107, 73, 67, 75, +76, 80, 81, 108, 82, 82, 81, 98, 82, 82, - 89, 90, 104, 61, 100, 109, 70, 83, 101, 110, - 99, 83, 118, 114, 84, 105, 60, 102, 62, 62, - 106, 69, 130, 83, 115, 77, 77, 83, 127, 127, - 81, 222, 82, 82, 128, 221, 128, 127, 127, 129, - 129, 156, 156, 129, 129, 83, 129, 129, 156, 156, - 83, 61, 70, 119, 156, 156, 125, 156, 156, 156, - 156, 83, 156, 156, 156, 156, 83, 220, 218, 175, - 59, 217, 59, 59, 59, 59, 59, 64, 216, 64, - 64, 68, 215, 68, 68, 68, 68, 68, 91, 214, - 213, 91, 121, 211, 210, 121, 122, 122, 209, 122, +89, 90, 104, 61, 100, 109, 70, 83, 101, 110, +99, 83, 118, 114, 84, 105, 60, 102, 62, 62, +106, 69, 130, 83, 115, 77, 77, 83, 127, 127, +81, 222, 82, 82, 128, 221, 128, 127, 127, 129, +129, 156, 156, 129, 129, 83, 129, 129, 156, 156, +83, 61, 70, 119, 156, 156, 125, 156, 156, 156, +156, 83, 156, 156, 156, 156, 83, 220, 218, 175, +59, 217, 59, 59, 59, 59, 59, 64, 216, 64, +64, 68, 215, 68, 68, 68, 68, 68, 91, 214, +213, 91, 121, 211, 210, 121, 122, 122, 209, 122, - 125, 208, 125, 125, 125, 125, 125, 153, 153, 207, - 153, 155, 155, 155, 155, 155, 155, 155, 174, 174, - 174, 174, 174, 174, 174, 212, 212, 206, 212, 212, - 212, 212, 219, 219, 219, 219, 219, 219, 219, 205, - 204, 203, 202, 201, 200, 199, 198, 197, 196, 195, - 194, 193, 192, 191, 190, 189, 188, 187, 186, 185, - 184, 183, 182, 181, 180, 179, 178, 177, 176, 154, - 154, 173, 172, 171, 170, 169, 168, 167, 166, 165, - 164, 163, 162, 161, 160, 159, 158, 157, 123, 123, - 154, 152, 151, 150, 149, 148, 147, 146, 145, 144, +125, 208, 125, 125, 125, 125, 125, 153, 153, 207, +153, 155, 155, 155, 155, 155, 155, 155, 174, 174, +174, 174, 174, 174, 174, 212, 212, 206, 212, 212, +212, 212, 219, 219, 219, 219, 219, 219, 219, 205, +204, 203, 202, 201, 200, 199, 198, 197, 196, 195, +194, 193, 192, 191, 190, 189, 188, 187, 186, 185, +184, 183, 182, 181, 180, 179, 178, 177, 176, 154, +154, 173, 172, 171, 170, 169, 168, 167, 166, 165, +164, 163, 162, 161, 160, 159, 158, 157, 123, 123, +154, 152, 151, 150, 149, 148, 147, 146, 145, 144, - 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, - 133, 132, 131, 126, 124, 68, 123, 59, 120, 56, - 117, 116, 113, 112, 111, 103, 97, 96, 95, 94, - 93, 92, 88, 85, 71, 56, 223, 3, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, +143, 142, 141, 140, 139, 138, 137, 136, 135, 134, +133, 132, 131, 126, 124, 68, 123, 59, 120, 56, +117, 116, 113, 112, 111, 103, 97, 96, 95, 94, +93, 92, 88, 85, 71, 56, 223, 3, 223, 223, +223, 223, 223, 223, 223, 223, 223, 223, 223, 223, +223, 223, 223, 223, 223, 223, 223, 223, 223, 223, +223, 223, 223, 223, 223, 223, 223, 223, 223, 223, +223, 223, 223, 223, 223, 223, 223, 223, 223, 223, +223, 223, 223, 223, 223, 223, 223, 223, 223, 223, +223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223 - } ; +223, 223, 223, 223, 223 +}; static yyconst short int yy_chk[406] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 8, 9, 10, - 10, 11, 11, 12, 10, 13, 11, 17, 20, 20, - 21, 19, 26, 26, 8, 21, 44, 17, 12, 19, - 19, 21, 22, 44, 22, 22, 23, 40, 23, 23, +{ 0, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 8, 9, 10, +10, 11, 11, 12, 10, 13, 11, 17, 20, 20, +21, 19, 26, 26, 8, 21, 44, 17, 12, 19, +19, 21, 22, 44, 22, 22, 23, 40, 23, 23, - 28, 28, 43, 9, 41, 45, 13, 22, 41, 45, - 40, 23, 53, 49, 22, 43, 59, 41, 62, 62, - 43, 68, 231, 22, 49, 77, 77, 23, 81, 81, - 82, 218, 82, 82, 83, 217, 83, 127, 127, 83, - 83, 126, 126, 128, 128, 82, 129, 129, 155, 155, - 127, 59, 68, 53, 156, 156, 126, 174, 174, 202, - 202, 82, 212, 212, 219, 219, 127, 214, 210, 156, - 224, 208, 224, 224, 224, 224, 224, 225, 207, 225, - 225, 226, 206, 226, 226, 226, 226, 226, 227, 204, - 203, 227, 228, 201, 200, 228, 229, 229, 198, 229, +28, 28, 43, 9, 41, 45, 13, 22, 41, 45, +40, 23, 53, 49, 22, 43, 59, 41, 62, 62, +43, 68, 231, 22, 49, 77, 77, 23, 81, 81, +82, 218, 82, 82, 83, 217, 83, 127, 127, 83, +83, 126, 126, 128, 128, 82, 129, 129, 155, 155, +127, 59, 68, 53, 156, 156, 126, 174, 174, 202, +202, 82, 212, 212, 219, 219, 127, 214, 210, 156, +224, 208, 224, 224, 224, 224, 224, 225, 207, 225, +225, 226, 206, 226, 226, 226, 226, 226, 227, 204, +203, 227, 228, 201, 200, 228, 229, 229, 198, 229, - 230, 197, 230, 230, 230, 230, 230, 232, 232, 196, - 232, 233, 233, 233, 233, 233, 233, 233, 234, 234, - 234, 234, 234, 234, 234, 235, 235, 195, 235, 235, - 235, 235, 236, 236, 236, 236, 236, 236, 236, 194, - 193, 192, 190, 188, 187, 186, 185, 184, 183, 182, - 180, 179, 178, 176, 175, 173, 171, 170, 169, 168, - 167, 166, 165, 164, 162, 161, 160, 158, 157, 154, - 153, 152, 151, 150, 149, 148, 147, 145, 144, 143, - 142, 141, 140, 139, 138, 137, 136, 135, 123, 122, - 121, 117, 116, 115, 114, 113, 112, 110, 109, 106, +230, 197, 230, 230, 230, 230, 230, 232, 232, 196, +232, 233, 233, 233, 233, 233, 233, 233, 234, 234, +234, 234, 234, 234, 234, 235, 235, 195, 235, 235, +235, 235, 236, 236, 236, 236, 236, 236, 236, 194, +193, 192, 190, 188, 187, 186, 185, 184, 183, 182, +180, 179, 178, 176, 175, 173, 171, 170, 169, 168, +167, 166, 165, 164, 162, 161, 160, 158, 157, 154, +153, 152, 151, 150, 149, 148, 147, 145, 144, 143, +142, 141, 140, 139, 138, 137, 136, 135, 123, 122, +121, 117, 116, 115, 114, 113, 112, 110, 109, 106, - 105, 104, 103, 101, 100, 99, 98, 97, 96, 94, - 93, 90, 86, 79, 74, 70, 64, 61, 57, 56, - 51, 50, 48, 47, 46, 42, 39, 38, 37, 34, - 33, 32, 27, 24, 16, 5, 3, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, +105, 104, 103, 101, 100, 99, 98, 97, 96, 94, +93, 90, 86, 79, 74, 70, 64, 61, 57, 56, +51, 50, 48, 47, 46, 42, 39, 38, 37, 34, +33, 32, 27, 24, 16, 5, 3, 223, 223, 223, +223, 223, 223, 223, 223, 223, 223, 223, 223, 223, +223, 223, 223, 223, 223, 223, 223, 223, 223, 223, +223, 223, 223, 223, 223, 223, 223, 223, 223, 223, +223, 223, 223, 223, 223, 223, 223, 223, 223, 223, +223, 223, 223, 223, 223, 223, 223, 223, 223, 223, +223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223 - } ; +223, 223, 223, 223, 223 +}; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; /* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ +* any uses of REJECT which flex missed. +*/ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 @@ -568,7 +568,7 @@ struct Token // Can't have ctors in structs used in unions, so we have this. template< typename T > -inline Token< T > MakeToken( T value, U32 lineNumber ) +inline Token< T > MakeToken(T value, U32 lineNumber) { Token< T > result; result.value = value; @@ -617,7 +617,7 @@ inline int isatty(int) { return 0; } buf[n++] = (char) c; \ result = n; \ } - + // General helper stuff. static int lineIndex; @@ -634,30 +634,30 @@ void CMDrestart(FILE *in); #line 635 "CMDscan.cpp" /* Macros after this point can all be overridden by user definitions in - * section 1. - */ +* section 1. +*/ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus -extern "C" int yywrap YY_PROTO(( void )); +extern "C" int yywrap YY_PROTO((void)); #else -extern int yywrap YY_PROTO(( void )); +extern int yywrap YY_PROTO((void)); #endif #endif #ifndef YY_NO_UNPUT -static void yyunput YY_PROTO(( int c, char *buf_ptr )); +static void yyunput YY_PROTO((int c, char *buf_ptr)); #endif #ifndef yytext_ptr -static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +static void yy_flex_strncpy YY_PROTO((char *, yyconst char *, int)); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus -static int yyinput YY_PROTO(( void )); +static int yyinput YY_PROTO((void)); #else -static int input YY_PROTO(( void )); +static int input YY_PROTO((void)); #endif #endif @@ -666,13 +666,13 @@ static int yy_start_stack_ptr = 0; static int yy_start_stack_depth = 0; static int *yy_start_stack = 0; #ifndef YY_NO_PUSH_STATE -static void yy_push_state YY_PROTO(( int new_state )); +static void yy_push_state YY_PROTO((int new_state)); #endif #ifndef YY_NO_POP_STATE -static void yy_pop_state YY_PROTO(( void )); +static void yy_pop_state YY_PROTO((void)); #endif #ifndef YY_NO_TOP_STATE -static int yy_top_state YY_PROTO(( void )); +static int yy_top_state YY_PROTO((void)); #endif #else @@ -690,9 +690,9 @@ YY_MALLOC_DECL #endif #else /* Just try to get by without declaring the routines. This will fail - * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) - * or sizeof(void*) != sizeof(int). - */ +* miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) +* or sizeof(void*) != sizeof(int). +*/ #endif #endif @@ -705,37 +705,37 @@ YY_MALLOC_DECL #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ +* we now use fwrite(). +*/ #define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ +* is returned in "result". +*/ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ - if ( yy_current_buffer->yy_is_interactive ) \ - { \ - int c = '*', n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ - && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ +* we don't want an extra ';' after the "return" because that will cause +* some compilers to complain about unreachable statements. +*/ #ifndef yyterminate #define yyterminate() return YY_NULL #endif @@ -751,15 +751,15 @@ YY_MALLOC_DECL #endif /* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ +* easily add parameters. +*/ #ifndef YY_DECL #define YY_DECL int yylex YY_PROTO(( void )) #endif /* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ +* have been set up. +*/ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif @@ -770,778 +770,777 @@ YY_MALLOC_DECL #endif #define YY_RULE_SETUP \ - YY_USER_ACTION + YY_USER_ACTION YY_DECL - { - yy_state_type yy_current_state; - char *yy_cp, *yy_bp; - int yy_act; +{ + register yy_state_type yy_current_state; +register char *yy_cp, *yy_bp; +register int yy_act; #line 105 "CMDscan.l" - ; +; #line 785 "CMDscan.cpp" - if ( yy_init ) - { - yy_init = 0; +if (yy_init) +{ + yy_init = 0; #ifdef YY_USER_INIT - YY_USER_INIT; + YY_USER_INIT; #endif - if ( ! yy_start ) - yy_start = 1; /* first start state */ + if (!yy_start) + yy_start = 1; /* first start state */ - if ( ! yyin ) - yyin = stdin; + if (!yyin) + yyin = stdin; - if ( ! yyout ) - yyout = stdout; + if (!yyout) + yyout = stdout; - if ( ! yy_current_buffer ) - yy_current_buffer = - yy_create_buffer( yyin, YY_BUF_SIZE ); + if (!yy_current_buffer) + yy_current_buffer = + yy_create_buffer(yyin, YY_BUF_SIZE); - yy_load_buffer_state(); - } + yy_load_buffer_state(); +} - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yy_c_buf_p; +while (1) /* loops until end-of-file is reached */ +{ + yy_cp = yy_c_buf_p; - /* Support of yytext. */ - *yy_cp = yy_hold_char; + /* Support of yytext. */ + *yy_cp = yy_hold_char; - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; - yy_current_state = yy_start; + yy_current_state = yy_start; yy_match: - do - { - YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 224 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 338 ); + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if (yy_accept[yy_current_state]) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) + { + yy_current_state = (int)yy_def[yy_current_state]; + if (yy_current_state >= 224) + yy_c = yy_meta[(unsigned int)yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int)yy_c]; + ++yy_cp; + } while (yy_base[yy_current_state] != 338); yy_find_action: + yy_act = yy_accept[yy_current_state]; + if (yy_act == 0) + { /* have to back up */ + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - yy_act = yy_accept[yy_current_state]; - } + } - YY_DO_BEFORE_ACTION; + YY_DO_BEFORE_ACTION; -do_action: /* This label is used only to access EOF actions. */ +do_action: /* This label is used only to access EOF actions. */ - switch ( yy_act ) + switch (yy_act) { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = yy_hold_char; yy_cp = yy_last_accepting_cpos; yy_current_state = yy_last_accepting_state; goto yy_find_action; -case 1: -YY_RULE_SETUP + case 1: + YY_RULE_SETUP #line 107 "CMDscan.l" -{ } - YY_BREAK -case 2: -YY_RULE_SETUP + {} + YY_BREAK + case 2: + YY_RULE_SETUP #line 108 "CMDscan.l" -{ return(Sc_ScanDocBlock()); } - YY_BREAK -case 3: -YY_RULE_SETUP + { return(Sc_ScanDocBlock()); } + YY_BREAK + case 3: + YY_RULE_SETUP #line 109 "CMDscan.l" -; - YY_BREAK -case 4: -YY_RULE_SETUP + ; + YY_BREAK + case 4: + YY_RULE_SETUP #line 110 "CMDscan.l" -; - YY_BREAK -case 5: -YY_RULE_SETUP + ; + YY_BREAK + case 5: + YY_RULE_SETUP #line 111 "CMDscan.l" -{lineIndex++;} - YY_BREAK -case 6: -YY_RULE_SETUP + { lineIndex++; } + YY_BREAK + case 6: + YY_RULE_SETUP #line 112 "CMDscan.l" -{ return(Sc_ScanString(STRATOM)); } - YY_BREAK -case 7: -YY_RULE_SETUP + { return(Sc_ScanString(STRATOM)); } + YY_BREAK + case 7: + YY_RULE_SETUP #line 113 "CMDscan.l" -{ return(Sc_ScanString(TAGATOM)); } - YY_BREAK -case 8: -YY_RULE_SETUP + { return(Sc_ScanString(TAGATOM)); } + YY_BREAK + case 8: + YY_RULE_SETUP #line 114 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opEQ, lineIndex ); return opEQ; } - YY_BREAK -case 9: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opEQ, lineIndex); return opEQ; } + YY_BREAK + case 9: + YY_RULE_SETUP #line 115 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opNE, lineIndex ); return opNE; } - YY_BREAK -case 10: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opNE, lineIndex); return opNE; } + YY_BREAK + case 10: + YY_RULE_SETUP #line 116 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opGE, lineIndex ); return opGE; } - YY_BREAK -case 11: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opGE, lineIndex); return opGE; } + YY_BREAK + case 11: + YY_RULE_SETUP #line 117 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opLE, lineIndex ); return opLE; } - YY_BREAK -case 12: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opLE, lineIndex); return opLE; } + YY_BREAK + case 12: + YY_RULE_SETUP #line 118 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opAND, lineIndex ); return opAND; } - YY_BREAK -case 13: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opAND, lineIndex); return opAND; } + YY_BREAK + case 13: + YY_RULE_SETUP #line 119 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opOR, lineIndex ); return opOR; } - YY_BREAK -case 14: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opOR, lineIndex); return opOR; } + YY_BREAK + case 14: + YY_RULE_SETUP #line 120 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opCOLONCOLON, lineIndex ); return opCOLONCOLON; } - YY_BREAK -case 15: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opCOLONCOLON, lineIndex); return opCOLONCOLON; } + YY_BREAK + case 15: + YY_RULE_SETUP #line 121 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opMINUSMINUS, lineIndex ); return opMINUSMINUS; } - YY_BREAK -case 16: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opMINUSMINUS, lineIndex); return opMINUSMINUS; } + YY_BREAK + case 16: + YY_RULE_SETUP #line 122 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opPLUSPLUS, lineIndex ); return opPLUSPLUS; } - YY_BREAK -case 17: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opPLUSPLUS, lineIndex); return opPLUSPLUS; } + YY_BREAK + case 17: + YY_RULE_SETUP #line 123 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opSTREQ, lineIndex ); return opSTREQ; } - YY_BREAK -case 18: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opSTREQ, lineIndex); return opSTREQ; } + YY_BREAK + case 18: + YY_RULE_SETUP #line 124 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opSTRNE, lineIndex ); return opSTRNE; } - YY_BREAK -case 19: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opSTRNE, lineIndex); return opSTRNE; } + YY_BREAK + case 19: + YY_RULE_SETUP #line 125 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opSHL, lineIndex ); return opSHL; } - YY_BREAK -case 20: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opSHL, lineIndex); return opSHL; } + YY_BREAK + case 20: + YY_RULE_SETUP #line 126 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opSHR, lineIndex ); return opSHR; } - YY_BREAK -case 21: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opSHR, lineIndex); return opSHR; } + YY_BREAK + case 21: + YY_RULE_SETUP #line 127 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opPLASN, lineIndex ); return opPLASN; } - YY_BREAK -case 22: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opPLASN, lineIndex); return opPLASN; } + YY_BREAK + case 22: + YY_RULE_SETUP #line 128 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opMIASN, lineIndex ); return opMIASN; } - YY_BREAK -case 23: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opMIASN, lineIndex); return opMIASN; } + YY_BREAK + case 23: + YY_RULE_SETUP #line 129 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opMLASN, lineIndex ); return opMLASN; } - YY_BREAK -case 24: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opMLASN, lineIndex); return opMLASN; } + YY_BREAK + case 24: + YY_RULE_SETUP #line 130 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opDVASN, lineIndex ); return opDVASN; } - YY_BREAK -case 25: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opDVASN, lineIndex); return opDVASN; } + YY_BREAK + case 25: + YY_RULE_SETUP #line 131 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opMODASN, lineIndex ); return opMODASN; } - YY_BREAK -case 26: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opMODASN, lineIndex); return opMODASN; } + YY_BREAK + case 26: + YY_RULE_SETUP #line 132 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opANDASN, lineIndex ); return opANDASN; } - YY_BREAK -case 27: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opANDASN, lineIndex); return opANDASN; } + YY_BREAK + case 27: + YY_RULE_SETUP #line 133 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opXORASN, lineIndex ); return opXORASN; } - YY_BREAK -case 28: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opXORASN, lineIndex); return opXORASN; } + YY_BREAK + case 28: + YY_RULE_SETUP #line 134 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opORASN, lineIndex ); return opORASN; } - YY_BREAK -case 29: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opORASN, lineIndex); return opORASN; } + YY_BREAK + case 29: + YY_RULE_SETUP #line 135 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opSLASN, lineIndex ); return opSLASN; } - YY_BREAK -case 30: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opSLASN, lineIndex); return opSLASN; } + YY_BREAK + case 30: + YY_RULE_SETUP #line 136 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opSRASN, lineIndex ); return opSRASN; } - YY_BREAK -case 31: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opSRASN, lineIndex); return opSRASN; } + YY_BREAK + case 31: + YY_RULE_SETUP #line 137 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opINTNAME, lineIndex ); return opINTNAME; } - YY_BREAK -case 32: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opINTNAME, lineIndex); return opINTNAME; } + YY_BREAK + case 32: + YY_RULE_SETUP #line 138 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( opINTNAMER, lineIndex ); return opINTNAMER; } - YY_BREAK -case 33: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(opINTNAMER, lineIndex); return opINTNAMER; } + YY_BREAK + case 33: + YY_RULE_SETUP #line 139 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( '\n', lineIndex ); return '@'; } - YY_BREAK -case 34: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >('\n', lineIndex); return '@'; } + YY_BREAK + case 34: + YY_RULE_SETUP #line 140 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( '\t', lineIndex ); return '@'; } - YY_BREAK -case 35: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >('\t', lineIndex); return '@'; } + YY_BREAK + case 35: + YY_RULE_SETUP #line 141 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( ' ', lineIndex ); return '@'; } - YY_BREAK -case 36: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(' ', lineIndex); return '@'; } + YY_BREAK + case 36: + YY_RULE_SETUP #line 142 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( 0, lineIndex ); return '@'; } - YY_BREAK -case 37: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(0, lineIndex); return '@'; } + YY_BREAK + case 37: + YY_RULE_SETUP #line 143 "CMDscan.l" -{ /* this comment stops syntax highlighting from getting messed up when editing the lexer in TextPad */ - int c = 0, l; - for ( ; ; ) + { /* this comment stops syntax highlighting from getting messed up when editing the lexer in TextPad */ + int c = 0, l; + for (; ; ) { l = c; c = yyinput(); // Is this an open comment? - if ( c == EOF ) + if (c == EOF) { - CMDerror( "unexpected end of file found in comment" ); + CMDerror("unexpected end of file found in comment"); break; } // Increment line numbers. - else if ( c == '\n' ) + else if (c == '\n') lineIndex++; // Did we find the end of the comment? - else if ( l == '*' && c == '/' ) + else if (l == '*' && c == '/') break; } - } - YY_BREAK -case 38: + } + YY_BREAK + case 38: #line 167 "CMDscan.l" -case 39: + case 39: #line 168 "CMDscan.l" -case 40: + case 40: #line 169 "CMDscan.l" -case 41: + case 41: #line 170 "CMDscan.l" -case 42: + case 42: #line 171 "CMDscan.l" -case 43: + case 43: #line 172 "CMDscan.l" -case 44: + case 44: #line 173 "CMDscan.l" -case 45: + case 45: #line 174 "CMDscan.l" -case 46: + case 46: #line 175 "CMDscan.l" -case 47: + case 47: #line 176 "CMDscan.l" -case 48: + case 48: #line 177 "CMDscan.l" -case 49: + case 49: #line 178 "CMDscan.l" -case 50: + case 50: #line 179 "CMDscan.l" -case 51: + case 51: #line 180 "CMDscan.l" -case 52: + case 52: #line 181 "CMDscan.l" -case 53: + case 53: #line 182 "CMDscan.l" -case 54: + case 54: #line 183 "CMDscan.l" -case 55: + case 55: #line 184 "CMDscan.l" -case 56: + case 56: #line 185 "CMDscan.l" -case 57: + case 57: #line 186 "CMDscan.l" -case 58: + case 58: #line 187 "CMDscan.l" -case 59: + case 59: #line 188 "CMDscan.l" -case 60: + case 60: #line 189 "CMDscan.l" -case 61: -YY_RULE_SETUP + case 61: + YY_RULE_SETUP #line 189 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( CMDtext[ 0 ], lineIndex ); return CMDtext[ 0 ]; } - YY_BREAK -case 62: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(CMDtext[0], lineIndex); return CMDtext[0]; } + YY_BREAK + case 62: + YY_RULE_SETUP #line 190 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwIN, lineIndex ); return(rwIN); } - YY_BREAK -case 63: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwIN, lineIndex); return(rwIN); } + YY_BREAK + case 63: + YY_RULE_SETUP #line 191 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwCASEOR, lineIndex ); return(rwCASEOR); } - YY_BREAK -case 64: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwCASEOR, lineIndex); return(rwCASEOR); } + YY_BREAK + case 64: + YY_RULE_SETUP #line 192 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwBREAK, lineIndex ); return(rwBREAK); } - YY_BREAK -case 65: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwBREAK, lineIndex); return(rwBREAK); } + YY_BREAK + case 65: + YY_RULE_SETUP #line 193 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwRETURN, lineIndex ); return(rwRETURN); } - YY_BREAK -case 66: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwRETURN, lineIndex); return(rwRETURN); } + YY_BREAK + case 66: + YY_RULE_SETUP #line 194 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwELSE, lineIndex ); return(rwELSE); } - YY_BREAK -case 67: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwELSE, lineIndex); return(rwELSE); } + YY_BREAK + case 67: + YY_RULE_SETUP #line 195 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwASSERT, lineIndex ); return(rwASSERT); } - YY_BREAK -case 68: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwASSERT, lineIndex); return(rwASSERT); } + YY_BREAK + case 68: + YY_RULE_SETUP #line 196 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwWHILE, lineIndex ); return(rwWHILE); } - YY_BREAK -case 69: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwWHILE, lineIndex); return(rwWHILE); } + YY_BREAK + case 69: + YY_RULE_SETUP #line 197 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwDO, lineIndex ); return(rwDO); } - YY_BREAK -case 70: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwDO, lineIndex); return(rwDO); } + YY_BREAK + case 70: + YY_RULE_SETUP #line 198 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwIF, lineIndex ); return(rwIF); } - YY_BREAK -case 71: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwIF, lineIndex); return(rwIF); } + YY_BREAK + case 71: + YY_RULE_SETUP #line 199 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwFOREACHSTR, lineIndex ); return(rwFOREACHSTR); } - YY_BREAK -case 72: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwFOREACHSTR, lineIndex); return(rwFOREACHSTR); } + YY_BREAK + case 72: + YY_RULE_SETUP #line 200 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwFOREACH, lineIndex ); return(rwFOREACH); } - YY_BREAK -case 73: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwFOREACH, lineIndex); return(rwFOREACH); } + YY_BREAK + case 73: + YY_RULE_SETUP #line 201 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwFOR, lineIndex ); return(rwFOR); } - YY_BREAK -case 74: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwFOR, lineIndex); return(rwFOR); } + YY_BREAK + case 74: + YY_RULE_SETUP #line 202 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwCONTINUE, lineIndex ); return(rwCONTINUE); } - YY_BREAK -case 75: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwCONTINUE, lineIndex); return(rwCONTINUE); } + YY_BREAK + case 75: + YY_RULE_SETUP #line 203 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwDEFINE, lineIndex ); return(rwDEFINE); } - YY_BREAK -case 76: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwDEFINE, lineIndex); return(rwDEFINE); } + YY_BREAK + case 76: + YY_RULE_SETUP #line 204 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwDECLARE, lineIndex ); return(rwDECLARE); } - YY_BREAK -case 77: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwDECLARE, lineIndex); return(rwDECLARE); } + YY_BREAK + case 77: + YY_RULE_SETUP #line 205 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwDECLARESINGLETON, lineIndex ); return(rwDECLARESINGLETON); } - YY_BREAK -case 78: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwDECLARESINGLETON, lineIndex); return(rwDECLARESINGLETON); } + YY_BREAK + case 78: + YY_RULE_SETUP #line 206 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwDATABLOCK, lineIndex ); return(rwDATABLOCK); } - YY_BREAK -case 79: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwDATABLOCK, lineIndex); return(rwDATABLOCK); } + YY_BREAK + case 79: + YY_RULE_SETUP #line 207 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwCASE, lineIndex ); return(rwCASE); } - YY_BREAK -case 80: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwCASE, lineIndex); return(rwCASE); } + YY_BREAK + case 80: + YY_RULE_SETUP #line 208 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwSWITCHSTR, lineIndex ); return(rwSWITCHSTR); } - YY_BREAK -case 81: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwSWITCHSTR, lineIndex); return(rwSWITCHSTR); } + YY_BREAK + case 81: + YY_RULE_SETUP #line 209 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwSWITCH, lineIndex ); return(rwSWITCH); } - YY_BREAK -case 82: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwSWITCH, lineIndex); return(rwSWITCH); } + YY_BREAK + case 82: + YY_RULE_SETUP #line 210 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwDEFAULT, lineIndex ); return(rwDEFAULT); } - YY_BREAK -case 83: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwDEFAULT, lineIndex); return(rwDEFAULT); } + YY_BREAK + case 83: + YY_RULE_SETUP #line 211 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwPACKAGE, lineIndex ); return(rwPACKAGE); } - YY_BREAK -case 84: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwPACKAGE, lineIndex); return(rwPACKAGE); } + YY_BREAK + case 84: + YY_RULE_SETUP #line 212 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( rwNAMESPACE, lineIndex ); return(rwNAMESPACE); } - YY_BREAK -case 85: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(rwNAMESPACE, lineIndex); return(rwNAMESPACE); } + YY_BREAK + case 85: + YY_RULE_SETUP #line 213 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( 1, lineIndex ); return INTCONST; } - YY_BREAK -case 86: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(1, lineIndex); return INTCONST; } + YY_BREAK + case 86: + YY_RULE_SETUP #line 214 "CMDscan.l" -{ CMDlval.i = MakeToken< int >( 0, lineIndex ); return INTCONST; } - YY_BREAK -case 87: -YY_RULE_SETUP + { CMDlval.i = MakeToken< int >(0, lineIndex); return INTCONST; } + YY_BREAK + case 87: + YY_RULE_SETUP #line 215 "CMDscan.l" -{ return(Sc_ScanVar()); } - YY_BREAK -case 88: -YY_RULE_SETUP + { return(Sc_ScanVar()); } + YY_BREAK + case 88: + YY_RULE_SETUP #line 216 "CMDscan.l" -{ return Sc_ScanIdent(); } - YY_BREAK -case 89: -YY_RULE_SETUP + { return Sc_ScanIdent(); } + YY_BREAK + case 89: + YY_RULE_SETUP #line 217 "CMDscan.l" -return(Sc_ScanHex()); - YY_BREAK -case 90: -YY_RULE_SETUP + return(Sc_ScanHex()); + YY_BREAK + case 90: + YY_RULE_SETUP #line 218 "CMDscan.l" -{ CMDtext[CMDleng] = 0; CMDlval.i = MakeToken< int >( dAtoi(CMDtext), lineIndex ); return INTCONST; } - YY_BREAK -case 91: -YY_RULE_SETUP + { CMDtext[CMDleng] = 0; CMDlval.i = MakeToken< int >(dAtoi(CMDtext), lineIndex); return INTCONST; } + YY_BREAK + case 91: + YY_RULE_SETUP #line 219 "CMDscan.l" -return Sc_ScanNum(); - YY_BREAK -case 92: -YY_RULE_SETUP + return Sc_ScanNum(); + YY_BREAK + case 92: + YY_RULE_SETUP #line 220 "CMDscan.l" -return(ILLEGAL_TOKEN); - YY_BREAK -case 93: -YY_RULE_SETUP + return(ILLEGAL_TOKEN); + YY_BREAK + case 93: + YY_RULE_SETUP #line 221 "CMDscan.l" -return(ILLEGAL_TOKEN); - YY_BREAK -case 94: -YY_RULE_SETUP + return(ILLEGAL_TOKEN); + YY_BREAK + case 94: + YY_RULE_SETUP #line 222 "CMDscan.l" -ECHO; - YY_BREAK + ECHO; + YY_BREAK #line 1291 "CMDscan.cpp" -case YY_STATE_EOF(INITIAL): - yyterminate(); + case YY_STATE_EOF(INITIAL): + yyterminate(); - case YY_END_OF_BUFFER: + case YY_END_OF_BUFFER: { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int)(yy_cp - yytext_ptr) - 1; - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yy_hold_char; + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + if (yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW) { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between yy_current_buffer and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yy_n_chars = yy_current_buffer->yy_n_chars; - yy_current_buffer->yy_input_file = yyin; - yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; } - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if (yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars]) { /* This was really a NUL. */ - yy_state_type yy_next_state; + yy_state_type yy_next_state; - yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; - yy_current_state = yy_get_previous_state(); + yy_current_state = yy_get_previous_state(); - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ - yy_next_state = yy_try_NUL_trans( yy_current_state ); + yy_next_state = yy_try_NUL_trans(yy_current_state); - yy_bp = yytext_ptr + YY_MORE_ADJ; + yy_bp = yytext_ptr + YY_MORE_ADJ; - if ( yy_next_state ) + if (yy_next_state) { - /* Consume the NUL. */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; } - else - { - yy_cp = yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - else + { + yy_cp = yy_c_buf_p; + goto yy_find_action; + } + } + + else switch (yy_get_next_buffer()) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if (yywrap()) { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; } - break; + + else + { + if (!yy_did_buffer_switch_on_eof) + YY_NEW_FILE; + } + break; } - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = - yytext_ptr + yy_amount_of_matched_text; + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; - yy_current_state = yy_get_previous_state(); + yy_current_state = yy_get_previous_state(); - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_match; + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; - yy_current_state = yy_get_previous_state(); + yy_current_state = yy_get_previous_state(); - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; } - break; + break; } - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found"); } /* end of action switch */ - } /* end of scanning one token */ - } /* end of yylex */ +} /* end of scanning one token */ +} /* end of yylex */ -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ + /* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ -static int yy_get_next_buffer() - { - char *dest = yy_current_buffer->yy_ch_buf; - char *source = yytext_ptr; - int number_to_move, i; + static int yy_get_next_buffer() +{ + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; int ret_val; - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + if (yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1]) YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); + "fatal flex scanner internal error--end of buffer missed"); - if ( yy_current_buffer->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) - { + if (yy_current_buffer->yy_fill_buffer == 0) + { /* Don't try to fill the buffer, so this is an EOF. */ + if (yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1) + { /* We matched a singled characater, the EOB, so - * treat this as a final EOF. - */ + * treat this as a final EOF. + */ return EOB_ACT_END_OF_FILE; - } + } else - { + { /* We matched some text prior to the EOB, first - * process it. - */ + * process it. + */ return EOB_ACT_LAST_MATCH; - } } + } /* Try to read more data. */ /* First move last chars to start of buffer. */ - number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + number_to_move = (int)(yy_c_buf_p - yytext_ptr) - 1; - for ( i = 0; i < number_to_move; ++i ) + for (i = 0; i < number_to_move; ++i) *(dest++) = *(source++); - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + if (yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING) /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ + * just force an EOF + */ yy_n_chars = 0; else - { + { int num_to_read = yy_current_buffer->yy_buf_size - number_to_move - 1; - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ + while (num_to_read <= 0) + { /* Not enough room in the buffer - grow it. */ #ifdef YY_USES_REJECT YY_FATAL_ERROR( -"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); + "input buffer overflow, can't enlarge buffer because scanner uses REJECT"); #else - /* just a shorter name for the current buffer */ + /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = yy_current_buffer; int yy_c_buf_p_offset = - (int) (yy_c_buf_p - b->yy_ch_buf); + (int)(yy_c_buf_p - b->yy_ch_buf); - if ( b->yy_is_our_buffer ) - { + if (b->yy_is_our_buffer) + { int new_size = b->yy_buf_size * 2; - if ( new_size <= 0 ) + if (new_size <= 0) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ - yy_flex_realloc( (void *) b->yy_ch_buf, - b->yy_buf_size + 2 ); - } + yy_flex_realloc((void *)b->yy_ch_buf, + b->yy_buf_size + 2); + } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; - if ( ! b->yy_ch_buf ) + if (!b->yy_ch_buf) YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); + "fatal error - scanner input buffer overflow"); yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = yy_current_buffer->yy_buf_size - - number_to_move - 1; + number_to_move - 1; #endif - } + } - if ( num_to_read > YY_READ_BUF_SIZE ) + if (num_to_read > YY_READ_BUF_SIZE) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); + YY_INPUT((&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read); + } + + if (yy_n_chars == 0) + { + if (number_to_move == YY_MORE_ADJ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart(yyin); } - if ( yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); - } - else - { + { ret_val = EOB_ACT_LAST_MATCH; yy_current_buffer->yy_buffer_status = YY_BUFFER_EOF_PENDING; - } } + } else ret_val = EOB_ACT_CONTINUE_SCAN; @@ -1553,116 +1552,116 @@ static int yy_get_next_buffer() yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; return ret_val; - } +} /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state() - { - yy_state_type yy_current_state; - char *yy_cp; +{ + register yy_state_type yy_current_state; + register char *yy_cp; yy_current_state = yy_start; - for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + for (yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if (yy_accept[yy_current_state]) { - YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { yy_last_accepting_state = yy_current_state; yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 224 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } + while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) + { + yy_current_state = (int)yy_def[yy_current_state]; + if (yy_current_state >= 224) + yy_c = yy_meta[(unsigned int)yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int)yy_c]; + } return yy_current_state; - } +} /* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ +* +* synopsis +* next_state = yy_try_NUL_trans( current_state ); +*/ #ifdef YY_USE_PROTOS -static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +static yy_state_type yy_try_NUL_trans(yy_state_type yy_current_state) #else -static yy_state_type yy_try_NUL_trans( yy_current_state ) +static yy_state_type yy_try_NUL_trans(yy_current_state) yy_state_type yy_current_state; #endif - { - int yy_is_jam; - char *yy_cp = yy_c_buf_p; +{ + register int yy_is_jam; + register char *yy_cp = yy_c_buf_p; - YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { + register YY_CHAR yy_c = 1; + if (yy_accept[yy_current_state]) + { yy_last_accepting_state = yy_current_state; yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 224 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state) + { + yy_current_state = (int)yy_def[yy_current_state]; + if (yy_current_state >= 224) + yy_c = yy_meta[(unsigned int)yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int)yy_c]; yy_is_jam = (yy_current_state == 223); return yy_is_jam ? 0 : yy_current_state; - } +} #ifndef YY_NO_UNPUT #ifdef YY_USE_PROTOS -static void yyunput( int c, char *yy_bp ) +static void yyunput(int c, register char *yy_bp) #else -static void yyunput( c, yy_bp ) +static void yyunput(c, yy_bp) int c; -char *yy_bp; +register char *yy_bp; #endif - { - char *yy_cp = yy_c_buf_p; +{ + register char *yy_cp = yy_c_buf_p; /* undo effects of setting up yytext */ *yy_cp = yy_hold_char; - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - int number_to_move = yy_n_chars + 2; - char *dest = &yy_current_buffer->yy_ch_buf[ - yy_current_buffer->yy_buf_size + 2]; - char *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; + if (yy_cp < yy_current_buffer->yy_ch_buf + 2) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; - while ( source > yy_current_buffer->yy_ch_buf ) + while (source > yy_current_buffer->yy_ch_buf) *--dest = *--source; - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); + yy_cp += (int)(dest - source); + yy_bp += (int)(dest - source); yy_n_chars = yy_current_buffer->yy_buf_size; - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } + if (yy_cp < yy_current_buffer->yy_ch_buf + 2) + YY_FATAL_ERROR("flex scanner push-back overflow"); + } - *--yy_cp = (char) c; + *--yy_cp = (char)c; yytext_ptr = yy_bp; yy_hold_char = *yy_cp; yy_c_buf_p = yy_cp; - } -#endif /* ifndef YY_NO_UNPUT */ +} +#endif /* ifndef YY_NO_UNPUT */ #ifdef __cplusplus @@ -1670,45 +1669,45 @@ static int yyinput() #else static int input() #endif - { +{ int c; *yy_c_buf_p = yy_hold_char; - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { + if (*yy_c_buf_p == YY_END_OF_BUFFER_CHAR) + { /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if (yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars]) /* This was really a NUL. */ *yy_c_buf_p = '\0'; else - { /* need more input */ + { /* need more input */ yytext_ptr = yy_c_buf_p; ++yy_c_buf_p; - switch ( yy_get_next_buffer() ) - { + switch (yy_get_next_buffer()) + { case EOB_ACT_END_OF_FILE: + { + if (yywrap()) { - if ( yywrap() ) - { yy_c_buf_p = - yytext_ptr + YY_MORE_ADJ; + yytext_ptr + YY_MORE_ADJ; return EOF; - } + } - if ( ! yy_did_buffer_switch_on_eof ) + if (!yy_did_buffer_switch_on_eof) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif - } + } case EOB_ACT_CONTINUE_SCAN: yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; @@ -1717,150 +1716,150 @@ static int input() case EOB_ACT_LAST_MATCH: #ifdef __cplusplus YY_FATAL_ERROR( - "unexpected last match in yyinput()" ); + "unexpected last match in yyinput()"); #else YY_FATAL_ERROR( - "unexpected last match in input()" ); + "unexpected last match in input()"); #endif - } } } + } - c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ - *yy_c_buf_p = '\0'; /* preserve yytext */ + c = *(unsigned char *)yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ yy_hold_char = *++yy_c_buf_p; return c; - } +} #ifdef YY_USE_PROTOS -void yyrestart( FILE *input_file ) +void yyrestart(FILE *input_file) #else -void yyrestart( input_file ) +void yyrestart(input_file) FILE *input_file; #endif - { - if ( ! yy_current_buffer ) - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); +{ + if (!yy_current_buffer) + yy_current_buffer = yy_create_buffer(yyin, YY_BUF_SIZE); - yy_init_buffer( yy_current_buffer, input_file ); + yy_init_buffer(yy_current_buffer, input_file); yy_load_buffer_state(); - } +} #ifdef YY_USE_PROTOS -void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +void yy_switch_to_buffer(YY_BUFFER_STATE new_buffer) #else -void yy_switch_to_buffer( new_buffer ) +void yy_switch_to_buffer(new_buffer) YY_BUFFER_STATE new_buffer; #endif - { - if ( yy_current_buffer == new_buffer ) +{ + if (yy_current_buffer == new_buffer) return; - if ( yy_current_buffer ) - { + if (yy_current_buffer) + { /* Flush out information for old buffer. */ *yy_c_buf_p = yy_hold_char; yy_current_buffer->yy_buf_pos = yy_c_buf_p; yy_current_buffer->yy_n_chars = yy_n_chars; - } + } yy_current_buffer = new_buffer; yy_load_buffer_state(); /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ yy_did_buffer_switch_on_eof = 1; - } +} #ifdef YY_USE_PROTOS -void yy_load_buffer_state( void ) +void yy_load_buffer_state(void) #else void yy_load_buffer_state() #endif - { +{ yy_n_chars = yy_current_buffer->yy_n_chars; yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; yyin = yy_current_buffer->yy_input_file; yy_hold_char = *yy_c_buf_p; - } +} #ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +YY_BUFFER_STATE yy_create_buffer(FILE *file, int size) #else -YY_BUFFER_STATE yy_create_buffer( file, size ) +YY_BUFFER_STATE yy_create_buffer(file, size) FILE *file; int size; #endif - { +{ YY_BUFFER_STATE b; - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + b = (YY_BUFFER_STATE)yy_flex_alloc(sizeof(struct yy_buffer_state)); + if (!b) + YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()"); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *)yy_flex_alloc(b->yy_buf_size + 2); + if (!b->yy_ch_buf) + YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()"); b->yy_is_our_buffer = 1; - yy_init_buffer( b, file ); + yy_init_buffer(b, file); return b; - } +} #ifdef YY_USE_PROTOS -void yy_delete_buffer( YY_BUFFER_STATE b ) +void yy_delete_buffer(YY_BUFFER_STATE b) #else -void yy_delete_buffer( b ) +void yy_delete_buffer(b) YY_BUFFER_STATE b; #endif - { - if ( ! b ) +{ + if (!b) return; - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; + if (b == yy_current_buffer) + yy_current_buffer = (YY_BUFFER_STATE)0; - if ( b->yy_is_our_buffer ) - yy_flex_free( (void *) b->yy_ch_buf ); + if (b->yy_is_our_buffer) + yy_flex_free((void *)b->yy_ch_buf); - yy_flex_free( (void *) b ); - } + yy_flex_free((void *)b); +} #ifndef YY_ALWAYS_INTERACTIVE #ifndef YY_NEVER_INTERACTIVE -extern int isatty YY_PROTO(( int )); +extern int isatty YY_PROTO((int)); #endif #endif #ifdef YY_USE_PROTOS -void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +void yy_init_buffer(YY_BUFFER_STATE b, FILE *file) #else -void yy_init_buffer( b, file ) +void yy_init_buffer(b, file) YY_BUFFER_STATE b; FILE *file; #endif - { - yy_flush_buffer( b ); +{ + yy_flush_buffer(b); b->yy_input_file = file; b->yy_fill_buffer = 1; @@ -1871,26 +1870,26 @@ FILE *file; #if YY_NEVER_INTERACTIVE b->yy_is_interactive = 0; #else - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + b->yy_is_interactive = file ? (isatty(fileno(file)) > 0) : 0; #endif #endif - } +} #ifdef YY_USE_PROTOS -void yy_flush_buffer( YY_BUFFER_STATE b ) +void yy_flush_buffer(YY_BUFFER_STATE b) #else -void yy_flush_buffer( b ) +void yy_flush_buffer(b) YY_BUFFER_STATE b; #endif - { +{ b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; @@ -1899,33 +1898,33 @@ YY_BUFFER_STATE b; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; - if ( b == yy_current_buffer ) + if (b == yy_current_buffer) yy_load_buffer_state(); - } +} #ifndef YY_NO_SCAN_BUFFER #ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +YY_BUFFER_STATE yy_scan_buffer(char *base, yy_size_t size) #else -YY_BUFFER_STATE yy_scan_buffer( base, size ) +YY_BUFFER_STATE yy_scan_buffer(base, size) char *base; yy_size_t size; #endif - { +{ YY_BUFFER_STATE b; - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) + if (size < 2 || + base[size - 2] != YY_END_OF_BUFFER_CHAR || + base[size - 1] != YY_END_OF_BUFFER_CHAR) /* They forgot to leave room for the EOB's. */ return 0; - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + b = (YY_BUFFER_STATE)yy_flex_alloc(sizeof(struct yy_buffer_state)); + if (!b) + YY_FATAL_ERROR("out of dynamic memory in yy_scan_buffer()"); - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; @@ -1935,39 +1934,39 @@ yy_size_t size; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; - yy_switch_to_buffer( b ); + yy_switch_to_buffer(b); return b; - } +} #endif #ifndef YY_NO_SCAN_STRING #ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_string( yyconst char *str ) +YY_BUFFER_STATE yy_scan_string(yyconst char *str) #else -YY_BUFFER_STATE yy_scan_string( str ) +YY_BUFFER_STATE yy_scan_string(str) yyconst char *str; #endif - { +{ int len; - for ( len = 0; str[len]; ++len ) + for (len = 0; str[len]; ++len) ; - return yy_scan_bytes( str, len ); - } + return yy_scan_bytes(str, len); +} #endif #ifndef YY_NO_SCAN_BYTES #ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +YY_BUFFER_STATE yy_scan_bytes(yyconst char *bytes, int len) #else -YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +YY_BUFFER_STATE yy_scan_bytes(bytes, len) yyconst char *bytes; int len; #endif - { +{ YY_BUFFER_STATE b; char *buf; yy_size_t n; @@ -1975,79 +1974,79 @@ int len; /* Get memory for full buffer, including space for trailing EOB's. */ n = len + 2; - buf = (char *) yy_flex_alloc( n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + buf = (char *)yy_flex_alloc(n); + if (!buf) + YY_FATAL_ERROR("out of dynamic memory in yy_scan_bytes()"); - for ( i = 0; i < len; ++i ) + for (i = 0; i < len; ++i) buf[i] = bytes[i]; - buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + buf[len] = buf[len + 1] = YY_END_OF_BUFFER_CHAR; - b = yy_scan_buffer( buf, n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + b = yy_scan_buffer(buf, n); + if (!b) + YY_FATAL_ERROR("bad buffer in yy_scan_bytes()"); /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ + * away when we're done. + */ b->yy_is_our_buffer = 1; return b; - } +} #endif #ifndef YY_NO_PUSH_STATE #ifdef YY_USE_PROTOS -static void yy_push_state( int new_state ) +static void yy_push_state(int new_state) #else -static void yy_push_state( new_state ) +static void yy_push_state(new_state) int new_state; #endif +{ + if (yy_start_stack_ptr >= yy_start_stack_depth) { - if ( yy_start_stack_ptr >= yy_start_stack_depth ) - { yy_size_t new_size; yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yy_start_stack_depth * sizeof( int ); + new_size = yy_start_stack_depth * sizeof(int); - if ( ! yy_start_stack ) - yy_start_stack = (int *) yy_flex_alloc( new_size ); + if (!yy_start_stack) + yy_start_stack = (int *)yy_flex_alloc(new_size); else - yy_start_stack = (int *) yy_flex_realloc( - (void *) yy_start_stack, new_size ); + yy_start_stack = (int *)yy_flex_realloc( + (void *)yy_start_stack, new_size); - if ( ! yy_start_stack ) + if (!yy_start_stack) YY_FATAL_ERROR( - "out of memory expanding start-condition stack" ); - } + "out of memory expanding start-condition stack"); + } yy_start_stack[yy_start_stack_ptr++] = YY_START; BEGIN(new_state); - } +} #endif #ifndef YY_NO_POP_STATE static void yy_pop_state() - { - if ( --yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); +{ + if (--yy_start_stack_ptr < 0) + YY_FATAL_ERROR("start-condition stack underflow"); BEGIN(yy_start_stack[yy_start_stack_ptr]); - } +} #endif #ifndef YY_NO_TOP_STATE static int yy_top_state() - { +{ return yy_start_stack[yy_start_stack_ptr - 1]; - } +} #endif #ifndef YY_EXIT_FAILURE @@ -2055,15 +2054,15 @@ static int yy_top_state() #endif #ifdef YY_USE_PROTOS -static void yy_fatal_error( yyconst char msg[] ) +static void yy_fatal_error(yyconst char msg[]) #else -static void yy_fatal_error( msg ) +static void yy_fatal_error(msg) char msg[]; #endif - { - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); - } +{ + (void)fprintf(stderr, "%s\n", msg); + exit(YY_EXIT_FAILURE); +} @@ -2071,81 +2070,81 @@ char msg[]; #undef yyless #define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - yytext[yyleng] = yy_hold_char; \ - yy_c_buf_p = yytext + n - YY_MORE_ADJ; \ - yy_hold_char = *yy_c_buf_p; \ - *yy_c_buf_p = '\0'; \ - yyleng = n; \ - } \ - while ( 0 ) + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n - YY_MORE_ADJ; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) /* Internal utility routines. */ #ifndef yytext_ptr #ifdef YY_USE_PROTOS -static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +static void yy_flex_strncpy(char *s1, yyconst char *s2, int n) #else -static void yy_flex_strncpy( s1, s2, n ) +static void yy_flex_strncpy(s1, s2, n) char *s1; yyconst char *s2; int n; #endif - { - int i; - for ( i = 0; i < n; ++i ) +{ + register int i; + for (i = 0; i < n; ++i) s1[i] = s2[i]; - } +} #endif #ifdef YY_USE_PROTOS -static void *yy_flex_alloc( yy_size_t size ) +static void *yy_flex_alloc(yy_size_t size) #else -static void *yy_flex_alloc( size ) +static void *yy_flex_alloc(size) yy_size_t size; #endif - { - return (void *) malloc( size ); - } +{ + return (void *)malloc(size); +} #ifdef YY_USE_PROTOS -static void *yy_flex_realloc( void *ptr, yy_size_t size ) +static void *yy_flex_realloc(void *ptr, yy_size_t size) #else -static void *yy_flex_realloc( ptr, size ) +static void *yy_flex_realloc(ptr, size) void *ptr; yy_size_t size; #endif - { +{ /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); - } + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *)realloc((char *)ptr, size); +} #ifdef YY_USE_PROTOS -static void yy_flex_free( void *ptr ) +static void yy_flex_free(void *ptr) #else -static void yy_flex_free( ptr ) +static void yy_flex_free(ptr) void *ptr; #endif - { - free( ptr ); - } +{ + free(ptr); +} #if YY_MAIN int main() - { +{ yylex(); return 0; - } +} #endif #line 222 "CMDscan.l" @@ -2173,59 +2172,59 @@ void CMDerror(char *format, ...) const int BUFMAX = 1024; char tempBuf[BUFMAX]; va_list args; - va_start( args, format ); + va_start(args, format); #ifdef TORQUE_OS_WIN - _vsnprintf( tempBuf, BUFMAX, format, args ); + _vsnprintf(tempBuf, BUFMAX, format, args); #else - vsnprintf( tempBuf, BUFMAX, format, args ); + vsnprintf(tempBuf, BUFMAX, format, args); #endif - va_end(args); + va_end(args); - if(fileName) + if (fileName) { Con::errorf(ConsoleLogEntry::Script, "%s Line: %d - %s", fileName, lineIndex, tempBuf); #ifndef NO_ADVANCED_ERROR_REPORT // dhc - lineIndex is bogus. let's try to add some sanity back in. - int i,j,n; + int i, j, n; char c; int linediv = 1; // first, walk the buffer, trying to detect line ending type. // this is imperfect, if inconsistant line endings exist... - for (i=0; iBUFMAX>>2) break; // at least get a little data + c = scanBuffer[scanIndex - i]; + if ((c == '\r' || c == '\n') && i>BUFMAX >> 2) break; // at least get a little data n++; i++; } // find next lineending - while (n>1) // cap at half-buf-size forward + while (n>1) // cap at half-buf-size forward { - c = scanBuffer[scanIndex+j]; - if (c==0) break; - if ((c=='\r' || c=='\n') && j>BUFMAX>>2) break; // at least get a little data + c = scanBuffer[scanIndex + j]; + if (c == 0) break; + if ((c == '\r' || c == '\n') && j>BUFMAX >> 2) break; // at least get a little data n++; j++; } if (i) i--; // chop off extra linefeed. if (j) j--; // chop off extra linefeed. - // build our little text block - if (i) dStrncpy(tempBuf,scanBuffer+scanIndex-i,i); - dStrncpy(tempBuf+i,"##", 2); // bracketing. - tempBuf[i+2] = scanBuffer[scanIndex]; // copy the halt character. - dStrncpy(tempBuf+i+3,"##", 2); // bracketing. - if (j) dStrncpy(tempBuf+i+5,scanBuffer+scanIndex+1,j); // +1 to go past current char. - tempBuf[i+j+5] = 0; // null terminate - for(n=0; n>> Advanced script error report. Line %d.", lineIndex); Con::warnf(ConsoleLogEntry::Script, ">>> Some error context, with ## on sides of error halt:"); @@ -2242,7 +2241,7 @@ void CMDerror(char *format, ...) Con::setVariable("$ScriptError", tempBuf); // We also need to mark that we came up with a new error. - static S32 sScriptErrorHash=1000; + static S32 sScriptErrorHash = 1000; Con::setIntVariable("$ScriptErrorHash", sScriptErrorHash++); } else @@ -2260,7 +2259,7 @@ void CMDSetScanBuffer(const char *sb, const char *fn) int CMDgetc() { int ret = scanBuffer[scanIndex]; - if(ret) + if (ret) scanIndex++; else ret = -1; @@ -2278,13 +2277,13 @@ static int Sc_ScanVar() CMDtext[CMDleng] = 0; // Make it a stringtable string! - CMDlval.s = MakeToken< StringTableEntry >( StringTable->insert(CMDtext), lineIndex ); + CMDlval.s = MakeToken< StringTableEntry >(StringTable->insert(CMDtext), lineIndex); return(VAR); } static int charConv(int in) { - switch(in) + switch (in) { case 'r': return '\r'; @@ -2299,11 +2298,11 @@ static int charConv(int in) static int getHexDigit(char c) { - if(c >= '0' && c <= '9') + if (c >= '0' && c <= '9') return c - '0'; - if(c >= 'A' && c <= 'F') + if (c >= 'A' && c <= 'F') return c - 'A' + 10; - if(c >= 'a' && c <= 'f') + if (c >= 'a' && c <= 'f') return c - 'a' + 10; return -1; } @@ -2311,40 +2310,40 @@ static int getHexDigit(char c) static int Sc_ScanDocBlock() { S32 len = dStrlen(CMDtext); - char* text = (char *) consoleAlloc(len + 1); + char* text = (char *)consoleAlloc(len + 1); S32 line = lineIndex; - for( S32 i = 0, j = 0; j <= len; j++ ) + for (S32 i = 0, j = 0; j <= len; j++) { - if( ( j <= (len - 2) ) && ( CMDtext[j] == '/' ) && ( CMDtext[j + 1] == '/' ) && ( CMDtext[j + 2] == '/' ) ) + if ((j <= (len - 2)) && (CMDtext[j] == '/') && (CMDtext[j + 1] == '/') && (CMDtext[j + 2] == '/')) { j += 2; continue; } - if( CMDtext[j] == '\r' ) + if (CMDtext[j] == '\r') continue; - if( CMDtext[j] == '\n' ) + if (CMDtext[j] == '\n') lineIndex++; text[i++] = CMDtext[j]; } - CMDlval.str = MakeToken< char* >( text, line ); + CMDlval.str = MakeToken< char* >(text, line); return(DOCBLOCK); } static int Sc_ScanString(int ret) { CMDtext[CMDleng - 1] = 0; - if(!collapseEscape(CMDtext+1)) + if (!collapseEscape(CMDtext + 1)) return -1; - - char* buffer = ( char* ) consoleAlloc( dStrlen( CMDtext ) ); - dStrcpy( buffer, CMDtext + 1 ); - - CMDlval.str = MakeToken< char* >( buffer, lineIndex ); + + char* buffer = (char*)consoleAlloc(dStrlen(CMDtext)); + dStrcpy(buffer, CMDtext + 1); + + CMDlval.str = MakeToken< char* >(buffer, lineIndex); return ret; } @@ -2354,96 +2353,96 @@ static int Sc_ScanIdent() CMDtext[CMDleng] = 0; - if((type = ConsoleBaseType::getTypeByName(CMDtext)) != NULL) + if ((type = ConsoleBaseType::getTypeByName(CMDtext)) != NULL) { /* It's a type */ - CMDlval.i = MakeToken< int >( type->getTypeID(), lineIndex ); + CMDlval.i = MakeToken< int >(type->getTypeID(), lineIndex); return TYPEIDENT; } /* It's an identifier */ - CMDlval.s = MakeToken< StringTableEntry >( StringTable->insert(CMDtext), lineIndex ); + CMDlval.s = MakeToken< StringTableEntry >(StringTable->insert(CMDtext), lineIndex); return IDENT; } void expandEscape(char *dest, const char *src) { U8 c; - while((c = (U8) *src++) != 0) + while ((c = (U8)*src++) != 0) { - if(c == '\"') + if (c == '\"') { *dest++ = '\\'; *dest++ = '\"'; } - else if(c == '\\') + else if (c == '\\') { *dest++ = '\\'; *dest++ = '\\'; } - else if(c == '\r') + else if (c == '\r') { *dest++ = '\\'; *dest++ = 'r'; } - else if(c == '\n') + else if (c == '\n') { *dest++ = '\\'; *dest++ = 'n'; } - else if(c == '\t') + else if (c == '\t') { *dest++ = '\\'; *dest++ = 't'; } - else if(c == '\'') + else if (c == '\'') { *dest++ = '\\'; *dest++ = '\''; } - else if((c >= 1 && c <= 7) || - (c >= 11 && c <= 12) || - (c >= 14 && c <= 15)) + else if ((c >= 1 && c <= 7) || + (c >= 11 && c <= 12) || + (c >= 14 && c <= 15)) { - /* Remap around: \b = 0x8, \t = 0x9, \n = 0xa, \r = 0xd */ - static U8 expandRemap[15] = { 0x0, - 0x0, - 0x1, - 0x2, - 0x3, - 0x4, - 0x5, - 0x6, - 0x0, - 0x0, - 0x0, - 0x7, - 0x8, - 0x0, - 0x9 }; + /* Remap around: \b = 0x8, \t = 0x9, \n = 0xa, \r = 0xd */ + static U8 expandRemap[15] = { 0x0, + 0x0, + 0x1, + 0x2, + 0x3, + 0x4, + 0x5, + 0x6, + 0x0, + 0x0, + 0x0, + 0x7, + 0x8, + 0x0, + 0x9 }; *dest++ = '\\'; *dest++ = 'c'; - if(c == 15) + if (c == 15) *dest++ = 'r'; - else if(c == 16) + else if (c == 16) *dest++ = 'p'; - else if(c == 17) + else if (c == 17) *dest++ = 'o'; else *dest++ = expandRemap[c] + '0'; } - else if(c < 32) + else if (c < 32) { *dest++ = '\\'; *dest++ = 'x'; S32 dig1 = c >> 4; S32 dig2 = c & 0xf; - if(dig1 < 10) + if (dig1 < 10) dig1 += '0'; else dig1 += 'A' - 10; - if(dig2 < 10) + if (dig2 < 10) dig2 += '0'; else dig2 += 'A' - 10; @@ -2459,56 +2458,56 @@ void expandEscape(char *dest, const char *src) bool collapseEscape(char *buf) { S32 len = dStrlen(buf) + 1; - for(S32 i = 0; i < len;) + for (S32 i = 0; i < len;) { - if(buf[i] == '\\') + if (buf[i] == '\\') { - if(buf[i+1] == 'x') + if (buf[i + 1] == 'x') { - S32 dig1 = getHexDigit(buf[i+2]); - if(dig1 == -1) + S32 dig1 = getHexDigit(buf[i + 2]); + if (dig1 == -1) return false; - S32 dig2 = getHexDigit(buf[i+3]); - if(dig2 == -1) + S32 dig2 = getHexDigit(buf[i + 3]); + if (dig2 == -1) return false; buf[i] = dig1 * 16 + dig2; dMemmove(buf + i + 1, buf + i + 4, len - i - 3); len -= 3; i++; } - else if(buf[i+1] == 'c') + else if (buf[i + 1] == 'c') { /* Remap around: \b = 0x8, \t = 0x9, \n = 0xa, \r = 0xd */ static U8 collapseRemap[10] = { 0x1, - 0x2, - 0x3, - 0x4, - 0x5, - 0x6, - 0x7, - 0xb, - 0xc, - 0xe }; + 0x2, + 0x3, + 0x4, + 0x5, + 0x6, + 0x7, + 0xb, + 0xc, + 0xe }; - if(buf[i+2] == 'r') - buf[i] = 15; - else if(buf[i+2] == 'p') + if (buf[i + 2] == 'r') + buf[i] = 15; + else if (buf[i + 2] == 'p') buf[i] = 16; - else if(buf[i+2] == 'o') + else if (buf[i + 2] == 'o') buf[i] = 17; else { - int dig1 = buf[i+2] - '0'; - if(dig1 < 0 || dig1 > 9) - return false; - buf[i] = collapseRemap[dig1]; + int dig1 = buf[i + 2] - '0'; + if (dig1 < 0 || dig1 > 9) + return false; + buf[i] = collapseRemap[dig1]; } // Make sure we don't put 0x1 at the beginning of the string. if ((buf[i] == 0x1) && (i == 0)) { buf[i] = 0x2; - buf[i+1] = 0x1; + buf[i + 1] = 0x1; dMemmove(buf + i + 2, buf + i + 3, len - i - 1); len -= 1; } @@ -2521,7 +2520,7 @@ bool collapseEscape(char *buf) } else { - buf[i] = charConv(buf[i+1]); + buf[i] = charConv(buf[i + 1]); dMemmove(buf + i + 1, buf + i + 2, len - i - 1); len--; i++; @@ -2536,7 +2535,7 @@ bool collapseEscape(char *buf) static int Sc_ScanNum() { CMDtext[CMDleng] = 0; - CMDlval.f = MakeToken< double >( dAtof(CMDtext), lineIndex ); + CMDlval.f = MakeToken< double >(dAtof(CMDtext), lineIndex); return(FLTCONST); } @@ -2544,7 +2543,7 @@ static int Sc_ScanHex() { S32 val = 0; dSscanf(CMDtext, "%x", &val); - CMDlval.i = MakeToken< int >( val, lineIndex ); + CMDlval.i = MakeToken< int >(val, lineIndex); return INTCONST; } diff --git a/Engine/source/console/ast.h b/Engine/source/console/ast.h index f1327a75a..65b20a926 100644 --- a/Engine/source/console/ast.h +++ b/Engine/source/console/ast.h @@ -56,7 +56,7 @@ struct StmtNode StmtNode(); virtual ~StmtNode() {} - + /// @name next Accessors /// @{ @@ -99,17 +99,17 @@ struct StmtNode struct BreakStmtNode : StmtNode { - static BreakStmtNode *alloc( S32 lineNumber ); + static BreakStmtNode *alloc(S32 lineNumber); + - U32 compileStmt(CodeStream &codeStream, U32 ip); DBG_STMT_TYPE(BreakStmtNode); }; struct ContinueStmtNode : StmtNode { - static ContinueStmtNode *alloc( S32 lineNumber ); - + static ContinueStmtNode *alloc(S32 lineNumber); + U32 compileStmt(CodeStream &codeStream, U32 ip); DBG_STMT_TYPE(ContinueStmtNode); }; @@ -117,7 +117,7 @@ struct ContinueStmtNode : StmtNode /// A mathematical expression. struct ExprNode : StmtNode { - + U32 compileStmt(CodeStream &codeStream, U32 ip); virtual U32 compile(CodeStream &codeStream, U32 ip, TypeReq type) = 0; @@ -128,8 +128,8 @@ struct ReturnStmtNode : StmtNode { ExprNode *expr; - static ReturnStmtNode *alloc( S32 lineNumber, ExprNode *expr ); - + static ReturnStmtNode *alloc(S32 lineNumber, ExprNode *expr); + U32 compileStmt(CodeStream &codeStream, U32 ip); DBG_STMT_TYPE(ReturnStmtNode); }; @@ -143,10 +143,10 @@ struct IfStmtNode : StmtNode bool integer; bool propagate; - static IfStmtNode *alloc( S32 lineNumber, ExprNode *testExpr, StmtNode *ifBlock, StmtNode *elseBlock, bool propagateThrough ); + static IfStmtNode *alloc(S32 lineNumber, ExprNode *testExpr, StmtNode *ifBlock, StmtNode *elseBlock, bool propagateThrough); void propagateSwitchExpr(ExprNode *left, bool string); ExprNode *getSwitchOR(ExprNode *left, ExprNode *list, bool string); - + U32 compileStmt(CodeStream &codeStream, U32 ip); DBG_STMT_TYPE(IfStmtNode); }; @@ -163,8 +163,8 @@ struct LoopStmtNode : StmtNode U32 loopBlockStartOffset; bool integer; - static LoopStmtNode *alloc( S32 lineNumber, ExprNode *testExpr, ExprNode *initExpr, ExprNode *endLoopExpr, StmtNode *loopBlock, bool isDoLoop ); - + static LoopStmtNode *alloc(S32 lineNumber, ExprNode *testExpr, ExprNode *initExpr, ExprNode *endLoopExpr, StmtNode *loopBlock, bool isDoLoop); + U32 compileStmt(CodeStream &codeStream, U32 ip); DBG_STMT_TYPE(LoopStmtNode); }; @@ -174,22 +174,22 @@ struct IterStmtNode : StmtNode { /// Local variable name to use for the container element. StringTableEntry varName; - + /// Expression evaluating to a SimSet object. ExprNode* containerExpr; - + /// The statement body. StmtNode* body; - + /// If true, this is a 'foreach$'. bool isStringIter; - + /// Bytecode size of body statement. Set by precompileStmt. U32 bodySize; - - static IterStmtNode* alloc( S32 lineNumber, StringTableEntry varName, ExprNode* containerExpr, StmtNode* body, bool isStringIter ); - - U32 compileStmt( CodeStream &codeStream, U32 ip ); + + static IterStmtNode* alloc(S32 lineNumber, StringTableEntry varName, ExprNode* containerExpr, StmtNode* body, bool isStringIter); + + U32 compileStmt(CodeStream &codeStream, U32 ip); }; /// A binary mathematical expression (ie, left op right). @@ -202,8 +202,8 @@ struct BinaryExprNode : ExprNode struct FloatBinaryExprNode : BinaryExprNode { - static FloatBinaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *left, ExprNode *right ); - + static FloatBinaryExprNode *alloc(S32 lineNumber, S32 op, ExprNode *left, ExprNode *right); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(FloatBinaryExprNode); @@ -215,8 +215,8 @@ struct ConditionalExprNode : ExprNode ExprNode *trueExpr; ExprNode *falseExpr; bool integer; - static ConditionalExprNode *alloc( S32 lineNumber, ExprNode *testExpr, ExprNode *trueExpr, ExprNode *falseExpr ); - + static ConditionalExprNode *alloc(S32 lineNumber, ExprNode *testExpr, ExprNode *trueExpr, ExprNode *falseExpr); + virtual U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); virtual TypeReq getPreferredType(); DBG_STMT_TYPE(ConditionalExprNode); @@ -227,10 +227,10 @@ struct IntBinaryExprNode : BinaryExprNode TypeReq subType; U32 operand; - static IntBinaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *left, ExprNode *right ); + static IntBinaryExprNode *alloc(S32 lineNumber, S32 op, ExprNode *left, ExprNode *right); void getSubTypeOperand(); - + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(IntBinaryExprNode); @@ -239,8 +239,8 @@ struct IntBinaryExprNode : BinaryExprNode struct StreqExprNode : BinaryExprNode { bool eq; - static StreqExprNode *alloc( S32 lineNumber, ExprNode *left, ExprNode *right, bool eq ); - + static StreqExprNode *alloc(S32 lineNumber, ExprNode *left, ExprNode *right, bool eq); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(StreqExprNode); @@ -249,8 +249,8 @@ struct StreqExprNode : BinaryExprNode struct StrcatExprNode : BinaryExprNode { S32 appendChar; - static StrcatExprNode *alloc( S32 lineNumber, ExprNode *left, ExprNode *right, S32 appendChar ); - + static StrcatExprNode *alloc(S32 lineNumber, ExprNode *left, ExprNode *right, S32 appendChar); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(StrcatExprNode); @@ -258,9 +258,9 @@ struct StrcatExprNode : BinaryExprNode struct CommaCatExprNode : BinaryExprNode { - static CommaCatExprNode *alloc( S32 lineNumber, ExprNode *left, ExprNode *right ); + static CommaCatExprNode *alloc(S32 lineNumber, ExprNode *left, ExprNode *right); + - U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(CommaCatExprNode); @@ -272,8 +272,8 @@ struct IntUnaryExprNode : ExprNode ExprNode *expr; bool integer; - static IntUnaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *expr ); - + static IntUnaryExprNode *alloc(S32 lineNumber, S32 op, ExprNode *expr); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(IntUnaryExprNode); @@ -284,8 +284,8 @@ struct FloatUnaryExprNode : ExprNode S32 op; ExprNode *expr; - static FloatUnaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *expr ); - + static FloatUnaryExprNode *alloc(S32 lineNumber, S32 op, ExprNode *expr); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(FloatUnaryExprNode); @@ -296,8 +296,8 @@ struct VarNode : ExprNode StringTableEntry varName; ExprNode *arrayIndex; - static VarNode *alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex ); - + static VarNode *alloc(S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(VarNode); @@ -308,8 +308,8 @@ struct IntNode : ExprNode S32 value; U32 index; // if it's converted to float/string - static IntNode *alloc( S32 lineNumber, S32 value ); - + static IntNode *alloc(S32 lineNumber, S32 value); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(IntNode); @@ -320,8 +320,8 @@ struct FloatNode : ExprNode F64 value; U32 index; - static FloatNode *alloc( S32 lineNumber, F64 value ); - + static FloatNode *alloc(S32 lineNumber, F64 value); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(FloatNode); @@ -335,8 +335,8 @@ struct StrConstNode : ExprNode bool tag; bool doc; // Specifies that this string is a documentation block. - static StrConstNode *alloc( S32 lineNumber, char *str, bool tag, bool doc = false ); - + static StrConstNode *alloc(S32 lineNumber, char *str, bool tag, bool doc = false); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(StrConstNode); @@ -348,8 +348,8 @@ struct ConstantNode : ExprNode F64 fVal; U32 index; - static ConstantNode *alloc( S32 lineNumber, StringTableEntry value ); - + static ConstantNode *alloc(S32 lineNumber, StringTableEntry value); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(ConstantNode); @@ -362,8 +362,8 @@ struct AssignExprNode : ExprNode ExprNode *arrayIndex; TypeReq subType; - static AssignExprNode *alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr ); - + static AssignExprNode *alloc(S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(AssignExprNode); @@ -386,8 +386,8 @@ struct AssignOpExprNode : ExprNode U32 operand; TypeReq subType; - static AssignOpExprNode *alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr, S32 op ); - + static AssignOpExprNode *alloc(S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr, S32 op); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(AssignOpExprNode); @@ -399,8 +399,8 @@ struct TTagSetStmtNode : StmtNode ExprNode *valueExpr; ExprNode *stringExpr; - static TTagSetStmtNode *alloc( S32 lineNumber, StringTableEntry tag, ExprNode *valueExpr, ExprNode *stringExpr ); - + static TTagSetStmtNode *alloc(S32 lineNumber, StringTableEntry tag, ExprNode *valueExpr, ExprNode *stringExpr); + U32 compileStmt(CodeStream &codeStream, U32 ip); DBG_STMT_TYPE(TTagSetStmtNode); }; @@ -409,8 +409,8 @@ struct TTagDerefNode : ExprNode { ExprNode *expr; - static TTagDerefNode *alloc( S32 lineNumber, ExprNode *expr ); - + static TTagDerefNode *alloc(S32 lineNumber, ExprNode *expr); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(TTagDerefNode); @@ -420,8 +420,8 @@ struct TTagExprNode : ExprNode { StringTableEntry tag; - static TTagExprNode *alloc( S32 lineNumber, StringTableEntry tag ); - + static TTagExprNode *alloc(S32 lineNumber, StringTableEntry tag); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(TTagExprNode); @@ -439,21 +439,33 @@ struct FuncCallExprNode : ExprNode ParentCall }; - static FuncCallExprNode *alloc( S32 lineNumber, StringTableEntry funcName, StringTableEntry nameSpace, ExprNode *args, bool dot ); - + static FuncCallExprNode *alloc(S32 lineNumber, StringTableEntry funcName, StringTableEntry nameSpace, ExprNode *args, bool dot); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(FuncCallExprNode); }; +struct FuncPointerCallExprNode : ExprNode +{ + ExprNode *funcPointer; + ExprNode *args; + + static FuncPointerCallExprNode *alloc(S32 lineNumber, ExprNode *stmt, ExprNode *args); + + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); + TypeReq getPreferredType(); + DBG_STMT_TYPE(FuncPointerCallExprNode); +}; + struct AssertCallExprNode : ExprNode { ExprNode *testExpr; const char *message; U32 messageIndex; - static AssertCallExprNode *alloc( S32 lineNumber, ExprNode *testExpr, const char *message ); - + static AssertCallExprNode *alloc(S32 lineNumber, ExprNode *testExpr, const char *message); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(AssertCallExprNode); @@ -472,8 +484,8 @@ struct SlotAccessNode : ExprNode ExprNode *objectExpr, *arrayExpr; StringTableEntry slotName; - static SlotAccessNode *alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName ); - + static SlotAccessNode *alloc(S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(SlotAccessNode); @@ -492,8 +504,8 @@ struct InternalSlotAccessNode : ExprNode ExprNode *objectExpr, *slotExpr; bool recurse; - static InternalSlotAccessNode *alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *slotExpr, bool recurse ); - + static InternalSlotAccessNode *alloc(S32 lineNumber, ExprNode *objectExpr, ExprNode *slotExpr, bool recurse); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(InternalSlotAccessNode); @@ -506,8 +518,8 @@ struct SlotAssignNode : ExprNode ExprNode *valueExpr; U32 typeID; - static SlotAssignNode *alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName, ExprNode *valueExpr, U32 typeID = -1 ); - + static SlotAssignNode *alloc(S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName, ExprNode *valueExpr, U32 typeID = -1); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(SlotAssignNode); @@ -522,8 +534,8 @@ struct SlotAssignOpNode : ExprNode U32 operand; TypeReq subType; - static SlotAssignOpNode *alloc( S32 lineNumber, ExprNode *objectExpr, StringTableEntry slotName, ExprNode *arrayExpr, S32 op, ExprNode *valueExpr ); - + static SlotAssignOpNode *alloc(S32 lineNumber, ExprNode *objectExpr, StringTableEntry slotName, ExprNode *arrayExpr, S32 op, ExprNode *valueExpr); + U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); TypeReq getPreferredType(); DBG_STMT_TYPE(SlotAssignOpNode); @@ -542,8 +554,8 @@ struct ObjectDeclNode : ExprNode bool isClassNameInternal; bool isSingleton; - static ObjectDeclNode *alloc( S32 lineNumber, ExprNode *classNameExpr, ExprNode *objectNameExpr, ExprNode *argList, StringTableEntry parentObject, SlotAssignNode *slotDecls, ObjectDeclNode *subObjects, bool isDatablock, bool classNameInternal, bool isSingleton ); - + static ObjectDeclNode *alloc(S32 lineNumber, ExprNode *classNameExpr, ExprNode *objectNameExpr, ExprNode *argList, StringTableEntry parentObject, SlotAssignNode *slotDecls, ObjectDeclNode *subObjects, bool isDatablock, bool classNameInternal, bool isSingleton); + U32 precompileSubObject(bool); U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compileSubObject(CodeStream &codeStream, U32 ip, bool); @@ -567,8 +579,8 @@ struct FunctionDeclStmtNode : StmtNode U32 endOffset; U32 argc; - static FunctionDeclStmtNode *alloc( S32 lineNumber, StringTableEntry fnName, StringTableEntry nameSpace, VarNode *args, StmtNode *stmts ); - + static FunctionDeclStmtNode *alloc(S32 lineNumber, StringTableEntry fnName, StringTableEntry nameSpace, VarNode *args, StmtNode *stmts); + U32 compileStmt(CodeStream &codeStream, U32 ip); void setPackage(StringTableEntry packageName); DBG_STMT_TYPE(FunctionDeclStmtNode); diff --git a/Engine/source/console/astAlloc.cpp b/Engine/source/console/astAlloc.cpp index fb69f49d5..75fbe151c 100644 --- a/Engine/source/console/astAlloc.cpp +++ b/Engine/source/console/astAlloc.cpp @@ -38,25 +38,25 @@ using namespace Compiler; //------------------------------------------------------------ -BreakStmtNode *BreakStmtNode::alloc( S32 lineNumber ) +BreakStmtNode *BreakStmtNode::alloc(S32 lineNumber) { - BreakStmtNode *ret = (BreakStmtNode *) consoleAlloc(sizeof(BreakStmtNode)); + BreakStmtNode *ret = (BreakStmtNode *)consoleAlloc(sizeof(BreakStmtNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; return ret; } -ContinueStmtNode *ContinueStmtNode::alloc( S32 lineNumber ) +ContinueStmtNode *ContinueStmtNode::alloc(S32 lineNumber) { - ContinueStmtNode *ret = (ContinueStmtNode *) consoleAlloc(sizeof(ContinueStmtNode)); + ContinueStmtNode *ret = (ContinueStmtNode *)consoleAlloc(sizeof(ContinueStmtNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; return ret; } -ReturnStmtNode *ReturnStmtNode::alloc( S32 lineNumber, ExprNode *expr) +ReturnStmtNode *ReturnStmtNode::alloc(S32 lineNumber, ExprNode *expr) { - ReturnStmtNode *ret = (ReturnStmtNode *) consoleAlloc(sizeof(ReturnStmtNode)); + ReturnStmtNode *ret = (ReturnStmtNode *)consoleAlloc(sizeof(ReturnStmtNode)); constructInPlace(ret); ret->expr = expr; ret->dbgLineNumber = lineNumber; @@ -64,9 +64,9 @@ ReturnStmtNode *ReturnStmtNode::alloc( S32 lineNumber, ExprNode *expr) return ret; } -IfStmtNode *IfStmtNode::alloc( S32 lineNumber, ExprNode *testExpr, StmtNode *ifBlock, StmtNode *elseBlock, bool propagate ) +IfStmtNode *IfStmtNode::alloc(S32 lineNumber, ExprNode *testExpr, StmtNode *ifBlock, StmtNode *elseBlock, bool propagate) { - IfStmtNode *ret = (IfStmtNode *) consoleAlloc(sizeof(IfStmtNode)); + IfStmtNode *ret = (IfStmtNode *)consoleAlloc(sizeof(IfStmtNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; @@ -78,9 +78,9 @@ IfStmtNode *IfStmtNode::alloc( S32 lineNumber, ExprNode *testExpr, StmtNode *ifB return ret; } -LoopStmtNode *LoopStmtNode::alloc( S32 lineNumber, ExprNode *initExpr, ExprNode *testExpr, ExprNode *endLoopExpr, StmtNode *loopBlock, bool isDoLoop ) +LoopStmtNode *LoopStmtNode::alloc(S32 lineNumber, ExprNode *initExpr, ExprNode *testExpr, ExprNode *endLoopExpr, StmtNode *loopBlock, bool isDoLoop) { - LoopStmtNode *ret = (LoopStmtNode *) consoleAlloc(sizeof(LoopStmtNode)); + LoopStmtNode *ret = (LoopStmtNode *)consoleAlloc(sizeof(LoopStmtNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->testExpr = testExpr; @@ -92,28 +92,28 @@ LoopStmtNode *LoopStmtNode::alloc( S32 lineNumber, ExprNode *initExpr, ExprNode // Deal with setting some dummy constant nodes if we weren't provided with // info... This allows us to play nice with missing parts of for(;;) for // instance. - if(!ret->testExpr) ret->testExpr = IntNode::alloc( lineNumber, 1 ); + if (!ret->testExpr) ret->testExpr = IntNode::alloc(lineNumber, 1); return ret; } -IterStmtNode* IterStmtNode::alloc( S32 lineNumber, StringTableEntry varName, ExprNode* containerExpr, StmtNode* body, bool isStringIter ) +IterStmtNode* IterStmtNode::alloc(S32 lineNumber, StringTableEntry varName, ExprNode* containerExpr, StmtNode* body, bool isStringIter) { - IterStmtNode* ret = ( IterStmtNode* ) consoleAlloc( sizeof( IterStmtNode ) ); - constructInPlace( ret ); - + IterStmtNode* ret = (IterStmtNode*)consoleAlloc(sizeof(IterStmtNode)); + constructInPlace(ret); + ret->dbgLineNumber = lineNumber; ret->varName = varName; ret->containerExpr = containerExpr; ret->body = body; ret->isStringIter = isStringIter; - + return ret; } -FloatBinaryExprNode *FloatBinaryExprNode::alloc( S32 lineNumber, S32 op, ExprNode *left, ExprNode *right ) +FloatBinaryExprNode *FloatBinaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode *left, ExprNode *right) { - FloatBinaryExprNode *ret = (FloatBinaryExprNode *) consoleAlloc(sizeof(FloatBinaryExprNode)); + FloatBinaryExprNode *ret = (FloatBinaryExprNode *)consoleAlloc(sizeof(FloatBinaryExprNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; @@ -124,9 +124,9 @@ FloatBinaryExprNode *FloatBinaryExprNode::alloc( S32 lineNumber, S32 op, ExprNod return ret; } -IntBinaryExprNode *IntBinaryExprNode::alloc( S32 lineNumber, S32 op, ExprNode *left, ExprNode *right ) +IntBinaryExprNode *IntBinaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode *left, ExprNode *right) { - IntBinaryExprNode *ret = (IntBinaryExprNode *) consoleAlloc(sizeof(IntBinaryExprNode)); + IntBinaryExprNode *ret = (IntBinaryExprNode *)consoleAlloc(sizeof(IntBinaryExprNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; @@ -137,9 +137,9 @@ IntBinaryExprNode *IntBinaryExprNode::alloc( S32 lineNumber, S32 op, ExprNode *l return ret; } -StreqExprNode *StreqExprNode::alloc( S32 lineNumber, ExprNode *left, ExprNode *right, bool eq ) +StreqExprNode *StreqExprNode::alloc(S32 lineNumber, ExprNode *left, ExprNode *right, bool eq) { - StreqExprNode *ret = (StreqExprNode *) consoleAlloc(sizeof(StreqExprNode)); + StreqExprNode *ret = (StreqExprNode *)consoleAlloc(sizeof(StreqExprNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->left = left; @@ -149,9 +149,9 @@ StreqExprNode *StreqExprNode::alloc( S32 lineNumber, ExprNode *left, ExprNode *r return ret; } -StrcatExprNode *StrcatExprNode::alloc( S32 lineNumber, ExprNode *left, ExprNode *right, S32 appendChar ) +StrcatExprNode *StrcatExprNode::alloc(S32 lineNumber, ExprNode *left, ExprNode *right, S32 appendChar) { - StrcatExprNode *ret = (StrcatExprNode *) consoleAlloc(sizeof(StrcatExprNode)); + StrcatExprNode *ret = (StrcatExprNode *)consoleAlloc(sizeof(StrcatExprNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->left = left; @@ -161,9 +161,9 @@ StrcatExprNode *StrcatExprNode::alloc( S32 lineNumber, ExprNode *left, ExprNode return ret; } -CommaCatExprNode *CommaCatExprNode::alloc( S32 lineNumber, ExprNode *left, ExprNode *right ) +CommaCatExprNode *CommaCatExprNode::alloc(S32 lineNumber, ExprNode *left, ExprNode *right) { - CommaCatExprNode *ret = (CommaCatExprNode *) consoleAlloc(sizeof(CommaCatExprNode)); + CommaCatExprNode *ret = (CommaCatExprNode *)consoleAlloc(sizeof(CommaCatExprNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->left = left; @@ -172,9 +172,9 @@ CommaCatExprNode *CommaCatExprNode::alloc( S32 lineNumber, ExprNode *left, ExprN return ret; } -IntUnaryExprNode *IntUnaryExprNode::alloc( S32 lineNumber, S32 op, ExprNode *expr ) +IntUnaryExprNode *IntUnaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode *expr) { - IntUnaryExprNode *ret = (IntUnaryExprNode *) consoleAlloc(sizeof(IntUnaryExprNode)); + IntUnaryExprNode *ret = (IntUnaryExprNode *)consoleAlloc(sizeof(IntUnaryExprNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->op = op; @@ -182,9 +182,9 @@ IntUnaryExprNode *IntUnaryExprNode::alloc( S32 lineNumber, S32 op, ExprNode *exp return ret; } -FloatUnaryExprNode *FloatUnaryExprNode::alloc( S32 lineNumber, S32 op, ExprNode *expr ) +FloatUnaryExprNode *FloatUnaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode *expr) { - FloatUnaryExprNode *ret = (FloatUnaryExprNode *) consoleAlloc(sizeof(FloatUnaryExprNode)); + FloatUnaryExprNode *ret = (FloatUnaryExprNode *)consoleAlloc(sizeof(FloatUnaryExprNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->op = op; @@ -192,9 +192,9 @@ FloatUnaryExprNode *FloatUnaryExprNode::alloc( S32 lineNumber, S32 op, ExprNode return ret; } -VarNode *VarNode::alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex ) +VarNode *VarNode::alloc(S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex) { - VarNode *ret = (VarNode *) consoleAlloc(sizeof(VarNode)); + VarNode *ret = (VarNode *)consoleAlloc(sizeof(VarNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->varName = varName; @@ -202,18 +202,18 @@ VarNode *VarNode::alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arr return ret; } -IntNode *IntNode::alloc( S32 lineNumber, S32 value ) +IntNode *IntNode::alloc(S32 lineNumber, S32 value) { - IntNode *ret = (IntNode *) consoleAlloc(sizeof(IntNode)); + IntNode *ret = (IntNode *)consoleAlloc(sizeof(IntNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->value = value; return ret; } -ConditionalExprNode *ConditionalExprNode::alloc( S32 lineNumber, ExprNode *testExpr, ExprNode *trueExpr, ExprNode *falseExpr ) +ConditionalExprNode *ConditionalExprNode::alloc(S32 lineNumber, ExprNode *testExpr, ExprNode *trueExpr, ExprNode *falseExpr) { - ConditionalExprNode *ret = (ConditionalExprNode *) consoleAlloc(sizeof(ConditionalExprNode)); + ConditionalExprNode *ret = (ConditionalExprNode *)consoleAlloc(sizeof(ConditionalExprNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->testExpr = testExpr; @@ -223,22 +223,22 @@ ConditionalExprNode *ConditionalExprNode::alloc( S32 lineNumber, ExprNode *testE return ret; } -FloatNode *FloatNode::alloc( S32 lineNumber, F64 value ) +FloatNode *FloatNode::alloc(S32 lineNumber, F64 value) { - FloatNode *ret = (FloatNode *) consoleAlloc(sizeof(FloatNode)); + FloatNode *ret = (FloatNode *)consoleAlloc(sizeof(FloatNode)); constructInPlace(ret); - + ret->dbgLineNumber = lineNumber; ret->value = value; return ret; } -StrConstNode *StrConstNode::alloc( S32 lineNumber, char *str, bool tag, bool doc ) +StrConstNode *StrConstNode::alloc(S32 lineNumber, char *str, bool tag, bool doc) { - StrConstNode *ret = (StrConstNode *) consoleAlloc(sizeof(StrConstNode)); + StrConstNode *ret = (StrConstNode *)consoleAlloc(sizeof(StrConstNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; - ret->str = (char *) consoleAlloc(dStrlen(str) + 1); + ret->str = (char *)consoleAlloc(dStrlen(str) + 1); ret->tag = tag; ret->doc = doc; dStrcpy(ret->str, str); @@ -246,18 +246,18 @@ StrConstNode *StrConstNode::alloc( S32 lineNumber, char *str, bool tag, bool doc return ret; } -ConstantNode *ConstantNode::alloc( S32 lineNumber, StringTableEntry value ) +ConstantNode *ConstantNode::alloc(S32 lineNumber, StringTableEntry value) { - ConstantNode *ret = (ConstantNode *) consoleAlloc(sizeof(ConstantNode)); + ConstantNode *ret = (ConstantNode *)consoleAlloc(sizeof(ConstantNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->value = value; return ret; } -AssignExprNode *AssignExprNode::alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr ) +AssignExprNode *AssignExprNode::alloc(S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr) { - AssignExprNode *ret = (AssignExprNode *) consoleAlloc(sizeof(AssignExprNode)); + AssignExprNode *ret = (AssignExprNode *)consoleAlloc(sizeof(AssignExprNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->varName = varName; @@ -267,9 +267,9 @@ AssignExprNode *AssignExprNode::alloc( S32 lineNumber, StringTableEntry varName, return ret; } -AssignOpExprNode *AssignOpExprNode::alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr, S32 op ) +AssignOpExprNode *AssignOpExprNode::alloc(S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr, S32 op) { - AssignOpExprNode *ret = (AssignOpExprNode *) consoleAlloc(sizeof(AssignOpExprNode)); + AssignOpExprNode *ret = (AssignOpExprNode *)consoleAlloc(sizeof(AssignOpExprNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->varName = varName; @@ -279,9 +279,9 @@ AssignOpExprNode *AssignOpExprNode::alloc( S32 lineNumber, StringTableEntry varN return ret; } -TTagSetStmtNode *TTagSetStmtNode::alloc( S32 lineNumber, StringTableEntry tag, ExprNode *valueExpr, ExprNode *stringExpr ) +TTagSetStmtNode *TTagSetStmtNode::alloc(S32 lineNumber, StringTableEntry tag, ExprNode *valueExpr, ExprNode *stringExpr) { - TTagSetStmtNode *ret = (TTagSetStmtNode *) consoleAlloc(sizeof(TTagSetStmtNode)); + TTagSetStmtNode *ret = (TTagSetStmtNode *)consoleAlloc(sizeof(TTagSetStmtNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->tag = tag; @@ -290,37 +290,37 @@ TTagSetStmtNode *TTagSetStmtNode::alloc( S32 lineNumber, StringTableEntry tag, E return ret; } -TTagDerefNode *TTagDerefNode::alloc( S32 lineNumber, ExprNode *expr ) +TTagDerefNode *TTagDerefNode::alloc(S32 lineNumber, ExprNode *expr) { - TTagDerefNode *ret = (TTagDerefNode *) consoleAlloc(sizeof(TTagDerefNode)); + TTagDerefNode *ret = (TTagDerefNode *)consoleAlloc(sizeof(TTagDerefNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->expr = expr; return ret; } -TTagExprNode *TTagExprNode::alloc( S32 lineNumber, StringTableEntry tag ) +TTagExprNode *TTagExprNode::alloc(S32 lineNumber, StringTableEntry tag) { - TTagExprNode *ret = (TTagExprNode *) consoleAlloc(sizeof(TTagExprNode)); + TTagExprNode *ret = (TTagExprNode *)consoleAlloc(sizeof(TTagExprNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->tag = tag; return ret; } -FuncCallExprNode *FuncCallExprNode::alloc( S32 lineNumber, StringTableEntry funcName, StringTableEntry nameSpace, ExprNode *args, bool dot ) +FuncCallExprNode *FuncCallExprNode::alloc(S32 lineNumber, StringTableEntry funcName, StringTableEntry nameSpace, ExprNode *args, bool dot) { - FuncCallExprNode *ret = (FuncCallExprNode *) consoleAlloc(sizeof(FuncCallExprNode)); + FuncCallExprNode *ret = (FuncCallExprNode *)consoleAlloc(sizeof(FuncCallExprNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->funcName = funcName; ret->nameSpace = nameSpace; ret->args = args; - if(dot) + if (dot) ret->callType = MethodCall; else { - if(nameSpace && !dStricmp(nameSpace, "Parent")) + if (nameSpace && !dStricmp(nameSpace, "Parent")) ret->callType = ParentCall; else ret->callType = FunctionCall; @@ -328,27 +328,37 @@ FuncCallExprNode *FuncCallExprNode::alloc( S32 lineNumber, StringTableEntry func return ret; } -AssertCallExprNode *AssertCallExprNode::alloc( S32 lineNumber, ExprNode *testExpr, const char *message ) +FuncPointerCallExprNode *FuncPointerCallExprNode::alloc(S32 lineNumber, ExprNode *funcPointer, ExprNode *args) { - #ifdef TORQUE_ENABLE_SCRIPTASSERTS - - AssertCallExprNode *ret = (AssertCallExprNode *) consoleAlloc(sizeof(FuncCallExprNode)); - constructInPlace(ret); - ret->dbgLineNumber = lineNumber; - ret->testExpr = testExpr; - ret->message = message ? message : "TorqueScript assert!"; - return ret; - - #else - - return NULL; - - #endif + FuncPointerCallExprNode *ret = (FuncPointerCallExprNode *)consoleAlloc(sizeof(FuncPointerCallExprNode)); + constructInPlace(ret); + ret->dbgLineNumber = lineNumber; + ret->funcPointer = funcPointer; + ret->args = args; + return ret; } -SlotAccessNode *SlotAccessNode::alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName ) +AssertCallExprNode *AssertCallExprNode::alloc(S32 lineNumber, ExprNode *testExpr, const char *message) { - SlotAccessNode *ret = (SlotAccessNode *) consoleAlloc(sizeof(SlotAccessNode)); +#ifdef TORQUE_ENABLE_SCRIPTASSERTS + + AssertCallExprNode *ret = (AssertCallExprNode *)consoleAlloc(sizeof(FuncCallExprNode)); + constructInPlace(ret); + ret->dbgLineNumber = lineNumber; + ret->testExpr = testExpr; + ret->message = message ? message : "TorqueScript assert!"; + return ret; + +#else + + return NULL; + +#endif +} + +SlotAccessNode *SlotAccessNode::alloc(S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName) +{ + SlotAccessNode *ret = (SlotAccessNode *)consoleAlloc(sizeof(SlotAccessNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->objectExpr = objectExpr; @@ -357,9 +367,9 @@ SlotAccessNode *SlotAccessNode::alloc( S32 lineNumber, ExprNode *objectExpr, Exp return ret; } -InternalSlotAccessNode *InternalSlotAccessNode::alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *slotExpr, bool recurse ) +InternalSlotAccessNode *InternalSlotAccessNode::alloc(S32 lineNumber, ExprNode *objectExpr, ExprNode *slotExpr, bool recurse) { - InternalSlotAccessNode *ret = (InternalSlotAccessNode *) consoleAlloc(sizeof(InternalSlotAccessNode)); + InternalSlotAccessNode *ret = (InternalSlotAccessNode *)consoleAlloc(sizeof(InternalSlotAccessNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->objectExpr = objectExpr; @@ -368,9 +378,9 @@ InternalSlotAccessNode *InternalSlotAccessNode::alloc( S32 lineNumber, ExprNode return ret; } -SlotAssignNode *SlotAssignNode::alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName, ExprNode *valueExpr, U32 typeID /* = -1 */ ) +SlotAssignNode *SlotAssignNode::alloc(S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName, ExprNode *valueExpr, U32 typeID /* = -1 */) { - SlotAssignNode *ret = (SlotAssignNode *) consoleAlloc(sizeof(SlotAssignNode)); + SlotAssignNode *ret = (SlotAssignNode *)consoleAlloc(sizeof(SlotAssignNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->objectExpr = objectExpr; @@ -381,9 +391,9 @@ SlotAssignNode *SlotAssignNode::alloc( S32 lineNumber, ExprNode *objectExpr, Exp return ret; } -SlotAssignOpNode *SlotAssignOpNode::alloc( S32 lineNumber, ExprNode *objectExpr, StringTableEntry slotName, ExprNode *arrayExpr, S32 op, ExprNode *valueExpr ) +SlotAssignOpNode *SlotAssignOpNode::alloc(S32 lineNumber, ExprNode *objectExpr, StringTableEntry slotName, ExprNode *arrayExpr, S32 op, ExprNode *valueExpr) { - SlotAssignOpNode *ret = (SlotAssignOpNode *) consoleAlloc(sizeof(SlotAssignOpNode)); + SlotAssignOpNode *ret = (SlotAssignOpNode *)consoleAlloc(sizeof(SlotAssignOpNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->objectExpr = objectExpr; @@ -394,9 +404,9 @@ SlotAssignOpNode *SlotAssignOpNode::alloc( S32 lineNumber, ExprNode *objectExpr, return ret; } -ObjectDeclNode *ObjectDeclNode::alloc( S32 lineNumber, ExprNode *classNameExpr, ExprNode *objectNameExpr, ExprNode *argList, StringTableEntry parentObject, SlotAssignNode *slotDecls, ObjectDeclNode *subObjects, bool isDatablock, bool classNameInternal, bool isSingleton ) +ObjectDeclNode *ObjectDeclNode::alloc(S32 lineNumber, ExprNode *classNameExpr, ExprNode *objectNameExpr, ExprNode *argList, StringTableEntry parentObject, SlotAssignNode *slotDecls, ObjectDeclNode *subObjects, bool isDatablock, bool classNameInternal, bool isSingleton) { - ObjectDeclNode *ret = (ObjectDeclNode *) consoleAlloc(sizeof(ObjectDeclNode)); + ObjectDeclNode *ret = (ObjectDeclNode *)consoleAlloc(sizeof(ObjectDeclNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->classNameExpr = classNameExpr; @@ -408,16 +418,16 @@ ObjectDeclNode *ObjectDeclNode::alloc( S32 lineNumber, ExprNode *classNameExpr, ret->isClassNameInternal = classNameInternal; ret->isSingleton = isSingleton; ret->failOffset = 0; - if(parentObject) + if (parentObject) ret->parentObject = parentObject; else ret->parentObject = StringTable->EmptyString(); return ret; } -FunctionDeclStmtNode *FunctionDeclStmtNode::alloc( S32 lineNumber, StringTableEntry fnName, StringTableEntry nameSpace, VarNode *args, StmtNode *stmts ) +FunctionDeclStmtNode *FunctionDeclStmtNode::alloc(S32 lineNumber, StringTableEntry fnName, StringTableEntry nameSpace, VarNode *args, StmtNode *stmts) { - FunctionDeclStmtNode *ret = (FunctionDeclStmtNode *) consoleAlloc(sizeof(FunctionDeclStmtNode)); + FunctionDeclStmtNode *ret = (FunctionDeclStmtNode *)consoleAlloc(sizeof(FunctionDeclStmtNode)); constructInPlace(ret); ret->dbgLineNumber = lineNumber; ret->fnName = fnName; diff --git a/Engine/source/console/astNodes.cpp b/Engine/source/console/astNodes.cpp index 3fc8c04c9..6ea557703 100644 --- a/Engine/source/console/astNodes.cpp +++ b/Engine/source/console/astNodes.cpp @@ -42,15 +42,89 @@ struct Token }; #include "console/cmdgram.h" - namespace Compiler { U32 compileBlock(StmtNode *block, CodeStream &codeStream, U32 ip) { - for(StmtNode *walk = block; walk; walk = walk->getNext()) + for (StmtNode *walk = block; walk; walk = walk->getNext()) ip = walk->compileStmt(codeStream, ip); return codeStream.tell(); } + + inline bool isSimpleVarLookup(ExprNode *arrayExpr, StringTableEntry &varName) + { + if (arrayExpr == nullptr) + { + varName = StringTable->insert(""); + return false; + } + + // No double arrays allowed for optimization. + VarNode *var = dynamic_cast(arrayExpr); + if (var && !var->arrayIndex) + { + StringTableEntry arrayVar = StringTable->insert(var->varName); + precompileIdent(arrayVar); + varName = arrayVar; + return true; + } + return false; + } + + // Do not allow 'recursive' %this optimizations. It can lead to weird bytecode + // generation since we can only optimize one expression at a time. + static bool OnlyOneThisOptimization = false; + + inline bool isThisVar(ExprNode *objectExpr) + { + // If we are currently optimizing a this var, don't allow extra optimization. + if (objectExpr == nullptr || OnlyOneThisOptimization) + return false; + + VarNode *thisVar = dynamic_cast(objectExpr); + if (thisVar && thisVar->varName == StringTable->insert("%this")) + return true; + return false; + } + + inline void optimizeThisPointer(CodeStream &codeStream, ExprNode *arrayExpr, U32 &ip, StringTableEntry slotName) + { + OnlyOneThisOptimization = true; + + // Is the array a simple variable? If so, we can optimize that. + StringTableEntry varName = nullptr; + bool simple = false; + + if (arrayExpr) + { + simple = isSimpleVarLookup(arrayExpr, varName); + if (!simple) + { + // Less optimized array setting. + codeStream.emit(OP_ADVANCE_STR); + ip = arrayExpr->compile(codeStream, ip, TypeReqString); + } + } + + codeStream.emit(OP_SETCURFIELD_THIS); + codeStream.emitSTE(slotName); + + if (arrayExpr) + { + if (simple) + { + codeStream.emit(OP_SETCURFIELD_ARRAY_VAR); + codeStream.emitSTE(varName); + } + else + { + codeStream.emit(OP_SETCURFIELD_ARRAY); + codeStream.emit(OP_TERMINATE_REWIND_STR); + } + } + + OnlyOneThisOptimization = false; + } } using namespace Compiler; @@ -77,7 +151,7 @@ void StmtNode::setPackage(StringTableEntry) void StmtNode::append(StmtNode *next) { StmtNode *walk = this; - while(walk->next) + while (walk->next) walk = walk->next; walk->next = next; } @@ -96,68 +170,68 @@ void FunctionDeclStmtNode::setPackage(StringTableEntry packageName) static U32 conversionOp(TypeReq src, TypeReq dst) { - if(src == TypeReqString) + if (src == TypeReqString) { - switch(dst) + switch (dst) { - case TypeReqUInt: - return OP_STR_TO_UINT; - case TypeReqFloat: - return OP_STR_TO_FLT; - case TypeReqNone: - return OP_STR_TO_NONE; - case TypeReqVar: - return OP_SAVEVAR_STR; - default: - break; + case TypeReqUInt: + return OP_STR_TO_UINT; + case TypeReqFloat: + return OP_STR_TO_FLT; + case TypeReqNone: + return OP_STR_TO_NONE; + case TypeReqVar: + return OP_SAVEVAR_STR; + default: + break; } } - else if(src == TypeReqFloat) + else if (src == TypeReqFloat) { - switch(dst) + switch (dst) { - case TypeReqUInt: - return OP_FLT_TO_UINT; - case TypeReqString: - return OP_FLT_TO_STR; - case TypeReqNone: - return OP_FLT_TO_NONE; - case TypeReqVar: - return OP_SAVEVAR_FLT; - default: - break; + case TypeReqUInt: + return OP_FLT_TO_UINT; + case TypeReqString: + return OP_FLT_TO_STR; + case TypeReqNone: + return OP_FLT_TO_NONE; + case TypeReqVar: + return OP_SAVEVAR_FLT; + default: + break; } } - else if(src == TypeReqUInt) + else if (src == TypeReqUInt) { - switch(dst) + switch (dst) { - case TypeReqFloat: - return OP_UINT_TO_FLT; - case TypeReqString: - return OP_UINT_TO_STR; - case TypeReqNone: - return OP_UINT_TO_NONE; - case TypeReqVar: - return OP_SAVEVAR_UINT; - default: - break; + case TypeReqFloat: + return OP_UINT_TO_FLT; + case TypeReqString: + return OP_UINT_TO_STR; + case TypeReqNone: + return OP_UINT_TO_NONE; + case TypeReqVar: + return OP_SAVEVAR_UINT; + default: + break; } } - else if(src == TypeReqVar) + else if (src == TypeReqVar) { - switch(dst) + switch (dst) { - case TypeReqUInt: - return OP_LOADVAR_UINT; - case TypeReqFloat: - return OP_LOADVAR_FLT; - case TypeReqString: - return OP_LOADVAR_STR; - case TypeReqNone: - return OP_COPYVAR_TO_NONE; - default: - break; + case TypeReqUInt: + return OP_LOADVAR_UINT; + case TypeReqFloat: + return OP_LOADVAR_FLT; + case TypeReqString: + return OP_LOADVAR_STR; + case TypeReqNone: + return OP_COPYVAR_TO_NONE; + default: + break; } } return OP_INVALID; @@ -167,7 +241,7 @@ static U32 conversionOp(TypeReq src, TypeReq dst) U32 BreakStmtNode::compileStmt(CodeStream &codeStream, U32 ip) { - if(codeStream.inLoop()) + if (codeStream.inLoop()) { addBreakLine(codeStream); codeStream.emit(OP_JMP); @@ -184,7 +258,7 @@ U32 BreakStmtNode::compileStmt(CodeStream &codeStream, U32 ip) U32 ContinueStmtNode::compileStmt(CodeStream &codeStream, U32 ip) { - if(codeStream.inLoop()) + if (codeStream.inLoop()) { addBreakLine(codeStream); codeStream.emit(OP_JMP); @@ -210,7 +284,7 @@ U32 ExprNode::compileStmt(CodeStream &codeStream, U32 ip) U32 ReturnStmtNode::compileStmt(CodeStream &codeStream, U32 ip) { addBreakLine(codeStream); - if(!expr) + if (!expr) codeStream.emit(OP_RETURN_VOID); else { @@ -220,15 +294,15 @@ U32 ReturnStmtNode::compileStmt(CodeStream &codeStream, U32 ip) // Return the correct type switch (walkType) { - case TypeReqUInt: - codeStream.emit(OP_RETURN_UINT); - break; - case TypeReqFloat: - codeStream.emit(OP_RETURN_FLT); - break; - default: - codeStream.emit(OP_RETURN); - break; + case TypeReqUInt: + codeStream.emit(OP_RETURN_UINT); + break; + case TypeReqFloat: + codeStream.emit(OP_RETURN_FLT); + break; + default: + codeStream.emit(OP_RETURN); + break; } } return codeStream.tell(); @@ -238,30 +312,30 @@ U32 ReturnStmtNode::compileStmt(CodeStream &codeStream, U32 ip) ExprNode *IfStmtNode::getSwitchOR(ExprNode *left, ExprNode *list, bool string) { - ExprNode *nextExpr = (ExprNode *) list->getNext(); + ExprNode *nextExpr = (ExprNode *)list->getNext(); ExprNode *test; - if(string) - test = StreqExprNode::alloc( left->dbgLineNumber, left, list, true ); + if (string) + test = StreqExprNode::alloc(left->dbgLineNumber, left, list, true); else - test = IntBinaryExprNode::alloc( left->dbgLineNumber, opEQ, left, list ); - if(!nextExpr) + test = IntBinaryExprNode::alloc(left->dbgLineNumber, opEQ, left, list); + if (!nextExpr) return test; - return IntBinaryExprNode::alloc( test->dbgLineNumber, opOR, test, getSwitchOR( left, nextExpr, string ) ); + return IntBinaryExprNode::alloc(test->dbgLineNumber, opOR, test, getSwitchOR(left, nextExpr, string)); } void IfStmtNode::propagateSwitchExpr(ExprNode *left, bool string) { testExpr = getSwitchOR(left, testExpr, string); - if(propagate && elseBlock) - ((IfStmtNode *) elseBlock)->propagateSwitchExpr(left, string); + if (propagate && elseBlock) + ((IfStmtNode *)elseBlock)->propagateSwitchExpr(left, string); } U32 IfStmtNode::compileStmt(CodeStream &codeStream, U32 ip) { U32 endifIp, elseIp; addBreakLine(codeStream); - - if(testExpr->getPreferredType() == TypeReqUInt) + + if (testExpr->getPreferredType() == TypeReqUInt) { integer = true; } @@ -273,14 +347,14 @@ U32 IfStmtNode::compileStmt(CodeStream &codeStream, U32 ip) ip = testExpr->compile(codeStream, ip, integer ? TypeReqUInt : TypeReqFloat); codeStream.emit(integer ? OP_JMPIFNOT : OP_JMPIFFNOT); - if(elseBlock) + if (elseBlock) { elseIp = codeStream.emit(0); elseOffset = compileBlock(ifBlock, codeStream, ip) + 2; codeStream.emit(OP_JMP); endifIp = codeStream.emit(0); endifOffset = compileBlock(elseBlock, codeStream, ip); - + codeStream.patch(endifIp, endifOffset); codeStream.patch(elseIp, elseOffset); } @@ -288,10 +362,10 @@ U32 IfStmtNode::compileStmt(CodeStream &codeStream, U32 ip) { endifIp = codeStream.emit(0); endifOffset = compileBlock(ifBlock, codeStream, ip); - + codeStream.patch(endifIp, endifOffset); } - + // Resolve fixes return codeStream.tell(); } @@ -300,7 +374,7 @@ U32 IfStmtNode::compileStmt(CodeStream &codeStream, U32 ip) U32 LoopStmtNode::compileStmt(CodeStream &codeStream, U32 ip) { - if(testExpr->getPreferredType() == TypeReqUInt) + if (testExpr->getPreferredType() == TypeReqUInt) { integer = true; } @@ -308,7 +382,7 @@ U32 LoopStmtNode::compileStmt(CodeStream &codeStream, U32 ip) { integer = false; } - + // if it's a for loop or a while loop it goes: // initExpr // testExpr @@ -320,7 +394,7 @@ U32 LoopStmtNode::compileStmt(CodeStream &codeStream, U32 ip) // testExpr // OP_JMPIF loopStartPoint // breakPoint: - + // otherwise if it's a do ... while() it goes: // initExpr // loopStartPoint: @@ -330,19 +404,19 @@ U32 LoopStmtNode::compileStmt(CodeStream &codeStream, U32 ip) // testExpr // OP_JMPIF loopStartPoint // breakPoint: - + // loopBlockStart == start of loop block // continue == skip to end // break == exit loop - - + + addBreakLine(codeStream); codeStream.pushFixScope(true); - - if(initExpr) + + if (initExpr) ip = initExpr->compile(codeStream, ip, TypeReqNone); - if(!isDoLoop) + if (!isDoLoop) { ip = testExpr->compile(codeStream, ip, integer ? TypeReqUInt : TypeReqFloat); codeStream.emit(integer ? OP_JMPIFNOT : OP_JMPIFFNOT); @@ -353,25 +427,25 @@ U32 LoopStmtNode::compileStmt(CodeStream &codeStream, U32 ip) loopBlockStartOffset = codeStream.tell(); continueOffset = compileBlock(loopBlock, codeStream, ip); - if(endLoopExpr) + if (endLoopExpr) ip = endLoopExpr->compile(codeStream, ip, TypeReqNone); ip = testExpr->compile(codeStream, ip, integer ? TypeReqUInt : TypeReqFloat); codeStream.emit(integer ? OP_JMPIF : OP_JMPIFF); codeStream.emitFix(CodeStream::FIXTYPE_LOOPBLOCKSTART); - + breakOffset = codeStream.tell(); // exit loop - + codeStream.fixLoop(loopBlockStartOffset, breakOffset, continueOffset); codeStream.popFixScope(); - + return codeStream.tell(); } //------------------------------------------------------------ -U32 IterStmtNode::compileStmt( CodeStream &codeStream, U32 ip ) +U32 IterStmtNode::compileStmt(CodeStream &codeStream, U32 ip) { // Instruction sequence: // @@ -384,33 +458,33 @@ U32 IterStmtNode::compileStmt( CodeStream &codeStream, U32 ip ) // .break: // OP_ITER_END // .fail: - + addBreakLine(codeStream); - + codeStream.pushFixScope(true); - + const U32 startIp = ip; - containerExpr->compile( codeStream, startIp, TypeReqString ); - + containerExpr->compile(codeStream, startIp, TypeReqString); + codeStream.emit(isStringIter ? OP_ITER_BEGIN_STR : OP_ITER_BEGIN); - codeStream.emitSTE( varName ); + codeStream.emitSTE(varName); const U32 finalFix = codeStream.emit(0); const U32 continueIp = codeStream.emit(OP_ITER); codeStream.emitFix(CodeStream::FIXTYPE_BREAK); const U32 bodyIp = codeStream.tell(); - - const U32 jmpIp = compileBlock( body, codeStream, bodyIp); + + const U32 jmpIp = compileBlock(body, codeStream, bodyIp); const U32 breakIp = jmpIp + 2; const U32 finalIp = breakIp + 1; - + codeStream.emit(OP_JMP); codeStream.emitFix(CodeStream::FIXTYPE_CONTINUE); codeStream.emit(OP_ITER_END); - + codeStream.patch(finalFix, finalIp); codeStream.fixLoop(bodyIp, breakIp, continueIp); codeStream.popFixScope(); - + return codeStream.tell(); } @@ -423,7 +497,7 @@ U32 ConditionalExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) // trueExpr // JMP end // falseExpr - if(testExpr->getPreferredType() == TypeReqUInt) + if (testExpr->getPreferredType() == TypeReqUInt) { integer = true; } @@ -431,10 +505,10 @@ U32 ConditionalExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { integer = false; } - + ip = testExpr->compile(codeStream, ip, integer ? TypeReqUInt : TypeReqFloat); codeStream.emit(integer ? OP_JMPIFNOT : OP_JMPIFFNOT); - + U32 jumpElseIp = codeStream.emit(0); ip = trueExpr->compile(codeStream, ip, type); codeStream.emit(OP_JMP); @@ -442,7 +516,7 @@ U32 ConditionalExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) codeStream.patch(jumpElseIp, codeStream.tell()); ip = falseExpr->compile(codeStream, ip, type); codeStream.patch(jumpEndIp, codeStream.tell()); - + return codeStream.tell(); } @@ -458,23 +532,23 @@ U32 FloatBinaryExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) ip = right->compile(codeStream, ip, TypeReqFloat); ip = left->compile(codeStream, ip, TypeReqFloat); U32 operand = OP_INVALID; - switch(op) + switch (op) { - case '+': - operand = OP_ADD; - break; - case '-': - operand = OP_SUB; - break; - case '/': - operand = OP_DIV; - break; - case '*': - operand = OP_MUL; - break; + case '+': + operand = OP_ADD; + break; + case '-': + operand = OP_SUB; + break; + case '/': + operand = OP_DIV; + break; + case '*': + operand = OP_MUL; + break; } codeStream.emit(operand); - if(type != TypeReqFloat) + if (type != TypeReqFloat) codeStream.emit(conversionOp(TypeReqFloat, type)); return codeStream.tell(); } @@ -489,64 +563,64 @@ TypeReq FloatBinaryExprNode::getPreferredType() void IntBinaryExprNode::getSubTypeOperand() { subType = TypeReqUInt; - switch(op) + switch (op) { - case '^': - operand = OP_XOR; - break; - case '%': - operand = OP_MOD; - break; - case '&': - operand = OP_BITAND; - break; - case '|': - operand = OP_BITOR; - break; - case '<': - operand = OP_CMPLT; - subType = TypeReqFloat; - break; - case '>': - operand = OP_CMPGR; - subType = TypeReqFloat; - break; - case opGE: - operand = OP_CMPGE; - subType = TypeReqFloat; - break; - case opLE: - operand = OP_CMPLE; - subType = TypeReqFloat; - break; - case opEQ: - operand = OP_CMPEQ; - subType = TypeReqFloat; - break; - case opNE: - operand = OP_CMPNE; - subType = TypeReqFloat; - break; - case opOR: - operand = OP_OR; - break; - case opAND: - operand = OP_AND; - break; - case opSHR: - operand = OP_SHR; - break; - case opSHL: - operand = OP_SHL; - break; + case '^': + operand = OP_XOR; + break; + case '%': + operand = OP_MOD; + break; + case '&': + operand = OP_BITAND; + break; + case '|': + operand = OP_BITOR; + break; + case '<': + operand = OP_CMPLT; + subType = TypeReqFloat; + break; + case '>': + operand = OP_CMPGR; + subType = TypeReqFloat; + break; + case opGE: + operand = OP_CMPGE; + subType = TypeReqFloat; + break; + case opLE: + operand = OP_CMPLE; + subType = TypeReqFloat; + break; + case opEQ: + operand = OP_CMPEQ; + subType = TypeReqFloat; + break; + case opNE: + operand = OP_CMPNE; + subType = TypeReqFloat; + break; + case opOR: + operand = OP_OR; + break; + case opAND: + operand = OP_AND; + break; + case opSHR: + operand = OP_SHR; + break; + case opSHL: + operand = OP_SHL; + break; } } U32 IntBinaryExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { getSubTypeOperand(); - - if(operand == OP_OR || operand == OP_AND) + + if (operand == OP_OR || operand == OP_AND) { ip = left->compile(codeStream, ip, subType); codeStream.emit(operand == OP_OR ? OP_JMPIF_NP : OP_JMPIFNOT_NP); @@ -560,7 +634,7 @@ U32 IntBinaryExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) ip = left->compile(codeStream, ip, subType); codeStream.emit(operand); } - if(type != TypeReqUInt) + if (type != TypeReqUInt) codeStream.emit(conversionOp(TypeReqUInt, type)); return codeStream.tell(); } @@ -579,14 +653,14 @@ U32 StreqExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) // eval str right // OP_COMPARE_STR // optional conversion - + ip = left->compile(codeStream, ip, TypeReqString); codeStream.emit(OP_ADVANCE_STR_NUL); ip = right->compile(codeStream, ip, TypeReqString); codeStream.emit(OP_COMPARE_STR); - if(!eq) + if (!eq) codeStream.emit(OP_NOT); - if(type != TypeReqUInt) + if (type != TypeReqUInt) codeStream.emit(conversionOp(TypeReqUInt, type)); return codeStream.tell(); } @@ -601,7 +675,7 @@ TypeReq StreqExprNode::getPreferredType() U32 StrcatExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { ip = left->compile(codeStream, ip, TypeReqString); - if(!appendChar) + if (!appendChar) codeStream.emit(OP_ADVANCE_STR); else { @@ -610,9 +684,9 @@ U32 StrcatExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) } ip = right->compile(codeStream, ip, TypeReqString); codeStream.emit(OP_REWIND_STR); - if(type == TypeReqUInt) + if (type == TypeReqUInt) codeStream.emit(OP_STR_TO_UINT); - else if(type == TypeReqFloat) + else if (type == TypeReqFloat) codeStream.emit(OP_STR_TO_FLT); return codeStream.tell(); } @@ -634,11 +708,11 @@ U32 CommaCatExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) // At this point the stack has the concatenated string. // But we're paranoid, so accept (but whine) if we get an oddity... - if(type == TypeReqUInt || type == TypeReqFloat) + if (type == TypeReqUInt || type == TypeReqFloat) Con::warnf(ConsoleLogEntry::General, "%s (%d): converting comma string to a number... probably wrong.", dbgFileName, dbgLineNumber); - if(type == TypeReqUInt) + if (type == TypeReqUInt) codeStream.emit(OP_STR_TO_UINT); - else if(type == TypeReqFloat) + else if (type == TypeReqFloat) codeStream.emit(OP_STR_TO_FLT); return codeStream.tell(); } @@ -654,15 +728,15 @@ U32 IntUnaryExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { integer = true; TypeReq prefType = expr->getPreferredType(); - if(op == '!' && (prefType == TypeReqFloat || prefType == TypeReqString)) + if (op == '!' && (prefType == TypeReqFloat || prefType == TypeReqString)) integer = false; - + ip = expr->compile(codeStream, ip, integer ? TypeReqUInt : TypeReqFloat); - if(op == '!') + if (op == '!') codeStream.emit(integer ? OP_NOT : OP_NOTF); - else if(op == '~') + else if (op == '~') codeStream.emit(OP_ONESCOMPLEMENT); - if(type != TypeReqUInt) + if (type != TypeReqUInt) codeStream.emit(conversionOp(TypeReqUInt, type)); return codeStream.tell(); } @@ -678,7 +752,7 @@ U32 FloatUnaryExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { ip = expr->compile(codeStream, ip, TypeReqFloat); codeStream.emit(OP_NEG); - if(type != TypeReqFloat) + if (type != TypeReqFloat) codeStream.emit(conversionOp(TypeReqFloat, type)); return codeStream.tell(); } @@ -692,53 +766,95 @@ TypeReq FloatUnaryExprNode::getPreferredType() U32 VarNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { - // if this has an arrayIndex... - // OP_LOADIMMED_IDENT - // varName - // OP_ADVANCE_STR - // evaluate arrayIndex TypeReqString - // OP_REWIND_STR - // OP_SETCURVAR_ARRAY - // OP_LOADVAR (type) - + // if this has an arrayIndex and we are not short circuiting from a constant. + // if we are a var node + // OP_SETCURVAR_ARRAY_VARLOOKUP + // varName + // varNodeVarName + + // else + // OP_LOADIMMED_IDENT + // varName + // OP_ADVANCE_STR + // evaluate arrayIndex TypeReqString + // OP_REWIND_STR + // OP_SETCURVAR_ARRAY + // OP_LOADVAR (type) + // else // OP_SETCURVAR // varName // OP_LOADVAR (type) - - if(type == TypeReqNone) + + if (type == TypeReqNone) return codeStream.tell(); - + + bool shortCircuit = false; + if (arrayIndex) + { + // If we have a constant, shortcircuit the array logic. + + IntNode *intNode = dynamic_cast(arrayIndex); + StrConstNode *strNode = dynamic_cast(arrayIndex); + if (intNode) + { + varName = StringTable->insert(avar("%s%d", varName, intNode->value)); + shortCircuit = true; + } + else if (strNode) + { + varName = StringTable->insert(avar("%s%s", varName, strNode->str)); + shortCircuit = true; + } + } + precompileIdent(varName); - codeStream.emit(arrayIndex ? OP_LOADIMMED_IDENT : OP_SETCURVAR); - codeStream.emitSTE(varName); - - if(arrayIndex) + if (arrayIndex && !shortCircuit) { - codeStream.emit(OP_ADVANCE_STR); - ip = arrayIndex->compile(codeStream, ip, TypeReqString); - codeStream.emit(OP_REWIND_STR); - codeStream.emit(OP_SETCURVAR_ARRAY); + // Ok, lets try to optimize %var[%someothervar] as this is + // a common case for array usage. + StringTableEntry varNodeVarName; + if (isSimpleVarLookup(arrayIndex, varNodeVarName)) + { + codeStream.emit(OP_SETCURVAR_ARRAY_VARLOOKUP); + codeStream.emitSTE(varName); + codeStream.emitSTE(varNodeVarName); + } + else + { + codeStream.emit(OP_LOADIMMED_IDENT); + codeStream.emitSTE(varName); + codeStream.emit(OP_ADVANCE_STR); + ip = arrayIndex->compile(codeStream, ip, TypeReqString); + codeStream.emit(OP_REWIND_STR); + codeStream.emit(OP_SETCURVAR_ARRAY); + } } - switch(type) + else { - case TypeReqUInt: - codeStream.emit(OP_LOADVAR_UINT); - break; - case TypeReqFloat: - codeStream.emit(OP_LOADVAR_FLT); - break; - case TypeReqString: - codeStream.emit(OP_LOADVAR_STR); - break; - case TypeReqVar: - codeStream.emit(OP_LOADVAR_VAR); - break; - case TypeReqNone: - break; - default: - break; + codeStream.emit(OP_SETCURVAR); + codeStream.emitSTE(varName); + } + + switch (type) + { + case TypeReqUInt: + codeStream.emit(OP_LOADVAR_UINT); + break; + case TypeReqFloat: + codeStream.emit(OP_LOADVAR_FLT); + break; + case TypeReqString: + codeStream.emit(OP_LOADVAR_STR); + break; + case TypeReqVar: + codeStream.emit(OP_LOADVAR_VAR); + break; + case TypeReqNone: + break; + default: + break; } return codeStream.tell(); } @@ -752,27 +868,27 @@ TypeReq VarNode::getPreferredType() U32 IntNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { - if(type == TypeReqString) + if (type == TypeReqString) index = getCurrentStringTable()->addIntString(value); - else if(type == TypeReqFloat) + else if (type == TypeReqFloat) index = getCurrentFloatTable()->add(value); - - switch(type) + + switch (type) { - case TypeReqUInt: - codeStream.emit(OP_LOADIMMED_UINT); - codeStream.emit(value); - break; - case TypeReqString: - codeStream.emit(OP_LOADIMMED_STR); - codeStream.emit(index); - break; - case TypeReqFloat: - codeStream.emit(OP_LOADIMMED_FLT); - codeStream.emit(index); - break; - case TypeReqNone: - break; + case TypeReqUInt: + codeStream.emit(OP_LOADIMMED_UINT); + codeStream.emit(value); + break; + case TypeReqString: + codeStream.emit(OP_LOADIMMED_STR); + codeStream.emit(index); + break; + case TypeReqFloat: + codeStream.emit(OP_LOADIMMED_FLT); + codeStream.emit(index); + break; + case TypeReqNone: + break; } return codeStream.tell(); } @@ -786,27 +902,27 @@ TypeReq IntNode::getPreferredType() U32 FloatNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { - if(type == TypeReqString) + if (type == TypeReqString) index = getCurrentStringTable()->addFloatString(value); - else if(type == TypeReqFloat) + else if (type == TypeReqFloat) index = getCurrentFloatTable()->add(value); - - switch(type) + + switch (type) { - case TypeReqUInt: - codeStream.emit(OP_LOADIMMED_UINT); - codeStream.emit(U32(value)); - break; - case TypeReqString: - codeStream.emit(OP_LOADIMMED_STR); - codeStream.emit(index); - break; - case TypeReqFloat: - codeStream.emit(OP_LOADIMMED_FLT); - codeStream.emit(index); - break; - case TypeReqNone: - break; + case TypeReqUInt: + codeStream.emit(OP_LOADIMMED_UINT); + codeStream.emit(U32(value)); + break; + case TypeReqString: + codeStream.emit(OP_LOADIMMED_STR); + codeStream.emit(index); + break; + case TypeReqFloat: + codeStream.emit(OP_LOADIMMED_FLT); + codeStream.emit(index); + break; + case TypeReqNone: + break; } return codeStream.tell(); } @@ -821,25 +937,25 @@ TypeReq FloatNode::getPreferredType() U32 StrConstNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { // Early out for documentation block. - if( doc ) + if (doc) { index = getCurrentStringTable()->add(str, true, tag); } - else if(type == TypeReqString) + else if (type == TypeReqString) { index = getCurrentStringTable()->add(str, true, tag); } else if (type != TypeReqNone) { fVal = consoleStringToNumber(str, dbgFileName, dbgLineNumber); - if(type == TypeReqFloat) + if (type == TypeReqFloat) { index = getCurrentFloatTable()->add(fVal); } } - + // If this is a DOCBLOCK, then process w/ appropriate op... - if( doc ) + if (doc) { codeStream.emit(OP_DOCBLOCK_STR); codeStream.emit(index); @@ -847,22 +963,22 @@ U32 StrConstNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) } // Otherwise, deal with it normally as a string literal case. - switch(type) + switch (type) { - case TypeReqString: - codeStream.emit(tag ? OP_TAG_TO_STR : OP_LOADIMMED_STR); - codeStream.emit(index); - break; - case TypeReqUInt: - codeStream.emit(OP_LOADIMMED_UINT); - codeStream.emit(U32(fVal)); - break; - case TypeReqFloat: - codeStream.emit(OP_LOADIMMED_FLT); - codeStream.emit(index); - break; - case TypeReqNone: - break; + case TypeReqString: + codeStream.emit(tag ? OP_TAG_TO_STR : OP_LOADIMMED_STR); + codeStream.emit(index); + break; + case TypeReqUInt: + codeStream.emit(OP_LOADIMMED_UINT); + codeStream.emit(U32(fVal)); + break; + case TypeReqFloat: + codeStream.emit(OP_LOADIMMED_FLT); + codeStream.emit(index); + break; + case TypeReqNone: + break; } return codeStream.tell(); } @@ -876,33 +992,33 @@ TypeReq StrConstNode::getPreferredType() U32 ConstantNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { - if(type == TypeReqString) + if (type == TypeReqString) { precompileIdent(value); } else if (type != TypeReqNone) { fVal = consoleStringToNumber(value, dbgFileName, dbgLineNumber); - if(type == TypeReqFloat) + if (type == TypeReqFloat) index = getCurrentFloatTable()->add(fVal); } - - switch(type) + + switch (type) { - case TypeReqString: - codeStream.emit(OP_LOADIMMED_IDENT); - codeStream.emitSTE(value); - break; - case TypeReqUInt: - codeStream.emit(OP_LOADIMMED_UINT); - codeStream.emit(U32(fVal)); - break; - case TypeReqFloat: - codeStream.emit(OP_LOADIMMED_FLT); - codeStream.emit(index); - break; - case TypeReqNone: - break; + case TypeReqString: + codeStream.emit(OP_LOADIMMED_IDENT); + codeStream.emitSTE(value); + break; + case TypeReqUInt: + codeStream.emit(OP_LOADIMMED_UINT); + codeStream.emit(U32(fVal)); + break; + case TypeReqFloat: + codeStream.emit(OP_LOADIMMED_FLT); + codeStream.emit(index); + break; + case TypeReqNone: + break; } return ip; } @@ -917,9 +1033,9 @@ TypeReq ConstantNode::getPreferredType() U32 AssignExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { subType = expr->getPreferredType(); - if(subType == TypeReqNone) + if (subType == TypeReqNone) subType = type; - if(subType == TypeReqNone) + if (subType == TypeReqNone) { // What we need to do in this case is turn it into a VarNode reference. // Unfortunately other nodes such as field access (SlotAccessNode) @@ -934,41 +1050,87 @@ U32 AssignExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) subType = TypeReqString; } } - // if it's an array expr, the formula is: + + //if we are an array index and we are gonna short circuit + // eval expr + // compute new varName + // OP_SETCURVAR_CREATE + // varName + // OP_SAVEVAR + + //else if it's an array expr and we don't short circuit, the formula is: // eval expr // (push and pop if it's TypeReqString) OP_ADVANCE_STR - // OP_LOADIMMED_IDENT - // varName - // OP_ADVANCE_STR - // eval array - // OP_REWIND_STR - // OP_SETCURVAR_ARRAY_CREATE + // if array lookup is varnode + // OP_SETCURVAR_ARRAY_CREATE_VARLOOKUP + // varName + // varNodeVarName + // else + // OP_LOADIMMED_IDENT + // varName + // OP_ADVANCE_STR + // eval array + // OP_REWIND_STR + // OP_SETCURVAR_ARRAY_CREATE + // endif // OP_TERMINATE_REWIND_STR // OP_SAVEVAR - + //else // eval expr // OP_SETCURVAR_CREATE // varname // OP_SAVEVAR - - precompileIdent(varName); - + ip = expr->compile(codeStream, ip, subType); - if(arrayIndex) + bool shortCircuit = false; + if (arrayIndex) { - if(subType == TypeReqString) + // If we have a constant, shortcircuit the array logic. + + IntNode *intNode = dynamic_cast(arrayIndex); + StrConstNode *strNode = dynamic_cast(arrayIndex); + if (intNode) + { + varName = StringTable->insert(avar("%s%d", varName, intNode->value)); + shortCircuit = true; + } + else if (strNode) + { + varName = StringTable->insert(avar("%s%s", varName, strNode->str)); + shortCircuit = true; + } + } + + precompileIdent(varName); + + if (arrayIndex && !shortCircuit) + { + if (subType == TypeReqString) codeStream.emit(OP_ADVANCE_STR); - codeStream.emit(OP_LOADIMMED_IDENT); - codeStream.emitSTE(varName); - - codeStream.emit(OP_ADVANCE_STR); - ip = arrayIndex->compile(codeStream, ip, TypeReqString); - codeStream.emit(OP_REWIND_STR); - codeStream.emit(OP_SETCURVAR_ARRAY_CREATE); - if(subType == TypeReqString) + // Ok, lets try to optimize %var[%someothervar] as this is + // a common case for array usage. + StringTableEntry varNodeVarName; + if (isSimpleVarLookup(arrayIndex, varNodeVarName)) + { + codeStream.emit(OP_SETCURVAR_ARRAY_CREATE_VARLOOKUP); + codeStream.emitSTE(varName); + codeStream.emitSTE(varNodeVarName); + } + else + { + codeStream.emit(OP_LOADIMMED_IDENT); + codeStream.emitSTE(varName); + + codeStream.emit(OP_ADVANCE_STR); + ip = arrayIndex->compile(codeStream, ip, TypeReqString); + codeStream.emit(OP_REWIND_STR); + codeStream.emit(OP_SETCURVAR_ARRAY_CREATE); + } + + if (subType == TypeReqString) codeStream.emit(OP_TERMINATE_REWIND_STR); } else @@ -976,24 +1138,24 @@ U32 AssignExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) codeStream.emit(OP_SETCURVAR_CREATE); codeStream.emitSTE(varName); } - switch(subType) + switch (subType) { - case TypeReqString: - codeStream.emit(OP_SAVEVAR_STR); - break; - case TypeReqUInt: - codeStream.emit(OP_SAVEVAR_UINT); - break; - case TypeReqFloat: - codeStream.emit(OP_SAVEVAR_FLT); - break; - case TypeReqVar: - codeStream.emit(OP_SAVEVAR_VAR); - break; - case TypeReqNone: - break; + case TypeReqString: + codeStream.emit(OP_SAVEVAR_STR); + break; + case TypeReqUInt: + codeStream.emit(OP_SAVEVAR_UINT); + break; + case TypeReqFloat: + codeStream.emit(OP_SAVEVAR_FLT); + break; + case TypeReqVar: + codeStream.emit(OP_SAVEVAR_VAR); + break; + case TypeReqNone: + break; } - if(type != subType) + if (type != subType) codeStream.emit(conversionOp(subType, type)); return ip; } @@ -1007,97 +1169,178 @@ TypeReq AssignExprNode::getPreferredType() static void getAssignOpTypeOp(S32 op, TypeReq &type, U32 &operand) { - switch(op) + switch (op) { - case '+': - type = TypeReqFloat; - operand = OP_ADD; - break; - case '-': - type = TypeReqFloat; - operand = OP_SUB; - break; - case '*': - type = TypeReqFloat; - operand = OP_MUL; - break; - case '/': - type = TypeReqFloat; - operand = OP_DIV; - break; - case '%': - type = TypeReqUInt; - operand = OP_MOD; - break; - case '&': - type = TypeReqUInt; - operand = OP_BITAND; - break; - case '^': - type = TypeReqUInt; - operand = OP_XOR; - break; - case '|': - type = TypeReqUInt; - operand = OP_BITOR; - break; - case opSHL: - type = TypeReqUInt; - operand = OP_SHL; - break; - case opSHR: - type = TypeReqUInt; - operand = OP_SHR; - break; - } + case '+': + case opPLUSPLUS: + type = TypeReqFloat; + operand = OP_ADD; + break; + case '-': + case opMINUSMINUS: + type = TypeReqFloat; + operand = OP_SUB; + break; + case '*': + type = TypeReqFloat; + operand = OP_MUL; + break; + case '/': + type = TypeReqFloat; + operand = OP_DIV; + break; + case '%': + type = TypeReqUInt; + operand = OP_MOD; + break; + case '&': + type = TypeReqUInt; + operand = OP_BITAND; + break; + case '^': + type = TypeReqUInt; + operand = OP_XOR; + break; + case '|': + type = TypeReqUInt; + operand = OP_BITOR; + break; + case opSHL: + type = TypeReqUInt; + operand = OP_SHL; + break; + case opSHR: + type = TypeReqUInt; + operand = OP_SHR; + break; + } } U32 AssignOpExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { - + // goes like this... - // eval expr as float or int - // if there's an arrayIndex - - // OP_LOADIMMED_IDENT - // varName - // OP_ADVANCE_STR - // eval arrayIndex stringwise - // OP_REWIND_STR - // OP_SETCURVAR_ARRAY_CREATE - - // else - // OP_SETCURVAR_CREATE - // varName - - // OP_LOADVAR_FLT or UINT - // operand - // OP_SAVEVAR_FLT or UINT - + // + // IF no array index && (op == OPPLUSPLUS or op == OPMINUSMINUS) + // if op == OPPLUSPLUS + // OP_INC + // varName + // else if op == OPMINUSMINUS + // OP_DEC + // varName + // else + // OP_INVALID + // endif + // ELSE + // eval expr as float or int + // if there's an arrayIndex and we don't short circuit + // if arrayIndex is a var node + // OP_SETCURVAR_ARRAY_CREATE_VARLOOKUP + // varName + // varNodeVarName + // else + // OP_LOADIMMED_IDENT + // varName + // OP_ADVANCE_STR + // eval arrayIndex stringwise + // OP_REWIND_STR + // OP_SETCURVAR_ARRAY_CREATE + // endif + // else + // OP_SETCURVAR_CREATE + // varName + // endif + // OP_LOADVAR_FLT or UINT + // operand + // OP_SAVEVAR_FLT or UINT + // ENDIF + // + // if subtype != type + // convert type + // endif + // conversion OP if necessary. getAssignOpTypeOp(op, subType, operand); - precompileIdent(varName); - - ip = expr->compile(codeStream, ip, subType); - if(!arrayIndex) + + // ++ or -- optimization support for non indexed variables. + if ((!arrayIndex) && (op == opPLUSPLUS || op == opMINUSMINUS)) { - codeStream.emit(OP_SETCURVAR_CREATE); - codeStream.emitSTE(varName); + precompileIdent(varName); + + if (op == opPLUSPLUS) + { + codeStream.emit(OP_INC); + codeStream.emitSTE(varName); + } + else if (op == opMINUSMINUS) + { + codeStream.emit(OP_DEC); + codeStream.emitSTE(varName); + } + else + { + // This should NEVER happen. This is just for sanity. + AssertISV(false, "Tried to use ++ or -- but something weird happened."); + codeStream.emit(OP_INVALID); + } } else { - codeStream.emit(OP_LOADIMMED_IDENT); - codeStream.emitSTE(varName); - - codeStream.emit(OP_ADVANCE_STR); - ip = arrayIndex->compile(codeStream, ip, TypeReqString); - codeStream.emit(OP_REWIND_STR); - codeStream.emit(OP_SETCURVAR_ARRAY_CREATE); + ip = expr->compile(codeStream, ip, subType); + + bool shortCircuit = false; + if (arrayIndex) + { + // If we have a constant, shortcircuit the array logic. + + IntNode *intNode = dynamic_cast(arrayIndex); + StrConstNode *strNode = dynamic_cast(arrayIndex); + if (intNode) + { + varName = StringTable->insert(avar("%s%d", varName, intNode->value)); + shortCircuit = true; + } + else if (strNode) + { + varName = StringTable->insert(avar("%s%s", varName, strNode->str)); + shortCircuit = true; + } + } + + precompileIdent(varName); + + if (!arrayIndex || shortCircuit) + { + codeStream.emit(OP_SETCURVAR_CREATE); + codeStream.emitSTE(varName); + } + else + { + // Ok, lets try to optimize %var[%someothervar] as this is + // a common case for array usage. + StringTableEntry varNodeVarName; + if (isSimpleVarLookup(arrayIndex, varNodeVarName)) + { + codeStream.emit(OP_SETCURVAR_ARRAY_CREATE_VARLOOKUP); + codeStream.emitSTE(varName); + codeStream.emitSTE(varNodeVarName); + } + else + { + codeStream.emit(OP_LOADIMMED_IDENT); + codeStream.emitSTE(varName); + + codeStream.emit(OP_ADVANCE_STR); + ip = arrayIndex->compile(codeStream, ip, TypeReqString); + codeStream.emit(OP_REWIND_STR); + codeStream.emit(OP_SETCURVAR_ARRAY_CREATE); + } + } + codeStream.emit((subType == TypeReqFloat) ? OP_LOADVAR_FLT : OP_LOADVAR_UINT); + codeStream.emit(operand); + codeStream.emit((subType == TypeReqFloat) ? OP_SAVEVAR_FLT : OP_SAVEVAR_UINT); } - codeStream.emit((subType == TypeReqFloat) ? OP_LOADVAR_FLT : OP_LOADVAR_UINT); - codeStream.emit(operand); - codeStream.emit((subType == TypeReqFloat) ? OP_SAVEVAR_FLT : OP_SAVEVAR_UINT); - if(subType != type) + if (subType != type) codeStream.emit(conversionOp(subType, type)); return codeStream.tell(); } @@ -1146,17 +1389,44 @@ U32 FuncCallExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) // OP_PUSH_FRAME // arg OP_PUSH arg OP_PUSH arg OP_PUSH // eval all the args, then call the function. - + // OP_CALLFUNC // function // namespace // isDot - + precompileIdent(funcName); precompileIdent(nameSpace); - + codeStream.emit(OP_PUSH_FRAME); - for(ExprNode *walk = args; walk; walk = (ExprNode *) walk->getNext()) + + bool isThisCall = false; + + ExprNode *walk = args; + + // Try to optimize the this pointer call if it is a variable + // that we are loading. + if (callType == MethodCall) + { + // We cannot optimize array indices because it can have quite + // a bit of code to figure out the array index. + VarNode *var = dynamic_cast(args); + if (var && !var->arrayIndex) + { + precompileIdent(var->varName); + + // Are we a %this call? + isThisCall = (var->varName == StringTable->insert("%this")); + + codeStream.emit(OP_PUSH_THIS); + codeStream.emitSTE(var->varName); + + // inc args since we took care of first arg. + walk = (ExprNode*)walk ->getNext(); + } + } + + for (; walk; walk = (ExprNode *)walk->getNext()) { TypeReq walkType = walk->getPreferredType(); if (walkType == TypeReqNone) walkType = TypeReqString; @@ -1174,16 +1444,25 @@ U32 FuncCallExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) break; } } - if(callType == MethodCall || callType == ParentCall) - codeStream.emit(OP_CALLFUNC); - else - codeStream.emit(OP_CALLFUNC_RESOLVE); - codeStream.emitSTE(funcName); - codeStream.emitSTE(nameSpace); - - codeStream.emit(callType); - if(type != TypeReqString) + if (isThisCall) + { + codeStream.emit(OP_CALLFUNC_THIS); + codeStream.emitSTE(funcName); + } + else + { + if (callType == MethodCall || callType == ParentCall) + codeStream.emit(OP_CALLFUNC); + else + codeStream.emit(OP_CALLFUNC_RESOLVE); + + codeStream.emitSTE(funcName); + codeStream.emitSTE(nameSpace); + codeStream.emit(callType); + } + + if (type != TypeReqString) codeStream.emit(conversionOp(TypeReqString, type)); return codeStream.tell(); } @@ -1193,20 +1472,63 @@ TypeReq FuncCallExprNode::getPreferredType() return TypeReqString; } +//------------------------------------------------------------ + +U32 FuncPointerCallExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) +{ + // OP_PUSH_FRAME + // arg OP_PUSH arg OP_PUSH arg OP_PUSH + // eval all the args, then call the function. + + // eval fn pointer + // OP_CALLFUNC_POINTER + + codeStream.emit(OP_PUSH_FRAME); + for (ExprNode *walk = args; walk; walk = (ExprNode *)walk->getNext()) + { + TypeReq walkType = walk->getPreferredType(); + if (walkType == TypeReqNone) walkType = TypeReqString; + ip = walk->compile(codeStream, ip, walkType); + switch (walk->getPreferredType()) + { + case TypeReqFloat: + codeStream.emit(OP_PUSH_FLT); + break; + case TypeReqUInt: + codeStream.emit(OP_PUSH_UINT); + break; + default: + codeStream.emit(OP_PUSH); + break; + } + } + + ip = funcPointer->compile(codeStream, ip, TypeReqString); + codeStream.emit(OP_CALLFUNC_POINTER); + + if (type != TypeReqString) + codeStream.emit(conversionOp(TypeReqString, type)); + return codeStream.tell(); +} + +TypeReq FuncPointerCallExprNode::getPreferredType() +{ + return TypeReqString; +} //------------------------------------------------------------ -U32 AssertCallExprNode::compile( CodeStream &codeStream, U32 ip, TypeReq type ) +U32 AssertCallExprNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { - #ifdef TORQUE_ENABLE_SCRIPTASSERTS - - messageIndex = getCurrentStringTable()->add( message, true, false ); - - ip = testExpr->compile( codeStream, ip, TypeReqUInt ); - codeStream.emit(OP_ASSERT); - codeStream.emit(messageIndex); +#ifdef TORQUE_ENABLE_SCRIPTASSERTS - #endif + messageIndex = getCurrentStringTable()->add(message, true, false); + + ip = testExpr->compile(codeStream, ip, TypeReqUInt); + codeStream.emit(OP_ASSERT); + codeStream.emit(messageIndex); + +#endif return codeStream.tell(); } @@ -1220,37 +1542,45 @@ TypeReq AssertCallExprNode::getPreferredType() U32 SlotAccessNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { - if(type == TypeReqNone) + if (type == TypeReqNone) return ip; - + precompileIdent(slotName); - if(arrayExpr) + // check if object is %this. If we are, we can do additional optimizations. + if (isThisVar(objectExpr)) { - // eval array - // OP_ADVANCE_STR - // evaluate object expression sub (OP_SETCURFIELD) - // OP_TERMINATE_REWIND_STR - // OP_SETCURFIELDARRAY - // total add of 4 + array precomp - - ip = arrayExpr->compile(codeStream, ip, TypeReqString); - codeStream.emit(OP_ADVANCE_STR); + optimizeThisPointer(codeStream, arrayExpr, ip, slotName); } - ip = objectExpr->compile(codeStream, ip, TypeReqString); - codeStream.emit(OP_SETCUROBJECT); - - codeStream.emit(OP_SETCURFIELD); - - codeStream.emitSTE(slotName); + else + { + if (arrayExpr) + { + // eval array + // OP_ADVANCE_STR + // evaluate object expression sub (OP_SETCURFIELD) + // OP_TERMINATE_REWIND_STR + // OP_SETCURFIELDARRAY + // total add of 4 + array precomp - if(arrayExpr) - { - codeStream.emit(OP_TERMINATE_REWIND_STR); - codeStream.emit(OP_SETCURFIELD_ARRAY); + ip = arrayExpr->compile(codeStream, ip, TypeReqString); + codeStream.emit(OP_ADVANCE_STR); + } + ip = objectExpr->compile(codeStream, ip, TypeReqString); + codeStream.emit(OP_SETCUROBJECT); + + codeStream.emit(OP_SETCURFIELD); + + codeStream.emitSTE(slotName); + + if (arrayExpr) + { + codeStream.emit(OP_TERMINATE_REWIND_STR); + codeStream.emit(OP_SETCURFIELD_ARRAY); + } } - - switch(type) + + switch (type) { case TypeReqUInt: codeStream.emit(OP_LOADFIELD_UINT); @@ -1276,7 +1606,7 @@ TypeReq SlotAccessNode::getPreferredType() U32 InternalSlotAccessNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { - if(type == TypeReqNone) + if (type == TypeReqNone) return ip; ip = objectExpr->compile(codeStream, ip, TypeReqString); @@ -1286,7 +1616,7 @@ U32 InternalSlotAccessNode::compile(CodeStream &codeStream, U32 ip, TypeReq type codeStream.emit(OP_SETCUROBJECT_INTERNAL); codeStream.emit(recurse); - if(type != TypeReqUInt) + if (type != TypeReqUInt) codeStream.emit(conversionOp(TypeReqUInt, type)); return codeStream.tell(); } @@ -1301,22 +1631,22 @@ TypeReq InternalSlotAccessNode::getPreferredType() U32 SlotAssignNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { // first eval the expression TypeReqString - + // if it's an array: - + // if OP_ADVANCE_STR 1 // eval array - + // OP_ADVANCE_STR 1 // evaluate object expr // OP_SETCUROBJECT 1 // OP_SETCURFIELD 1 // fieldName 1 // OP_TERMINATE_REWIND_STR 1 - + // OP_SETCURFIELDARRAY 1 // OP_TERMINATE_REWIND_STR 1 - + // else // OP_ADVANCE_STR // evaluate object expr @@ -1324,45 +1654,54 @@ U32 SlotAssignNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) // OP_SETCURFIELD // fieldName // OP_TERMINATE_REWIND_STR - + // OP_SAVEFIELD // convert to return type if necessary. - + precompileIdent(slotName); - + ip = valueExpr->compile(codeStream, ip, TypeReqString); - codeStream.emit(OP_ADVANCE_STR); - if(arrayExpr) + + if (isThisVar(objectExpr)) { - ip = arrayExpr->compile(codeStream, ip, TypeReqString); - codeStream.emit(OP_ADVANCE_STR); - } - if(objectExpr) - { - ip = objectExpr->compile(codeStream, ip, TypeReqString); - codeStream.emit(OP_SETCUROBJECT); + optimizeThisPointer(codeStream, arrayExpr, ip, slotName); } else - codeStream.emit(OP_SETCUROBJECT_NEW); - codeStream.emit(OP_SETCURFIELD); - codeStream.emitSTE(slotName); - - if(arrayExpr) { + codeStream.emit(OP_ADVANCE_STR); + if (arrayExpr) + { + ip = arrayExpr->compile(codeStream, ip, TypeReqString); + codeStream.emit(OP_ADVANCE_STR); + } + if (objectExpr) + { + ip = objectExpr->compile(codeStream, ip, TypeReqString); + codeStream.emit(OP_SETCUROBJECT); + } + else + codeStream.emit(OP_SETCUROBJECT_NEW); + codeStream.emit(OP_SETCURFIELD); + codeStream.emitSTE(slotName); + + if (arrayExpr) + { + codeStream.emit(OP_TERMINATE_REWIND_STR); + codeStream.emit(OP_SETCURFIELD_ARRAY); + } + codeStream.emit(OP_TERMINATE_REWIND_STR); - codeStream.emit(OP_SETCURFIELD_ARRAY); } - codeStream.emit(OP_TERMINATE_REWIND_STR); codeStream.emit(OP_SAVEFIELD_STR); - if(typeID != -1) + if (typeID != -1) { codeStream.emit(OP_SETCURFIELD_TYPE); codeStream.emit(typeID); } - if(type != TypeReqString) + if (type != TypeReqString) codeStream.emit(conversionOp(TypeReqString, type)); return codeStream.tell(); } @@ -1377,7 +1716,7 @@ TypeReq SlotAssignNode::getPreferredType() U32 SlotAssignOpNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { // first eval the expression as its type - + // if it's an array: // eval array // OP_ADVANCE_STR @@ -1387,41 +1726,49 @@ U32 SlotAssignOpNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) // fieldName // OP_TERMINATE_REWIND_STR // OP_SETCURFIELDARRAY - + // else // evaluate object expr // OP_SETCUROBJECT // OP_SETCURFIELD // fieldName - + // OP_LOADFIELD of appropriate type // operand // OP_SAVEFIELD of appropriate type // convert to return type if necessary. - + getAssignOpTypeOp(op, subType, operand); precompileIdent(slotName); - + ip = valueExpr->compile(codeStream, ip, subType); - if(arrayExpr) + + if (isThisVar(objectExpr)) { - ip = arrayExpr->compile(codeStream, ip, TypeReqString); - codeStream.emit(OP_ADVANCE_STR); + optimizeThisPointer(codeStream, arrayExpr, ip, slotName); } - ip = objectExpr->compile(codeStream, ip, TypeReqString); - codeStream.emit(OP_SETCUROBJECT); - codeStream.emit(OP_SETCURFIELD); - codeStream.emitSTE(slotName); - - if(arrayExpr) + else { - codeStream.emit(OP_TERMINATE_REWIND_STR); - codeStream.emit(OP_SETCURFIELD_ARRAY); + if (arrayExpr) + { + ip = arrayExpr->compile(codeStream, ip, TypeReqString); + codeStream.emit(OP_ADVANCE_STR); + } + ip = objectExpr->compile(codeStream, ip, TypeReqString); + codeStream.emit(OP_SETCUROBJECT); + codeStream.emit(OP_SETCURFIELD); + codeStream.emitSTE(slotName); + + if (arrayExpr) + { + codeStream.emit(OP_TERMINATE_REWIND_STR); + codeStream.emit(OP_SETCURFIELD_ARRAY); + } } codeStream.emit((subType == TypeReqFloat) ? OP_LOADFIELD_FLT : OP_LOADFIELD_UINT); codeStream.emit(operand); codeStream.emit((subType == TypeReqFloat) ? OP_SAVEFIELD_FLT : OP_SAVEFIELD_UINT); - if(subType != type) + if (subType != type) codeStream.emit(conversionOp(subType, type)); return codeStream.tell(); } @@ -1437,7 +1784,7 @@ TypeReq SlotAssignOpNode::getPreferredType() U32 ObjectDeclNode::compileSubObject(CodeStream &codeStream, U32 ip, bool root) { // goes - + // OP_PUSHFRAME 1 // name expr // OP_PUSH 1 @@ -1449,17 +1796,17 @@ U32 ObjectDeclNode::compileSubObject(CodeStream &codeStream, U32 ip, bool root) // isSingleton 1 // lineNumber 1 // fail point 1 - + // for each field, eval // OP_ADD_OBJECT (to UINT[0]) 1 // root? 1 - + // add all the sub objects. // OP_END_OBJECT 1 // root? 1 // To fix the stack issue [7/9/2007 Black] // OP_FINISH_OBJECT <-- fail point jumps to this opcode - + codeStream.emit(OP_PUSH_FRAME); ip = classNameExpr->compile(codeStream, ip, TypeReqString); @@ -1467,7 +1814,7 @@ U32 ObjectDeclNode::compileSubObject(CodeStream &codeStream, U32 ip, bool root) ip = objectNameExpr->compile(codeStream, ip, TypeReqString); codeStream.emit(OP_PUSH); - for(ExprNode *exprWalk = argList; exprWalk; exprWalk = (ExprNode *) exprWalk->getNext()) + for (ExprNode *exprWalk = argList; exprWalk; exprWalk = (ExprNode *)exprWalk->getNext()) { TypeReq walkType = exprWalk->getPreferredType(); if (walkType == TypeReqNone) walkType = TypeReqString; @@ -1482,7 +1829,7 @@ U32 ObjectDeclNode::compileSubObject(CodeStream &codeStream, U32 ip, bool root) break; default: codeStream.emit(OP_PUSH); - break; + break; } } codeStream.emit(OP_CREATE_OBJECT); @@ -1493,35 +1840,35 @@ U32 ObjectDeclNode::compileSubObject(CodeStream &codeStream, U32 ip, bool root) codeStream.emit(isSingleton); codeStream.emit(dbgLineNumber); const U32 failIp = codeStream.emit(0); - for(SlotAssignNode *slotWalk = slotDecls; slotWalk; slotWalk = (SlotAssignNode *) slotWalk->getNext()) + for (SlotAssignNode *slotWalk = slotDecls; slotWalk; slotWalk = (SlotAssignNode *)slotWalk->getNext()) ip = slotWalk->compile(codeStream, ip, TypeReqNone); codeStream.emit(OP_ADD_OBJECT); codeStream.emit(root); - for(ObjectDeclNode *objectWalk = subObjects; objectWalk; objectWalk = (ObjectDeclNode *) objectWalk->getNext()) + for (ObjectDeclNode *objectWalk = subObjects; objectWalk; objectWalk = (ObjectDeclNode *)objectWalk->getNext()) ip = objectWalk->compileSubObject(codeStream, ip, false); codeStream.emit(OP_END_OBJECT); codeStream.emit(root || isDatablock); // Added to fix the object creation issue [7/9/2007 Black] failOffset = codeStream.emit(OP_FINISH_OBJECT); - + codeStream.patch(failIp, failOffset); - + return codeStream.tell(); } U32 ObjectDeclNode::compile(CodeStream &codeStream, U32 ip, TypeReq type) { // root object decl does: - + // push 0 onto the UINT stack OP_LOADIMMED_UINT // precompiles the subObject(true) // UINT stack now has object id // type conv to type - + codeStream.emit(OP_LOADIMMED_UINT); codeStream.emit(0); ip = compileSubObject(codeStream, ip, true); - if(type != TypeReqUInt) + if (type != TypeReqUInt) codeStream.emit(conversionOp(TypeReqUInt, type)); return codeStream.tell(); } @@ -1547,31 +1894,31 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream &codeStream, U32 ip) // OP_RETURN_VOID setCurrentStringTable(&getFunctionStringTable()); setCurrentFloatTable(&getFunctionFloatTable()); - + argc = 0; - for(VarNode *walk = args; walk; walk = (VarNode *)((StmtNode*)walk)->getNext()) + for (VarNode *walk = args; walk; walk = (VarNode *)((StmtNode*)walk)->getNext()) { precompileIdent(walk->varName); argc++; } - + CodeBlock::smInFunction = true; - + precompileIdent(fnName); precompileIdent(nameSpace); precompileIdent(package); - + CodeBlock::smInFunction = false; - + codeStream.emit(OP_FUNC_DECL); codeStream.emitSTE(fnName); codeStream.emitSTE(nameSpace); codeStream.emitSTE(package); - - codeStream.emit(U32( bool(stmts != NULL) ? 1 : 0 ) + U32( dbgLineNumber << 1 )); + + codeStream.emit(U32(bool(stmts != NULL) ? 1 : 0) + U32(dbgLineNumber << 1)); const U32 endIp = codeStream.emit(0); codeStream.emit(argc); - for(VarNode *walk = args; walk; walk = (VarNode *)((StmtNode*)walk)->getNext()) + for (VarNode *walk = args; walk; walk = (VarNode *)((StmtNode*)walk)->getNext()) { codeStream.emitSTE(walk->varName); } @@ -1584,11 +1931,11 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream &codeStream, U32 ip) CodeBlock::smInFunction = false; codeStream.emit(OP_RETURN_VOID); - + codeStream.patch(endIp, codeStream.tell()); - + setCurrentStringTable(&getGlobalStringTable()); setCurrentFloatTable(&getGlobalFloatTable()); - + return ip; } diff --git a/Engine/source/console/cmdgram.cpp b/Engine/source/console/cmdgram.cpp index 39fe8d3c3..b5051786b 100644 --- a/Engine/source/console/cmdgram.cpp +++ b/Engine/source/console/cmdgram.cpp @@ -1,6 +1,6 @@ /* A Bison parser, made from cmdgram.y with Bison version GNU Bison version 1.24 - */ +*/ #define YYBISON 1 /* Identify Bison output. */ @@ -11,78 +11,78 @@ #define yychar CMDchar #define yydebug CMDdebug #define yynerrs CMDnerrs -#define rwDEFINE 258 -#define rwENDDEF 259 -#define rwDECLARE 260 -#define rwDECLARESINGLETON 261 -#define rwBREAK 262 -#define rwELSE 263 -#define rwCONTINUE 264 -#define rwGLOBAL 265 -#define rwIF 266 -#define rwNIL 267 -#define rwRETURN 268 -#define rwWHILE 269 -#define rwDO 270 -#define rwENDIF 271 -#define rwENDWHILE 272 -#define rwENDFOR 273 -#define rwDEFAULT 274 -#define rwFOR 275 -#define rwFOREACH 276 -#define rwFOREACHSTR 277 -#define rwIN 278 -#define rwDATABLOCK 279 -#define rwSWITCH 280 -#define rwCASE 281 -#define rwSWITCHSTR 282 -#define rwCASEOR 283 -#define rwPACKAGE 284 -#define rwNAMESPACE 285 -#define rwCLASS 286 -#define rwASSERT 287 -#define ILLEGAL_TOKEN 288 -#define CHRCONST 289 -#define INTCONST 290 -#define TTAG 291 -#define VAR 292 -#define IDENT 293 -#define TYPEIDENT 294 -#define DOCBLOCK 295 -#define STRATOM 296 -#define TAGATOM 297 -#define FLTCONST 298 -#define opINTNAME 299 -#define opINTNAMER 300 -#define opMINUSMINUS 301 -#define opPLUSPLUS 302 -#define STMT_SEP 303 -#define opSHL 304 -#define opSHR 305 -#define opPLASN 306 -#define opMIASN 307 -#define opMLASN 308 -#define opDVASN 309 -#define opMODASN 310 -#define opANDASN 311 -#define opXORASN 312 -#define opORASN 313 -#define opSLASN 314 -#define opSRASN 315 -#define opCAT 316 -#define opEQ 317 -#define opNE 318 -#define opGE 319 -#define opLE 320 -#define opAND 321 -#define opOR 322 -#define opSTREQ 323 -#define opCOLONCOLON 324 -#define opMDASN 325 -#define opNDASN 326 -#define opNTASN 327 -#define opSTRNE 328 -#define UNARY 329 +#define rwDEFINE 258 +#define rwENDDEF 259 +#define rwDECLARE 260 +#define rwDECLARESINGLETON 261 +#define rwBREAK 262 +#define rwELSE 263 +#define rwCONTINUE 264 +#define rwGLOBAL 265 +#define rwIF 266 +#define rwNIL 267 +#define rwRETURN 268 +#define rwWHILE 269 +#define rwDO 270 +#define rwENDIF 271 +#define rwENDWHILE 272 +#define rwENDFOR 273 +#define rwDEFAULT 274 +#define rwFOR 275 +#define rwFOREACH 276 +#define rwFOREACHSTR 277 +#define rwIN 278 +#define rwDATABLOCK 279 +#define rwSWITCH 280 +#define rwCASE 281 +#define rwSWITCHSTR 282 +#define rwCASEOR 283 +#define rwPACKAGE 284 +#define rwNAMESPACE 285 +#define rwCLASS 286 +#define rwASSERT 287 +#define ILLEGAL_TOKEN 288 +#define CHRCONST 289 +#define INTCONST 290 +#define TTAG 291 +#define VAR 292 +#define IDENT 293 +#define TYPEIDENT 294 +#define DOCBLOCK 295 +#define STRATOM 296 +#define TAGATOM 297 +#define FLTCONST 298 +#define opINTNAME 299 +#define opINTNAMER 300 +#define opMINUSMINUS 301 +#define opPLUSPLUS 302 +#define STMT_SEP 303 +#define opSHL 304 +#define opSHR 305 +#define opPLASN 306 +#define opMIASN 307 +#define opMLASN 308 +#define opDVASN 309 +#define opMODASN 310 +#define opANDASN 311 +#define opXORASN 312 +#define opORASN 313 +#define opSLASN 314 +#define opSRASN 315 +#define opCAT 316 +#define opEQ 317 +#define opNE 318 +#define opGE 319 +#define opLE 320 +#define opAND 321 +#define opOR 322 +#define opSTREQ 323 +#define opCOLONCOLON 324 +#define opMDASN 325 +#define opNDASN 326 +#define opNTASN 327 +#define opSTRNE 328 +#define UNARY 329 #line 1 "cmdgram.y" @@ -129,13 +129,13 @@ struct Token #line 44 "cmdgram.y" - /* Reserved Word Definitions */ +/* Reserved Word Definitions */ #line 55 "cmdgram.y" - /* Constants and Identifier Definitions */ +/* Constants and Identifier Definitions */ #line 69 "cmdgram.y" - /* Operator Definitions */ +/* Operator Definitions */ #line 82 "cmdgram.y" typedef union { @@ -158,16 +158,16 @@ typedef union { #ifndef YYLTYPE typedef - struct yyltype - { - int timestamp; - int first_line; - int first_column; - int last_line; - int last_column; - char *text; - } - yyltype; +struct yyltype +{ + int timestamp; + int first_line; + int first_column; + int last_line; + int last_column; + char *text; +} +yyltype; #define YYLTYPE yyltype #endif @@ -182,165 +182,165 @@ typedef -#define YYFINAL 388 -#define YYFLAG -32768 -#define YYNTBASE 100 +#define YYFINAL 391 +#define YYFLAG -32768 +#define YYNTBASE 100 #define YYTRANSLATE(x) ((unsigned)(x) <= 329 ? yytranslate[x] : 140) -static const char yytranslate[] = { 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 64, 2, 2, 2, 54, 53, 2, 55, - 56, 46, 44, 57, 45, 51, 47, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 58, 59, 48, - 50, 49, 96, 65, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 92, 2, 99, 62, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 60, 52, 61, 63, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 93, 94, 95, 97, 98 +static const char yytranslate[] = { 0, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 64, 2, 2, 2, 54, 53, 2, 55, +56, 46, 44, 57, 45, 51, 47, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 58, 59, 48, +50, 49, 96, 65, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +92, 2, 99, 62, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 60, 52, 61, 63, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 1, 2, 3, 4, 5, +6, 7, 8, 9, 10, 11, 12, 13, 14, 15, +16, 17, 18, 19, 20, 21, 22, 23, 24, 25, +26, 27, 28, 29, 30, 31, 32, 33, 34, 35, +36, 37, 38, 39, 40, 41, 42, 43, 66, 67, +68, 69, 70, 71, 72, 73, 74, 75, 76, 77, +78, 79, 80, 81, 82, 83, 84, 85, 86, 87, +88, 89, 90, 91, 93, 94, 95, 97, 98 }; #if YYDEBUG != 0 -static const short yyprhs[] = { 0, - 0, 2, 3, 6, 8, 10, 12, 19, 21, 24, - 25, 28, 30, 32, 34, 36, 38, 40, 43, 46, - 49, 53, 56, 61, 68, 70, 79, 90, 91, 93, - 95, 99, 110, 121, 129, 142, 152, 163, 171, 172, - 175, 176, 178, 179, 182, 183, 185, 187, 190, 193, - 197, 201, 203, 211, 219, 224, 232, 238, 240, 244, - 250, 258, 264, 271, 281, 290, 299, 307, 316, 324, - 332, 339, 347, 355, 357, 359, 363, 367, 371, 375, - 379, 383, 387, 391, 395, 398, 401, 403, 409, 413, - 417, 421, 425, 429, 433, 437, 441, 445, 449, 453, - 457, 461, 464, 467, 469, 471, 473, 475, 477, 479, - 481, 483, 485, 490, 498, 502, 509, 513, 517, 519, - 523, 525, 527, 530, 533, 536, 539, 542, 545, 548, - 551, 554, 557, 559, 561, 563, 567, 574, 577, 583, - 586, 590, 596, 601, 608, 615, 620, 627, 628, 630, - 632, 636, 637, 639, 641, 644, 649, 655, 660, 668, - 677, 679 +static const short yyprhs[] = { 0, +0, 2, 3, 6, 8, 10, 12, 19, 21, 24, +25, 28, 30, 32, 34, 36, 38, 40, 43, 46, +49, 53, 56, 61, 68, 70, 79, 90, 91, 93, +95, 99, 110, 121, 129, 142, 152, 163, 171, 172, +175, 176, 178, 179, 182, 183, 185, 187, 190, 193, +197, 201, 203, 211, 219, 224, 232, 238, 240, 244, +250, 258, 264, 271, 281, 290, 299, 307, 316, 324, +332, 339, 347, 355, 357, 359, 363, 367, 371, 375, +379, 383, 387, 391, 395, 398, 401, 403, 409, 413, +417, 421, 425, 429, 433, 437, 441, 445, 449, 453, +457, 461, 464, 467, 469, 471, 473, 475, 477, 479, +481, 483, 485, 490, 498, 502, 509, 513, 517, 519, +523, 525, 527, 530, 533, 536, 539, 542, 545, 548, +551, 554, 557, 559, 561, 563, 567, 574, 577, 583, +586, 590, 596, 601, 608, 615, 620, 625, 632, 633, +635, 637, 641, 642, 644, 646, 649, 654, 660, 665, +673, 682, 684 }; -static const short yyrhs[] = { 101, - 0, 0, 101, 102, 0, 106, 0, 107, 0, 103, - 0, 29, 38, 60, 104, 61, 59, 0, 107, 0, - 104, 107, 0, 0, 105, 106, 0, 121, 0, 122, - 0, 123, 0, 124, 0, 110, 0, 118, 0, 7, - 59, 0, 9, 59, 0, 13, 59, 0, 13, 126, - 59, 0, 125, 59, 0, 36, 50, 126, 59, 0, - 36, 50, 126, 57, 126, 59, 0, 40, 0, 3, - 38, 55, 108, 56, 60, 105, 61, 0, 3, 38, - 91, 38, 55, 108, 56, 60, 105, 61, 0, 0, - 109, 0, 37, 0, 109, 57, 37, 0, 24, 129, - 55, 126, 112, 56, 60, 136, 61, 59, 0, 5, - 129, 55, 113, 112, 114, 56, 60, 115, 61, 0, - 5, 129, 55, 113, 112, 114, 56, 0, 5, 129, - 55, 92, 113, 99, 112, 114, 56, 60, 115, 61, - 0, 5, 129, 55, 92, 113, 99, 112, 114, 56, - 0, 6, 129, 55, 113, 112, 114, 56, 60, 115, - 61, 0, 6, 129, 55, 113, 112, 114, 56, 0, - 0, 58, 38, 0, 0, 126, 0, 0, 57, 135, - 0, 0, 137, 0, 116, 0, 137, 116, 0, 111, - 59, 0, 116, 111, 59, 0, 60, 105, 61, 0, - 106, 0, 25, 55, 126, 56, 60, 119, 61, 0, - 27, 55, 126, 56, 60, 119, 61, 0, 26, 120, - 58, 105, 0, 26, 120, 58, 105, 19, 58, 105, - 0, 26, 120, 58, 105, 119, 0, 126, 0, 120, - 28, 126, 0, 11, 55, 126, 56, 117, 0, 11, - 55, 126, 56, 117, 8, 117, 0, 14, 55, 126, - 56, 117, 0, 15, 117, 14, 55, 126, 56, 0, - 20, 55, 126, 59, 126, 59, 126, 56, 117, 0, - 20, 55, 126, 59, 126, 59, 56, 117, 0, 20, - 55, 126, 59, 59, 126, 56, 117, 0, 20, 55, - 126, 59, 59, 56, 117, 0, 20, 55, 59, 126, - 59, 126, 56, 117, 0, 20, 55, 59, 126, 59, - 56, 117, 0, 20, 55, 59, 59, 126, 56, 117, - 0, 20, 55, 59, 59, 56, 117, 0, 21, 55, - 37, 23, 126, 56, 117, 0, 22, 55, 37, 23, - 126, 56, 117, 0, 131, 0, 131, 0, 55, 126, - 56, 0, 126, 62, 126, 0, 126, 54, 126, 0, - 126, 53, 126, 0, 126, 52, 126, 0, 126, 44, - 126, 0, 126, 45, 126, 0, 126, 46, 126, 0, - 126, 47, 126, 0, 45, 126, 0, 46, 126, 0, - 36, 0, 126, 96, 126, 58, 126, 0, 126, 48, - 126, 0, 126, 49, 126, 0, 126, 86, 126, 0, - 126, 87, 126, 0, 126, 84, 126, 0, 126, 85, - 126, 0, 126, 89, 126, 0, 126, 71, 126, 0, - 126, 72, 126, 0, 126, 88, 126, 0, 126, 90, - 126, 0, 126, 97, 126, 0, 126, 65, 126, 0, - 64, 126, 0, 63, 126, 0, 42, 0, 43, 0, - 35, 0, 7, 0, 127, 0, 128, 0, 38, 0, - 41, 0, 37, 0, 37, 92, 139, 99, 0, 3, - 55, 108, 56, 60, 105, 61, 0, 126, 51, 38, - 0, 126, 51, 38, 92, 139, 99, 0, 126, 66, - 129, 0, 126, 67, 129, 0, 38, 0, 55, 126, - 56, 0, 69, 0, 68, 0, 73, 126, 0, 74, - 126, 0, 75, 126, 0, 76, 126, 0, 77, 126, - 0, 78, 126, 0, 79, 126, 0, 80, 126, 0, - 81, 126, 0, 82, 126, 0, 132, 0, 133, 0, - 111, 0, 37, 50, 126, 0, 37, 92, 139, 99, - 50, 126, 0, 37, 130, 0, 37, 92, 139, 99, - 130, 0, 127, 130, 0, 127, 50, 126, 0, 127, - 50, 60, 135, 61, 0, 38, 55, 134, 56, 0, - 38, 91, 38, 55, 134, 56, 0, 126, 51, 38, - 55, 134, 56, 0, 32, 55, 126, 56, 0, 32, - 55, 126, 57, 41, 56, 0, 0, 135, 0, 126, - 0, 135, 57, 126, 0, 0, 137, 0, 138, 0, - 137, 138, 0, 38, 50, 126, 59, 0, 39, 38, - 50, 126, 59, 0, 24, 50, 126, 59, 0, 38, - 92, 139, 99, 50, 126, 59, 0, 39, 38, 92, - 139, 99, 50, 126, 59, 0, 126, 0, 139, 57, - 126, 0 +static const short yyrhs[] = { 101, +0, 0, 101, 102, 0, 106, 0, 107, 0, 103, +0, 29, 38, 60, 104, 61, 59, 0, 107, 0, +104, 107, 0, 0, 105, 106, 0, 121, 0, 122, +0, 123, 0, 124, 0, 110, 0, 118, 0, 7, +59, 0, 9, 59, 0, 13, 59, 0, 13, 126, +59, 0, 125, 59, 0, 36, 50, 126, 59, 0, +36, 50, 126, 57, 126, 59, 0, 40, 0, 3, +38, 55, 108, 56, 60, 105, 61, 0, 3, 38, +91, 38, 55, 108, 56, 60, 105, 61, 0, 0, +109, 0, 37, 0, 109, 57, 37, 0, 24, 129, +55, 126, 112, 56, 60, 136, 61, 59, 0, 5, +129, 55, 113, 112, 114, 56, 60, 115, 61, 0, +5, 129, 55, 113, 112, 114, 56, 0, 5, 129, +55, 92, 113, 99, 112, 114, 56, 60, 115, 61, +0, 5, 129, 55, 92, 113, 99, 112, 114, 56, +0, 6, 129, 55, 113, 112, 114, 56, 60, 115, +61, 0, 6, 129, 55, 113, 112, 114, 56, 0, +0, 58, 38, 0, 0, 126, 0, 0, 57, 135, +0, 0, 137, 0, 116, 0, 137, 116, 0, 111, +59, 0, 116, 111, 59, 0, 60, 105, 61, 0, +106, 0, 25, 55, 126, 56, 60, 119, 61, 0, +27, 55, 126, 56, 60, 119, 61, 0, 26, 120, +58, 105, 0, 26, 120, 58, 105, 19, 58, 105, +0, 26, 120, 58, 105, 119, 0, 126, 0, 120, +28, 126, 0, 11, 55, 126, 56, 117, 0, 11, +55, 126, 56, 117, 8, 117, 0, 14, 55, 126, +56, 117, 0, 15, 117, 14, 55, 126, 56, 0, +20, 55, 126, 59, 126, 59, 126, 56, 117, 0, +20, 55, 126, 59, 126, 59, 56, 117, 0, 20, +55, 126, 59, 59, 126, 56, 117, 0, 20, 55, +126, 59, 59, 56, 117, 0, 20, 55, 59, 126, +59, 126, 56, 117, 0, 20, 55, 59, 126, 59, +56, 117, 0, 20, 55, 59, 59, 126, 56, 117, +0, 20, 55, 59, 59, 56, 117, 0, 21, 55, +37, 23, 126, 56, 117, 0, 22, 55, 37, 23, +126, 56, 117, 0, 131, 0, 131, 0, 55, 126, +56, 0, 126, 62, 126, 0, 126, 54, 126, 0, +126, 53, 126, 0, 126, 52, 126, 0, 126, 44, +126, 0, 126, 45, 126, 0, 126, 46, 126, 0, +126, 47, 126, 0, 45, 126, 0, 46, 126, 0, +36, 0, 126, 96, 126, 58, 126, 0, 126, 48, +126, 0, 126, 49, 126, 0, 126, 86, 126, 0, +126, 87, 126, 0, 126, 84, 126, 0, 126, 85, +126, 0, 126, 89, 126, 0, 126, 71, 126, 0, +126, 72, 126, 0, 126, 88, 126, 0, 126, 90, +126, 0, 126, 97, 126, 0, 126, 65, 126, 0, +64, 126, 0, 63, 126, 0, 42, 0, 43, 0, +35, 0, 7, 0, 127, 0, 128, 0, 38, 0, +41, 0, 37, 0, 37, 92, 139, 99, 0, 3, +55, 108, 56, 60, 105, 61, 0, 126, 51, 38, +0, 126, 51, 38, 92, 139, 99, 0, 126, 66, +129, 0, 126, 67, 129, 0, 38, 0, 55, 126, +56, 0, 69, 0, 68, 0, 73, 126, 0, 74, +126, 0, 75, 126, 0, 76, 126, 0, 77, 126, +0, 78, 126, 0, 79, 126, 0, 80, 126, 0, +81, 126, 0, 82, 126, 0, 132, 0, 133, 0, +111, 0, 37, 50, 126, 0, 37, 92, 139, 99, +50, 126, 0, 37, 130, 0, 37, 92, 139, 99, +130, 0, 127, 130, 0, 127, 50, 126, 0, 127, +50, 60, 135, 61, 0, 38, 55, 134, 56, 0, +38, 91, 38, 55, 134, 56, 0, 126, 51, 38, +55, 134, 56, 0, 126, 55, 134, 56, 0, 32, +55, 126, 56, 0, 32, 55, 126, 57, 41, 56, +0, 0, 135, 0, 126, 0, 135, 57, 126, 0, +0, 137, 0, 138, 0, 137, 138, 0, 38, 50, +126, 59, 0, 39, 38, 50, 126, 59, 0, 24, +50, 126, 59, 0, 38, 92, 139, 99, 50, 126, +59, 0, 39, 38, 92, 139, 99, 50, 126, 59, +0, 126, 0, 139, 57, 126, 0 }; #endif #if YYDEBUG != 0 static const short yyrline[] = { 0, - 161, 166, 168, 173, 175, 177, 182, 187, 189, 194, - 196, 201, 202, 203, 204, 205, 206, 207, 209, 211, - 213, 215, 217, 219, 221, 226, 228, 233, 235, 240, - 242, 247, 252, 254, 256, 258, 260, 262, 267, 269, - 274, 276, 281, 283, 288, 290, 292, 294, 299, 301, - 306, 308, 313, 315, 320, 322, 324, 329, 331, 336, - 338, 343, 345, 350, 352, 354, 356, 358, 360, 362, - 364, 369, 371, 376, 381, 383, 385, 387, 389, 391, - 393, 395, 397, 399, 401, 403, 405, 407, 409, 411, - 413, 415, 417, 419, 421, 423, 425, 427, 429, 431, - 433, 435, 437, 439, 441, 443, 445, 447, 449, 451, - 453, 455, 457, 459, 477, 479, 484, 486, 491, 493, - 498, 500, 502, 504, 506, 508, 510, 512, 514, 516, - 518, 520, 525, 527, 529, 531, 533, 535, 537, 539, - 541, 543, 548, 550, 552, 557, 559, 564, 566, 571, - 573, 578, 580, 585, 587, 592, 594, 596, 598, 600, - 605, 607 +161, 166, 168, 173, 175, 177, 182, 187, 189, 194, +196, 201, 202, 203, 204, 205, 206, 207, 209, 211, +213, 215, 217, 219, 221, 226, 228, 233, 235, 240, +242, 247, 252, 254, 256, 258, 260, 262, 267, 269, +274, 276, 281, 283, 288, 290, 292, 294, 299, 301, +306, 308, 313, 315, 320, 322, 324, 329, 331, 336, +338, 343, 345, 350, 352, 354, 356, 358, 360, 362, +364, 369, 371, 376, 381, 383, 385, 387, 389, 391, +393, 395, 397, 399, 401, 403, 405, 407, 409, 411, +413, 415, 417, 419, 421, 423, 425, 427, 429, 431, +433, 435, 437, 439, 441, 443, 445, 447, 449, 451, +453, 455, 457, 459, 477, 479, 484, 486, 491, 493, +498, 500, 502, 504, 506, 508, 510, 512, 514, 516, +518, 520, 525, 527, 529, 531, 533, 535, 537, 539, +541, 543, 548, 550, 552, 554, 559, 561, 566, 568, +573, 575, 580, 582, 587, 589, 594, 596, 598, 600, +602, 607, 609 }; -static const char * const yytname[] = { "$","error","$undefined.","rwDEFINE", +static const char * const yytname[] = { "$","error","$undefined.","rwDEFINE", "rwENDDEF","rwDECLARE","rwDECLARESINGLETON","rwBREAK","rwELSE","rwCONTINUE", "rwGLOBAL","rwIF","rwNIL","rwRETURN","rwWHILE","rwDO","rwENDIF","rwENDWHILE", "rwENDFOR","rwDEFAULT","rwFOR","rwFOREACH","rwFOREACHSTR","rwIN","rwDATABLOCK", @@ -363,787 +363,805 @@ static const char * const yytname[] = { "$","error","$undefined.","rwDEFINE", }; #endif -static const short yyr1[] = { 0, - 100, 101, 101, 102, 102, 102, 103, 104, 104, 105, - 105, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 107, 107, 108, 108, 109, - 109, 110, 111, 111, 111, 111, 111, 111, 112, 112, - 113, 113, 114, 114, 115, 115, 115, 115, 116, 116, - 117, 117, 118, 118, 119, 119, 119, 120, 120, 121, - 121, 122, 122, 123, 123, 123, 123, 123, 123, 123, - 123, 124, 124, 125, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 127, 127, 128, 128, 129, 129, - 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, - 130, 130, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 132, 132, 132, 133, 133, 134, 134, 135, - 135, 136, 136, 137, 137, 138, 138, 138, 138, 138, - 139, 139 +static const short yyr1[] = { 0, +100, 101, 101, 102, 102, 102, 103, 104, 104, 105, +105, 106, 106, 106, 106, 106, 106, 106, 106, 106, +106, 106, 106, 106, 106, 107, 107, 108, 108, 109, +109, 110, 111, 111, 111, 111, 111, 111, 112, 112, +113, 113, 114, 114, 115, 115, 115, 115, 116, 116, +117, 117, 118, 118, 119, 119, 119, 120, 120, 121, +121, 122, 122, 123, 123, 123, 123, 123, 123, 123, +123, 124, 124, 125, 126, 126, 126, 126, 126, 126, +126, 126, 126, 126, 126, 126, 126, 126, 126, 126, +126, 126, 126, 126, 126, 126, 126, 126, 126, 126, +126, 126, 126, 126, 126, 126, 126, 126, 126, 126, +126, 126, 126, 126, 127, 127, 128, 128, 129, 129, +130, 130, 130, 130, 130, 130, 130, 130, 130, 130, +130, 130, 131, 131, 131, 131, 131, 131, 131, 131, +131, 131, 132, 132, 132, 132, 133, 133, 134, 134, +135, 135, 136, 136, 137, 137, 138, 138, 138, 138, +138, 139, 139 }; -static const short yyr2[] = { 0, - 1, 0, 2, 1, 1, 1, 6, 1, 2, 0, - 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, - 3, 2, 4, 6, 1, 8, 10, 0, 1, 1, - 3, 10, 10, 7, 12, 9, 10, 7, 0, 2, - 0, 1, 0, 2, 0, 1, 1, 2, 2, 3, - 3, 1, 7, 7, 4, 7, 5, 1, 3, 5, - 7, 5, 6, 9, 8, 8, 7, 8, 7, 7, - 6, 7, 7, 1, 1, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 2, 2, 1, 5, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 4, 7, 3, 6, 3, 3, 1, 3, - 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 1, 1, 1, 3, 6, 2, 5, 2, - 3, 5, 4, 6, 6, 4, 6, 0, 1, 1, - 3, 0, 1, 1, 2, 4, 5, 4, 7, 8, - 1, 3 +static const short yyr2[] = { 0, +1, 0, 2, 1, 1, 1, 6, 1, 2, 0, +2, 1, 1, 1, 1, 1, 1, 2, 2, 2, +3, 2, 4, 6, 1, 8, 10, 0, 1, 1, +3, 10, 10, 7, 12, 9, 10, 7, 0, 2, +0, 1, 0, 2, 0, 1, 1, 2, 2, 3, +3, 1, 7, 7, 4, 7, 5, 1, 3, 5, +7, 5, 6, 9, 8, 8, 7, 8, 7, 7, +6, 7, 7, 1, 1, 3, 3, 3, 3, 3, +3, 3, 3, 3, 2, 2, 1, 5, 3, 3, +3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +3, 2, 2, 1, 1, 1, 1, 1, 1, 1, +1, 1, 4, 7, 3, 6, 3, 3, 1, 3, +1, 1, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 1, 1, 1, 3, 6, 2, 5, 2, +3, 5, 4, 6, 6, 4, 4, 6, 0, 1, +1, 3, 0, 1, 1, 2, 4, 5, 4, 7, +8, 1, 3 }; -static const short yydefact[] = { 2, - 1, 0, 0, 0, 107, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 106, 87, - 112, 110, 25, 111, 104, 105, 0, 0, 0, 0, - 0, 3, 6, 4, 5, 16, 135, 17, 12, 13, - 14, 15, 0, 0, 108, 109, 75, 133, 134, 0, - 28, 119, 0, 0, 0, 18, 19, 0, 0, 107, - 87, 20, 0, 75, 0, 10, 52, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 122, 121, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 138, 148, 0, 85, 86, 0, 103, 102, 22, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 140, 28, 0, 30, - 0, 29, 0, 41, 41, 0, 21, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 136, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 161, 0, 150, 0, 149, 0, 76, 81, 82, - 83, 84, 89, 90, 115, 80, 79, 78, 77, 101, - 117, 118, 96, 97, 93, 94, 91, 92, 98, 95, - 99, 0, 100, 0, 141, 0, 0, 0, 0, 120, - 41, 39, 42, 39, 0, 0, 51, 11, 0, 0, - 0, 0, 0, 0, 39, 0, 0, 0, 0, 8, - 146, 0, 0, 23, 0, 113, 143, 0, 148, 148, - 0, 0, 0, 0, 28, 10, 31, 0, 0, 43, - 43, 60, 62, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 0, 162, 0, - 139, 151, 0, 0, 0, 88, 142, 10, 0, 0, - 39, 40, 0, 0, 0, 0, 63, 71, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 147, 24, 137, 144, 145, 116, 0, 0, 114, - 43, 44, 34, 38, 61, 70, 69, 0, 67, 0, - 0, 0, 72, 73, 152, 0, 58, 53, 54, 26, - 10, 0, 45, 45, 68, 66, 65, 0, 0, 0, - 0, 0, 153, 154, 0, 10, 0, 36, 0, 0, - 47, 46, 0, 64, 0, 0, 0, 0, 0, 155, - 59, 55, 27, 45, 49, 33, 0, 48, 37, 0, - 0, 0, 0, 0, 32, 0, 57, 0, 50, 158, - 156, 0, 0, 0, 10, 35, 0, 157, 0, 56, - 0, 0, 159, 0, 160, 0, 0, 0 +static const short yydefact[] = { 2, +1, 0, 0, 0, 107, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 106, 87, +112, 110, 25, 111, 104, 105, 0, 0, 0, 0, +0, 3, 6, 4, 5, 16, 135, 17, 12, 13, +14, 15, 0, 0, 108, 109, 75, 133, 134, 0, +28, 119, 0, 0, 0, 18, 19, 0, 0, 107, +87, 20, 0, 75, 0, 10, 52, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 122, 121, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 138, 149, 0, 85, 86, 0, 103, 102, 22, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +149, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 140, 28, 0, +30, 0, 29, 0, 41, 41, 0, 21, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 136, 123, 124, 125, 126, 127, 128, 129, 130, +131, 132, 162, 0, 151, 0, 150, 0, 76, 81, +82, 83, 84, 89, 90, 115, 80, 79, 78, 0, +77, 101, 117, 118, 96, 97, 93, 94, 91, 92, +98, 95, 99, 0, 100, 0, 141, 0, 0, 0, +0, 120, 41, 39, 42, 39, 0, 0, 51, 11, +0, 0, 0, 0, 0, 0, 39, 0, 0, 0, +0, 8, 147, 0, 0, 23, 0, 113, 143, 0, +149, 149, 0, 146, 0, 0, 0, 28, 10, 31, +0, 0, 43, 43, 60, 62, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 9, 0, +0, 163, 0, 139, 152, 0, 0, 0, 88, 142, +10, 0, 0, 39, 40, 0, 0, 0, 0, 63, +71, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 7, 148, 24, 137, 144, 145, 116, +0, 0, 114, 43, 44, 34, 38, 61, 70, 69, +0, 67, 0, 0, 0, 72, 73, 153, 0, 58, +53, 54, 26, 10, 0, 45, 45, 68, 66, 65, +0, 0, 0, 0, 0, 154, 155, 0, 10, 0, +36, 0, 0, 47, 46, 0, 64, 0, 0, 0, +0, 0, 156, 59, 55, 27, 45, 49, 33, 0, +48, 37, 0, 0, 0, 0, 0, 32, 0, 57, +0, 50, 159, 157, 0, 0, 0, 10, 35, 0, +158, 0, 56, 0, 0, 160, 0, 161, 0, 0, +0 }; -static const short yydefgoto[] = { 386, - 1, 32, 33, 219, 139, 67, 35, 131, 132, 36, - 37, 240, 202, 274, 340, 341, 68, 38, 289, 316, - 39, 40, 41, 42, 43, 44, 45, 46, 54, 92, - 64, 48, 49, 165, 166, 332, 342, 334, 163 +static const short yydefgoto[] = { 389, +1, 32, 33, 221, 140, 67, 35, 132, 133, 36, +37, 243, 204, 277, 343, 344, 68, 38, 292, 319, +39, 40, 41, 42, 43, 44, 45, 46, 54, 92, +64, 48, 49, 166, 167, 335, 345, 337, 164 }; -static const short yypact[] = {-32768, - 210, -14, -2, -2, -38, -28, -11, 829, 4, 418, - 13, 64, 69, -2, 70, 71, 85, 72,-32768, 52, - 462, -40,-32768,-32768,-32768,-32768, 1225, 1225, 1225, 1225, - 1225,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768, 75, 2688, 560,-32768, 76,-32768,-32768, -22, - 92,-32768, 1225, 81, 86,-32768,-32768, 1225, 88,-32768, --32768,-32768, 1338,-32768, 1225,-32768,-32768, 116, 873, 103, - 107, 90, 1225, 1225, 96, 1225, 1225, 1225,-32768,-32768, - 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, - 1225,-32768, 1225, 93, 30, 30, 1392, 30, 30,-32768, - 1225, 1225, 1225, 1225, 1225, 1225, 108, 1225, 1225, 1225, - 1225, 1225, -2, -2, 1225, 1225, 1225, 1225, 1225, 1225, - 1225, 1225, 1225, 1225, 1225, 917,-32768, 92, 110,-32768, - 98, 95, 1446, 20, 1225, 1500,-32768, 1554, 550, 105, - 961, 1608, 138, 139, 1225, 1662, 1716, 164, 1230, 1284, - 2688, 2688, 2688, 2688, 2688, 2688, 2688, 2688, 2688, 2688, - 2688, 2688, -39, 2688, 117, 115, 119,-32768, 47, 47, - 30, 30, 2945, 2945, -25, 2829, 2887, 30, 2858, 257, --32768,-32768, 421, 421, 2916, 2916, 2945, 2945, 2800, 2771, - 257, 1770, 257, 1225, 2688, 121, 120, 118, 151,-32768, - 1225, 133, 2688, 133, 418, 418,-32768,-32768, 1225, 1005, - 1824, 1049, 1225, 1225, 1878, 132, 134, 155, 11,-32768, --32768, 154, 1225,-32768, 1225, 2950,-32768, 1225, 1225, 1225, - 1225, 1225, -15, 136, 92,-32768,-32768, 101, 159, 141, - 141, 193,-32768, 1932, 418, 1986, 1093, 1137, 2040, 2094, - 2148, 146, 177, 177, 147,-32768, 153, 2202, 2688, 1225, --32768, 2688, 156, 158, -35, 2742,-32768,-32768, 162, 650, - 133,-32768, 1225, 166, 170, 418,-32768,-32768, 418, 418, - 2256, 418, 2310, 1181, 418, 418, 150, 1225, 167, 168, --32768,-32768,-32768, 2688,-32768,-32768,-32768, 695, 160,-32768, - 141, 115, 173, 176,-32768,-32768,-32768, 418,-32768, 418, - 418, 2364,-32768,-32768, 68, 12, 2688,-32768,-32768,-32768, --32768, 171, 94, 94,-32768,-32768,-32768, 418, 161, -21, - 200, 179, 68,-32768, 1225,-32768, 740, 181, 184, 188, - 99, 94, 196,-32768, 1225, 1225, 1225, -18, 195,-32768, - 2688, 144,-32768, 94,-32768,-32768, 199, 99,-32768, 2418, - 2472, -9, 1225, 1225,-32768, 201,-32768, 202,-32768,-32768, --32768, 211, 2526, -8,-32768,-32768, 1225,-32768, 212, 785, - 2580, 1225,-32768, 2634,-32768, 260, 264,-32768 +static const short yypact[] = { -32768, +213, -7, 55, 55, -37, -25, -18, 490, -13, 422, +5, 14, 41, 55, 47, 49, 9, 51,-32768, 57, +566, -23,-32768,-32768,-32768,-32768, 1187, 1187, 1187, 1187, +1187,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768, -5, 2650, 3021,-32768, 35,-32768,-32768, -12, +62,-32768, 1187, 67, 68,-32768,-32768, 1187, 69,-32768, +-32768,-32768, 1300,-32768, 1187,-32768,-32768, 103, 835, 88, +89, 77, 1187, 1187, 73, 1187, 1187, 1187,-32768,-32768, +1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, +1187,-32768, 1187, 96, 219, 219, 1354, 219, 219,-32768, +1187, 1187, 1187, 1187, 1187, 1187, 97, 1187, 1187, 1187, +1187, 1187, 1187, 55, 55, 1187, 1187, 1187, 1187, 1187, +1187, 1187, 1187, 1187, 1187, 1187, 879,-32768, 62, 98, +-32768, 81, 91, 1408, 21, 1187, 1462,-32768, 1516, 556, +95, 923, 1570, 123, 131, 1187, 1624, 1678, 152, 1192, +1246, 2650, 2650, 2650, 2650, 2650, 2650, 2650, 2650, 2650, +2650, 2650, 2650, -38, 2650, 100, 104, 111,-32768, 145, +145, 219, 219, 3015, 3015, -40, 2845, 2939, 219, 112, +2892, 143,-32768,-32768, 277, 277, 2986, 2986, 3015, 3015, +2798, 2751, 143, 1732, 143, 1187, 2650, 113, 116, 107, +135,-32768, 1187, 119, 2650, 119, 422, 422,-32768,-32768, +1187, 967, 1786, 1011, 1187, 1187, 1840, 122, 126, 157, +13,-32768,-32768, 162, 1187,-32768, 1187, 3041,-32768, 1187, +1187, 1187, 1187,-32768, 1187, 44, 144, 62,-32768,-32768, +106, 170, 156, 156, 209,-32768, 1894, 422, 1948, 1055, +1099, 2002, 2056, 2110, 165, 197, 197, 166,-32768, 173, +2164, 2650, 1187,-32768, 2650, 174, 175, -28, 2704,-32768, +-32768, 176, 656, 119,-32768, 1187, 180, 183, 422,-32768, +-32768, 422, 422, 2218, 422, 2272, 1143, 422, 422, 181, +1187, 182, 185,-32768,-32768,-32768, 2650,-32768,-32768,-32768, +701, 184,-32768, 156, 104, 192, 200,-32768,-32768,-32768, +422,-32768, 422, 422, 2326,-32768,-32768, 76, 12, 2650, +-32768,-32768,-32768,-32768, 201, 92, 92,-32768,-32768,-32768, +422, 211, -20, 224, 202, 76,-32768, 1187,-32768, 746, +204, 206, 205, 39, 92, 208,-32768, 1187, 1187, 1187, +-17, 212,-32768, 2650, 138,-32768, 92,-32768,-32768, 216, +39,-32768, 2380, 2434, -21, 1187, 1187,-32768, 221,-32768, +222,-32768,-32768,-32768, 217, 2488, -8,-32768,-32768, 1187, +-32768, 230, 791, 2542, 1187,-32768, 2596,-32768, 289, 290, +-32768 }; -static const short yypgoto[] = {-32768, --32768,-32768,-32768,-32768, -233, 0, -132, -120,-32768,-32768, - -304, -176, -123, -228, -277, -76, -200,-32768, -243,-32768, --32768,-32768,-32768,-32768,-32768, 285,-32768,-32768, 3, -43, - -1,-32768,-32768, -108, -184,-32768, -48, -299, -227 +static const short yypgoto[] = { -32768, +-32768,-32768,-32768,-32768, -236, 0, -132, -118,-32768,-32768, +-306, -192, -113, -231, -262, -54, -202,-32768, -247,-32768, +-32768,-32768,-32768,-32768,-32768, 288,-32768,-32768, 4, -43, +-1,-32768,-32768, -104, -184,-32768, -26, -295, -229 }; -#define YYLAST 3042 +#define YYLAST 3123 -static const short yytable[] = { 47, - 34, 127, 270, 265, 242, 243, 55, 196, 47, 233, - 290, 204, 275, 218, 93, 220, 72, 225, 339, 339, - 56, 225, 59, 50, 3, 4, 60, 241, 346, 230, - 57, 363, 128, 350, 298, 52, 357, 339, 252, 335, - 51, 228, 350, 58, 278, 267, 343, 225, 225, 339, - 94, 18, 53, 357, 19, 61, 21, 22, 65, 226, - 24, 25, 26, 297, 27, 28, 231, 69, 129, 336, - 347, 255, 322, 364, 29, 305, 368, 238, 306, 307, - 107, 309, 30, 31, 313, 314, 256, 337, 302, 372, - 379, 329, 103, 104, 301, 113, 114, 107, 3, 4, - 110, 77, 352, 3, 4, 330, 331, 325, 367, 326, - 327, 201, 113, 114, 269, 181, 182, 329, 70, 362, - 263, 264, 75, 71, 73, 74, 76, 344, 130, 140, - 167, 330, 331, 100, -74, 134, 374, 47, 208, 143, - 135, 380, 51, 144, 145, 175, 59, 197, 3, 4, - 5, 199, 6, 198, 7, 148, 8, 9, 10, 209, - 213, 214, 366, 11, 12, 13, 218, 14, 15, 288, - 16, 228, 227, 229, 235, 18, 234, 236, 19, 20, - 21, 22, 261, 23, 24, 25, 26, 237, 27, 28, - 239, 253, 50, 254, 257, 268, 272, 273, 29, 271, - 276, 287, 288, 47, 47, 291, 30, 31, 292, 315, - 345, 295, 2, 296, 3, 4, 5, 299, 6, 321, - 7, 303, 8, 9, 10, 304, 338, 318, 319, 11, - 12, 13, 323, 14, 15, 324, 16, 348, 17, 349, - 354, 18, 355, 47, 19, 20, 21, 22, 356, 23, - 24, 25, 26, 365, 27, 28, 359, 369, 375, 387, - 377, 382, 376, 388, 29, 358, 333, 0, 47, 208, - 0, 0, 30, 31, 47, 0, 0, 47, 47, 0, - 47, 0, 0, 47, 47, 0, 0, 0, 0, 0, - 0, 0, 63, 0, 0, 0, 47, 208, 0, 0, - 101, 102, 103, 104, 0, 0, 47, 107, 47, 47, - 110, 95, 96, 97, 98, 99, 0, 0, 0, 0, - 0, 0, 113, 114, 0, 0, 47, 115, 116, 0, - 0, 0, 0, 0, 0, 47, 208, 133, 0, 0, - 0, 0, 136, 0, 0, 0, 0, 0, 0, 138, - 47, 208, 0, 142, 0, 0, 0, 146, 147, 0, - 149, 150, 151, 0, 0, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 0, 164, 47, 208, - 0, 0, 0, 0, 0, 169, 170, 171, 172, 173, - 174, 0, 176, 177, 178, 179, 180, 0, 0, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, - 195, 0, 0, 0, 0, 0, 0, 0, 203, 203, - 59, 0, 3, 4, 5, 211, 6, 0, 7, 215, - 8, 9, 10, 0, 0, 0, 0, 11, 12, 13, - 0, 14, 15, 0, 16, 0, 0, 0, 0, 18, - 0, 0, 19, 20, 21, 22, 0, 23, 24, 25, - 26, 0, 27, 28, 101, 102, 103, 104, 0, 0, - 0, 107, 29, 0, 110, 0, 0, 66, 164, 0, - 30, 31, 0, 0, 0, 203, 113, 114, 0, 0, - 0, 0, 0, 244, 246, 0, 249, 250, 251, 0, - 0, 0, 0, 0, 0, 0, 0, 258, 0, 259, - 0, 78, 262, 164, 164, 162, 266, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, - 80, 281, 283, 0, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 294, 0, 0, 0, 0, 0, - 0, 0, 59, 91, 3, 4, 5, 164, 6, 0, - 7, 0, 8, 9, 10, 0, 0, 0, 312, 11, - 12, 13, 317, 14, 15, 0, 16, 0, 0, 0, - 0, 18, 0, 0, 19, 20, 21, 22, 0, 23, - 24, 25, 26, 0, 27, 28, 0, 0, 0, 0, - 0, 0, 0, 0, 29, 0, 0, 0, 0, 126, - 207, 0, 30, 31, 0, 0, 0, 0, 0, 351, - 0, 0, 0, 0, 0, 0, 0, 79, 80, 360, - 361, 162, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 0, 0, 0, 0, 0, 373, 162, 0, - 0, 0, 59, 0, 3, 4, 5, 0, 6, 0, - 7, 381, 8, 9, 10, 0, 384, 0, 0, 11, - 12, 13, 0, 14, 15, 0, 16, 0, 0, 0, - 0, 18, 0, 0, 19, 20, 21, 22, 0, 23, - 24, 25, 26, 0, 27, 28, 0, 59, 0, 3, - 4, 5, 0, 6, 29, 7, 0, 8, 9, 10, - 300, 0, 30, 31, 11, 12, 13, 0, 14, 15, - 0, 16, 0, 0, 0, 0, 18, 0, 0, 19, - 20, 21, 22, 0, 23, 24, 25, 26, 0, 27, - 28, 0, 59, 0, 3, 4, 5, 0, 6, 29, - 7, 0, 8, 9, 10, 320, 0, 30, 31, 11, - 12, 13, 0, 14, 15, 0, 16, 0, 0, 0, - 0, 18, 0, 0, 19, 20, 21, 22, 0, 23, - 24, 25, 26, 0, 27, 28, 0, 59, 0, 3, - 4, 5, 0, 6, 29, 7, 0, 8, 9, 10, - 353, 0, 30, 31, 11, 12, 13, 0, 14, 15, - 0, 16, 0, 0, 0, 0, 18, 0, 0, 19, - 20, 21, 22, 0, 23, 24, 25, 26, 0, 27, - 28, 59, 0, 3, 4, 60, 0, 0, 0, 29, - 0, 0, 0, 0, 0, 0, 0, 30, 31, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 18, 0, 0, 19, 61, 21, 22, 0, 0, 24, - 25, 26, 0, 27, 28, 59, 0, 3, 4, 60, - 0, 0, 0, 29, 0, 0, 0, 62, 0, 0, - 0, 30, 31, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 18, 0, 0, 19, 61, 21, - 22, 0, 0, 24, 25, 26, 0, 27, 28, 59, - 0, 3, 4, 60, 0, 0, 0, 29, 0, 0, - 0, 141, 0, 0, 0, 30, 31, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, - 0, 19, 61, 21, 22, 0, 0, 24, 25, 26, - 0, 27, 28, 59, 0, 3, 4, 60, 0, 0, - 0, 29, 0, 0, 0, 0, 194, 0, 0, 30, - 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 18, 0, 0, 19, 61, 21, 22, 0, - 0, 24, 25, 26, 0, 27, 28, 59, 0, 3, - 4, 60, 0, 0, 0, 29, 0, 0, 0, 210, - 0, 0, 0, 30, 31, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, - 61, 21, 22, 0, 0, 24, 25, 26, 0, 27, - 28, 59, 0, 3, 4, 60, 0, 0, 0, 29, - 245, 0, 0, 0, 0, 0, 0, 30, 31, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 18, 0, 0, 19, 61, 21, 22, 0, 0, 24, - 25, 26, 0, 27, 28, 59, 0, 3, 4, 60, - 0, 0, 0, 29, 0, 0, 0, 248, 0, 0, - 0, 30, 31, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 18, 0, 0, 19, 61, 21, - 22, 0, 0, 24, 25, 26, 0, 27, 28, 59, - 0, 3, 4, 60, 0, 0, 0, 29, 280, 0, - 0, 0, 0, 0, 0, 30, 31, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, - 0, 19, 61, 21, 22, 0, 0, 24, 25, 26, - 0, 27, 28, 59, 0, 3, 4, 60, 0, 0, - 0, 29, 282, 0, 0, 0, 0, 0, 0, 30, - 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 18, 0, 0, 19, 61, 21, 22, 0, - 0, 24, 25, 26, 0, 27, 28, 59, 0, 3, - 4, 60, 0, 0, 0, 29, 311, 0, 0, 0, - 0, 0, 0, 30, 31, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, - 61, 21, 22, 0, 0, 24, 25, 26, 0, 27, - 28, 0, 0, 101, 102, 103, 104, 105, 106, 29, - 107, 108, 109, 110, 0, 221, 222, 30, 31, 0, - 0, 111, 0, 0, 112, 113, 114, 0, 0, 0, - 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 117, 118, 119, 120, 121, 122, 123, - 0, 0, 0, 0, 0, 124, 125, 101, 102, 103, - 104, 105, 106, 0, 107, 108, 109, 110, 0, 0, - 223, 0, 224, 0, 0, 111, 0, 0, 112, 113, - 114, 0, 0, 0, 115, 116, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 117, 118, 119, - 120, 121, 122, 123, 0, 0, 0, 0, 0, 124, - 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, - 109, 110, 0, 0, 0, 0, 137, 0, 0, 111, - 0, 0, 112, 113, 114, 0, 0, 0, 115, 116, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 117, 118, 119, 120, 121, 122, 123, 0, 0, - 0, 0, 0, 124, 125, 101, 102, 103, 104, 105, - 106, 0, 107, 108, 109, 110, 0, 168, 0, 0, - 0, 0, 0, 111, 0, 0, 112, 113, 114, 0, - 0, 0, 115, 116, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 117, 118, 119, 120, 121, - 122, 123, 0, 0, 0, 0, 0, 124, 125, 101, - 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, - 0, 200, 0, 0, 0, 0, 0, 111, 0, 0, - 112, 113, 114, 0, 0, 0, 115, 116, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, - 118, 119, 120, 121, 122, 123, 0, 0, 0, 0, - 0, 124, 125, 101, 102, 103, 104, 105, 106, 0, - 107, 108, 109, 110, 0, 205, 0, 0, 0, 0, - 0, 111, 0, 0, 112, 113, 114, 0, 0, 0, - 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 117, 118, 119, 120, 121, 122, 123, - 0, 0, 0, 0, 0, 124, 125, 101, 102, 103, - 104, 105, 106, 0, 107, 108, 109, 110, 0, 206, - 0, 0, 0, 0, 0, 111, 0, 0, 112, 113, - 114, 0, 0, 0, 115, 116, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 117, 118, 119, - 120, 121, 122, 123, 0, 0, 0, 0, 0, 124, - 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, - 109, 110, 0, 0, 0, 0, 212, 0, 0, 111, - 0, 0, 112, 113, 114, 0, 0, 0, 115, 116, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 117, 118, 119, 120, 121, 122, 123, 0, 0, - 0, 0, 0, 124, 125, 101, 102, 103, 104, 105, - 106, 0, 107, 108, 109, 110, 0, 216, 0, 0, - 0, 0, 0, 111, 0, 0, 112, 113, 114, 0, - 0, 0, 115, 116, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 117, 118, 119, 120, 121, - 122, 123, 0, 0, 0, 0, 0, 124, 125, 101, - 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, - 0, 217, 0, 0, 0, 0, 0, 111, 0, 0, - 112, 113, 114, 0, 0, 0, 115, 116, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, - 118, 119, 120, 121, 122, 123, 0, 0, 0, 0, - 0, 124, 125, 101, 102, 103, 104, 105, 106, 0, - 107, 108, 109, 110, 0, 0, 0, 232, 0, 0, - 0, 111, 0, 0, 112, 113, 114, 0, 0, 0, - 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 117, 118, 119, 120, 121, 122, 123, - 0, 0, 0, 0, 0, 124, 125, 101, 102, 103, - 104, 105, 106, 0, 107, 108, 109, 110, 0, 0, - 0, 0, 247, 0, 0, 111, 0, 0, 112, 113, - 114, 0, 0, 0, 115, 116, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 117, 118, 119, - 120, 121, 122, 123, 0, 0, 0, 0, 0, 124, - 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, - 109, 110, 0, 0, 0, 239, 0, 0, 0, 111, - 0, 0, 112, 113, 114, 0, 0, 0, 115, 116, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 117, 118, 119, 120, 121, 122, 123, 0, 0, - 0, 0, 0, 124, 125, 101, 102, 103, 104, 105, - 106, 0, 107, 108, 109, 110, 0, 277, 0, 0, - 0, 0, 0, 111, 0, 0, 112, 113, 114, 0, - 0, 0, 115, 116, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 117, 118, 119, 120, 121, - 122, 123, 0, 0, 0, 0, 0, 124, 125, 101, - 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, - 0, 279, 0, 0, 0, 0, 0, 111, 0, 0, - 112, 113, 114, 0, 0, 0, 115, 116, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, - 118, 119, 120, 121, 122, 123, 0, 0, 0, 0, - 0, 124, 125, 101, 102, 103, 104, 105, 106, 0, - 107, 108, 109, 110, 0, 0, 0, 0, 284, 0, - 0, 111, 0, 0, 112, 113, 114, 0, 0, 0, - 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 117, 118, 119, 120, 121, 122, 123, - 0, 0, 0, 0, 0, 124, 125, 101, 102, 103, - 104, 105, 106, 0, 107, 108, 109, 110, 0, 285, - 0, 0, 0, 0, 0, 111, 0, 0, 112, 113, - 114, 0, 0, 0, 115, 116, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 117, 118, 119, - 120, 121, 122, 123, 0, 0, 0, 0, 0, 124, - 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, - 109, 110, 0, 286, 0, 0, 0, 0, 0, 111, - 0, 0, 112, 113, 114, 0, 0, 0, 115, 116, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 117, 118, 119, 120, 121, 122, 123, 0, 0, - 0, 0, 0, 124, 125, 101, 102, 103, 104, 105, - 106, 0, 107, 108, 109, 110, 0, 0, 0, 0, - 293, 0, 0, 111, 0, 0, 112, 113, 114, 0, - 0, 0, 115, 116, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 117, 118, 119, 120, 121, - 122, 123, 0, 0, 0, 0, 0, 124, 125, 101, - 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, - 0, 308, 0, 0, 0, 0, 0, 111, 0, 0, - 112, 113, 114, 0, 0, 0, 115, 116, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, - 118, 119, 120, 121, 122, 123, 0, 0, 0, 0, - 0, 124, 125, 101, 102, 103, 104, 105, 106, 0, - 107, 108, 109, 110, 0, 310, 0, 0, 0, 0, - 0, 111, 0, 0, 112, 113, 114, 0, 0, 0, - 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 117, 118, 119, 120, 121, 122, 123, - 0, 0, 0, 0, 0, 124, 125, 101, 102, 103, - 104, 105, 106, 0, 107, 108, 109, 110, 0, 328, - 0, 0, 0, 0, 0, 111, 0, 0, 112, 113, - 114, 0, 0, 0, 115, 116, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 117, 118, 119, - 120, 121, 122, 123, 0, 0, 0, 0, 0, 124, - 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, - 109, 110, 0, 0, 0, 0, 370, 0, 0, 111, - 0, 0, 112, 113, 114, 0, 0, 0, 115, 116, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 117, 118, 119, 120, 121, 122, 123, 0, 0, - 0, 0, 0, 124, 125, 101, 102, 103, 104, 105, - 106, 0, 107, 108, 109, 110, 0, 0, 0, 0, - 371, 0, 0, 111, 0, 0, 112, 113, 114, 0, - 0, 0, 115, 116, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 117, 118, 119, 120, 121, - 122, 123, 0, 0, 0, 0, 0, 124, 125, 101, - 102, 103, 104, 105, 106, 0, 107, 108, 109, 110, - 0, 0, 0, 0, 378, 0, 0, 111, 0, 0, - 112, 113, 114, 0, 0, 0, 115, 116, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, - 118, 119, 120, 121, 122, 123, 0, 0, 0, 0, - 0, 124, 125, 101, 102, 103, 104, 105, 106, 0, - 107, 108, 109, 110, 0, 0, 0, 0, 383, 0, - 0, 111, 0, 0, 112, 113, 114, 0, 0, 0, - 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 117, 118, 119, 120, 121, 122, 123, - 0, 0, 0, 0, 0, 124, 125, 101, 102, 103, - 104, 105, 106, 0, 107, 108, 109, 110, 0, 0, - 0, 0, 385, 0, 0, 111, 0, 0, 112, 113, - 114, 0, 0, 0, 115, 116, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 117, 118, 119, - 120, 121, 122, 123, 0, 0, 0, 0, 0, 124, - 125, 101, 102, 103, 104, 105, 106, 0, 107, 108, - 109, 110, 0, 0, 0, 0, 0, 0, 0, 111, - 0, 0, 112, 113, 114, 0, 0, 0, 115, 116, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 117, 118, 119, 120, 121, 122, 123, 0, 0, - 0, 0, 0, 124, 125, 101, 102, 103, 104, 105, - 106, 0, 107, 108, 109, 110, 0, 0, 0, 0, - 0, 0, 0, 111, 0, 0, 112, 113, 114, 0, - 0, 0, 115, 116, 101, 102, 103, 104, 105, 106, - 0, 107, 108, 109, 110, 117, 118, 119, 120, 121, - 122, 123, 111, 0, 0, 112, 113, 114, 125, 0, - 0, 115, 116, 101, 102, 103, 104, 105, 106, 0, - 107, 108, 109, 110, 117, 118, 119, 120, 121, 0, - 123, 111, 0, 0, 112, 113, 114, 125, 0, 0, - 115, 116, 101, 102, 103, 104, 105, 106, 0, 107, - 0, 109, 110, 117, 118, 119, 120, 0, 0, 123, - 111, 0, 0, 112, 113, 114, 125, 0, 0, 115, - 116, 101, 102, 103, 104, 105, 106, 0, 107, 0, - 109, 110, 117, 118, 119, 120, 0, 0, 123, 0, - 0, 0, 112, 113, 114, 125, 0, 0, 115, 116, - 101, 102, 103, 104, 105, 106, 0, 107, 0, 0, - 110, 117, 118, 119, 120, 0, 0, 123, 0, 0, - 0, 112, 113, 114, 125, 0, 0, 115, 116, 101, - 102, 103, 104, 105, 106, 0, 107, 0, 0, 110, - 117, 118, 119, 120, 0, 0, 123, 0, 0, 0, - 112, 113, 114, 125, 0, 0, 115, 116, 101, 102, - 103, 104, 0, 0, 0, 107, 0, 0, 110, 260, - 0, 119, 120, 0, 0, 123, 0, 0, 0, 112, - 113, 114, 125, 0, 0, 115, 116, 79, 80, 0, - 0, 0, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 0, 0, 123, 0, 0, 0, 0, 0, - 0, 125 +static const short yytable[] = { 47, +34, 128, 273, 268, 245, 246, 180, 55, 47, 293, +198, 236, 278, 244, 232, 220, 222, 72, 227, 342, +342, 56, 206, 59, 255, 3, 4, 60, 227, 349, +50, 93, 366, 57, 301, 227, 58, 360, 342, 338, +353, 65, 129, 3, 4, 281, 75, 51, 227, 353, +342, 233, 18, 100, 360, 19, 61, 21, 22, 69, +228, 24, 25, 26, 346, 27, 28, 94, 70, 339, +300, 350, 325, 258, 367, 29, 308, 375, 130, 309, +310, 304, 312, 30, 31, 316, 317, 340, 259, 241, +382, 305, 52, -74, 371, 71, 3, 4, 131, 332, +230, 73, 355, 74, 270, 76, 77, 370, 328, 53, +329, 330, 203, 333, 334, 332, 141, 183, 184, 272, +365, 135, 136, 51, 144, 145, 266, 267, 347, 333, +334, 146, 149, 168, 176, 199, 200, 377, 47, 210, +59, 383, 3, 4, 5, 215, 6, 201, 7, 211, +8, 9, 10, 216, 220, 229, 369, 11, 12, 13, +230, 14, 15, 291, 16, 231, 239, 234, 237, 18, +238, 240, 19, 20, 21, 22, 242, 23, 24, 25, +26, 256, 27, 28, 264, 257, 101, 102, 103, 104, +103, 104, 29, 107, 50, 107, 110, 111, 110, 111, +30, 31, 260, 271, 274, 47, 47, 275, 114, 115, +114, 115, 276, 116, 117, 2, 279, 3, 4, 5, +290, 6, 291, 7, 294, 8, 9, 10, 295, 298, +299, 302, 11, 12, 13, 306, 14, 15, 307, 16, +318, 17, 321, 324, 18, 322, 47, 19, 20, 21, +22, 326, 23, 24, 25, 26, 341, 27, 28, 327, +348, 351, 352, 357, 358, 359, 380, 29, 362, 107, +368, 47, 210, 111, 372, 30, 31, 47, 378, 385, +47, 47, 379, 47, 114, 115, 47, 47, 390, 391, +361, 336, 0, 0, 0, 63, 0, 0, 0, 47, +210, 0, 0, 0, 0, 0, 0, 0, 0, 47, +0, 47, 47, 0, 95, 96, 97, 98, 99, 0, +101, 102, 103, 104, 0, 0, 0, 107, 0, 47, +110, 111, 0, 0, 0, 0, 0, 0, 47, 210, +134, 0, 114, 115, 0, 137, 0, 0, 0, 0, +0, 0, 139, 47, 210, 0, 143, 0, 0, 0, +147, 148, 0, 150, 151, 152, 0, 0, 153, 154, +155, 156, 157, 158, 159, 160, 161, 162, 163, 0, +165, 47, 210, 0, 0, 0, 0, 0, 170, 171, +172, 173, 174, 175, 0, 177, 178, 179, 165, 181, +182, 0, 0, 185, 186, 187, 188, 189, 190, 191, +192, 193, 194, 195, 197, 0, 0, 0, 0, 0, +0, 0, 205, 205, 59, 0, 3, 4, 5, 213, +6, 0, 7, 217, 8, 9, 10, 0, 0, 0, +0, 11, 12, 13, 0, 14, 15, 0, 16, 0, +0, 0, 0, 18, 0, 0, 19, 20, 21, 22, +0, 23, 24, 25, 26, 0, 27, 28, 0, 0, +0, 0, 0, 0, 0, 0, 29, 0, 0, 0, +0, 66, 0, 165, 30, 31, 0, 0, 0, 0, +205, 0, 59, 0, 3, 4, 60, 0, 247, 249, +0, 252, 253, 254, 0, 0, 0, 0, 0, 0, +0, 0, 261, 0, 262, 0, 0, 265, 165, 165, +163, 18, 269, 0, 19, 61, 21, 22, 0, 0, +24, 25, 26, 0, 27, 28, 0, 284, 286, 0, +0, 0, 0, 0, 29, 0, 0, 0, 62, 0, +297, 0, 30, 31, 0, 0, 0, 0, 59, 0, +3, 4, 5, 165, 6, 0, 7, 0, 8, 9, +10, 0, 0, 0, 315, 11, 12, 13, 320, 14, +15, 0, 16, 0, 0, 0, 0, 18, 0, 0, +19, 20, 21, 22, 0, 23, 24, 25, 26, 0, +27, 28, 0, 0, 0, 0, 0, 0, 0, 0, +29, 0, 0, 0, 0, 78, 209, 0, 30, 31, +0, 0, 0, 0, 0, 354, 0, 0, 0, 0, +0, 0, 0, 79, 80, 363, 364, 163, 81, 82, +83, 84, 85, 86, 87, 88, 89, 90, 0, 0, +0, 0, 0, 376, 163, 0, 0, 91, 59, 0, +3, 4, 5, 0, 6, 0, 7, 384, 8, 9, +10, 0, 387, 0, 0, 11, 12, 13, 0, 14, +15, 0, 16, 0, 0, 0, 0, 18, 0, 0, +19, 20, 21, 22, 0, 23, 24, 25, 26, 0, +27, 28, 0, 59, 0, 3, 4, 5, 0, 6, +29, 7, 0, 8, 9, 10, 303, 0, 30, 31, +11, 12, 13, 0, 14, 15, 0, 16, 0, 0, +0, 0, 18, 0, 0, 19, 20, 21, 22, 0, +23, 24, 25, 26, 0, 27, 28, 0, 59, 0, +3, 4, 5, 0, 6, 29, 7, 0, 8, 9, +10, 323, 0, 30, 31, 11, 12, 13, 0, 14, +15, 0, 16, 0, 0, 0, 0, 18, 0, 0, +19, 20, 21, 22, 0, 23, 24, 25, 26, 0, +27, 28, 0, 59, 0, 3, 4, 5, 0, 6, +29, 7, 0, 8, 9, 10, 356, 0, 30, 31, +11, 12, 13, 0, 14, 15, 0, 16, 0, 0, +0, 0, 18, 0, 0, 19, 20, 21, 22, 0, +23, 24, 25, 26, 0, 27, 28, 59, 0, 3, +4, 60, 0, 0, 0, 29, 0, 0, 0, 0, +0, 0, 0, 30, 31, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 18, 0, 0, 19, +61, 21, 22, 0, 0, 24, 25, 26, 0, 27, +28, 59, 0, 3, 4, 60, 0, 0, 0, 29, +0, 0, 0, 142, 0, 0, 0, 30, 31, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +18, 0, 0, 19, 61, 21, 22, 0, 0, 24, +25, 26, 0, 27, 28, 59, 0, 3, 4, 60, +0, 0, 0, 29, 0, 0, 0, 0, 196, 0, +0, 30, 31, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 18, 0, 0, 19, 61, 21, +22, 0, 0, 24, 25, 26, 0, 27, 28, 59, +0, 3, 4, 60, 0, 0, 0, 29, 0, 0, +0, 212, 0, 0, 0, 30, 31, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 18, 0, +0, 19, 61, 21, 22, 0, 0, 24, 25, 26, +0, 27, 28, 59, 0, 3, 4, 60, 0, 0, +0, 29, 248, 0, 0, 0, 0, 0, 0, 30, +31, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 18, 0, 0, 19, 61, 21, 22, 0, +0, 24, 25, 26, 0, 27, 28, 59, 0, 3, +4, 60, 0, 0, 0, 29, 0, 0, 0, 251, +0, 0, 0, 30, 31, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 18, 0, 0, 19, +61, 21, 22, 0, 0, 24, 25, 26, 0, 27, +28, 59, 0, 3, 4, 60, 0, 0, 0, 29, +283, 0, 0, 0, 0, 0, 0, 30, 31, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +18, 0, 0, 19, 61, 21, 22, 0, 0, 24, +25, 26, 0, 27, 28, 59, 0, 3, 4, 60, +0, 0, 0, 29, 285, 0, 0, 0, 0, 0, +0, 30, 31, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 18, 0, 0, 19, 61, 21, +22, 0, 0, 24, 25, 26, 0, 27, 28, 59, +0, 3, 4, 60, 0, 0, 0, 29, 314, 0, +0, 0, 0, 0, 0, 30, 31, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 18, 0, +0, 19, 61, 21, 22, 0, 0, 24, 25, 26, +0, 27, 28, 0, 0, 101, 102, 103, 104, 105, +106, 29, 107, 108, 109, 110, 111, 223, 224, 30, +31, 0, 0, 112, 0, 0, 113, 114, 115, 0, +0, 0, 116, 117, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 118, 119, 120, 121, 122, +123, 124, 0, 0, 0, 0, 0, 125, 126, 101, +102, 103, 104, 105, 106, 0, 107, 108, 109, 110, +111, 0, 225, 0, 226, 0, 0, 112, 0, 0, +113, 114, 115, 0, 0, 0, 116, 117, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 118, +119, 120, 121, 122, 123, 124, 0, 0, 0, 0, +0, 125, 126, 101, 102, 103, 104, 105, 106, 0, +107, 108, 109, 110, 111, 0, 0, 0, 138, 0, +0, 112, 0, 0, 113, 114, 115, 0, 0, 0, +116, 117, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 118, 119, 120, 121, 122, 123, 124, +0, 0, 0, 0, 0, 125, 126, 101, 102, 103, +104, 105, 106, 0, 107, 108, 109, 110, 111, 169, +0, 0, 0, 0, 0, 112, 0, 0, 113, 114, +115, 0, 0, 0, 116, 117, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 118, 119, 120, +121, 122, 123, 124, 0, 0, 0, 0, 0, 125, +126, 101, 102, 103, 104, 105, 106, 0, 107, 108, +109, 110, 111, 202, 0, 0, 0, 0, 0, 112, +0, 0, 113, 114, 115, 0, 0, 0, 116, 117, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 118, 119, 120, 121, 122, 123, 124, 0, 0, +0, 0, 0, 125, 126, 101, 102, 103, 104, 105, +106, 0, 107, 108, 109, 110, 111, 207, 0, 0, +0, 0, 0, 112, 0, 0, 113, 114, 115, 0, +0, 0, 116, 117, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 118, 119, 120, 121, 122, +123, 124, 0, 0, 0, 0, 0, 125, 126, 101, +102, 103, 104, 105, 106, 0, 107, 108, 109, 110, +111, 208, 0, 0, 0, 0, 0, 112, 0, 0, +113, 114, 115, 0, 0, 0, 116, 117, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 118, +119, 120, 121, 122, 123, 124, 0, 0, 0, 0, +0, 125, 126, 101, 102, 103, 104, 105, 106, 0, +107, 108, 109, 110, 111, 0, 0, 0, 214, 0, +0, 112, 0, 0, 113, 114, 115, 0, 0, 0, +116, 117, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 118, 119, 120, 121, 122, 123, 124, +0, 0, 0, 0, 0, 125, 126, 101, 102, 103, +104, 105, 106, 0, 107, 108, 109, 110, 111, 218, +0, 0, 0, 0, 0, 112, 0, 0, 113, 114, +115, 0, 0, 0, 116, 117, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 118, 119, 120, +121, 122, 123, 124, 0, 0, 0, 0, 0, 125, +126, 101, 102, 103, 104, 105, 106, 0, 107, 108, +109, 110, 111, 219, 0, 0, 0, 0, 0, 112, +0, 0, 113, 114, 115, 0, 0, 0, 116, 117, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 118, 119, 120, 121, 122, 123, 124, 0, 0, +0, 0, 0, 125, 126, 101, 102, 103, 104, 105, +106, 0, 107, 108, 109, 110, 111, 0, 0, 235, +0, 0, 0, 112, 0, 0, 113, 114, 115, 0, +0, 0, 116, 117, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 118, 119, 120, 121, 122, +123, 124, 0, 0, 0, 0, 0, 125, 126, 101, +102, 103, 104, 105, 106, 0, 107, 108, 109, 110, +111, 0, 0, 0, 250, 0, 0, 112, 0, 0, +113, 114, 115, 0, 0, 0, 116, 117, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 118, +119, 120, 121, 122, 123, 124, 0, 0, 0, 0, +0, 125, 126, 101, 102, 103, 104, 105, 106, 0, +107, 108, 109, 110, 111, 0, 0, 242, 0, 0, +0, 112, 0, 0, 113, 114, 115, 0, 0, 0, +116, 117, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 118, 119, 120, 121, 122, 123, 124, +0, 0, 0, 0, 0, 125, 126, 101, 102, 103, +104, 105, 106, 0, 107, 108, 109, 110, 111, 280, +0, 0, 0, 0, 0, 112, 0, 0, 113, 114, +115, 0, 0, 0, 116, 117, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 118, 119, 120, +121, 122, 123, 124, 0, 0, 0, 0, 0, 125, +126, 101, 102, 103, 104, 105, 106, 0, 107, 108, +109, 110, 111, 282, 0, 0, 0, 0, 0, 112, +0, 0, 113, 114, 115, 0, 0, 0, 116, 117, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 118, 119, 120, 121, 122, 123, 124, 0, 0, +0, 0, 0, 125, 126, 101, 102, 103, 104, 105, +106, 0, 107, 108, 109, 110, 111, 0, 0, 0, +287, 0, 0, 112, 0, 0, 113, 114, 115, 0, +0, 0, 116, 117, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 118, 119, 120, 121, 122, +123, 124, 0, 0, 0, 0, 0, 125, 126, 101, +102, 103, 104, 105, 106, 0, 107, 108, 109, 110, +111, 288, 0, 0, 0, 0, 0, 112, 0, 0, +113, 114, 115, 0, 0, 0, 116, 117, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 118, +119, 120, 121, 122, 123, 124, 0, 0, 0, 0, +0, 125, 126, 101, 102, 103, 104, 105, 106, 0, +107, 108, 109, 110, 111, 289, 0, 0, 0, 0, +0, 112, 0, 0, 113, 114, 115, 0, 0, 0, +116, 117, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 118, 119, 120, 121, 122, 123, 124, +0, 0, 0, 0, 0, 125, 126, 101, 102, 103, +104, 105, 106, 0, 107, 108, 109, 110, 111, 0, +0, 0, 296, 0, 0, 112, 0, 0, 113, 114, +115, 0, 0, 0, 116, 117, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 118, 119, 120, +121, 122, 123, 124, 0, 0, 0, 0, 0, 125, +126, 101, 102, 103, 104, 105, 106, 0, 107, 108, +109, 110, 111, 311, 0, 0, 0, 0, 0, 112, +0, 0, 113, 114, 115, 0, 0, 0, 116, 117, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 118, 119, 120, 121, 122, 123, 124, 0, 0, +0, 0, 0, 125, 126, 101, 102, 103, 104, 105, +106, 0, 107, 108, 109, 110, 111, 313, 0, 0, +0, 0, 0, 112, 0, 0, 113, 114, 115, 0, +0, 0, 116, 117, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 118, 119, 120, 121, 122, +123, 124, 0, 0, 0, 0, 0, 125, 126, 101, +102, 103, 104, 105, 106, 0, 107, 108, 109, 110, +111, 331, 0, 0, 0, 0, 0, 112, 0, 0, +113, 114, 115, 0, 0, 0, 116, 117, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 118, +119, 120, 121, 122, 123, 124, 0, 0, 0, 0, +0, 125, 126, 101, 102, 103, 104, 105, 106, 0, +107, 108, 109, 110, 111, 0, 0, 0, 373, 0, +0, 112, 0, 0, 113, 114, 115, 0, 0, 0, +116, 117, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 118, 119, 120, 121, 122, 123, 124, +0, 0, 0, 0, 0, 125, 126, 101, 102, 103, +104, 105, 106, 0, 107, 108, 109, 110, 111, 0, +0, 0, 374, 0, 0, 112, 0, 0, 113, 114, +115, 0, 0, 0, 116, 117, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 118, 119, 120, +121, 122, 123, 124, 0, 0, 0, 0, 0, 125, +126, 101, 102, 103, 104, 105, 106, 0, 107, 108, +109, 110, 111, 0, 0, 0, 381, 0, 0, 112, +0, 0, 113, 114, 115, 0, 0, 0, 116, 117, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 118, 119, 120, 121, 122, 123, 124, 0, 0, +0, 0, 0, 125, 126, 101, 102, 103, 104, 105, +106, 0, 107, 108, 109, 110, 111, 0, 0, 0, +386, 0, 0, 112, 0, 0, 113, 114, 115, 0, +0, 0, 116, 117, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 118, 119, 120, 121, 122, +123, 124, 0, 0, 0, 0, 0, 125, 126, 101, +102, 103, 104, 105, 106, 0, 107, 108, 109, 110, +111, 0, 0, 0, 388, 0, 0, 112, 0, 0, +113, 114, 115, 0, 0, 0, 116, 117, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 118, +119, 120, 121, 122, 123, 124, 0, 0, 0, 0, +0, 125, 126, 101, 102, 103, 104, 105, 106, 0, +107, 108, 109, 110, 111, 0, 0, 0, 0, 0, +0, 112, 0, 0, 113, 114, 115, 0, 0, 0, +116, 117, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 118, 119, 120, 121, 122, 123, 124, +0, 0, 0, 0, 0, 125, 126, 101, 102, 103, +104, 105, 106, 0, 107, 108, 109, 110, 111, 0, +0, 0, 0, 0, 0, 112, 0, 0, 113, 114, +115, 0, 0, 0, 116, 117, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 118, 119, 120, +121, 122, 123, 124, 101, 102, 103, 104, 105, 106, +126, 107, 108, 109, 110, 111, 0, 0, 0, 0, +0, 0, 112, 0, 0, 113, 114, 115, 0, 0, +0, 116, 117, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 118, 119, 120, 121, 122, 0, +124, 101, 102, 103, 104, 105, 106, 126, 107, 108, +109, 110, 111, 0, 0, 0, 0, 0, 0, 112, +0, 0, 113, 114, 115, 0, 0, 0, 116, 117, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 118, 119, 120, 121, 0, 0, 124, 101, 102, +103, 104, 105, 106, 126, 107, 0, 109, 110, 111, +0, 0, 0, 0, 0, 0, 112, 0, 0, 113, +114, 115, 0, 0, 0, 116, 117, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 118, 119, +120, 121, 0, 0, 124, 101, 102, 103, 104, 105, +106, 126, 107, 0, 109, 110, 111, 0, 0, 0, +0, 0, 0, 0, 0, 0, 113, 114, 115, 0, +0, 0, 116, 117, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 118, 119, 120, 121, 0, +0, 124, 101, 102, 103, 104, 105, 106, 126, 107, +0, 0, 110, 111, 0, 0, 0, 0, 0, 0, +0, 0, 0, 113, 114, 115, 0, 0, 0, 116, +117, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 118, 119, 120, 121, 0, 0, 124, 101, +102, 103, 104, 105, 106, 126, 107, 0, 0, 110, +111, 0, 0, 0, 0, 0, 0, 0, 0, 0, +113, 114, 115, 0, 0, 0, 116, 117, 101, 102, +103, 104, 0, 0, 0, 107, 0, 0, 110, 111, +127, 120, 121, 0, 0, 124, 0, 0, 0, 113, +114, 115, 126, 0, 0, 116, 117, 0, 79, 80, +263, 0, 0, 81, 82, 83, 84, 85, 86, 87, +88, 89, 90, 0, 124, 0, 0, 0, 79, 80, +0, 126, 0, 81, 82, 83, 84, 85, 86, 87, +88, 89, 90 }; -static const short yycheck[] = { 1, - 1, 45, 236, 231, 205, 206, 4, 128, 10, 194, - 254, 135, 241, 3, 55, 148, 14, 57, 323, 324, - 59, 57, 3, 38, 5, 6, 7, 204, 50, 55, - 59, 50, 55, 333, 268, 38, 341, 342, 215, 28, - 55, 57, 342, 55, 245, 61, 324, 57, 57, 354, - 91, 32, 55, 358, 35, 36, 37, 38, 55, 99, - 41, 42, 43, 99, 45, 46, 92, 55, 91, 58, - 92, 61, 301, 92, 55, 276, 354, 201, 279, 280, - 51, 282, 63, 64, 285, 286, 219, 321, 273, 99, - 99, 24, 46, 47, 271, 66, 67, 51, 5, 6, - 54, 50, 336, 5, 6, 38, 39, 308, 352, 310, - 311, 92, 66, 67, 235, 113, 114, 24, 55, 347, - 229, 230, 38, 55, 55, 55, 55, 328, 37, 14, - 38, 38, 39, 59, 59, 55, 364, 139, 139, 37, - 55, 375, 55, 37, 55, 38, 3, 38, 5, 6, - 7, 57, 9, 56, 11, 60, 13, 14, 15, 55, - 23, 23, 19, 20, 21, 22, 3, 24, 25, 26, - 27, 57, 56, 55, 55, 32, 56, 60, 35, 36, - 37, 38, 226, 40, 41, 42, 43, 37, 45, 46, - 58, 60, 38, 60, 41, 60, 38, 57, 55, 99, - 8, 56, 26, 205, 206, 59, 63, 64, 56, 60, - 50, 56, 3, 56, 5, 6, 7, 56, 9, 60, - 11, 56, 13, 14, 15, 56, 56, 61, 61, 20, - 21, 22, 60, 24, 25, 60, 27, 38, 29, 61, - 60, 32, 59, 245, 35, 36, 37, 38, 61, 40, - 41, 42, 43, 59, 45, 46, 61, 59, 58, 0, - 50, 50, 61, 0, 55, 342, 315, -1, 270, 270, - -1, -1, 63, 64, 276, -1, -1, 279, 280, -1, - 282, -1, -1, 285, 286, -1, -1, -1, -1, -1, - -1, -1, 8, -1, -1, -1, 298, 298, -1, -1, - 44, 45, 46, 47, -1, -1, 308, 51, 310, 311, - 54, 27, 28, 29, 30, 31, -1, -1, -1, -1, - -1, -1, 66, 67, -1, -1, 328, 71, 72, -1, - -1, -1, -1, -1, -1, 337, 337, 53, -1, -1, - -1, -1, 58, -1, -1, -1, -1, -1, -1, 65, - 352, 352, -1, 69, -1, -1, -1, 73, 74, -1, - 76, 77, 78, -1, -1, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, -1, 93, 380, 380, - -1, -1, -1, -1, -1, 101, 102, 103, 104, 105, - 106, -1, 108, 109, 110, 111, 112, -1, -1, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, -1, -1, -1, -1, -1, -1, -1, 134, 135, - 3, -1, 5, 6, 7, 141, 9, -1, 11, 145, - 13, 14, 15, -1, -1, -1, -1, 20, 21, 22, - -1, 24, 25, -1, 27, -1, -1, -1, -1, 32, - -1, -1, 35, 36, 37, 38, -1, 40, 41, 42, - 43, -1, 45, 46, 44, 45, 46, 47, -1, -1, - -1, 51, 55, -1, 54, -1, -1, 60, 194, -1, - 63, 64, -1, -1, -1, 201, 66, 67, -1, -1, - -1, -1, -1, 209, 210, -1, 212, 213, 214, -1, - -1, -1, -1, -1, -1, -1, -1, 223, -1, 225, - -1, 50, 228, 229, 230, 231, 232, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 68, - 69, 247, 248, -1, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 260, -1, -1, -1, -1, -1, - -1, -1, 3, 92, 5, 6, 7, 273, 9, -1, - 11, -1, 13, 14, 15, -1, -1, -1, 284, 20, - 21, 22, 288, 24, 25, -1, 27, -1, -1, -1, - -1, 32, -1, -1, 35, 36, 37, 38, -1, 40, - 41, 42, 43, -1, 45, 46, -1, -1, -1, -1, - -1, -1, -1, -1, 55, -1, -1, -1, -1, 50, - 61, -1, 63, 64, -1, -1, -1, -1, -1, 335, - -1, -1, -1, -1, -1, -1, -1, 68, 69, 345, - 346, 347, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, -1, -1, -1, -1, -1, 363, 364, -1, - -1, -1, 3, -1, 5, 6, 7, -1, 9, -1, - 11, 377, 13, 14, 15, -1, 382, -1, -1, 20, - 21, 22, -1, 24, 25, -1, 27, -1, -1, -1, - -1, 32, -1, -1, 35, 36, 37, 38, -1, 40, - 41, 42, 43, -1, 45, 46, -1, 3, -1, 5, - 6, 7, -1, 9, 55, 11, -1, 13, 14, 15, - 61, -1, 63, 64, 20, 21, 22, -1, 24, 25, - -1, 27, -1, -1, -1, -1, 32, -1, -1, 35, - 36, 37, 38, -1, 40, 41, 42, 43, -1, 45, - 46, -1, 3, -1, 5, 6, 7, -1, 9, 55, - 11, -1, 13, 14, 15, 61, -1, 63, 64, 20, - 21, 22, -1, 24, 25, -1, 27, -1, -1, -1, - -1, 32, -1, -1, 35, 36, 37, 38, -1, 40, - 41, 42, 43, -1, 45, 46, -1, 3, -1, 5, - 6, 7, -1, 9, 55, 11, -1, 13, 14, 15, - 61, -1, 63, 64, 20, 21, 22, -1, 24, 25, - -1, 27, -1, -1, -1, -1, 32, -1, -1, 35, - 36, 37, 38, -1, 40, 41, 42, 43, -1, 45, - 46, 3, -1, 5, 6, 7, -1, -1, -1, 55, - -1, -1, -1, -1, -1, -1, -1, 63, 64, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 32, -1, -1, 35, 36, 37, 38, -1, -1, 41, - 42, 43, -1, 45, 46, 3, -1, 5, 6, 7, - -1, -1, -1, 55, -1, -1, -1, 59, -1, -1, - -1, 63, 64, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 32, -1, -1, 35, 36, 37, - 38, -1, -1, 41, 42, 43, -1, 45, 46, 3, - -1, 5, 6, 7, -1, -1, -1, 55, -1, -1, - -1, 59, -1, -1, -1, 63, 64, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 32, -1, - -1, 35, 36, 37, 38, -1, -1, 41, 42, 43, - -1, 45, 46, 3, -1, 5, 6, 7, -1, -1, - -1, 55, -1, -1, -1, -1, 60, -1, -1, 63, - 64, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 32, -1, -1, 35, 36, 37, 38, -1, - -1, 41, 42, 43, -1, 45, 46, 3, -1, 5, - 6, 7, -1, -1, -1, 55, -1, -1, -1, 59, - -1, -1, -1, 63, 64, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 32, -1, -1, 35, - 36, 37, 38, -1, -1, 41, 42, 43, -1, 45, - 46, 3, -1, 5, 6, 7, -1, -1, -1, 55, - 56, -1, -1, -1, -1, -1, -1, 63, 64, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 32, -1, -1, 35, 36, 37, 38, -1, -1, 41, - 42, 43, -1, 45, 46, 3, -1, 5, 6, 7, - -1, -1, -1, 55, -1, -1, -1, 59, -1, -1, - -1, 63, 64, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 32, -1, -1, 35, 36, 37, - 38, -1, -1, 41, 42, 43, -1, 45, 46, 3, - -1, 5, 6, 7, -1, -1, -1, 55, 56, -1, - -1, -1, -1, -1, -1, 63, 64, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 32, -1, - -1, 35, 36, 37, 38, -1, -1, 41, 42, 43, - -1, 45, 46, 3, -1, 5, 6, 7, -1, -1, - -1, 55, 56, -1, -1, -1, -1, -1, -1, 63, - 64, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 32, -1, -1, 35, 36, 37, 38, -1, - -1, 41, 42, 43, -1, 45, 46, 3, -1, 5, - 6, 7, -1, -1, -1, 55, 56, -1, -1, -1, - -1, -1, -1, 63, 64, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 32, -1, -1, 35, - 36, 37, 38, -1, -1, 41, 42, 43, -1, 45, - 46, -1, -1, 44, 45, 46, 47, 48, 49, 55, - 51, 52, 53, 54, -1, 56, 57, 63, 64, -1, - -1, 62, -1, -1, 65, 66, 67, -1, -1, -1, - 71, 72, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 84, 85, 86, 87, 88, 89, 90, - -1, -1, -1, -1, -1, 96, 97, 44, 45, 46, - 47, 48, 49, -1, 51, 52, 53, 54, -1, -1, - 57, -1, 59, -1, -1, 62, -1, -1, 65, 66, - 67, -1, -1, -1, 71, 72, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 84, 85, 86, - 87, 88, 89, 90, -1, -1, -1, -1, -1, 96, - 97, 44, 45, 46, 47, 48, 49, -1, 51, 52, - 53, 54, -1, -1, -1, -1, 59, -1, -1, 62, - -1, -1, 65, 66, 67, -1, -1, -1, 71, 72, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 84, 85, 86, 87, 88, 89, 90, -1, -1, - -1, -1, -1, 96, 97, 44, 45, 46, 47, 48, - 49, -1, 51, 52, 53, 54, -1, 56, -1, -1, - -1, -1, -1, 62, -1, -1, 65, 66, 67, -1, - -1, -1, 71, 72, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 84, 85, 86, 87, 88, - 89, 90, -1, -1, -1, -1, -1, 96, 97, 44, - 45, 46, 47, 48, 49, -1, 51, 52, 53, 54, - -1, 56, -1, -1, -1, -1, -1, 62, -1, -1, - 65, 66, 67, -1, -1, -1, 71, 72, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, - 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, - -1, 96, 97, 44, 45, 46, 47, 48, 49, -1, - 51, 52, 53, 54, -1, 56, -1, -1, -1, -1, - -1, 62, -1, -1, 65, 66, 67, -1, -1, -1, - 71, 72, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 84, 85, 86, 87, 88, 89, 90, - -1, -1, -1, -1, -1, 96, 97, 44, 45, 46, - 47, 48, 49, -1, 51, 52, 53, 54, -1, 56, - -1, -1, -1, -1, -1, 62, -1, -1, 65, 66, - 67, -1, -1, -1, 71, 72, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 84, 85, 86, - 87, 88, 89, 90, -1, -1, -1, -1, -1, 96, - 97, 44, 45, 46, 47, 48, 49, -1, 51, 52, - 53, 54, -1, -1, -1, -1, 59, -1, -1, 62, - -1, -1, 65, 66, 67, -1, -1, -1, 71, 72, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 84, 85, 86, 87, 88, 89, 90, -1, -1, - -1, -1, -1, 96, 97, 44, 45, 46, 47, 48, - 49, -1, 51, 52, 53, 54, -1, 56, -1, -1, - -1, -1, -1, 62, -1, -1, 65, 66, 67, -1, - -1, -1, 71, 72, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 84, 85, 86, 87, 88, - 89, 90, -1, -1, -1, -1, -1, 96, 97, 44, - 45, 46, 47, 48, 49, -1, 51, 52, 53, 54, - -1, 56, -1, -1, -1, -1, -1, 62, -1, -1, - 65, 66, 67, -1, -1, -1, 71, 72, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, - 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, - -1, 96, 97, 44, 45, 46, 47, 48, 49, -1, - 51, 52, 53, 54, -1, -1, -1, 58, -1, -1, - -1, 62, -1, -1, 65, 66, 67, -1, -1, -1, - 71, 72, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 84, 85, 86, 87, 88, 89, 90, - -1, -1, -1, -1, -1, 96, 97, 44, 45, 46, - 47, 48, 49, -1, 51, 52, 53, 54, -1, -1, - -1, -1, 59, -1, -1, 62, -1, -1, 65, 66, - 67, -1, -1, -1, 71, 72, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 84, 85, 86, - 87, 88, 89, 90, -1, -1, -1, -1, -1, 96, - 97, 44, 45, 46, 47, 48, 49, -1, 51, 52, - 53, 54, -1, -1, -1, 58, -1, -1, -1, 62, - -1, -1, 65, 66, 67, -1, -1, -1, 71, 72, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 84, 85, 86, 87, 88, 89, 90, -1, -1, - -1, -1, -1, 96, 97, 44, 45, 46, 47, 48, - 49, -1, 51, 52, 53, 54, -1, 56, -1, -1, - -1, -1, -1, 62, -1, -1, 65, 66, 67, -1, - -1, -1, 71, 72, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 84, 85, 86, 87, 88, - 89, 90, -1, -1, -1, -1, -1, 96, 97, 44, - 45, 46, 47, 48, 49, -1, 51, 52, 53, 54, - -1, 56, -1, -1, -1, -1, -1, 62, -1, -1, - 65, 66, 67, -1, -1, -1, 71, 72, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, - 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, - -1, 96, 97, 44, 45, 46, 47, 48, 49, -1, - 51, 52, 53, 54, -1, -1, -1, -1, 59, -1, - -1, 62, -1, -1, 65, 66, 67, -1, -1, -1, - 71, 72, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 84, 85, 86, 87, 88, 89, 90, - -1, -1, -1, -1, -1, 96, 97, 44, 45, 46, - 47, 48, 49, -1, 51, 52, 53, 54, -1, 56, - -1, -1, -1, -1, -1, 62, -1, -1, 65, 66, - 67, -1, -1, -1, 71, 72, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 84, 85, 86, - 87, 88, 89, 90, -1, -1, -1, -1, -1, 96, - 97, 44, 45, 46, 47, 48, 49, -1, 51, 52, - 53, 54, -1, 56, -1, -1, -1, -1, -1, 62, - -1, -1, 65, 66, 67, -1, -1, -1, 71, 72, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 84, 85, 86, 87, 88, 89, 90, -1, -1, - -1, -1, -1, 96, 97, 44, 45, 46, 47, 48, - 49, -1, 51, 52, 53, 54, -1, -1, -1, -1, - 59, -1, -1, 62, -1, -1, 65, 66, 67, -1, - -1, -1, 71, 72, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 84, 85, 86, 87, 88, - 89, 90, -1, -1, -1, -1, -1, 96, 97, 44, - 45, 46, 47, 48, 49, -1, 51, 52, 53, 54, - -1, 56, -1, -1, -1, -1, -1, 62, -1, -1, - 65, 66, 67, -1, -1, -1, 71, 72, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, - 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, - -1, 96, 97, 44, 45, 46, 47, 48, 49, -1, - 51, 52, 53, 54, -1, 56, -1, -1, -1, -1, - -1, 62, -1, -1, 65, 66, 67, -1, -1, -1, - 71, 72, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 84, 85, 86, 87, 88, 89, 90, - -1, -1, -1, -1, -1, 96, 97, 44, 45, 46, - 47, 48, 49, -1, 51, 52, 53, 54, -1, 56, - -1, -1, -1, -1, -1, 62, -1, -1, 65, 66, - 67, -1, -1, -1, 71, 72, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 84, 85, 86, - 87, 88, 89, 90, -1, -1, -1, -1, -1, 96, - 97, 44, 45, 46, 47, 48, 49, -1, 51, 52, - 53, 54, -1, -1, -1, -1, 59, -1, -1, 62, - -1, -1, 65, 66, 67, -1, -1, -1, 71, 72, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 84, 85, 86, 87, 88, 89, 90, -1, -1, - -1, -1, -1, 96, 97, 44, 45, 46, 47, 48, - 49, -1, 51, 52, 53, 54, -1, -1, -1, -1, - 59, -1, -1, 62, -1, -1, 65, 66, 67, -1, - -1, -1, 71, 72, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 84, 85, 86, 87, 88, - 89, 90, -1, -1, -1, -1, -1, 96, 97, 44, - 45, 46, 47, 48, 49, -1, 51, 52, 53, 54, - -1, -1, -1, -1, 59, -1, -1, 62, -1, -1, - 65, 66, 67, -1, -1, -1, 71, 72, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 84, - 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, - -1, 96, 97, 44, 45, 46, 47, 48, 49, -1, - 51, 52, 53, 54, -1, -1, -1, -1, 59, -1, - -1, 62, -1, -1, 65, 66, 67, -1, -1, -1, - 71, 72, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 84, 85, 86, 87, 88, 89, 90, - -1, -1, -1, -1, -1, 96, 97, 44, 45, 46, - 47, 48, 49, -1, 51, 52, 53, 54, -1, -1, - -1, -1, 59, -1, -1, 62, -1, -1, 65, 66, - 67, -1, -1, -1, 71, 72, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 84, 85, 86, - 87, 88, 89, 90, -1, -1, -1, -1, -1, 96, - 97, 44, 45, 46, 47, 48, 49, -1, 51, 52, - 53, 54, -1, -1, -1, -1, -1, -1, -1, 62, - -1, -1, 65, 66, 67, -1, -1, -1, 71, 72, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 84, 85, 86, 87, 88, 89, 90, -1, -1, - -1, -1, -1, 96, 97, 44, 45, 46, 47, 48, - 49, -1, 51, 52, 53, 54, -1, -1, -1, -1, - -1, -1, -1, 62, -1, -1, 65, 66, 67, -1, - -1, -1, 71, 72, 44, 45, 46, 47, 48, 49, - -1, 51, 52, 53, 54, 84, 85, 86, 87, 88, - 89, 90, 62, -1, -1, 65, 66, 67, 97, -1, - -1, 71, 72, 44, 45, 46, 47, 48, 49, -1, - 51, 52, 53, 54, 84, 85, 86, 87, 88, -1, - 90, 62, -1, -1, 65, 66, 67, 97, -1, -1, - 71, 72, 44, 45, 46, 47, 48, 49, -1, 51, - -1, 53, 54, 84, 85, 86, 87, -1, -1, 90, - 62, -1, -1, 65, 66, 67, 97, -1, -1, 71, - 72, 44, 45, 46, 47, 48, 49, -1, 51, -1, - 53, 54, 84, 85, 86, 87, -1, -1, 90, -1, - -1, -1, 65, 66, 67, 97, -1, -1, 71, 72, - 44, 45, 46, 47, 48, 49, -1, 51, -1, -1, - 54, 84, 85, 86, 87, -1, -1, 90, -1, -1, - -1, 65, 66, 67, 97, -1, -1, 71, 72, 44, - 45, 46, 47, 48, 49, -1, 51, -1, -1, 54, - 84, 85, 86, 87, -1, -1, 90, -1, -1, -1, - 65, 66, 67, 97, -1, -1, 71, 72, 44, 45, - 46, 47, -1, -1, -1, 51, -1, -1, 54, 50, - -1, 86, 87, -1, -1, 90, -1, -1, -1, 65, - 66, 67, 97, -1, -1, 71, 72, 68, 69, -1, - -1, -1, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, -1, -1, 90, -1, -1, -1, -1, -1, - -1, 97 +static const short yycheck[] = { 1, +1, 45, 239, 233, 207, 208, 111, 4, 10, 257, +129, 196, 244, 206, 55, 3, 149, 14, 57, 326, +327, 59, 136, 3, 217, 5, 6, 7, 57, 50, +38, 55, 50, 59, 271, 57, 55, 344, 345, 28, +336, 55, 55, 5, 6, 248, 38, 55, 57, 345, +357, 92, 32, 59, 361, 35, 36, 37, 38, 55, +99, 41, 42, 43, 327, 45, 46, 91, 55, 58, +99, 92, 304, 61, 92, 55, 279, 99, 91, 282, +283, 274, 285, 63, 64, 288, 289, 324, 221, 203, +99, 276, 38, 59, 357, 55, 5, 6, 37, 24, +57, 55, 339, 55, 61, 55, 50, 355, 311, 55, +313, 314, 92, 38, 39, 24, 14, 114, 115, 238, +350, 55, 55, 55, 37, 37, 231, 232, 331, 38, +39, 55, 60, 38, 38, 38, 56, 367, 140, 140, +3, 378, 5, 6, 7, 23, 9, 57, 11, 55, +13, 14, 15, 23, 3, 56, 19, 20, 21, 22, +57, 24, 25, 26, 27, 55, 60, 56, 56, 32, +55, 37, 35, 36, 37, 38, 58, 40, 41, 42, +43, 60, 45, 46, 228, 60, 44, 45, 46, 47, +46, 47, 55, 51, 38, 51, 54, 55, 54, 55, +63, 64, 41, 60, 99, 207, 208, 38, 66, 67, +66, 67, 57, 71, 72, 3, 8, 5, 6, 7, +56, 9, 26, 11, 59, 13, 14, 15, 56, 56, +56, 56, 20, 21, 22, 56, 24, 25, 56, 27, +60, 29, 61, 60, 32, 61, 248, 35, 36, 37, +38, 60, 40, 41, 42, 43, 56, 45, 46, 60, +50, 38, 61, 60, 59, 61, 50, 55, 61, 51, +59, 273, 273, 55, 59, 63, 64, 279, 58, 50, +282, 283, 61, 285, 66, 67, 288, 289, 0, 0, +345, 318, -1, -1, -1, 8, -1, -1, -1, 301, +301, -1, -1, -1, -1, -1, -1, -1, -1, 311, +-1, 313, 314, -1, 27, 28, 29, 30, 31, -1, +44, 45, 46, 47, -1, -1, -1, 51, -1, 331, +54, 55, -1, -1, -1, -1, -1, -1, 340, 340, +53, -1, 66, 67, -1, 58, -1, -1, -1, -1, +-1, -1, 65, 355, 355, -1, 69, -1, -1, -1, +73, 74, -1, 76, 77, 78, -1, -1, 81, 82, +83, 84, 85, 86, 87, 88, 89, 90, 91, -1, +93, 383, 383, -1, -1, -1, -1, -1, 101, 102, +103, 104, 105, 106, -1, 108, 109, 110, 111, 112, +113, -1, -1, 116, 117, 118, 119, 120, 121, 122, +123, 124, 125, 126, 127, -1, -1, -1, -1, -1, +-1, -1, 135, 136, 3, -1, 5, 6, 7, 142, +9, -1, 11, 146, 13, 14, 15, -1, -1, -1, +-1, 20, 21, 22, -1, 24, 25, -1, 27, -1, +-1, -1, -1, 32, -1, -1, 35, 36, 37, 38, +-1, 40, 41, 42, 43, -1, 45, 46, -1, -1, +-1, -1, -1, -1, -1, -1, 55, -1, -1, -1, +-1, 60, -1, 196, 63, 64, -1, -1, -1, -1, +203, -1, 3, -1, 5, 6, 7, -1, 211, 212, +-1, 214, 215, 216, -1, -1, -1, -1, -1, -1, +-1, -1, 225, -1, 227, -1, -1, 230, 231, 232, +233, 32, 235, -1, 35, 36, 37, 38, -1, -1, +41, 42, 43, -1, 45, 46, -1, 250, 251, -1, +-1, -1, -1, -1, 55, -1, -1, -1, 59, -1, +263, -1, 63, 64, -1, -1, -1, -1, 3, -1, +5, 6, 7, 276, 9, -1, 11, -1, 13, 14, +15, -1, -1, -1, 287, 20, 21, 22, 291, 24, +25, -1, 27, -1, -1, -1, -1, 32, -1, -1, +35, 36, 37, 38, -1, 40, 41, 42, 43, -1, +45, 46, -1, -1, -1, -1, -1, -1, -1, -1, +55, -1, -1, -1, -1, 50, 61, -1, 63, 64, +-1, -1, -1, -1, -1, 338, -1, -1, -1, -1, +-1, -1, -1, 68, 69, 348, 349, 350, 73, 74, +75, 76, 77, 78, 79, 80, 81, 82, -1, -1, +-1, -1, -1, 366, 367, -1, -1, 92, 3, -1, +5, 6, 7, -1, 9, -1, 11, 380, 13, 14, +15, -1, 385, -1, -1, 20, 21, 22, -1, 24, +25, -1, 27, -1, -1, -1, -1, 32, -1, -1, +35, 36, 37, 38, -1, 40, 41, 42, 43, -1, +45, 46, -1, 3, -1, 5, 6, 7, -1, 9, +55, 11, -1, 13, 14, 15, 61, -1, 63, 64, +20, 21, 22, -1, 24, 25, -1, 27, -1, -1, +-1, -1, 32, -1, -1, 35, 36, 37, 38, -1, +40, 41, 42, 43, -1, 45, 46, -1, 3, -1, +5, 6, 7, -1, 9, 55, 11, -1, 13, 14, +15, 61, -1, 63, 64, 20, 21, 22, -1, 24, +25, -1, 27, -1, -1, -1, -1, 32, -1, -1, +35, 36, 37, 38, -1, 40, 41, 42, 43, -1, +45, 46, -1, 3, -1, 5, 6, 7, -1, 9, +55, 11, -1, 13, 14, 15, 61, -1, 63, 64, +20, 21, 22, -1, 24, 25, -1, 27, -1, -1, +-1, -1, 32, -1, -1, 35, 36, 37, 38, -1, +40, 41, 42, 43, -1, 45, 46, 3, -1, 5, +6, 7, -1, -1, -1, 55, -1, -1, -1, -1, +-1, -1, -1, 63, 64, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, 32, -1, -1, 35, +36, 37, 38, -1, -1, 41, 42, 43, -1, 45, +46, 3, -1, 5, 6, 7, -1, -1, -1, 55, +-1, -1, -1, 59, -1, -1, -1, 63, 64, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +32, -1, -1, 35, 36, 37, 38, -1, -1, 41, +42, 43, -1, 45, 46, 3, -1, 5, 6, 7, +-1, -1, -1, 55, -1, -1, -1, -1, 60, -1, +-1, 63, 64, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, 32, -1, -1, 35, 36, 37, +38, -1, -1, 41, 42, 43, -1, 45, 46, 3, +-1, 5, 6, 7, -1, -1, -1, 55, -1, -1, +-1, 59, -1, -1, -1, 63, 64, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, 32, -1, +-1, 35, 36, 37, 38, -1, -1, 41, 42, 43, +-1, 45, 46, 3, -1, 5, 6, 7, -1, -1, +-1, 55, 56, -1, -1, -1, -1, -1, -1, 63, +64, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, 32, -1, -1, 35, 36, 37, 38, -1, +-1, 41, 42, 43, -1, 45, 46, 3, -1, 5, +6, 7, -1, -1, -1, 55, -1, -1, -1, 59, +-1, -1, -1, 63, 64, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, 32, -1, -1, 35, +36, 37, 38, -1, -1, 41, 42, 43, -1, 45, +46, 3, -1, 5, 6, 7, -1, -1, -1, 55, +56, -1, -1, -1, -1, -1, -1, 63, 64, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +32, -1, -1, 35, 36, 37, 38, -1, -1, 41, +42, 43, -1, 45, 46, 3, -1, 5, 6, 7, +-1, -1, -1, 55, 56, -1, -1, -1, -1, -1, +-1, 63, 64, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, 32, -1, -1, 35, 36, 37, +38, -1, -1, 41, 42, 43, -1, 45, 46, 3, +-1, 5, 6, 7, -1, -1, -1, 55, 56, -1, +-1, -1, -1, -1, -1, 63, 64, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, 32, -1, +-1, 35, 36, 37, 38, -1, -1, 41, 42, 43, +-1, 45, 46, -1, -1, 44, 45, 46, 47, 48, +49, 55, 51, 52, 53, 54, 55, 56, 57, 63, +64, -1, -1, 62, -1, -1, 65, 66, 67, -1, +-1, -1, 71, 72, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, 84, 85, 86, 87, 88, +89, 90, -1, -1, -1, -1, -1, 96, 97, 44, +45, 46, 47, 48, 49, -1, 51, 52, 53, 54, +55, -1, 57, -1, 59, -1, -1, 62, -1, -1, +65, 66, 67, -1, -1, -1, 71, 72, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, 84, +85, 86, 87, 88, 89, 90, -1, -1, -1, -1, +-1, 96, 97, 44, 45, 46, 47, 48, 49, -1, +51, 52, 53, 54, 55, -1, -1, -1, 59, -1, +-1, 62, -1, -1, 65, 66, 67, -1, -1, -1, +71, 72, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, 84, 85, 86, 87, 88, 89, 90, +-1, -1, -1, -1, -1, 96, 97, 44, 45, 46, +47, 48, 49, -1, 51, 52, 53, 54, 55, 56, +-1, -1, -1, -1, -1, 62, -1, -1, 65, 66, +67, -1, -1, -1, 71, 72, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, 84, 85, 86, +87, 88, 89, 90, -1, -1, -1, -1, -1, 96, +97, 44, 45, 46, 47, 48, 49, -1, 51, 52, +53, 54, 55, 56, -1, -1, -1, -1, -1, 62, +-1, -1, 65, 66, 67, -1, -1, -1, 71, 72, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, 84, 85, 86, 87, 88, 89, 90, -1, -1, +-1, -1, -1, 96, 97, 44, 45, 46, 47, 48, +49, -1, 51, 52, 53, 54, 55, 56, -1, -1, +-1, -1, -1, 62, -1, -1, 65, 66, 67, -1, +-1, -1, 71, 72, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, 84, 85, 86, 87, 88, +89, 90, -1, -1, -1, -1, -1, 96, 97, 44, +45, 46, 47, 48, 49, -1, 51, 52, 53, 54, +55, 56, -1, -1, -1, -1, -1, 62, -1, -1, +65, 66, 67, -1, -1, -1, 71, 72, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, 84, +85, 86, 87, 88, 89, 90, -1, -1, -1, -1, +-1, 96, 97, 44, 45, 46, 47, 48, 49, -1, +51, 52, 53, 54, 55, -1, -1, -1, 59, -1, +-1, 62, -1, -1, 65, 66, 67, -1, -1, -1, +71, 72, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, 84, 85, 86, 87, 88, 89, 90, +-1, -1, -1, -1, -1, 96, 97, 44, 45, 46, +47, 48, 49, -1, 51, 52, 53, 54, 55, 56, +-1, -1, -1, -1, -1, 62, -1, -1, 65, 66, +67, -1, -1, -1, 71, 72, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, 84, 85, 86, +87, 88, 89, 90, -1, -1, -1, -1, -1, 96, +97, 44, 45, 46, 47, 48, 49, -1, 51, 52, +53, 54, 55, 56, -1, -1, -1, -1, -1, 62, +-1, -1, 65, 66, 67, -1, -1, -1, 71, 72, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, 84, 85, 86, 87, 88, 89, 90, -1, -1, +-1, -1, -1, 96, 97, 44, 45, 46, 47, 48, +49, -1, 51, 52, 53, 54, 55, -1, -1, 58, +-1, -1, -1, 62, -1, -1, 65, 66, 67, -1, +-1, -1, 71, 72, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, 84, 85, 86, 87, 88, +89, 90, -1, -1, -1, -1, -1, 96, 97, 44, +45, 46, 47, 48, 49, -1, 51, 52, 53, 54, +55, -1, -1, -1, 59, -1, -1, 62, -1, -1, +65, 66, 67, -1, -1, -1, 71, 72, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, 84, +85, 86, 87, 88, 89, 90, -1, -1, -1, -1, +-1, 96, 97, 44, 45, 46, 47, 48, 49, -1, +51, 52, 53, 54, 55, -1, -1, 58, -1, -1, +-1, 62, -1, -1, 65, 66, 67, -1, -1, -1, +71, 72, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, 84, 85, 86, 87, 88, 89, 90, +-1, -1, -1, -1, -1, 96, 97, 44, 45, 46, +47, 48, 49, -1, 51, 52, 53, 54, 55, 56, +-1, -1, -1, -1, -1, 62, -1, -1, 65, 66, +67, -1, -1, -1, 71, 72, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, 84, 85, 86, +87, 88, 89, 90, -1, -1, -1, -1, -1, 96, +97, 44, 45, 46, 47, 48, 49, -1, 51, 52, +53, 54, 55, 56, -1, -1, -1, -1, -1, 62, +-1, -1, 65, 66, 67, -1, -1, -1, 71, 72, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, 84, 85, 86, 87, 88, 89, 90, -1, -1, +-1, -1, -1, 96, 97, 44, 45, 46, 47, 48, +49, -1, 51, 52, 53, 54, 55, -1, -1, -1, +59, -1, -1, 62, -1, -1, 65, 66, 67, -1, +-1, -1, 71, 72, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, 84, 85, 86, 87, 88, +89, 90, -1, -1, -1, -1, -1, 96, 97, 44, +45, 46, 47, 48, 49, -1, 51, 52, 53, 54, +55, 56, -1, -1, -1, -1, -1, 62, -1, -1, +65, 66, 67, -1, -1, -1, 71, 72, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, 84, +85, 86, 87, 88, 89, 90, -1, -1, -1, -1, +-1, 96, 97, 44, 45, 46, 47, 48, 49, -1, +51, 52, 53, 54, 55, 56, -1, -1, -1, -1, +-1, 62, -1, -1, 65, 66, 67, -1, -1, -1, +71, 72, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, 84, 85, 86, 87, 88, 89, 90, +-1, -1, -1, -1, -1, 96, 97, 44, 45, 46, +47, 48, 49, -1, 51, 52, 53, 54, 55, -1, +-1, -1, 59, -1, -1, 62, -1, -1, 65, 66, +67, -1, -1, -1, 71, 72, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, 84, 85, 86, +87, 88, 89, 90, -1, -1, -1, -1, -1, 96, +97, 44, 45, 46, 47, 48, 49, -1, 51, 52, +53, 54, 55, 56, -1, -1, -1, -1, -1, 62, +-1, -1, 65, 66, 67, -1, -1, -1, 71, 72, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, 84, 85, 86, 87, 88, 89, 90, -1, -1, +-1, -1, -1, 96, 97, 44, 45, 46, 47, 48, +49, -1, 51, 52, 53, 54, 55, 56, -1, -1, +-1, -1, -1, 62, -1, -1, 65, 66, 67, -1, +-1, -1, 71, 72, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, 84, 85, 86, 87, 88, +89, 90, -1, -1, -1, -1, -1, 96, 97, 44, +45, 46, 47, 48, 49, -1, 51, 52, 53, 54, +55, 56, -1, -1, -1, -1, -1, 62, -1, -1, +65, 66, 67, -1, -1, -1, 71, 72, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, 84, +85, 86, 87, 88, 89, 90, -1, -1, -1, -1, +-1, 96, 97, 44, 45, 46, 47, 48, 49, -1, +51, 52, 53, 54, 55, -1, -1, -1, 59, -1, +-1, 62, -1, -1, 65, 66, 67, -1, -1, -1, +71, 72, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, 84, 85, 86, 87, 88, 89, 90, +-1, -1, -1, -1, -1, 96, 97, 44, 45, 46, +47, 48, 49, -1, 51, 52, 53, 54, 55, -1, +-1, -1, 59, -1, -1, 62, -1, -1, 65, 66, +67, -1, -1, -1, 71, 72, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, 84, 85, 86, +87, 88, 89, 90, -1, -1, -1, -1, -1, 96, +97, 44, 45, 46, 47, 48, 49, -1, 51, 52, +53, 54, 55, -1, -1, -1, 59, -1, -1, 62, +-1, -1, 65, 66, 67, -1, -1, -1, 71, 72, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, 84, 85, 86, 87, 88, 89, 90, -1, -1, +-1, -1, -1, 96, 97, 44, 45, 46, 47, 48, +49, -1, 51, 52, 53, 54, 55, -1, -1, -1, +59, -1, -1, 62, -1, -1, 65, 66, 67, -1, +-1, -1, 71, 72, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, 84, 85, 86, 87, 88, +89, 90, -1, -1, -1, -1, -1, 96, 97, 44, +45, 46, 47, 48, 49, -1, 51, 52, 53, 54, +55, -1, -1, -1, 59, -1, -1, 62, -1, -1, +65, 66, 67, -1, -1, -1, 71, 72, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, -1, 84, +85, 86, 87, 88, 89, 90, -1, -1, -1, -1, +-1, 96, 97, 44, 45, 46, 47, 48, 49, -1, +51, 52, 53, 54, 55, -1, -1, -1, -1, -1, +-1, 62, -1, -1, 65, 66, 67, -1, -1, -1, +71, 72, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, 84, 85, 86, 87, 88, 89, 90, +-1, -1, -1, -1, -1, 96, 97, 44, 45, 46, +47, 48, 49, -1, 51, 52, 53, 54, 55, -1, +-1, -1, -1, -1, -1, 62, -1, -1, 65, 66, +67, -1, -1, -1, 71, 72, -1, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, 84, 85, 86, +87, 88, 89, 90, 44, 45, 46, 47, 48, 49, +97, 51, 52, 53, 54, 55, -1, -1, -1, -1, +-1, -1, 62, -1, -1, 65, 66, 67, -1, -1, +-1, 71, 72, -1, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, 84, 85, 86, 87, 88, -1, +90, 44, 45, 46, 47, 48, 49, 97, 51, 52, +53, 54, 55, -1, -1, -1, -1, -1, -1, 62, +-1, -1, 65, 66, 67, -1, -1, -1, 71, 72, +-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, 84, 85, 86, 87, -1, -1, 90, 44, 45, +46, 47, 48, 49, 97, 51, -1, 53, 54, 55, +-1, -1, -1, -1, -1, -1, 62, -1, -1, 65, +66, 67, -1, -1, -1, 71, 72, -1, -1, -1, +-1, -1, -1, -1, -1, -1, -1, -1, 84, 85, +86, 87, -1, -1, 90, 44, 45, 46, 47, 48, +49, 97, 51, -1, 53, 54, 55, -1, -1, -1, +-1, -1, -1, -1, -1, -1, 65, 66, 67, -1, +-1, -1, 71, 72, -1, -1, -1, -1, -1, -1, +-1, -1, -1, -1, -1, 84, 85, 86, 87, -1, +-1, 90, 44, 45, 46, 47, 48, 49, 97, 51, +-1, -1, 54, 55, -1, -1, -1, -1, -1, -1, +-1, -1, -1, 65, 66, 67, -1, -1, -1, 71, +72, -1, -1, -1, -1, -1, -1, -1, -1, -1, +-1, -1, 84, 85, 86, 87, -1, -1, 90, 44, +45, 46, 47, 48, 49, 97, 51, -1, -1, 54, +55, -1, -1, -1, -1, -1, -1, -1, -1, -1, +65, 66, 67, -1, -1, -1, 71, 72, 44, 45, +46, 47, -1, -1, -1, 51, -1, -1, 54, 55, +50, 86, 87, -1, -1, 90, -1, -1, -1, 65, +66, 67, 97, -1, -1, 71, 72, -1, 68, 69, +50, -1, -1, 73, 74, 75, 76, 77, 78, 79, +80, 81, 82, -1, 90, -1, -1, -1, 68, 69, +-1, 97, -1, 73, 74, 75, 76, 77, 78, 79, +80, 81, 82 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ #line 3 "bison.simple" /* Skeleton output parser for bison, - Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. +Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ +Bison output file, you may use that output file without restriction. +This special exception was added by the Free Software Foundation +in version 1.24 of Bison. */ #ifndef alloca #ifdef __GNUC__ @@ -1157,15 +1175,15 @@ static const short yycheck[] = { 1, #else /* not MSDOS, or __TURBOC__ */ #if defined(_AIX) #include - #pragma alloca +#pragma alloca #else /* not MSDOS, __TURBOC__, or _AIX */ #ifdef __hpux #ifdef __cplusplus extern "C" { -void *alloca (unsigned int); + void *alloca(unsigned int); }; #else /* not __cplusplus */ -void *alloca (); +void *alloca(); #endif /* not __cplusplus */ #endif /* __hpux */ #endif /* not _AIX */ @@ -1175,58 +1193,58 @@ void *alloca (); #endif /* alloca not defined. */ /* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ +when the %semantic_parser declaration is not specified in the grammar. +It was written by Richard Stallman by simplifying the hairy parser +used when %semantic_parser is specified. */ /* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ +It is replaced by the list of actions, each action +as one case of the switch. */ -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT return(0) -#define YYABORT return(1) -#define YYERROR goto yyerrlab1 +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY -2 +#define YYEOF 0 +#define YYACCEPT return(0) +#define YYABORT return(1) +#define YYERROR goto yyerrlab1 /* Like YYERROR except do call yyerror. - This remains here temporarily to ease the - transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab +This remains here temporarily to ease the +transition to the new meaning of YYERROR, for GCC. +Once GCC version 2 has supplanted version 1, this can go. */ +#define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(token, value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { yychar = (token), yylval = (value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { yyerror ("syntax error: cannot back up"); YYERROR; } \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { yychar = (token), yylval = (value); \ + yychar1 = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { yyerror ("syntax error: cannot back up"); YYERROR; } \ while (0) -#define YYTERROR 1 -#define YYERRCODE 256 +#define YYTERROR 1 +#define YYERRCODE 256 #ifndef YYPURE -#define YYLEX yylex() +#define YYLEX yylex() #endif #ifdef YYPURE #ifdef YYLSP_NEEDED #ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) +#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) #else -#define YYLEX yylex(&yylval, &yylloc) +#define YYLEX yylex(&yylval, &yylloc) #endif #else /* not YYLSP_NEEDED */ #ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, YYLEX_PARAM) +#define YYLEX yylex(&yylval, YYLEX_PARAM) #else -#define YYLEX yylex(&yylval) +#define YYLEX yylex(&yylval) #endif #endif /* not YYLSP_NEEDED */ #endif @@ -1235,32 +1253,32 @@ while (0) #ifndef YYPURE -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ +int yychar; /* the lookahead symbol */ +YYSTYPE yylval; /* the semantic value of the */ + /* lookahead symbol */ #ifdef YYLSP_NEEDED -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ +YYLTYPE yylloc; /* location data for the lookahead */ + /* symbol */ #endif -int yynerrs; /* number of parse errors so far */ +int yynerrs; /* number of parse errors so far */ #endif /* not YYPURE */ #if YYDEBUG != 0 -int yydebug; /* nonzero means print parse trace */ -/* Since this is uninitialized, it does not stop multiple parsers - from coexisting. */ +int yydebug; /* nonzero means print parse trace */ + /* Since this is uninitialized, it does not stop multiple parsers + from coexisting. */ #endif -/* YYINITDEPTH indicates the initial size of the parser's stacks */ + /* YYINITDEPTH indicates the initial size of the parser's stacks */ -#ifndef YYINITDEPTH +#ifndef YYINITDEPTH #define YYINITDEPTH 200 #endif -/* YYMAXDEPTH is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ + /* YYMAXDEPTH is the maximum size the stacks can grow to + (effective only if the built-in stack extension method is used). */ #if YYMAXDEPTH == 0 #undef YYMAXDEPTH @@ -1270,57 +1288,57 @@ int yydebug; /* nonzero means print parse trace */ #define YYMAXDEPTH 10000 #endif -/* Prevent warning if -Wstrict-prototypes. */ + /* Prevent warning if -Wstrict-prototypes. */ #ifdef __GNUC__ -int yyparse (void); +int yyparse(void); #endif - -#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -#define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#else /* not GNU C or C++ */ + +#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +#define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) +#else /* not GNU C or C++ */ #ifndef __cplusplus /* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ +in available built-in functions on various systems. */ static void -__yy_memcpy (from, to, count) - char *from; - char *to; - int count; +__yy_memcpy(from, to, count) +char *from; +char *to; +int count; { - char *f = from; - char *t = to; - int i = count; + register char *f = from; + register char *t = to; + register int i = count; - while (i-- > 0) - *t++ = *f++; + while (i-- > 0) + *t++ = *f++; } #else /* __cplusplus */ /* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ +in available built-in functions on various systems. */ static void -__yy_memcpy (char *from, char *to, int count) +__yy_memcpy(char *from, char *to, int count) { - char *f = from; - char *t = to; - int i = count; + register char *f = from; + register char *t = to; + register int i = count; - while (i-- > 0) - *t++ = *f++; + while (i-- > 0) + *t++ = *f++; } #endif #endif - + #line 192 "bison.simple" /* The user can define YYPARSE_PARAM as the name of an argument to be passed - into yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ +into yyparse. The argument should have type void *. +It should actually point to an object. +Grammar actions can access the variable by casting it +to the proper pointer type. */ #ifdef YYPARSE_PARAM #define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; @@ -1331,78 +1349,78 @@ __yy_memcpy (char *from, char *to, int count) int yyparse(YYPARSE_PARAM) - YYPARSE_PARAM_DECL +YYPARSE_PARAM_DECL { - int yystate; - int yyn; - short *yyssp; - YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1 = 0; /* lookahead token as an internal (translated) token number */ + register int yystate; + register int yyn; + register short *yyssp; + register YYSTYPE *yyvsp; + int yyerrstatus; /* number of tokens to shift before error messages enabled */ + int yychar1 = 0; /* lookahead token as an internal (translated) token number */ - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ + short yyssa[YYINITDEPTH]; /* the state stack */ + YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ + short *yyss = yyssa; /* refer to the stacks thru separate pointers */ + YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ #ifdef YYLSP_NEEDED - YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; + YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ + YYLTYPE *yyls = yylsa; + YYLTYPE *yylsp; #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) #else #define YYPOPSTACK (yyvsp--, yyssp--) #endif - int yystacksize = YYINITDEPTH; + int yystacksize = YYINITDEPTH; #ifdef YYPURE - int yychar; - YYSTYPE yylval; - int yynerrs; + int yychar; + YYSTYPE yylval; + int yynerrs; #ifdef YYLSP_NEEDED - YYLTYPE yylloc; + YYLTYPE yylloc; #endif #endif - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ + YYSTYPE yyval; /* the variable used to return */ + /* semantic values from the action */ + /* routines */ - int yylen; + int yylen; #if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Starting parse\n"); + if (yydebug) + fprintf(stderr, "Starting parse\n"); #endif - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ - yyssp = yyss - 1; - yyvsp = yyvs; + yyssp = yyss - 1; + yyvsp = yyvs; #ifdef YYLSP_NEEDED - yylsp = yyls; + yylsp = yyls; #endif -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks + /* Push a new state, which is found in yystate . */ + /* In all cases, when you get here, the value and location stacks have just been pushed. so pushing a state here evens the stacks. */ yynewstate: - *++yyssp = yystate; + *++yyssp = yystate; - if (yyssp >= yyss + yystacksize - 1) - { + if (yyssp >= yyss + yystacksize - 1) + { /* Give user a chance to reallocate the stack */ /* Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; @@ -1416,20 +1434,20 @@ yynewstate: #ifdef yyoverflow /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ + the data in use in that stack, in bytes. */ #ifdef YYLSP_NEEDED /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ + but that might be undefined if yyoverflow is a macro. */ yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yyls1, size * sizeof (*yylsp), - &yystacksize); + &yyss1, size * sizeof(*yyssp), + &yyvs1, size * sizeof(*yyvsp), + &yyls1, size * sizeof(*yylsp), + &yystacksize); #else yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yystacksize); + &yyss1, size * sizeof(*yyssp), + &yyvs1, size * sizeof(*yyvsp), + &yystacksize); #endif yyss = yyss1; yyvs = yyvs1; @@ -1439,20 +1457,20 @@ yynewstate: #else /* no yyoverflow */ /* Extend the stack our own way. */ if (yystacksize >= YYMAXDEPTH) - { - yyerror("parser stack overflow"); - return 2; - } + { + yyerror("parser stack overflow"); + return 2; + } yystacksize *= 2; if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; - yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); - __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); - yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); - __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + yystacksize = YYMAXDEPTH; + yyss = (short *)alloca(yystacksize * sizeof(*yyssp)); + __yy_memcpy((char *)yyss1, (char *)yyss, size * sizeof(*yyssp)); + yyvs = (YYSTYPE *)alloca(yystacksize * sizeof(*yyvsp)); + __yy_memcpy((char *)yyvs1, (char *)yyvs, size * sizeof(*yyvsp)); #ifdef YYLSP_NEEDED - yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); - __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + yyls = (YYLTYPE *)alloca(yystacksize * sizeof(*yylsp)); + __yy_memcpy((char *)yyls1, (char *)yyls, size * sizeof(*yylsp)); #endif #endif /* no yyoverflow */ @@ -1464,989 +1482,995 @@ yynewstate: #if YYDEBUG != 0 if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yystacksize); + fprintf(stderr, "Stack size increased to %d\n", yystacksize); #endif if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } + YYABORT; + } #if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); + if (yydebug) + fprintf(stderr, "Entering state %d\n", yystate); #endif - goto yybackup; - yybackup: + goto yybackup; +yybackup: -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ + /* Do appropriate processing given the current state. */ + /* Read a lookahead token if we need one and don't already have one. */ + /* yyresume: */ - /* First try to decide what to do without reference to lookahead token. */ + /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yydefault; - /* Not known => get a lookahead token if don't already have one. */ + /* Not known => get a lookahead token if don't already have one. */ - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ + /* yychar is either YYEMPTY or YYEOF + or a valid token in external form. */ - if (yychar == YYEMPTY) - { + if (yychar == YYEMPTY) + { #if YYDEBUG != 0 if (yydebug) - fprintf(stderr, "Reading a token: "); + fprintf(stderr, "Reading a token: "); #endif yychar = YYLEX; - } + } - /* Convert token to internal form (in yychar1) for indexing tables with */ + /* Convert token to internal form (in yychar1) for indexing tables with */ - if (yychar <= 0) /* This means end of input. */ - { + if (yychar <= 0) /* This means end of input. */ + { yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ + yychar = YYEOF; /* Don't call YYLEX any more */ #if YYDEBUG != 0 if (yydebug) - fprintf(stderr, "Now at end of input.\n"); + fprintf(stderr, "Now at end of input.\n"); #endif - } - else - { + } + else + { yychar1 = YYTRANSLATE(yychar); #if YYDEBUG != 0 if (yydebug) - { - fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise meaning - of a token, for further debugging info. */ + { + fprintf(stderr, "Next token is %d (%s", yychar, yytname[yychar1]); + /* Give the individual parser a way to print the precise meaning + of a token, for further debugging info. */ #ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); + YYPRINT(stderr, yychar, yylval); +#endif + fprintf(stderr, ")\n"); + } #endif - fprintf (stderr, ")\n"); } -#endif - } - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; + yyn += yychar1; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) + goto yydefault; - yyn = yytable[yyn]; + yyn = yytable[yyn]; - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ + /* yyn is what to do for this token type in this state. + Negative => reduce, -yyn is rule number. + Positive => shift, yyn is new state. + New state is final state => don't bother to shift, + just return success. + 0, or most negative number => error. */ - if (yyn < 0) - { + if (yyn < 0) + { if (yyn == YYFLAG) - goto yyerrlab; + goto yyerrlab; yyn = -yyn; goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; + } + else if (yyn == 0) + goto yyerrlab; - if (yyn == YYFINAL) - YYACCEPT; + if (yyn == YYFINAL) + YYACCEPT; - /* Shift the lookahead token. */ + /* Shift the lookahead token. */ #if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); + if (yydebug) + fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); #endif - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; - *++yyvsp = yylval; + *++yyvsp = yylval; #ifdef YYLSP_NEEDED - *++yylsp = yylloc; + *++yylsp = yylloc; #endif - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; + /* count tokens shifted since error; after three, turn off error status. */ + if (yyerrstatus) yyerrstatus--; - yystate = yyn; - goto yynewstate; + yystate = yyn; + goto yynewstate; -/* Do the default action for the current state. */ + /* Do the default action for the current state. */ yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; -/* Do a reduction. yyn is the number of a rule to reduce with. */ + /* Do a reduction. yyn is the number of a rule to reduce with. */ yyreduce: - yylen = yyr2[yyn]; - if (yylen > 0) - yyval = yyvsp[1-yylen]; /* implement default value of the action */ + yylen = yyr2[yyn]; + if (yylen > 0) + yyval = yyvsp[1 - yylen]; /* implement default value of the action */ #if YYDEBUG != 0 - if (yydebug) - { + if (yydebug) + { int i; - fprintf (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); + fprintf(stderr, "Reducing via rule %d (line %d), ", + yyn, yyrline[yyn]); /* Print the symbols being reduced, and their result. */ for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) - fprintf (stderr, "%s ", yytname[yyrhs[i]]); - fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } + fprintf(stderr, "%s ", yytname[yyrhs[i]]); + fprintf(stderr, " -> %s\n", yytname[yyr1[yyn]]); + } #endif - switch (yyn) { + switch (yyn) { -case 1: + case 1: #line 162 "cmdgram.y" -{ ; - break;} -case 2: + {; + break; } + case 2: #line 167 "cmdgram.y" -{ yyval.stmt = nil; ; - break;} -case 3: + { yyval.stmt = nil; ; + break; } + case 3: #line 169 "cmdgram.y" -{ if(!gStatementList) { gStatementList = yyvsp[0].stmt; } else { gStatementList->append(yyvsp[0].stmt); } ; - break;} -case 4: + { if (!gStatementList) { gStatementList = yyvsp[0].stmt; } + else { gStatementList->append(yyvsp[0].stmt); }; + break; } + case 4: #line 174 "cmdgram.y" -{ yyval.stmt = yyvsp[0].stmt; ; - break;} -case 5: + { yyval.stmt = yyvsp[0].stmt; ; + break; } + case 5: #line 176 "cmdgram.y" -{ yyval.stmt = yyvsp[0].stmt; ; - break;} -case 6: + { yyval.stmt = yyvsp[0].stmt; ; + break; } + case 6: #line 178 "cmdgram.y" -{ yyval.stmt = yyvsp[0].stmt; ; - break;} -case 7: + { yyval.stmt = yyvsp[0].stmt; ; + break; } + case 7: #line 183 "cmdgram.y" -{ yyval.stmt = yyvsp[-2].stmt; for(StmtNode *walk = (yyvsp[-2].stmt);walk;walk = walk->getNext() ) walk->setPackage(yyvsp[-4].s.value); ; - break;} -case 8: + { yyval.stmt = yyvsp[-2].stmt; for (StmtNode *walk = (yyvsp[-2].stmt); walk; walk = walk->getNext()) walk->setPackage(yyvsp[-4].s.value); ; + break; } + case 8: #line 188 "cmdgram.y" -{ yyval.stmt = yyvsp[0].stmt; ; - break;} -case 9: + { yyval.stmt = yyvsp[0].stmt; ; + break; } + case 9: #line 190 "cmdgram.y" -{ yyval.stmt = yyvsp[-1].stmt; (yyvsp[-1].stmt)->append(yyvsp[0].stmt); ; - break;} -case 10: + { yyval.stmt = yyvsp[-1].stmt; (yyvsp[-1].stmt)->append(yyvsp[0].stmt); ; + break; } + case 10: #line 195 "cmdgram.y" -{ yyval.stmt = nil; ; - break;} -case 11: + { yyval.stmt = nil; ; + break; } + case 11: #line 197 "cmdgram.y" -{ if(!yyvsp[-1].stmt) { yyval.stmt = yyvsp[0].stmt; } else { (yyvsp[-1].stmt)->append(yyvsp[0].stmt); yyval.stmt = yyvsp[-1].stmt; } ; - break;} -case 18: + { if (!yyvsp[-1].stmt) { yyval.stmt = yyvsp[0].stmt; } + else { (yyvsp[-1].stmt)->append(yyvsp[0].stmt); yyval.stmt = yyvsp[-1].stmt; }; + break; } + case 18: #line 208 "cmdgram.y" -{ yyval.stmt = BreakStmtNode::alloc( yyvsp[-1].i.lineNumber ); ; - break;} -case 19: + { yyval.stmt = BreakStmtNode::alloc(yyvsp[-1].i.lineNumber); ; + break; } + case 19: #line 210 "cmdgram.y" -{ yyval.stmt = ContinueStmtNode::alloc( yyvsp[-1].i.lineNumber ); ; - break;} -case 20: + { yyval.stmt = ContinueStmtNode::alloc(yyvsp[-1].i.lineNumber); ; + break; } + case 20: #line 212 "cmdgram.y" -{ yyval.stmt = ReturnStmtNode::alloc( yyvsp[-1].i.lineNumber, NULL ); ; - break;} -case 21: + { yyval.stmt = ReturnStmtNode::alloc(yyvsp[-1].i.lineNumber, NULL); ; + break; } + case 21: #line 214 "cmdgram.y" -{ yyval.stmt = ReturnStmtNode::alloc( yyvsp[-2].i.lineNumber, yyvsp[-1].expr ); ; - break;} -case 22: + { yyval.stmt = ReturnStmtNode::alloc(yyvsp[-2].i.lineNumber, yyvsp[-1].expr); ; + break; } + case 22: #line 216 "cmdgram.y" -{ yyval.stmt = yyvsp[-1].stmt; ; - break;} -case 23: + { yyval.stmt = yyvsp[-1].stmt; ; + break; } + case 23: #line 218 "cmdgram.y" -{ yyval.stmt = TTagSetStmtNode::alloc( yyvsp[-3].s.lineNumber, yyvsp[-3].s.value, yyvsp[-1].expr, NULL ); ; - break;} -case 24: + { yyval.stmt = TTagSetStmtNode::alloc(yyvsp[-3].s.lineNumber, yyvsp[-3].s.value, yyvsp[-1].expr, NULL); ; + break; } + case 24: #line 220 "cmdgram.y" -{ yyval.stmt = TTagSetStmtNode::alloc( yyvsp[-5].s.lineNumber, yyvsp[-5].s.value, yyvsp[-3].expr, yyvsp[-1].expr ); ; - break;} -case 25: + { yyval.stmt = TTagSetStmtNode::alloc(yyvsp[-5].s.lineNumber, yyvsp[-5].s.value, yyvsp[-3].expr, yyvsp[-1].expr); ; + break; } + case 25: #line 222 "cmdgram.y" -{ yyval.stmt = StrConstNode::alloc( yyvsp[0].str.lineNumber, yyvsp[0].str.value, false, true ); ; - break;} -case 26: + { yyval.stmt = StrConstNode::alloc(yyvsp[0].str.lineNumber, yyvsp[0].str.value, false, true); ; + break; } + case 26: #line 227 "cmdgram.y" -{ yyval.stmt = FunctionDeclStmtNode::alloc( yyvsp[-7].i.lineNumber, yyvsp[-6].s.value, NULL, yyvsp[-4].var, yyvsp[-1].stmt ); ; - break;} -case 27: + { yyval.stmt = FunctionDeclStmtNode::alloc(yyvsp[-7].i.lineNumber, yyvsp[-6].s.value, NULL, yyvsp[-4].var, yyvsp[-1].stmt); ; + break; } + case 27: #line 229 "cmdgram.y" -{ yyval.stmt = FunctionDeclStmtNode::alloc( yyvsp[-9].i.lineNumber, yyvsp[-6].s.value, yyvsp[-8].s.value, yyvsp[-4].var, yyvsp[-1].stmt ); ; - break;} -case 28: + { yyval.stmt = FunctionDeclStmtNode::alloc(yyvsp[-9].i.lineNumber, yyvsp[-6].s.value, yyvsp[-8].s.value, yyvsp[-4].var, yyvsp[-1].stmt); ; + break; } + case 28: #line 234 "cmdgram.y" -{ yyval.var = NULL; ; - break;} -case 29: + { yyval.var = NULL; ; + break; } + case 29: #line 236 "cmdgram.y" -{ yyval.var = yyvsp[0].var; ; - break;} -case 30: + { yyval.var = yyvsp[0].var; ; + break; } + case 30: #line 241 "cmdgram.y" -{ yyval.var = VarNode::alloc( yyvsp[0].s.lineNumber, yyvsp[0].s.value, NULL ); ; - break;} -case 31: + { yyval.var = VarNode::alloc(yyvsp[0].s.lineNumber, yyvsp[0].s.value, NULL); ; + break; } + case 31: #line 243 "cmdgram.y" -{ yyval.var = yyvsp[-2].var; ((StmtNode*)(yyvsp[-2].var))->append((StmtNode*)VarNode::alloc( yyvsp[0].s.lineNumber, yyvsp[0].s.value, NULL ) ); ; - break;} -case 32: + { yyval.var = yyvsp[-2].var; ((StmtNode*)(yyvsp[-2].var))->append((StmtNode*)VarNode::alloc(yyvsp[0].s.lineNumber, yyvsp[0].s.value, NULL)); ; + break; } + case 32: #line 248 "cmdgram.y" -{ yyval.stmt = ObjectDeclNode::alloc( yyvsp[-9].i.lineNumber, yyvsp[-8].expr, yyvsp[-6].expr, NULL, yyvsp[-5].s.value, yyvsp[-2].slist, NULL, true, false, false); ; - break;} -case 33: + { yyval.stmt = ObjectDeclNode::alloc(yyvsp[-9].i.lineNumber, yyvsp[-8].expr, yyvsp[-6].expr, NULL, yyvsp[-5].s.value, yyvsp[-2].slist, NULL, true, false, false); ; + break; } + case 33: #line 253 "cmdgram.y" -{ yyval.od = ObjectDeclNode::alloc( yyvsp[-9].i.lineNumber, yyvsp[-8].expr, yyvsp[-6].expr, yyvsp[-4].expr, yyvsp[-5].s.value, yyvsp[-1].odcl.slots, yyvsp[-1].odcl.decls, false, false, false); ; - break;} -case 34: + { yyval.od = ObjectDeclNode::alloc(yyvsp[-9].i.lineNumber, yyvsp[-8].expr, yyvsp[-6].expr, yyvsp[-4].expr, yyvsp[-5].s.value, yyvsp[-1].odcl.slots, yyvsp[-1].odcl.decls, false, false, false); ; + break; } + case 34: #line 255 "cmdgram.y" -{ yyval.od = ObjectDeclNode::alloc( yyvsp[-6].i.lineNumber, yyvsp[-5].expr, yyvsp[-3].expr, yyvsp[-1].expr, yyvsp[-2].s.value, NULL, NULL, false, false, false); ; - break;} -case 35: + { yyval.od = ObjectDeclNode::alloc(yyvsp[-6].i.lineNumber, yyvsp[-5].expr, yyvsp[-3].expr, yyvsp[-1].expr, yyvsp[-2].s.value, NULL, NULL, false, false, false); ; + break; } + case 35: #line 257 "cmdgram.y" -{ yyval.od = ObjectDeclNode::alloc( yyvsp[-11].i.lineNumber, yyvsp[-10].expr, yyvsp[-7].expr, yyvsp[-4].expr, yyvsp[-5].s.value, yyvsp[-1].odcl.slots, yyvsp[-1].odcl.decls, false, true, false); ; - break;} -case 36: + { yyval.od = ObjectDeclNode::alloc(yyvsp[-11].i.lineNumber, yyvsp[-10].expr, yyvsp[-7].expr, yyvsp[-4].expr, yyvsp[-5].s.value, yyvsp[-1].odcl.slots, yyvsp[-1].odcl.decls, false, true, false); ; + break; } + case 36: #line 259 "cmdgram.y" -{ yyval.od = ObjectDeclNode::alloc( yyvsp[-8].i.lineNumber, yyvsp[-7].expr, yyvsp[-4].expr, yyvsp[-1].expr, yyvsp[-2].s.value, NULL, NULL, false, true, false); ; - break;} -case 37: + { yyval.od = ObjectDeclNode::alloc(yyvsp[-8].i.lineNumber, yyvsp[-7].expr, yyvsp[-4].expr, yyvsp[-1].expr, yyvsp[-2].s.value, NULL, NULL, false, true, false); ; + break; } + case 37: #line 261 "cmdgram.y" -{ yyval.od = ObjectDeclNode::alloc( yyvsp[-9].i.lineNumber, yyvsp[-8].expr, yyvsp[-6].expr, yyvsp[-4].expr, yyvsp[-5].s.value, yyvsp[-1].odcl.slots, yyvsp[-1].odcl.decls, false, false, true); ; - break;} -case 38: + { yyval.od = ObjectDeclNode::alloc(yyvsp[-9].i.lineNumber, yyvsp[-8].expr, yyvsp[-6].expr, yyvsp[-4].expr, yyvsp[-5].s.value, yyvsp[-1].odcl.slots, yyvsp[-1].odcl.decls, false, false, true); ; + break; } + case 38: #line 263 "cmdgram.y" -{ yyval.od = ObjectDeclNode::alloc( yyvsp[-6].i.lineNumber, yyvsp[-5].expr, yyvsp[-3].expr, yyvsp[-1].expr, yyvsp[-2].s.value, NULL, NULL, false, false, true); ; - break;} -case 39: + { yyval.od = ObjectDeclNode::alloc(yyvsp[-6].i.lineNumber, yyvsp[-5].expr, yyvsp[-3].expr, yyvsp[-1].expr, yyvsp[-2].s.value, NULL, NULL, false, false, true); ; + break; } + case 39: #line 268 "cmdgram.y" -{ yyval.s.value = NULL; ; - break;} -case 40: + { yyval.s.value = NULL; ; + break; } + case 40: #line 270 "cmdgram.y" -{ yyval.s = yyvsp[0].s; ; - break;} -case 41: + { yyval.s = yyvsp[0].s; ; + break; } + case 41: #line 275 "cmdgram.y" -{ yyval.expr = StrConstNode::alloc( CodeBlock::smCurrentParser->getCurrentLine(), "", false); ; - break;} -case 42: + { yyval.expr = StrConstNode::alloc(CodeBlock::smCurrentParser->getCurrentLine(), "", false); ; + break; } + case 42: #line 277 "cmdgram.y" -{ yyval.expr = yyvsp[0].expr; ; - break;} -case 43: + { yyval.expr = yyvsp[0].expr; ; + break; } + case 43: #line 282 "cmdgram.y" -{ yyval.expr = NULL; ; - break;} -case 44: + { yyval.expr = NULL; ; + break; } + case 44: #line 284 "cmdgram.y" -{ yyval.expr = yyvsp[0].expr; ; - break;} -case 45: + { yyval.expr = yyvsp[0].expr; ; + break; } + case 45: #line 289 "cmdgram.y" -{ yyval.odcl.slots = NULL; yyval.odcl.decls = NULL; ; - break;} -case 46: + { yyval.odcl.slots = NULL; yyval.odcl.decls = NULL; ; + break; } + case 46: #line 291 "cmdgram.y" -{ yyval.odcl.slots = yyvsp[0].slist; yyval.odcl.decls = NULL; ; - break;} -case 47: + { yyval.odcl.slots = yyvsp[0].slist; yyval.odcl.decls = NULL; ; + break; } + case 47: #line 293 "cmdgram.y" -{ yyval.odcl.slots = NULL; yyval.odcl.decls = yyvsp[0].od; ; - break;} -case 48: + { yyval.odcl.slots = NULL; yyval.odcl.decls = yyvsp[0].od; ; + break; } + case 48: #line 295 "cmdgram.y" -{ yyval.odcl.slots = yyvsp[-1].slist; yyval.odcl.decls = yyvsp[0].od; ; - break;} -case 49: + { yyval.odcl.slots = yyvsp[-1].slist; yyval.odcl.decls = yyvsp[0].od; ; + break; } + case 49: #line 300 "cmdgram.y" -{ yyval.od = yyvsp[-1].od; ; - break;} -case 50: + { yyval.od = yyvsp[-1].od; ; + break; } + case 50: #line 302 "cmdgram.y" -{ yyvsp[-2].od->append(yyvsp[-1].od); yyval.od = yyvsp[-2].od; ; - break;} -case 51: + { yyvsp[-2].od->append(yyvsp[-1].od); yyval.od = yyvsp[-2].od; ; + break; } + case 51: #line 307 "cmdgram.y" -{ yyval.stmt = yyvsp[-1].stmt; ; - break;} -case 52: + { yyval.stmt = yyvsp[-1].stmt; ; + break; } + case 52: #line 309 "cmdgram.y" -{ yyval.stmt = yyvsp[0].stmt; ; - break;} -case 53: + { yyval.stmt = yyvsp[0].stmt; ; + break; } + case 53: #line 314 "cmdgram.y" -{ yyval.stmt = yyvsp[-1].ifnode; yyvsp[-1].ifnode->propagateSwitchExpr(yyvsp[-4].expr, false); ; - break;} -case 54: + { yyval.stmt = yyvsp[-1].ifnode; yyvsp[-1].ifnode->propagateSwitchExpr(yyvsp[-4].expr, false); ; + break; } + case 54: #line 316 "cmdgram.y" -{ yyval.stmt = yyvsp[-1].ifnode; yyvsp[-1].ifnode->propagateSwitchExpr(yyvsp[-4].expr, true); ; - break;} -case 55: + { yyval.stmt = yyvsp[-1].ifnode; yyvsp[-1].ifnode->propagateSwitchExpr(yyvsp[-4].expr, true); ; + break; } + case 55: #line 321 "cmdgram.y" -{ yyval.ifnode = IfStmtNode::alloc( yyvsp[-3].i.lineNumber, yyvsp[-2].expr, yyvsp[0].stmt, NULL, false); ; - break;} -case 56: + { yyval.ifnode = IfStmtNode::alloc(yyvsp[-3].i.lineNumber, yyvsp[-2].expr, yyvsp[0].stmt, NULL, false); ; + break; } + case 56: #line 323 "cmdgram.y" -{ yyval.ifnode = IfStmtNode::alloc( yyvsp[-6].i.lineNumber, yyvsp[-5].expr, yyvsp[-3].stmt, yyvsp[0].stmt, false); ; - break;} -case 57: + { yyval.ifnode = IfStmtNode::alloc(yyvsp[-6].i.lineNumber, yyvsp[-5].expr, yyvsp[-3].stmt, yyvsp[0].stmt, false); ; + break; } + case 57: #line 325 "cmdgram.y" -{ yyval.ifnode = IfStmtNode::alloc( yyvsp[-4].i.lineNumber, yyvsp[-3].expr, yyvsp[-1].stmt, yyvsp[0].ifnode, true); ; - break;} -case 58: + { yyval.ifnode = IfStmtNode::alloc(yyvsp[-4].i.lineNumber, yyvsp[-3].expr, yyvsp[-1].stmt, yyvsp[0].ifnode, true); ; + break; } + case 58: #line 330 "cmdgram.y" -{ yyval.expr = yyvsp[0].expr;; - break;} -case 59: + { yyval.expr = yyvsp[0].expr;; + break; } + case 59: #line 332 "cmdgram.y" -{ (yyvsp[-2].expr)->append(yyvsp[0].expr); yyval.expr=yyvsp[-2].expr; ; - break;} -case 60: + { (yyvsp[-2].expr)->append(yyvsp[0].expr); yyval.expr = yyvsp[-2].expr; ; + break; } + case 60: #line 337 "cmdgram.y" -{ yyval.stmt = IfStmtNode::alloc(yyvsp[-4].i.lineNumber, yyvsp[-2].expr, yyvsp[0].stmt, NULL, false); ; - break;} -case 61: + { yyval.stmt = IfStmtNode::alloc(yyvsp[-4].i.lineNumber, yyvsp[-2].expr, yyvsp[0].stmt, NULL, false); ; + break; } + case 61: #line 339 "cmdgram.y" -{ yyval.stmt = IfStmtNode::alloc(yyvsp[-6].i.lineNumber, yyvsp[-4].expr, yyvsp[-2].stmt, yyvsp[0].stmt, false); ; - break;} -case 62: + { yyval.stmt = IfStmtNode::alloc(yyvsp[-6].i.lineNumber, yyvsp[-4].expr, yyvsp[-2].stmt, yyvsp[0].stmt, false); ; + break; } + case 62: #line 344 "cmdgram.y" -{ yyval.stmt = LoopStmtNode::alloc(yyvsp[-4].i.lineNumber, nil, yyvsp[-2].expr, nil, yyvsp[0].stmt, false); ; - break;} -case 63: + { yyval.stmt = LoopStmtNode::alloc(yyvsp[-4].i.lineNumber, nil, yyvsp[-2].expr, nil, yyvsp[0].stmt, false); ; + break; } + case 63: #line 346 "cmdgram.y" -{ yyval.stmt = LoopStmtNode::alloc(yyvsp[-3].i.lineNumber, nil, yyvsp[-1].expr, nil, yyvsp[-4].stmt, true); ; - break;} -case 64: + { yyval.stmt = LoopStmtNode::alloc(yyvsp[-3].i.lineNumber, nil, yyvsp[-1].expr, nil, yyvsp[-4].stmt, true); ; + break; } + case 64: #line 351 "cmdgram.y" -{ yyval.stmt = LoopStmtNode::alloc(yyvsp[-8].i.lineNumber, yyvsp[-6].expr, yyvsp[-4].expr, yyvsp[-2].expr, yyvsp[0].stmt, false); ; - break;} -case 65: + { yyval.stmt = LoopStmtNode::alloc(yyvsp[-8].i.lineNumber, yyvsp[-6].expr, yyvsp[-4].expr, yyvsp[-2].expr, yyvsp[0].stmt, false); ; + break; } + case 65: #line 353 "cmdgram.y" -{ yyval.stmt = LoopStmtNode::alloc(yyvsp[-7].i.lineNumber, yyvsp[-5].expr, yyvsp[-3].expr, NULL, yyvsp[0].stmt, false); ; - break;} -case 66: + { yyval.stmt = LoopStmtNode::alloc(yyvsp[-7].i.lineNumber, yyvsp[-5].expr, yyvsp[-3].expr, NULL, yyvsp[0].stmt, false); ; + break; } + case 66: #line 355 "cmdgram.y" -{ yyval.stmt = LoopStmtNode::alloc(yyvsp[-7].i.lineNumber, yyvsp[-5].expr, NULL, yyvsp[-2].expr, yyvsp[0].stmt, false); ; - break;} -case 67: + { yyval.stmt = LoopStmtNode::alloc(yyvsp[-7].i.lineNumber, yyvsp[-5].expr, NULL, yyvsp[-2].expr, yyvsp[0].stmt, false); ; + break; } + case 67: #line 357 "cmdgram.y" -{ yyval.stmt = LoopStmtNode::alloc(yyvsp[-6].i.lineNumber, yyvsp[-4].expr, NULL, NULL, yyvsp[0].stmt, false); ; - break;} -case 68: + { yyval.stmt = LoopStmtNode::alloc(yyvsp[-6].i.lineNumber, yyvsp[-4].expr, NULL, NULL, yyvsp[0].stmt, false); ; + break; } + case 68: #line 359 "cmdgram.y" -{ yyval.stmt = LoopStmtNode::alloc(yyvsp[-7].i.lineNumber, NULL, yyvsp[-4].expr, yyvsp[-2].expr, yyvsp[0].stmt, false); ; - break;} -case 69: + { yyval.stmt = LoopStmtNode::alloc(yyvsp[-7].i.lineNumber, NULL, yyvsp[-4].expr, yyvsp[-2].expr, yyvsp[0].stmt, false); ; + break; } + case 69: #line 361 "cmdgram.y" -{ yyval.stmt = LoopStmtNode::alloc(yyvsp[-6].i.lineNumber, NULL, yyvsp[-3].expr, NULL, yyvsp[0].stmt, false); ; - break;} -case 70: + { yyval.stmt = LoopStmtNode::alloc(yyvsp[-6].i.lineNumber, NULL, yyvsp[-3].expr, NULL, yyvsp[0].stmt, false); ; + break; } + case 70: #line 363 "cmdgram.y" -{ yyval.stmt = LoopStmtNode::alloc(yyvsp[-6].i.lineNumber, NULL, NULL, yyvsp[-2].expr, yyvsp[0].stmt, false); ; - break;} -case 71: + { yyval.stmt = LoopStmtNode::alloc(yyvsp[-6].i.lineNumber, NULL, NULL, yyvsp[-2].expr, yyvsp[0].stmt, false); ; + break; } + case 71: #line 365 "cmdgram.y" -{ yyval.stmt = LoopStmtNode::alloc(yyvsp[-5].i.lineNumber, NULL, NULL, NULL, yyvsp[0].stmt, false); ; - break;} -case 72: + { yyval.stmt = LoopStmtNode::alloc(yyvsp[-5].i.lineNumber, NULL, NULL, NULL, yyvsp[0].stmt, false); ; + break; } + case 72: #line 370 "cmdgram.y" -{ yyval.stmt = IterStmtNode::alloc( yyvsp[-6].i.lineNumber, yyvsp[-4].s.value, yyvsp[-2].expr, yyvsp[0].stmt, false ); ; - break;} -case 73: + { yyval.stmt = IterStmtNode::alloc(yyvsp[-6].i.lineNumber, yyvsp[-4].s.value, yyvsp[-2].expr, yyvsp[0].stmt, false); ; + break; } + case 73: #line 372 "cmdgram.y" -{ yyval.stmt = IterStmtNode::alloc( yyvsp[-6].i.lineNumber, yyvsp[-4].s.value, yyvsp[-2].expr, yyvsp[0].stmt, true ); ; - break;} -case 74: + { yyval.stmt = IterStmtNode::alloc(yyvsp[-6].i.lineNumber, yyvsp[-4].s.value, yyvsp[-2].expr, yyvsp[0].stmt, true); ; + break; } + case 74: #line 377 "cmdgram.y" -{ yyval.stmt = yyvsp[0].expr; ; - break;} -case 75: + { yyval.stmt = yyvsp[0].expr; ; + break; } + case 75: #line 382 "cmdgram.y" -{ yyval.expr = yyvsp[0].expr; ; - break;} -case 76: + { yyval.expr = yyvsp[0].expr; ; + break; } + case 76: #line 384 "cmdgram.y" -{ yyval.expr = yyvsp[-1].expr; ; - break;} -case 77: + { yyval.expr = yyvsp[-1].expr; ; + break; } + case 77: #line 386 "cmdgram.y" -{ yyval.expr = IntBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 78: + { yyval.expr = IntBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 78: #line 388 "cmdgram.y" -{ yyval.expr = IntBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 79: + { yyval.expr = IntBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 79: #line 390 "cmdgram.y" -{ yyval.expr = IntBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 80: + { yyval.expr = IntBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 80: #line 392 "cmdgram.y" -{ yyval.expr = IntBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 81: + { yyval.expr = IntBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 81: #line 394 "cmdgram.y" -{ yyval.expr = FloatBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 82: + { yyval.expr = FloatBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 82: #line 396 "cmdgram.y" -{ yyval.expr = FloatBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 83: + { yyval.expr = FloatBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 83: #line 398 "cmdgram.y" -{ yyval.expr = FloatBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 84: + { yyval.expr = FloatBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 84: #line 400 "cmdgram.y" -{ yyval.expr = FloatBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 85: + { yyval.expr = FloatBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 85: #line 402 "cmdgram.y" -{ yyval.expr = FloatUnaryExprNode::alloc( yyvsp[-1].i.lineNumber, yyvsp[-1].i.value, yyvsp[0].expr); ; - break;} -case 86: + { yyval.expr = FloatUnaryExprNode::alloc(yyvsp[-1].i.lineNumber, yyvsp[-1].i.value, yyvsp[0].expr); ; + break; } + case 86: #line 404 "cmdgram.y" -{ yyval.expr = TTagDerefNode::alloc( yyvsp[-1].i.lineNumber, yyvsp[0].expr ); ; - break;} -case 87: + { yyval.expr = TTagDerefNode::alloc(yyvsp[-1].i.lineNumber, yyvsp[0].expr); ; + break; } + case 87: #line 406 "cmdgram.y" -{ yyval.expr = TTagExprNode::alloc( yyvsp[0].s.lineNumber, yyvsp[0].s.value ); ; - break;} -case 88: + { yyval.expr = TTagExprNode::alloc(yyvsp[0].s.lineNumber, yyvsp[0].s.value); ; + break; } + case 88: #line 408 "cmdgram.y" -{ yyval.expr = ConditionalExprNode::alloc( yyvsp[-4].expr->dbgLineNumber, yyvsp[-4].expr, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 89: + { yyval.expr = ConditionalExprNode::alloc(yyvsp[-4].expr->dbgLineNumber, yyvsp[-4].expr, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 89: #line 410 "cmdgram.y" -{ yyval.expr = IntBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 90: + { yyval.expr = IntBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 90: #line 412 "cmdgram.y" -{ yyval.expr = IntBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 91: + { yyval.expr = IntBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 91: #line 414 "cmdgram.y" -{ yyval.expr = IntBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 92: + { yyval.expr = IntBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 92: #line 416 "cmdgram.y" -{ yyval.expr = IntBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 93: + { yyval.expr = IntBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 93: #line 418 "cmdgram.y" -{ yyval.expr = IntBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 94: + { yyval.expr = IntBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 94: #line 420 "cmdgram.y" -{ yyval.expr = IntBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 95: + { yyval.expr = IntBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 95: #line 422 "cmdgram.y" -{ yyval.expr = IntBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 96: + { yyval.expr = IntBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 96: #line 424 "cmdgram.y" -{ yyval.expr = IntBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 97: + { yyval.expr = IntBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 97: #line 426 "cmdgram.y" -{ yyval.expr = IntBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 98: + { yyval.expr = IntBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 98: #line 428 "cmdgram.y" -{ yyval.expr = IntBinaryExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -case 99: + { yyval.expr = IntBinaryExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-1].i.value, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + case 99: #line 430 "cmdgram.y" -{ yyval.expr = StreqExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-2].expr, yyvsp[0].expr, true); ; - break;} -case 100: + { yyval.expr = StreqExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-2].expr, yyvsp[0].expr, true); ; + break; } + case 100: #line 432 "cmdgram.y" -{ yyval.expr = StreqExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-2].expr, yyvsp[0].expr, false); ; - break;} -case 101: + { yyval.expr = StreqExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-2].expr, yyvsp[0].expr, false); ; + break; } + case 101: #line 434 "cmdgram.y" -{ yyval.expr = StrcatExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-2].expr, yyvsp[0].expr, yyvsp[-1].i.value); ; - break;} -case 102: + { yyval.expr = StrcatExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-2].expr, yyvsp[0].expr, yyvsp[-1].i.value); ; + break; } + case 102: #line 436 "cmdgram.y" -{ yyval.expr = IntUnaryExprNode::alloc(yyvsp[-1].i.lineNumber, yyvsp[-1].i.value, yyvsp[0].expr); ; - break;} -case 103: + { yyval.expr = IntUnaryExprNode::alloc(yyvsp[-1].i.lineNumber, yyvsp[-1].i.value, yyvsp[0].expr); ; + break; } + case 103: #line 438 "cmdgram.y" -{ yyval.expr = IntUnaryExprNode::alloc(yyvsp[-1].i.lineNumber, yyvsp[-1].i.value, yyvsp[0].expr); ; - break;} -case 104: + { yyval.expr = IntUnaryExprNode::alloc(yyvsp[-1].i.lineNumber, yyvsp[-1].i.value, yyvsp[0].expr); ; + break; } + case 104: #line 440 "cmdgram.y" -{ yyval.expr = StrConstNode::alloc( yyvsp[0].str.lineNumber, yyvsp[0].str.value, true); ; - break;} -case 105: + { yyval.expr = StrConstNode::alloc(yyvsp[0].str.lineNumber, yyvsp[0].str.value, true); ; + break; } + case 105: #line 442 "cmdgram.y" -{ yyval.expr = FloatNode::alloc( yyvsp[0].f.lineNumber, yyvsp[0].f.value ); ; - break;} -case 106: + { yyval.expr = FloatNode::alloc(yyvsp[0].f.lineNumber, yyvsp[0].f.value); ; + break; } + case 106: #line 444 "cmdgram.y" -{ yyval.expr = IntNode::alloc( yyvsp[0].i.lineNumber, yyvsp[0].i.value ); ; - break;} -case 107: + { yyval.expr = IntNode::alloc(yyvsp[0].i.lineNumber, yyvsp[0].i.value); ; + break; } + case 107: #line 446 "cmdgram.y" -{ yyval.expr = ConstantNode::alloc( yyvsp[0].i.lineNumber, StringTable->insert("break")); ; - break;} -case 108: + { yyval.expr = ConstantNode::alloc(yyvsp[0].i.lineNumber, StringTable->insert("break")); ; + break; } + case 108: #line 448 "cmdgram.y" -{ yyval.expr = SlotAccessNode::alloc( yyvsp[0].slot.lineNumber, yyvsp[0].slot.object, yyvsp[0].slot.array, yyvsp[0].slot.slotName ); ; - break;} -case 109: + { yyval.expr = SlotAccessNode::alloc(yyvsp[0].slot.lineNumber, yyvsp[0].slot.object, yyvsp[0].slot.array, yyvsp[0].slot.slotName); ; + break; } + case 109: #line 450 "cmdgram.y" -{ yyval.expr = InternalSlotAccessNode::alloc( yyvsp[0].intslot.lineNumber, yyvsp[0].intslot.object, yyvsp[0].intslot.slotExpr, yyvsp[0].intslot.recurse); ; - break;} -case 110: + { yyval.expr = InternalSlotAccessNode::alloc(yyvsp[0].intslot.lineNumber, yyvsp[0].intslot.object, yyvsp[0].intslot.slotExpr, yyvsp[0].intslot.recurse); ; + break; } + case 110: #line 452 "cmdgram.y" -{ yyval.expr = ConstantNode::alloc( yyvsp[0].s.lineNumber, yyvsp[0].s.value ); ; - break;} -case 111: + { yyval.expr = ConstantNode::alloc(yyvsp[0].s.lineNumber, yyvsp[0].s.value); ; + break; } + case 111: #line 454 "cmdgram.y" -{ yyval.expr = StrConstNode::alloc( yyvsp[0].str.lineNumber, yyvsp[0].str.value, false); ; - break;} -case 112: + { yyval.expr = StrConstNode::alloc(yyvsp[0].str.lineNumber, yyvsp[0].str.value, false); ; + break; } + case 112: #line 456 "cmdgram.y" -{ yyval.expr = (ExprNode*)VarNode::alloc( yyvsp[0].s.lineNumber, yyvsp[0].s.value, NULL); ; - break;} -case 113: + { yyval.expr = (ExprNode*)VarNode::alloc(yyvsp[0].s.lineNumber, yyvsp[0].s.value, NULL); ; + break; } + case 113: #line 458 "cmdgram.y" -{ yyval.expr = (ExprNode*)VarNode::alloc( yyvsp[-3].s.lineNumber, yyvsp[-3].s.value, yyvsp[-1].expr ); ; - break;} -case 114: + { yyval.expr = (ExprNode*)VarNode::alloc(yyvsp[-3].s.lineNumber, yyvsp[-3].s.value, yyvsp[-1].expr); ; + break; } + case 114: #line 460 "cmdgram.y" -{ + { const U32 bufLen = 64; UTF8 buffer[bufLen]; dSprintf(buffer, bufLen, "__anonymous_function%d", gAnonFunctionID++); StringTableEntry fName = StringTable->insert(buffer); StmtNode *fndef = FunctionDeclStmtNode::alloc(yyvsp[-6].i.lineNumber, fName, NULL, yyvsp[-4].var, yyvsp[-1].stmt); - if(!gAnonFunctionList) + if (!gAnonFunctionList) gAnonFunctionList = fndef; else gAnonFunctionList->append(fndef); - yyval.expr = StrConstNode::alloc( yyvsp[-6].i.lineNumber, (UTF8*)fName, false ); - ; - break;} -case 115: + yyval.expr = StrConstNode::alloc(yyvsp[-6].i.lineNumber, (UTF8*)fName, false); + ; + break; } + case 115: #line 478 "cmdgram.y" -{ yyval.slot.lineNumber = yyvsp[-2].expr->dbgLineNumber; yyval.slot.object = yyvsp[-2].expr; yyval.slot.slotName = yyvsp[0].s.value; yyval.slot.array = NULL; ; - break;} -case 116: + { yyval.slot.lineNumber = yyvsp[-2].expr->dbgLineNumber; yyval.slot.object = yyvsp[-2].expr; yyval.slot.slotName = yyvsp[0].s.value; yyval.slot.array = NULL; ; + break; } + case 116: #line 480 "cmdgram.y" -{ yyval.slot.lineNumber = yyvsp[-5].expr->dbgLineNumber; yyval.slot.object = yyvsp[-5].expr; yyval.slot.slotName = yyvsp[-3].s.value; yyval.slot.array = yyvsp[-1].expr; ; - break;} -case 117: + { yyval.slot.lineNumber = yyvsp[-5].expr->dbgLineNumber; yyval.slot.object = yyvsp[-5].expr; yyval.slot.slotName = yyvsp[-3].s.value; yyval.slot.array = yyvsp[-1].expr; ; + break; } + case 117: #line 485 "cmdgram.y" -{ yyval.intslot.lineNumber = yyvsp[-2].expr->dbgLineNumber; yyval.intslot.object = yyvsp[-2].expr; yyval.intslot.slotExpr = yyvsp[0].expr; yyval.intslot.recurse = false; ; - break;} -case 118: + { yyval.intslot.lineNumber = yyvsp[-2].expr->dbgLineNumber; yyval.intslot.object = yyvsp[-2].expr; yyval.intslot.slotExpr = yyvsp[0].expr; yyval.intslot.recurse = false; ; + break; } + case 118: #line 487 "cmdgram.y" -{ yyval.intslot.lineNumber = yyvsp[-2].expr->dbgLineNumber; yyval.intslot.object = yyvsp[-2].expr; yyval.intslot.slotExpr = yyvsp[0].expr; yyval.intslot.recurse = true; ; - break;} -case 119: + { yyval.intslot.lineNumber = yyvsp[-2].expr->dbgLineNumber; yyval.intslot.object = yyvsp[-2].expr; yyval.intslot.slotExpr = yyvsp[0].expr; yyval.intslot.recurse = true; ; + break; } + case 119: #line 492 "cmdgram.y" -{ yyval.expr = ConstantNode::alloc( yyvsp[0].s.lineNumber, yyvsp[0].s.value ); ; - break;} -case 120: + { yyval.expr = ConstantNode::alloc(yyvsp[0].s.lineNumber, yyvsp[0].s.value); ; + break; } + case 120: #line 494 "cmdgram.y" -{ yyval.expr = yyvsp[-1].expr; ; - break;} -case 121: + { yyval.expr = yyvsp[-1].expr; ; + break; } + case 121: #line 499 "cmdgram.y" -{ yyval.asn.lineNumber = yyvsp[0].i.lineNumber; yyval.asn.token = '+'; yyval.asn.expr = FloatNode::alloc( yyvsp[0].i.lineNumber, 1 ); ; - break;} -case 122: + { yyval.asn.lineNumber = yyvsp[0].i.lineNumber; yyval.asn.token = opPLUSPLUS; yyval.asn.expr = FloatNode::alloc(yyvsp[0].i.lineNumber, 1); ; + break; } + case 122: #line 501 "cmdgram.y" -{ yyval.asn.lineNumber = yyvsp[0].i.lineNumber; yyval.asn.token = '-'; yyval.asn.expr = FloatNode::alloc( yyvsp[0].i.lineNumber, 1 ); ; - break;} -case 123: + { yyval.asn.lineNumber = yyvsp[0].i.lineNumber; yyval.asn.token = opMINUSMINUS; yyval.asn.expr = FloatNode::alloc(yyvsp[0].i.lineNumber, 1); ; + break; } + case 123: #line 503 "cmdgram.y" -{ yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = '+'; yyval.asn.expr = yyvsp[0].expr; ; - break;} -case 124: + { yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = '+'; yyval.asn.expr = yyvsp[0].expr; ; + break; } + case 124: #line 505 "cmdgram.y" -{ yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = '-'; yyval.asn.expr = yyvsp[0].expr; ; - break;} -case 125: + { yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = '-'; yyval.asn.expr = yyvsp[0].expr; ; + break; } + case 125: #line 507 "cmdgram.y" -{ yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = '*'; yyval.asn.expr = yyvsp[0].expr; ; - break;} -case 126: + { yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = '*'; yyval.asn.expr = yyvsp[0].expr; ; + break; } + case 126: #line 509 "cmdgram.y" -{ yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = '/'; yyval.asn.expr = yyvsp[0].expr; ; - break;} -case 127: + { yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = '/'; yyval.asn.expr = yyvsp[0].expr; ; + break; } + case 127: #line 511 "cmdgram.y" -{ yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = '%'; yyval.asn.expr = yyvsp[0].expr; ; - break;} -case 128: + { yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = '%'; yyval.asn.expr = yyvsp[0].expr; ; + break; } + case 128: #line 513 "cmdgram.y" -{ yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = '&'; yyval.asn.expr = yyvsp[0].expr; ; - break;} -case 129: + { yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = '&'; yyval.asn.expr = yyvsp[0].expr; ; + break; } + case 129: #line 515 "cmdgram.y" -{ yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = '^'; yyval.asn.expr = yyvsp[0].expr; ; - break;} -case 130: + { yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = '^'; yyval.asn.expr = yyvsp[0].expr; ; + break; } + case 130: #line 517 "cmdgram.y" -{ yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = '|'; yyval.asn.expr = yyvsp[0].expr; ; - break;} -case 131: + { yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = '|'; yyval.asn.expr = yyvsp[0].expr; ; + break; } + case 131: #line 519 "cmdgram.y" -{ yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = opSHL; yyval.asn.expr = yyvsp[0].expr; ; - break;} -case 132: + { yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = opSHL; yyval.asn.expr = yyvsp[0].expr; ; + break; } + case 132: #line 521 "cmdgram.y" -{ yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = opSHR; yyval.asn.expr = yyvsp[0].expr; ; - break;} -case 133: + { yyval.asn.lineNumber = yyvsp[-1].i.lineNumber; yyval.asn.token = opSHR; yyval.asn.expr = yyvsp[0].expr; ; + break; } + case 133: #line 526 "cmdgram.y" -{ yyval.expr = yyvsp[0].expr; ; - break;} -case 134: + { yyval.expr = yyvsp[0].expr; ; + break; } + case 134: #line 528 "cmdgram.y" -{ yyval.expr = yyvsp[0].expr; ; - break;} -case 135: + { yyval.expr = yyvsp[0].expr; ; + break; } + case 135: #line 530 "cmdgram.y" -{ yyval.expr = yyvsp[0].od; ; - break;} -case 136: + { yyval.expr = yyvsp[0].od; ; + break; } + case 136: #line 532 "cmdgram.y" -{ yyval.expr = AssignExprNode::alloc( yyvsp[-2].s.lineNumber, yyvsp[-2].s.value, NULL, yyvsp[0].expr); ; - break;} -case 137: + { yyval.expr = AssignExprNode::alloc(yyvsp[-2].s.lineNumber, yyvsp[-2].s.value, NULL, yyvsp[0].expr); ; + break; } + case 137: #line 534 "cmdgram.y" -{ yyval.expr = AssignExprNode::alloc( yyvsp[-5].s.lineNumber, yyvsp[-5].s.value, yyvsp[-3].expr, yyvsp[0].expr); ; - break;} -case 138: + { yyval.expr = AssignExprNode::alloc(yyvsp[-5].s.lineNumber, yyvsp[-5].s.value, yyvsp[-3].expr, yyvsp[0].expr); ; + break; } + case 138: #line 536 "cmdgram.y" -{ yyval.expr = AssignOpExprNode::alloc( yyvsp[-1].s.lineNumber, yyvsp[-1].s.value, NULL, yyvsp[0].asn.expr, yyvsp[0].asn.token); ; - break;} -case 139: + { yyval.expr = AssignOpExprNode::alloc(yyvsp[-1].s.lineNumber, yyvsp[-1].s.value, NULL, yyvsp[0].asn.expr, yyvsp[0].asn.token); ; + break; } + case 139: #line 538 "cmdgram.y" -{ yyval.expr = AssignOpExprNode::alloc( yyvsp[-4].s.lineNumber, yyvsp[-4].s.value, yyvsp[-2].expr, yyvsp[0].asn.expr, yyvsp[0].asn.token); ; - break;} -case 140: + { yyval.expr = AssignOpExprNode::alloc(yyvsp[-4].s.lineNumber, yyvsp[-4].s.value, yyvsp[-2].expr, yyvsp[0].asn.expr, yyvsp[0].asn.token); ; + break; } + case 140: #line 540 "cmdgram.y" -{ yyval.expr = SlotAssignOpNode::alloc( yyvsp[-1].slot.lineNumber, yyvsp[-1].slot.object, yyvsp[-1].slot.slotName, yyvsp[-1].slot.array, yyvsp[0].asn.token, yyvsp[0].asn.expr); ; - break;} -case 141: + { yyval.expr = SlotAssignOpNode::alloc(yyvsp[-1].slot.lineNumber, yyvsp[-1].slot.object, yyvsp[-1].slot.slotName, yyvsp[-1].slot.array, yyvsp[0].asn.token, yyvsp[0].asn.expr); ; + break; } + case 141: #line 542 "cmdgram.y" -{ yyval.expr = SlotAssignNode::alloc( yyvsp[-2].slot.lineNumber, yyvsp[-2].slot.object, yyvsp[-2].slot.array, yyvsp[-2].slot.slotName, yyvsp[0].expr); ; - break;} -case 142: + { yyval.expr = SlotAssignNode::alloc(yyvsp[-2].slot.lineNumber, yyvsp[-2].slot.object, yyvsp[-2].slot.array, yyvsp[-2].slot.slotName, yyvsp[0].expr); ; + break; } + case 142: #line 544 "cmdgram.y" -{ yyval.expr = SlotAssignNode::alloc( yyvsp[-4].slot.lineNumber, yyvsp[-4].slot.object, yyvsp[-4].slot.array, yyvsp[-4].slot.slotName, yyvsp[-1].expr); ; - break;} -case 143: + { yyval.expr = SlotAssignNode::alloc(yyvsp[-4].slot.lineNumber, yyvsp[-4].slot.object, yyvsp[-4].slot.array, yyvsp[-4].slot.slotName, yyvsp[-1].expr); ; + break; } + case 143: #line 549 "cmdgram.y" -{ yyval.expr = FuncCallExprNode::alloc( yyvsp[-3].s.lineNumber, yyvsp[-3].s.value, NULL, yyvsp[-1].expr, false); ; - break;} -case 144: + { yyval.expr = FuncCallExprNode::alloc(yyvsp[-3].s.lineNumber, yyvsp[-3].s.value, NULL, yyvsp[-1].expr, false); ; + break; } + case 144: #line 551 "cmdgram.y" -{ yyval.expr = FuncCallExprNode::alloc( yyvsp[-5].s.lineNumber, yyvsp[-3].s.value, yyvsp[-5].s.value, yyvsp[-1].expr, false); ; - break;} -case 145: + { yyval.expr = FuncCallExprNode::alloc(yyvsp[-5].s.lineNumber, yyvsp[-3].s.value, yyvsp[-5].s.value, yyvsp[-1].expr, false); ; + break; } + case 145: #line 553 "cmdgram.y" -{ yyvsp[-5].expr->append(yyvsp[-1].expr); yyval.expr = FuncCallExprNode::alloc( yyvsp[-5].expr->dbgLineNumber, yyvsp[-3].s.value, NULL, yyvsp[-5].expr, true); ; - break;} -case 146: -#line 558 "cmdgram.y" -{ yyval.expr = AssertCallExprNode::alloc( yyvsp[-3].i.lineNumber, yyvsp[-1].expr, NULL ); ; - break;} -case 147: + { yyvsp[-5].expr->append(yyvsp[-1].expr); yyval.expr = FuncCallExprNode::alloc(yyvsp[-5].expr->dbgLineNumber, yyvsp[-3].s.value, NULL, yyvsp[-5].expr, true); ; + break; } + case 146: +#line 555 "cmdgram.y" + { yyval.expr = FuncPointerCallExprNode::alloc(yyvsp[-3].expr->dbgLineNumber, yyvsp[-3].expr, yyvsp[-1].expr); ; + break; } + case 147: #line 560 "cmdgram.y" -{ yyval.expr = AssertCallExprNode::alloc( yyvsp[-5].i.lineNumber, yyvsp[-3].expr, yyvsp[-1].str.value ); ; - break;} -case 148: -#line 565 "cmdgram.y" -{ yyval.expr = NULL; ; - break;} -case 149: + { yyval.expr = AssertCallExprNode::alloc(yyvsp[-3].i.lineNumber, yyvsp[-1].expr, NULL); ; + break; } + case 148: +#line 562 "cmdgram.y" + { yyval.expr = AssertCallExprNode::alloc(yyvsp[-5].i.lineNumber, yyvsp[-3].expr, yyvsp[-1].str.value); ; + break; } + case 149: #line 567 "cmdgram.y" -{ yyval.expr = yyvsp[0].expr; ; - break;} -case 150: -#line 572 "cmdgram.y" -{ yyval.expr = yyvsp[0].expr; ; - break;} -case 151: + { yyval.expr = NULL; ; + break; } + case 150: +#line 569 "cmdgram.y" + { yyval.expr = yyvsp[0].expr; ; + break; } + case 151: #line 574 "cmdgram.y" -{ (yyvsp[-2].expr)->append(yyvsp[0].expr); yyval.expr = yyvsp[-2].expr; ; - break;} -case 152: -#line 579 "cmdgram.y" -{ yyval.slist = NULL; ; - break;} -case 153: + { yyval.expr = yyvsp[0].expr; ; + break; } + case 152: +#line 576 "cmdgram.y" + { (yyvsp[-2].expr)->append(yyvsp[0].expr); yyval.expr = yyvsp[-2].expr; ; + break; } + case 153: #line 581 "cmdgram.y" -{ yyval.slist = yyvsp[0].slist; ; - break;} -case 154: -#line 586 "cmdgram.y" -{ yyval.slist = yyvsp[0].slist; ; - break;} -case 155: + { yyval.slist = NULL; ; + break; } + case 154: +#line 583 "cmdgram.y" + { yyval.slist = yyvsp[0].slist; ; + break; } + case 155: #line 588 "cmdgram.y" -{ yyvsp[-1].slist->append(yyvsp[0].slist); yyval.slist = yyvsp[-1].slist; ; - break;} -case 156: -#line 593 "cmdgram.y" -{ yyval.slist = SlotAssignNode::alloc( yyvsp[-3].s.lineNumber, NULL, NULL, yyvsp[-3].s.value, yyvsp[-1].expr); ; - break;} -case 157: + { yyval.slist = yyvsp[0].slist; ; + break; } + case 156: +#line 590 "cmdgram.y" + { yyvsp[-1].slist->append(yyvsp[0].slist); yyval.slist = yyvsp[-1].slist; ; + break; } + case 157: #line 595 "cmdgram.y" -{ yyval.slist = SlotAssignNode::alloc( yyvsp[-4].i.lineNumber, NULL, NULL, yyvsp[-3].s.value, yyvsp[-1].expr, yyvsp[-4].i.value); ; - break;} -case 158: + { yyval.slist = SlotAssignNode::alloc(yyvsp[-3].s.lineNumber, NULL, NULL, yyvsp[-3].s.value, yyvsp[-1].expr); ; + break; } + case 158: #line 597 "cmdgram.y" -{ yyval.slist = SlotAssignNode::alloc( yyvsp[-3].i.lineNumber, NULL, NULL, StringTable->insert("datablock"), yyvsp[-1].expr); ; - break;} -case 159: + { yyval.slist = SlotAssignNode::alloc(yyvsp[-4].i.lineNumber, NULL, NULL, yyvsp[-3].s.value, yyvsp[-1].expr, yyvsp[-4].i.value); ; + break; } + case 159: #line 599 "cmdgram.y" -{ yyval.slist = SlotAssignNode::alloc( yyvsp[-6].s.lineNumber, NULL, yyvsp[-4].expr, yyvsp[-6].s.value, yyvsp[-1].expr); ; - break;} -case 160: + { yyval.slist = SlotAssignNode::alloc(yyvsp[-3].i.lineNumber, NULL, NULL, StringTable->insert("datablock"), yyvsp[-1].expr); ; + break; } + case 160: #line 601 "cmdgram.y" -{ yyval.slist = SlotAssignNode::alloc( yyvsp[-7].i.lineNumber, NULL, yyvsp[-4].expr, yyvsp[-6].s.value, yyvsp[-1].expr, yyvsp[-7].i.value); ; - break;} -case 161: -#line 606 "cmdgram.y" -{ yyval.expr = yyvsp[0].expr; ; - break;} -case 162: + { yyval.slist = SlotAssignNode::alloc(yyvsp[-6].s.lineNumber, NULL, yyvsp[-4].expr, yyvsp[-6].s.value, yyvsp[-1].expr); ; + break; } + case 161: +#line 603 "cmdgram.y" + { yyval.slist = SlotAssignNode::alloc(yyvsp[-7].i.lineNumber, NULL, yyvsp[-4].expr, yyvsp[-6].s.value, yyvsp[-1].expr, yyvsp[-7].i.value); ; + break; } + case 162: #line 608 "cmdgram.y" -{ yyval.expr = CommaCatExprNode::alloc( yyvsp[-2].expr->dbgLineNumber, yyvsp[-2].expr, yyvsp[0].expr); ; - break;} -} + { yyval.expr = yyvsp[0].expr; ; + break; } + case 163: +#line 610 "cmdgram.y" + { yyval.expr = CommaCatExprNode::alloc(yyvsp[-2].expr->dbgLineNumber, yyvsp[-2].expr, yyvsp[0].expr); ; + break; } + } /* the action file gets copied in in place of this dollarsign */ #line 487 "bison.simple" - - yyvsp -= yylen; - yyssp -= yylen; + + yyvsp -= yylen; + yyssp -= yylen; #ifdef YYLSP_NEEDED - yylsp -= yylen; + yylsp -= yylen; #endif #if YYDEBUG != 0 - if (yydebug) - { + if (yydebug) + { short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now"); + fprintf(stderr, "state stack now"); while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } + fprintf(stderr, " %d", *++ssp1); + fprintf(stderr, "\n"); + } #endif - *++yyvsp = yyval; + *++yyvsp = yyval; #ifdef YYLSP_NEEDED - yylsp++; - if (yylen == 0) - { + yylsp++; + if (yylen == 0) + { yylsp->first_line = yylloc.first_line; yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; + yylsp->last_line = (yylsp - 1)->last_line; + yylsp->last_column = (yylsp - 1)->last_column; yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } + } + else + { + yylsp->last_line = (yylsp + yylen - 1)->last_line; + yylsp->last_column = (yylsp + yylen - 1)->last_column; + } #endif - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ + /* Now "shift" the result of the reduction. + Determine what state that goes to, + based on the state we popped back to + and the rule number reduced by. */ - yyn = yyr1[yyn]; + yyn = yyr1[yyn]; - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; + yystate = yypgoto[yyn - YYNTBASE] + *yyssp; + if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTBASE]; - goto yynewstate; + goto yynewstate; yyerrlab: /* here on detecting error */ - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ - { + if (!yyerrstatus) + /* If not already recovering from an error, report this error. */ + { ++yynerrs; #ifdef YYERROR_VERBOSE yyn = yypact[yystate]; if (yyn > YYFLAG && yyn < YYLAST) - { - int size = 0; - char *msg; - int x, count; - - count = 0; - /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; - msg = (char *) malloc(size + 15); - if (msg != 0) - { - strcpy(msg, "parse error"); - - if (count < 5) { - count = 0; - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) + int size = 0; + char *msg; + int x, count; + + count = 0; + /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + size += strlen(yytname[x]) + 15, count++; + msg = (char *)malloc(size + 15); + if (msg != 0) + { + strcpy(msg, "parse error"); + + if (count < 5) { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; + count = 0; + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + { + strcat(msg, count == 0 ? ", expecting `" : " or `"); + strcat(msg, yytname[x]); + strcat(msg, "'"); + count++; + } } + yyerror(msg); + free(msg); + } + else + yyerror("parse error; also virtual memory exceeded"); } - yyerror(msg); - free(msg); - } - else - yyerror ("parse error; also virtual memory exceeded"); - } else #endif /* YYERROR_VERBOSE */ - yyerror("parse error"); - } + yyerror("parse error"); + } - goto yyerrlab1; + goto yyerrlab1; yyerrlab1: /* here on error raised explicitly by an action */ - if (yyerrstatus == 3) - { + if (yyerrstatus == 3) + { /* if just tried and failed to reuse lookahead token after an error, discard it. */ /* return failure if at end of input */ if (yychar == YYEOF) - YYABORT; + YYABORT; #if YYDEBUG != 0 if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); + fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); #endif yychar = YYEMPTY; - } + } - /* Else will try to reuse lookahead token - after shifting the error token. */ + /* Else will try to reuse lookahead token + after shifting the error token. */ - yyerrstatus = 3; /* Each real token shifted decrements this */ + yyerrstatus = 3; /* Each real token shifted decrements this */ - goto yyerrhandle; + goto yyerrhandle; yyerrdefault: /* current state does not do anything special for the error token. */ #if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; + /* This is wrong; only states that explicitly want error tokens + should shift them. */ + yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ + if (yyn) goto yydefault; #endif yyerrpop: /* pop the current state because it cannot handle the error token */ - if (yyssp == yyss) YYABORT; - yyvsp--; - yystate = *--yyssp; + if (yyssp == yyss) YYABORT; + yyvsp--; + yystate = *--yyssp; #ifdef YYLSP_NEEDED - yylsp--; + yylsp--; #endif #if YYDEBUG != 0 - if (yydebug) - { + if (yydebug) + { short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now"); + fprintf(stderr, "Error: state stack now"); while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } + fprintf(stderr, " %d", *++ssp1); + fprintf(stderr, "\n"); + } #endif yyerrhandle: - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yyerrdefault; - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; + yyn += YYTERROR; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) + goto yyerrdefault; - yyn = yytable[yyn]; - if (yyn < 0) - { + yyn = yytable[yyn]; + if (yyn < 0) + { if (yyn == YYFLAG) - goto yyerrpop; + goto yyerrpop; yyn = -yyn; goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; + } + else if (yyn == 0) + goto yyerrpop; - if (yyn == YYFINAL) - YYACCEPT; + if (yyn == YYFINAL) + YYACCEPT; #if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting error token, "); + if (yydebug) + fprintf(stderr, "Shifting error token, "); #endif - *++yyvsp = yylval; + *++yyvsp = yylval; #ifdef YYLSP_NEEDED - *++yylsp = yylloc; + *++yylsp = yylloc; #endif - yystate = yyn; - goto yynewstate; + yystate = yyn; + goto yynewstate; } -#line 610 "cmdgram.y" +#line 612 "cmdgram.y" diff --git a/Engine/source/console/cmdgram.h b/Engine/source/console/cmdgram.h index fc22f3df2..83736a565 100644 --- a/Engine/source/console/cmdgram.h +++ b/Engine/source/console/cmdgram.h @@ -15,78 +15,78 @@ typedef union { AssignDecl asn; IfStmtNode* ifnode; } YYSTYPE; -#define rwDEFINE 258 -#define rwENDDEF 259 -#define rwDECLARE 260 -#define rwDECLARESINGLETON 261 -#define rwBREAK 262 -#define rwELSE 263 -#define rwCONTINUE 264 -#define rwGLOBAL 265 -#define rwIF 266 -#define rwNIL 267 -#define rwRETURN 268 -#define rwWHILE 269 -#define rwDO 270 -#define rwENDIF 271 -#define rwENDWHILE 272 -#define rwENDFOR 273 -#define rwDEFAULT 274 -#define rwFOR 275 -#define rwFOREACH 276 -#define rwFOREACHSTR 277 -#define rwIN 278 -#define rwDATABLOCK 279 -#define rwSWITCH 280 -#define rwCASE 281 -#define rwSWITCHSTR 282 -#define rwCASEOR 283 -#define rwPACKAGE 284 -#define rwNAMESPACE 285 -#define rwCLASS 286 -#define rwASSERT 287 -#define ILLEGAL_TOKEN 288 -#define CHRCONST 289 -#define INTCONST 290 -#define TTAG 291 -#define VAR 292 -#define IDENT 293 -#define TYPEIDENT 294 -#define DOCBLOCK 295 -#define STRATOM 296 -#define TAGATOM 297 -#define FLTCONST 298 -#define opINTNAME 299 -#define opINTNAMER 300 -#define opMINUSMINUS 301 -#define opPLUSPLUS 302 -#define STMT_SEP 303 -#define opSHL 304 -#define opSHR 305 -#define opPLASN 306 -#define opMIASN 307 -#define opMLASN 308 -#define opDVASN 309 -#define opMODASN 310 -#define opANDASN 311 -#define opXORASN 312 -#define opORASN 313 -#define opSLASN 314 -#define opSRASN 315 -#define opCAT 316 -#define opEQ 317 -#define opNE 318 -#define opGE 319 -#define opLE 320 -#define opAND 321 -#define opOR 322 -#define opSTREQ 323 -#define opCOLONCOLON 324 -#define opMDASN 325 -#define opNDASN 326 -#define opNTASN 327 -#define opSTRNE 328 -#define UNARY 329 +#define rwDEFINE 258 +#define rwENDDEF 259 +#define rwDECLARE 260 +#define rwDECLARESINGLETON 261 +#define rwBREAK 262 +#define rwELSE 263 +#define rwCONTINUE 264 +#define rwGLOBAL 265 +#define rwIF 266 +#define rwNIL 267 +#define rwRETURN 268 +#define rwWHILE 269 +#define rwDO 270 +#define rwENDIF 271 +#define rwENDWHILE 272 +#define rwENDFOR 273 +#define rwDEFAULT 274 +#define rwFOR 275 +#define rwFOREACH 276 +#define rwFOREACHSTR 277 +#define rwIN 278 +#define rwDATABLOCK 279 +#define rwSWITCH 280 +#define rwCASE 281 +#define rwSWITCHSTR 282 +#define rwCASEOR 283 +#define rwPACKAGE 284 +#define rwNAMESPACE 285 +#define rwCLASS 286 +#define rwASSERT 287 +#define ILLEGAL_TOKEN 288 +#define CHRCONST 289 +#define INTCONST 290 +#define TTAG 291 +#define VAR 292 +#define IDENT 293 +#define TYPEIDENT 294 +#define DOCBLOCK 295 +#define STRATOM 296 +#define TAGATOM 297 +#define FLTCONST 298 +#define opINTNAME 299 +#define opINTNAMER 300 +#define opMINUSMINUS 301 +#define opPLUSPLUS 302 +#define STMT_SEP 303 +#define opSHL 304 +#define opSHR 305 +#define opPLASN 306 +#define opMIASN 307 +#define opMLASN 308 +#define opDVASN 309 +#define opMODASN 310 +#define opANDASN 311 +#define opXORASN 312 +#define opORASN 313 +#define opSLASN 314 +#define opSRASN 315 +#define opCAT 316 +#define opEQ 317 +#define opNE 318 +#define opGE 319 +#define opLE 320 +#define opAND 321 +#define opOR 322 +#define opSTREQ 323 +#define opCOLONCOLON 324 +#define opMDASN 325 +#define opNDASN 326 +#define opNTASN 327 +#define opSTRNE 328 +#define UNARY 329 extern YYSTYPE CMDlval; diff --git a/Engine/source/console/codeBlock.cpp b/Engine/source/console/codeBlock.cpp index 192b50f0f..3f5c3f292 100644 --- a/Engine/source/console/codeBlock.cpp +++ b/Engine/source/console/codeBlock.cpp @@ -63,11 +63,11 @@ CodeBlock::~CodeBlock() // Make sure we aren't lingering in the current code block... AssertFatal(smCurrentCodeBlock != this, "CodeBlock::~CodeBlock - Caught lingering in smCurrentCodeBlock!"); - if(name) + if (name) removeFromCodeList(); delete[] const_cast(globalStrings); delete[] const_cast(functionStrings); - + functionStringsMaxLen = 0; globalStringsMaxLen = 0; @@ -85,7 +85,7 @@ StringTableEntry CodeBlock::getCurrentCodeBlockName() return CodeBlock::getCurrentBlock()->name; else return NULL; -} +} StringTableEntry CodeBlock::getCurrentCodeBlockFullPath() { @@ -105,8 +105,8 @@ StringTableEntry CodeBlock::getCurrentCodeBlockModName() CodeBlock *CodeBlock::find(StringTableEntry name) { - for(CodeBlock *walk = CodeBlock::getCodeBlockList(); walk; walk = walk->nextFile) - if(walk->name == name) + for (CodeBlock *walk = CodeBlock::getCodeBlockList(); walk; walk = walk->nextFile) + if (walk->name == name) return walk; return NULL; } @@ -116,9 +116,9 @@ CodeBlock *CodeBlock::find(StringTableEntry name) void CodeBlock::addToCodeList() { // remove any code blocks with my name - for(CodeBlock **walk = &smCodeBlockList; *walk;walk = &((*walk)->nextFile)) + for (CodeBlock **walk = &smCodeBlockList; *walk; walk = &((*walk)->nextFile)) { - if((*walk)->name == name) + if ((*walk)->name == name) { *walk = (*walk)->nextFile; break; @@ -130,9 +130,9 @@ void CodeBlock::addToCodeList() void CodeBlock::clearAllBreaks() { - if(!lineBreakPairs) + if (!lineBreakPairs) return; - for(U32 i = 0; i < lineBreakPairCount; i++) + for (U32 i = 0; i < lineBreakPairCount; i++) { U32 *p = lineBreakPairs + i * 2; code[p[1]] = p[0] & 0xFF; @@ -141,12 +141,12 @@ void CodeBlock::clearAllBreaks() void CodeBlock::clearBreakpoint(U32 lineNumber) { - if(!lineBreakPairs) + if (!lineBreakPairs) return; - for(U32 i = 0; i < lineBreakPairCount; i++) + for (U32 i = 0; i < lineBreakPairCount; i++) { U32 *p = lineBreakPairs + i * 2; - if((p[0] >> 8) == lineNumber) + if ((p[0] >> 8) == lineNumber) { code[p[1]] = p[0] & 0xFF; return; @@ -156,9 +156,9 @@ void CodeBlock::clearBreakpoint(U32 lineNumber) void CodeBlock::setAllBreaks() { - if(!lineBreakPairs) + if (!lineBreakPairs) return; - for(U32 i = 0; i < lineBreakPairCount; i++) + for (U32 i = 0; i < lineBreakPairCount; i++) { U32 *p = lineBreakPairs + i * 2; code[p[1]] = OP_BREAK; @@ -167,13 +167,13 @@ void CodeBlock::setAllBreaks() bool CodeBlock::setBreakpoint(U32 lineNumber) { - if(!lineBreakPairs) + if (!lineBreakPairs) return false; - for(U32 i = 0; i < lineBreakPairCount; i++) + for (U32 i = 0; i < lineBreakPairCount; i++) { U32 *p = lineBreakPairs + i * 2; - if((p[0] >> 8) == lineNumber) + if ((p[0] >> 8) == lineNumber) { code[p[1]] = OP_BREAK; return true; @@ -185,15 +185,15 @@ bool CodeBlock::setBreakpoint(U32 lineNumber) U32 CodeBlock::findFirstBreakLine(U32 lineNumber) { - if(!lineBreakPairs) + if (!lineBreakPairs) return 0; - for(U32 i = 0; i < lineBreakPairCount; i++) + for (U32 i = 0; i < lineBreakPairCount; i++) { U32 *p = lineBreakPairs + i * 2; U32 line = (p[0] >> 8); - if( lineNumber <= line ) + if (lineNumber <= line) return line; } @@ -210,35 +210,35 @@ void CodeBlock::findBreakLine(U32 ip, U32 &line, U32 &instruction) { U32 min = 0; U32 max = lineBreakPairCount - 1; - LinePair *p = (LinePair *) lineBreakPairs; + LinePair *p = (LinePair *)lineBreakPairs; U32 found; - if(!lineBreakPairCount || p[min].ip > ip || p[max].ip < ip) + if (!lineBreakPairCount || p[min].ip > ip || p[max].ip < ip) { line = 0; instruction = OP_INVALID; return; } - else if(p[min].ip == ip) + else if (p[min].ip == ip) found = min; - else if(p[max].ip == ip) + else if (p[max].ip == ip) found = max; else { - for(;;) + for (;;) { - if(min == max - 1) + if (min == max - 1) { found = min; break; } U32 mid = (min + max) >> 1; - if(p[mid].ip == ip) + if (p[mid].ip == ip) { found = mid; break; } - else if(p[mid].ip > ip) + else if (p[mid].ip > ip) max = mid; else min = mid; @@ -260,9 +260,9 @@ const char *CodeBlock::getFileLine(U32 ip) void CodeBlock::removeFromCodeList() { - for(CodeBlock **walk = &smCodeBlockList; *walk; walk = &((*walk)->nextFile)) + for (CodeBlock **walk = &smCodeBlockList; *walk; walk = &((*walk)->nextFile)) { - if(*walk == this) + if (*walk == this) { *walk = nextFile; @@ -275,8 +275,8 @@ void CodeBlock::removeFromCodeList() // Let the telnet debugger know that this code // block has been unloaded and that it needs to // remove references to it. - if ( TelDebugger ) - TelDebugger->clearCodeBlockPointers( this ); + if (TelDebugger) + TelDebugger->clearCodeBlockPointers(this); } void CodeBlock::calcBreakList() @@ -285,21 +285,21 @@ void CodeBlock::calcBreakList() S32 line = -1; U32 seqCount = 0; U32 i; - for(i = 0; i < lineBreakPairCount; i++) + for (i = 0; i < lineBreakPairCount; i++) { U32 lineNumber = lineBreakPairs[i * 2]; - if(lineNumber == U32(line + 1)) + if (lineNumber == U32(line + 1)) seqCount++; else { - if(seqCount) + if (seqCount) size++; size++; seqCount = 1; } line = lineNumber; } - if(seqCount) + if (seqCount) size++; breakList = new U32[size]; @@ -308,15 +308,15 @@ void CodeBlock::calcBreakList() seqCount = 0; size = 0; - for(i = 0; i < lineBreakPairCount; i++) + for (i = 0; i < lineBreakPairCount; i++) { U32 lineNumber = lineBreakPairs[i * 2]; - if(lineNumber == U32(line + 1)) + if (lineNumber == U32(line + 1)) seqCount++; else { - if(seqCount) + if (seqCount) breakList[size++] = seqCount; breakList[size++] = lineNumber - getMax(0, line) - 1; seqCount = 1; @@ -325,10 +325,10 @@ void CodeBlock::calcBreakList() line = lineNumber; } - if(seqCount) + if (seqCount) breakList[size++] = seqCount; - for(i = 0; i < lineBreakPairCount; i++) + for (i = 0; i < lineBreakPairCount; i++) { U32 *p = lineBreakPairs + i * 2; p[0] = (p[0] << 8) | code[p[1]]; @@ -337,8 +337,8 @@ void CodeBlock::calcBreakList() // Let the telnet debugger know that this code // block has been loaded and that it can add break // points it has for it. - if ( TelDebugger ) - TelDebugger->addAllBreakpoints( this ); + if (TelDebugger) + TelDebugger->addAllBreakpoints(this); } bool CodeBlock::read(StringTableEntry fileName, Stream &st) @@ -348,19 +348,19 @@ bool CodeBlock::read(StringTableEntry fileName, Stream &st) name = fileName; - if(fileName) + if (fileName) { fullPath = NULL; - if(Platform::isFullPath(fileName)) + if (Platform::isFullPath(fileName)) fullPath = fileName; - if(dStrnicmp(exePath, fileName, dStrlen(exePath)) == 0) + if (dStrnicmp(exePath, fileName, dStrlen(exePath)) == 0) name = StringTable->insert(fileName + dStrlen(exePath) + 1, true); - else if(dStrnicmp(cwd, fileName, dStrlen(cwd)) == 0) + else if (dStrnicmp(cwd, fileName, dStrlen(cwd)) == 0) name = StringTable->insert(fileName + dStrlen(cwd) + 1, true); - if(fullPath == NULL) + if (fullPath == NULL) { char buf[1024]; fullPath = StringTable->insert(Platform::makeFullPathName(fileName, buf, sizeof(buf)), true); @@ -368,13 +368,13 @@ bool CodeBlock::read(StringTableEntry fileName, Stream &st) modPath = Con::getModNameFromPath(fileName); } - + // addToCodeList(); - U32 globalSize,size,i; + U32 globalSize, size, i; st.read(&size); - if(size) + if (size) { globalStrings = new char[size]; globalStringsMaxLen = size; @@ -382,24 +382,24 @@ bool CodeBlock::read(StringTableEntry fileName, Stream &st) } globalSize = size; st.read(&size); - if(size) + if (size) { functionStrings = new char[size]; functionStringsMaxLen = size; st.read(size, functionStrings); } st.read(&size); - if(size) + if (size) { globalFloats = new F64[size]; - for(U32 i = 0; i < size; i++) + for (U32 i = 0; i < size; i++) st.read(&globalFloats[i]); } st.read(&size); - if(size) + if (size) { functionFloats = new F64[size]; - for(U32 i = 0; i < size; i++) + for (U32 i = 0; i < size; i++) st.read(&functionFloats[i]); } U32 codeLength; @@ -409,17 +409,17 @@ bool CodeBlock::read(StringTableEntry fileName, Stream &st) U32 totSize = codeLength + lineBreakPairCount * 2; code = new U32[totSize]; - for(i = 0; i < codeLength; i++) + for (i = 0; i < codeLength; i++) { U8 b; st.read(&b); - if(b == 0xFF) + if (b == 0xFF) st.read(&code[i]); else code[i] = b; } - for(i = codeLength; i < totSize; i++) + for (i = codeLength; i < totSize; i++) st.read(&code[i]); lineBreakPairs = code + codeLength; @@ -427,26 +427,26 @@ bool CodeBlock::read(StringTableEntry fileName, Stream &st) // StringTable-ize our identifiers. U32 identCount; st.read(&identCount); - while(identCount--) + while (identCount--) { U32 offset; st.read(&offset); StringTableEntry ste; - if(offset < globalSize) + if (offset < globalSize) ste = StringTable->insert(globalStrings + offset); else ste = StringTable->EmptyString(); U32 count; st.read(&count); - while(count--) + while (count--) { U32 ip; st.read(&ip); - code[ip] = *((U32 *) &ste); + code[ip] = *((U32 *)&ste); } } - if(lineBreakPairCount) + if (lineBreakPairCount) calcBreakList(); return true; @@ -456,11 +456,11 @@ bool CodeBlock::read(StringTableEntry fileName, Stream &st) bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, const char *inScript, bool overrideNoDso) { AssertFatal(Con::isMainThread(), "Compiling code on a secondary thread"); - + // This will return true, but return value is ignored char *script; - chompUTF8BOM( inScript, &script ); - + chompUTF8BOM(inScript, &script); + gSyntaxError = false; consoleAllocReset(); @@ -490,19 +490,19 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con } - if(gSyntaxError) + if (gSyntaxError) { consoleAllocReset(); return false; - } + } #ifdef TORQUE_NO_DSO_GENERATION - if(!overrideNoDso) + if (!overrideNoDso) return false; #endif // !TORQUE_NO_DSO_GENERATION FileStream st; - if(!st.open(codeFileName, Torque::FS::File::Write)) + if (!st.open(codeFileName, Torque::FS::File::Write)) return false; st.write(U32(Con::DSOVersion)); @@ -513,7 +513,7 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con CodeStream codeStream; U32 lastIp; - if(gStatementList) + if (gStatementList) { lastIp = compileBlock(gStatementList, codeStream, 0) + 1; } @@ -522,10 +522,10 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con codeSize = 1; lastIp = 0; } - + codeStream.emit(OP_RETURN); codeStream.emitCodeStream(&codeSize, &code, &lineBreakPairs); - + lineBreakPairCount = codeStream.getNumLineBreaks(); // Write string table data... @@ -536,18 +536,18 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con getGlobalFloatTable().write(st); getFunctionFloatTable().write(st); - if(lastIp != codeSize) + if (lastIp != codeSize) Con::errorf(ConsoleLogEntry::General, "CodeBlock::compile - precompile size mismatch, a precompile/compile function pair is probably mismatched."); - + U32 totSize = codeSize + codeStream.getNumLineBreaks() * 2; st.write(codeSize); st.write(lineBreakPairCount); // Write out our bytecode, doing a bit of compression for low numbers. - U32 i; - for(i = 0; i < codeSize; i++) + U32 i; + for (i = 0; i < codeSize; i++) { - if(code[i] < 0xFF) + if (code[i] < 0xFF) st.write(U8(code[i])); else { @@ -557,7 +557,7 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con } // Write the break info... - for(i = codeSize; i < totSize; i++) + for (i = codeSize; i < totSize; i++) st.write(code[i]); getIdentTable().write(st); @@ -573,32 +573,32 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con ConsoleValueRef CodeBlock::compileExec(StringTableEntry fileName, const char *inString, bool noCalls, S32 setFrame) { AssertFatal(Con::isMainThread(), "Compiling code on a secondary thread"); - + // Check for a UTF8 script file char *string; - chompUTF8BOM( inString, &string ); + chompUTF8BOM(inString, &string); STEtoCode = evalSTEtoCode; consoleAllocReset(); name = fileName; - if(fileName) + if (fileName) { const StringTableEntry exePath = Platform::getMainDotCsDir(); const StringTableEntry cwd = Platform::getCurrentDirectory(); fullPath = NULL; - - if(Platform::isFullPath(fileName)) + + if (Platform::isFullPath(fileName)) fullPath = fileName; - if(dStrnicmp(exePath, fileName, dStrlen(exePath)) == 0) + if (dStrnicmp(exePath, fileName, dStrlen(exePath)) == 0) name = StringTable->insert(fileName + dStrlen(exePath) + 1, true); - else if(dStrnicmp(cwd, fileName, dStrlen(cwd)) == 0) + else if (dStrnicmp(cwd, fileName, dStrlen(cwd)) == 0) name = StringTable->insert(fileName + dStrlen(cwd) + 1, true); - if(fullPath == NULL) + if (fullPath == NULL) { char buf[1024]; fullPath = StringTable->insert(Platform::makeFullPathName(fileName, buf, sizeof(buf)), true); @@ -607,9 +607,9 @@ ConsoleValueRef CodeBlock::compileExec(StringTableEntry fileName, const char *in modPath = Con::getModNameFromPath(fileName); } - if(name) + if (name) addToCodeList(); - + gStatementList = NULL; gAnonFunctionList = NULL; @@ -632,7 +632,7 @@ ConsoleValueRef CodeBlock::compileExec(StringTableEntry fileName, const char *in } } - if(!gStatementList) + if (!gStatementList) { delete this; return ConsoleValueRef(); @@ -641,32 +641,32 @@ ConsoleValueRef CodeBlock::compileExec(StringTableEntry fileName, const char *in resetTables(); smInFunction = false; - + CodeStream codeStream; U32 lastIp = compileBlock(gStatementList, codeStream, 0); lineBreakPairCount = codeStream.getNumLineBreaks(); - globalStrings = getGlobalStringTable().build(); + globalStrings = getGlobalStringTable().build(); globalStringsMaxLen = getGlobalStringTable().totalLen; functionStrings = getFunctionStringTable().build(); functionStringsMaxLen = getFunctionStringTable().totalLen; - globalFloats = getGlobalFloatTable().build(); - functionFloats = getFunctionFloatTable().build(); - + globalFloats = getGlobalFloatTable().build(); + functionFloats = getFunctionFloatTable().build(); + codeStream.emit(OP_RETURN); codeStream.emitCodeStream(&codeSize, &code, &lineBreakPairs); - + //dumpInstructions(0, false); - + consoleAllocReset(); - if(lineBreakPairCount && fileName) + if (lineBreakPairCount && fileName) calcBreakList(); - if(lastIp+1 != codeSize) + if (lastIp + 1 != codeSize) Con::warnf(ConsoleLogEntry::General, "precompile size mismatch, precompile: %d compile: %d", codeSize, lastIp); return exec(0, fileName, NULL, 0, 0, noCalls, NULL, setFrame); @@ -682,85 +682,85 @@ void CodeBlock::incRefCount() void CodeBlock::decRefCount() { refCount--; - if(!refCount) + if (!refCount) delete this; } //------------------------------------------------------------------------- -String CodeBlock::getFunctionArgs( U32 ip ) +String CodeBlock::getFunctionArgs(U32 ip) { StringBuilder str; - - U32 fnArgc = code[ ip + 5 ]; - for( U32 i = 0; i < fnArgc; ++ i ) - { - StringTableEntry var = CodeToSTE(code, ip + (i*2) + 6); - - if( i != 0 ) - str.append( ", " ); - str.append( "string " ); + U32 fnArgc = code[ip + 5]; + for (U32 i = 0; i < fnArgc; ++i) + { + StringTableEntry var = CodeToSTE(code, ip + (i * 2) + 6); + + if (i != 0) + str.append(", "); + + str.append("string "); // Try to capture junked parameters - if( var[ 0 ] ) - str.append( var + 1 ); + if (var[0]) + str.append(var + 1); else - str.append( "JUNK" ); + str.append("JUNK"); } - + return str.end(); } //------------------------------------------------------------------------- -void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn ) +void CodeBlock::dumpInstructions(U32 startIp, bool upToReturn) { U32 ip = startIp; smInFunction = false; U32 endFuncIp = 0; - - while( ip < codeSize ) + + while (ip < codeSize) { if (ip > endFuncIp) { smInFunction = false; } - - switch( code[ ip ++ ] ) + + switch (code[ip++]) { - + case OP_FUNC_DECL: { - StringTableEntry fnName = CodeToSTE(code, ip); - StringTableEntry fnNamespace = CodeToSTE(code, ip+2); - StringTableEntry fnPackage = CodeToSTE(code, ip+4); - bool hasBody = bool(code[ip+6]); - U32 newIp = code[ ip + 7 ]; - U32 argc = code[ ip + 8 ]; + StringTableEntry fnName = CodeToSTE(code, ip); + StringTableEntry fnNamespace = CodeToSTE(code, ip + 2); + StringTableEntry fnPackage = CodeToSTE(code, ip + 4); + bool hasBody = bool(code[ip + 6]); + U32 newIp = code[ip + 7]; + U32 argc = code[ip + 8]; endFuncIp = newIp; - - Con::printf( "%i: OP_FUNC_DECL name=%s nspace=%s package=%s hasbody=%i newip=%i argc=%i", - ip - 1, fnName, fnNamespace, fnPackage, hasBody, newIp, argc ); - + + Con::printf("%i: OP_FUNC_DECL name=%s nspace=%s package=%s hasbody=%i newip=%i argc=%i", + ip - 1, fnName, fnNamespace, fnPackage, hasBody, newIp, argc); + // Skip args. - + ip += 9 + (argc * 2); smInFunction = true; break; } - + case OP_CREATE_OBJECT: { StringTableEntry objParent = CodeToSTE(code, ip); - bool isDataBlock = code[ip + 2]; - bool isInternal = code[ip + 3]; - bool isSingleton = code[ip + 4]; - U32 lineNumber = code[ip + 5]; - U32 failJump = code[ip + 6]; - - Con::printf( "%i: OP_CREATE_OBJECT objParent=%s isDataBlock=%i isInternal=%i isSingleton=%i lineNumber=%i failJump=%i", - ip - 1, objParent, isDataBlock, isInternal, isSingleton, lineNumber, failJump ); + bool isDataBlock = code[ip + 2]; + bool isInternal = code[ip + 3]; + bool isSingleton = code[ip + 4]; + U32 lineNumber = code[ip + 5]; + U32 failJump = code[ip + 6]; + + Con::printf("%i: OP_CREATE_OBJECT objParent=%s isDataBlock=%i isInternal=%i isSingleton=%i lineNumber=%i failJump=%i", + ip - 1, objParent, isDataBlock, isInternal, isSingleton, lineNumber, failJump); ip += 7; break; @@ -769,87 +769,87 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn ) case OP_ADD_OBJECT: { bool placeAtRoot = code[ip++]; - Con::printf( "%i: OP_ADD_OBJECT placeAtRoot=%i", ip - 1, placeAtRoot ); + Con::printf("%i: OP_ADD_OBJECT placeAtRoot=%i", ip - 1, placeAtRoot); break; } - + case OP_END_OBJECT: { bool placeAtRoot = code[ip++]; - Con::printf( "%i: OP_END_OBJECT placeAtRoot=%i", ip - 1, placeAtRoot ); + Con::printf("%i: OP_END_OBJECT placeAtRoot=%i", ip - 1, placeAtRoot); break; } - + case OP_FINISH_OBJECT: { - Con::printf( "%i: OP_FINISH_OBJECT", ip - 1 ); + Con::printf("%i: OP_FINISH_OBJECT", ip - 1); break; } - + case OP_JMPIFFNOT: { - Con::printf( "%i: OP_JMPIFFNOT ip=%i", ip - 1, code[ ip ] ); - ++ ip; + Con::printf("%i: OP_JMPIFFNOT ip=%i", ip - 1, code[ip]); + ++ip; break; } - + case OP_JMPIFNOT: { - Con::printf( "%i: OP_JMPIFNOT ip=%i", ip - 1, code[ ip ] ); - ++ ip; + Con::printf("%i: OP_JMPIFNOT ip=%i", ip - 1, code[ip]); + ++ip; break; } - + case OP_JMPIFF: { - Con::printf( "%i: OP_JMPIFF ip=%i", ip - 1, code[ ip ] ); - ++ ip; + Con::printf("%i: OP_JMPIFF ip=%i", ip - 1, code[ip]); + ++ip; break; } case OP_JMPIF: { - Con::printf( "%i: OP_JMPIF ip=%i", ip - 1, code[ ip ] ); - ++ ip; + Con::printf("%i: OP_JMPIF ip=%i", ip - 1, code[ip]); + ++ip; break; } case OP_JMPIFNOT_NP: { - Con::printf( "%i: OP_JMPIFNOT_NP ip=%i", ip - 1, code[ ip ] ); - ++ ip; + Con::printf("%i: OP_JMPIFNOT_NP ip=%i", ip - 1, code[ip]); + ++ip; break; } case OP_JMPIF_NP: { - Con::printf( "%i: OP_JMPIF_NP ip=%i", ip - 1, code[ ip ] ); - ++ ip; + Con::printf("%i: OP_JMPIF_NP ip=%i", ip - 1, code[ip]); + ++ip; break; } case OP_JMP: { - Con::printf( "%i: OP_JMP ip=%i", ip - 1, code[ ip ] ); - ++ ip; + Con::printf("%i: OP_JMP ip=%i", ip - 1, code[ip]); + ++ip; break; } case OP_RETURN: { - Con::printf( "%i: OP_RETURN", ip - 1 ); - - if( upToReturn ) + Con::printf("%i: OP_RETURN", ip - 1); + + if (upToReturn) return; - + break; } case OP_RETURN_VOID: { - Con::printf( "%i: OP_RETURNVOID", ip - 1 ); + Con::printf("%i: OP_RETURNVOID", ip - 1); - if( upToReturn ) + if (upToReturn) return; break; @@ -857,9 +857,9 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn ) case OP_RETURN_UINT: { - Con::printf( "%i: OP_RETURNUINT", ip - 1 ); + Con::printf("%i: OP_RETURNUINT", ip - 1); - if( upToReturn ) + if (upToReturn) return; break; @@ -867,9 +867,9 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn ) case OP_RETURN_FLT: { - Con::printf( "%i: OP_RETURNFLT", ip - 1 ); + Con::printf("%i: OP_RETURNFLT", ip - 1); - if( upToReturn ) + if (upToReturn) return; break; @@ -877,521 +877,593 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn ) case OP_CMPEQ: { - Con::printf( "%i: OP_CMPEQ", ip - 1 ); + Con::printf("%i: OP_CMPEQ", ip - 1); break; } case OP_CMPGR: { - Con::printf( "%i: OP_CMPGR", ip - 1 ); + Con::printf("%i: OP_CMPGR", ip - 1); break; } case OP_CMPGE: { - Con::printf( "%i: OP_CMPGE", ip - 1 ); + Con::printf("%i: OP_CMPGE", ip - 1); break; } case OP_CMPLT: { - Con::printf( "%i: OP_CMPLT", ip - 1 ); + Con::printf("%i: OP_CMPLT", ip - 1); break; } case OP_CMPLE: { - Con::printf( "%i: OP_CMPLE", ip - 1 ); + Con::printf("%i: OP_CMPLE", ip - 1); break; } case OP_CMPNE: { - Con::printf( "%i: OP_CMPNE", ip - 1 ); + Con::printf("%i: OP_CMPNE", ip - 1); break; } case OP_XOR: { - Con::printf( "%i: OP_XOR", ip - 1 ); + Con::printf("%i: OP_XOR", ip - 1); break; } case OP_MOD: { - Con::printf( "%i: OP_MOD", ip - 1 ); + Con::printf("%i: OP_MOD", ip - 1); break; } case OP_BITAND: { - Con::printf( "%i: OP_BITAND", ip - 1 ); + Con::printf("%i: OP_BITAND", ip - 1); break; } case OP_BITOR: { - Con::printf( "%i: OP_BITOR", ip - 1 ); + Con::printf("%i: OP_BITOR", ip - 1); break; } case OP_NOT: { - Con::printf( "%i: OP_NOT", ip - 1 ); + Con::printf("%i: OP_NOT", ip - 1); break; } case OP_NOTF: { - Con::printf( "%i: OP_NOTF", ip - 1 ); + Con::printf("%i: OP_NOTF", ip - 1); break; } case OP_ONESCOMPLEMENT: { - Con::printf( "%i: OP_ONESCOMPLEMENT", ip - 1 ); + Con::printf("%i: OP_ONESCOMPLEMENT", ip - 1); break; } case OP_SHR: { - Con::printf( "%i: OP_SHR", ip - 1 ); + Con::printf("%i: OP_SHR", ip - 1); break; } case OP_SHL: { - Con::printf( "%i: OP_SHL", ip - 1 ); + Con::printf("%i: OP_SHL", ip - 1); break; } case OP_AND: { - Con::printf( "%i: OP_AND", ip - 1 ); + Con::printf("%i: OP_AND", ip - 1); break; } case OP_OR: { - Con::printf( "%i: OP_OR", ip - 1 ); + Con::printf("%i: OP_OR", ip - 1); break; } case OP_ADD: { - Con::printf( "%i: OP_ADD", ip - 1 ); + Con::printf("%i: OP_ADD", ip - 1); break; } case OP_SUB: { - Con::printf( "%i: OP_SUB", ip - 1 ); + Con::printf("%i: OP_SUB", ip - 1); break; } case OP_MUL: { - Con::printf( "%i: OP_MUL", ip - 1 ); + Con::printf("%i: OP_MUL", ip - 1); break; } case OP_DIV: { - Con::printf( "%i: OP_DIV", ip - 1 ); + Con::printf("%i: OP_DIV", ip - 1); break; } case OP_NEG: { - Con::printf( "%i: OP_NEG", ip - 1 ); + Con::printf("%i: OP_NEG", ip - 1); + break; + } + + case OP_INC: + { + Con::printf("%i: OP_INC varName=%s", ip - 1, CodeToSTE(code, ip)); + ip += 2; + break; + } + + case OP_DEC: + { + Con::printf("%i: OP_DEC varName=%s", ip - 1, CodeToSTE(code, ip)); + ip += 2; break; } case OP_SETCURVAR: { StringTableEntry var = CodeToSTE(code, ip); - - Con::printf( "%i: OP_SETCURVAR var=%s", ip - 1, var ); + + Con::printf("%i: OP_SETCURVAR var=%s", ip - 1, var); ip += 2; break; } - + case OP_SETCURVAR_CREATE: { StringTableEntry var = CodeToSTE(code, ip); - - Con::printf( "%i: OP_SETCURVAR_CREATE var=%s", ip - 1, var ); + + Con::printf("%i: OP_SETCURVAR_CREATE var=%s", ip - 1, var); ip += 2; break; } - + case OP_SETCURVAR_ARRAY: { - Con::printf( "%i: OP_SETCURVAR_ARRAY", ip - 1 ); + Con::printf("%i: OP_SETCURVAR_ARRAY", ip - 1); break; } - + + case OP_SETCURVAR_ARRAY_VARLOOKUP: + { + StringTableEntry arrayName = CodeToSTE(code, ip); + StringTableEntry arrayLookup = CodeToSTE(code, ip + 2); + + Con::printf("%i: OP_SETCURVAR_ARRAY_VARLOOKUP arrayName=%s arrayLookup=%s", ip - 1, arrayName, arrayLookup); + ip += 4; + break; + } + case OP_SETCURVAR_ARRAY_CREATE: { - Con::printf( "%i: OP_SETCURVAR_ARRAY_CREATE", ip - 1 ); + Con::printf("%i: OP_SETCURVAR_ARRAY_CREATE", ip - 1); break; } - + + case OP_SETCURVAR_ARRAY_CREATE_VARLOOKUP: + { + StringTableEntry arrayName = CodeToSTE(code, ip); + StringTableEntry arrayLookup = CodeToSTE(code, ip + 2); + + Con::printf("%i: OP_SETCURVAR_ARRAY_CREATE_VARLOOKUP arrayName=%s arrayLookup=%s", ip - 1, arrayName, arrayLookup); + ip += 4; + break; + } + case OP_LOADVAR_UINT: { - Con::printf( "%i: OP_LOADVAR_UINT", ip - 1 ); + Con::printf("%i: OP_LOADVAR_UINT", ip - 1); break; } - + case OP_LOADVAR_FLT: { - Con::printf( "%i: OP_LOADVAR_FLT", ip - 1 ); + Con::printf("%i: OP_LOADVAR_FLT", ip - 1); break; } case OP_LOADVAR_STR: { - Con::printf( "%i: OP_LOADVAR_STR", ip - 1 ); + Con::printf("%i: OP_LOADVAR_STR", ip - 1); break; } case OP_LOADVAR_VAR: { - Con::printf( "%i: OP_LOADVAR_VAR", ip - 1 ); + Con::printf("%i: OP_LOADVAR_VAR", ip - 1); break; } case OP_SAVEVAR_UINT: { - Con::printf( "%i: OP_SAVEVAR_UINT", ip - 1 ); + Con::printf("%i: OP_SAVEVAR_UINT", ip - 1); break; } case OP_SAVEVAR_FLT: { - Con::printf( "%i: OP_SAVEVAR_FLT", ip - 1 ); + Con::printf("%i: OP_SAVEVAR_FLT", ip - 1); break; } case OP_SAVEVAR_STR: { - Con::printf( "%i: OP_SAVEVAR_STR", ip - 1 ); + Con::printf("%i: OP_SAVEVAR_STR", ip - 1); break; } case OP_SAVEVAR_VAR: { - Con::printf( "%i: OP_SAVEVAR_VAR", ip - 1 ); + Con::printf("%i: OP_SAVEVAR_VAR", ip - 1); break; } case OP_SETCUROBJECT: { - Con::printf( "%i: OP_SETCUROBJECT", ip - 1 ); + Con::printf("%i: OP_SETCUROBJECT", ip - 1); break; } case OP_SETCUROBJECT_NEW: { - Con::printf( "%i: OP_SETCUROBJECT_NEW", ip - 1 ); + Con::printf("%i: OP_SETCUROBJECT_NEW", ip - 1); break; } - + case OP_SETCUROBJECT_INTERNAL: { - Con::printf( "%i: OP_SETCUROBJECT_INTERNAL", ip - 1 ); - ++ ip; + Con::printf("%i: OP_SETCUROBJECT_INTERNAL", ip - 1); + ++ip; break; } - + case OP_SETCURFIELD: { StringTableEntry curField = CodeToSTE(code, ip); - Con::printf( "%i: OP_SETCURFIELD field=%s", ip - 1, curField ); + Con::printf("%i: OP_SETCURFIELD field=%s", ip - 1, curField); ip += 2; break; } - + case OP_SETCURFIELD_ARRAY: { - Con::printf( "%i: OP_SETCURFIELD_ARRAY", ip - 1 ); + Con::printf("%i: OP_SETCURFIELD_ARRAY", ip - 1); + break; + } + + case OP_SETCURFIELD_ARRAY_VAR: + { + StringTableEntry var = CodeToSTE(code, ip); + Con::printf("%i: OP_SETCURFIELD_ARRAY_VAR var=%s", ip - 1, var); + ip += 2; + break; + } + + case OP_SETCURFIELD_THIS: + { + StringTableEntry curField = CodeToSTE(code, ip); + Con::printf("%i: OP_SETCURFIELD_THIS field=%s", ip - 1, curField); + ip += 2; break; } case OP_SETCURFIELD_TYPE: { - U32 type = code[ ip ]; - Con::printf( "%i: OP_SETCURFIELD_TYPE type=%i", ip - 1, type ); - ++ ip; + U32 type = code[ip]; + Con::printf("%i: OP_SETCURFIELD_TYPE type=%i", ip - 1, type); + ++ip; break; } case OP_LOADFIELD_UINT: { - Con::printf( "%i: OP_LOADFIELD_UINT", ip - 1 ); + Con::printf("%i: OP_LOADFIELD_UINT", ip - 1); break; } case OP_LOADFIELD_FLT: { - Con::printf( "%i: OP_LOADFIELD_FLT", ip - 1 ); + Con::printf("%i: OP_LOADFIELD_FLT", ip - 1); break; } case OP_LOADFIELD_STR: { - Con::printf( "%i: OP_LOADFIELD_STR", ip - 1 ); + Con::printf("%i: OP_LOADFIELD_STR", ip - 1); break; } case OP_SAVEFIELD_UINT: { - Con::printf( "%i: OP_SAVEFIELD_UINT", ip - 1 ); + Con::printf("%i: OP_SAVEFIELD_UINT", ip - 1); break; } case OP_SAVEFIELD_FLT: { - Con::printf( "%i: OP_SAVEFIELD_FLT", ip - 1 ); + Con::printf("%i: OP_SAVEFIELD_FLT", ip - 1); break; } case OP_SAVEFIELD_STR: { - Con::printf( "%i: OP_SAVEFIELD_STR", ip - 1 ); + Con::printf("%i: OP_SAVEFIELD_STR", ip - 1); break; } case OP_STR_TO_UINT: { - Con::printf( "%i: OP_STR_TO_UINT", ip - 1 ); + Con::printf("%i: OP_STR_TO_UINT", ip - 1); break; } case OP_STR_TO_FLT: { - Con::printf( "%i: OP_STR_TO_FLT", ip - 1 ); + Con::printf("%i: OP_STR_TO_FLT", ip - 1); break; } case OP_STR_TO_NONE: { - Con::printf( "%i: OP_STR_TO_NONE", ip - 1 ); + Con::printf("%i: OP_STR_TO_NONE", ip - 1); break; } case OP_FLT_TO_UINT: { - Con::printf( "%i: OP_FLT_TO_UINT", ip - 1 ); + Con::printf("%i: OP_FLT_TO_UINT", ip - 1); break; } case OP_FLT_TO_STR: { - Con::printf( "%i: OP_FLT_TO_STR", ip - 1 ); + Con::printf("%i: OP_FLT_TO_STR", ip - 1); break; } case OP_FLT_TO_NONE: { - Con::printf( "%i: OP_FLT_TO_NONE", ip - 1 ); + Con::printf("%i: OP_FLT_TO_NONE", ip - 1); break; } case OP_UINT_TO_FLT: { - Con::printf( "%i: OP_SAVEFIELD_STR", ip - 1 ); + Con::printf("%i: OP_SAVEFIELD_STR", ip - 1); break; } case OP_UINT_TO_STR: { - Con::printf( "%i: OP_UINT_TO_STR", ip - 1 ); + Con::printf("%i: OP_UINT_TO_STR", ip - 1); break; } case OP_UINT_TO_NONE: { - Con::printf( "%i: OP_UINT_TO_NONE", ip - 1 ); + Con::printf("%i: OP_UINT_TO_NONE", ip - 1); break; } case OP_COPYVAR_TO_NONE: { - Con::printf( "%i: OP_COPYVAR_TO_NONE", ip - 1 ); + Con::printf("%i: OP_COPYVAR_TO_NONE", ip - 1); break; } case OP_LOADIMMED_UINT: { - U32 val = code[ ip ]; - Con::printf( "%i: OP_LOADIMMED_UINT val=%i", ip - 1, val ); - ++ ip; + U32 val = code[ip]; + Con::printf("%i: OP_LOADIMMED_UINT val=%i", ip - 1, val); + ++ip; break; } case OP_LOADIMMED_FLT: { - F64 val = (smInFunction ? functionFloats : globalFloats)[ code[ ip ] ]; - Con::printf( "%i: OP_LOADIMMED_FLT val=%f", ip - 1, val ); - ++ ip; + F64 val = (smInFunction ? functionFloats : globalFloats)[code[ip]]; + Con::printf("%i: OP_LOADIMMED_FLT val=%f", ip - 1, val); + ++ip; break; } case OP_TAG_TO_STR: { - const char* str = (smInFunction ? functionStrings : globalStrings) + code[ ip ]; - Con::printf( "%i: OP_TAG_TO_STR str=%s", ip - 1, str ); - ++ ip; + const char* str = (smInFunction ? functionStrings : globalStrings) + code[ip]; + Con::printf("%i: OP_TAG_TO_STR str=%s", ip - 1, str); + ++ip; break; } - + case OP_LOADIMMED_STR: { - const char* str = (smInFunction ? functionStrings : globalStrings) + code[ ip ]; - Con::printf( "%i: OP_LOADIMMED_STR str=%s", ip - 1, str ); - ++ ip; + const char* str = (smInFunction ? functionStrings : globalStrings) + code[ip]; + Con::printf("%i: OP_LOADIMMED_STR str=%s", ip - 1, str); + ++ip; break; } case OP_DOCBLOCK_STR: { - const char* str = (smInFunction ? functionStrings : globalStrings) + code[ ip ]; - Con::printf( "%i: OP_DOCBLOCK_STR str=%s", ip - 1, str ); - ++ ip; + const char* str = (smInFunction ? functionStrings : globalStrings) + code[ip]; + Con::printf("%i: OP_DOCBLOCK_STR str=%s", ip - 1, str); + ++ip; break; } - + case OP_LOADIMMED_IDENT: { StringTableEntry str = CodeToSTE(code, ip); - Con::printf( "%i: OP_LOADIMMED_IDENT str=%s", ip - 1, str ); + Con::printf("%i: OP_LOADIMMED_IDENT str=%s", ip - 1, str); ip += 2; break; } case OP_CALLFUNC_RESOLVE: { - StringTableEntry fnNamespace = CodeToSTE(code, ip+2); - StringTableEntry fnName = CodeToSTE(code, ip); - U32 callType = code[ip+2]; + StringTableEntry fnNamespace = CodeToSTE(code, ip + 2); + StringTableEntry fnName = CodeToSTE(code, ip); + U32 callType = code[ip + 2]; - Con::printf( "%i: OP_CALLFUNC_RESOLVE name=%s nspace=%s callType=%s", ip - 1, fnName, fnNamespace, + Con::printf("%i: OP_CALLFUNC_RESOLVE name=%s nspace=%s callType=%s", ip - 1, fnName, fnNamespace, callType == FuncCallExprNode::FunctionCall ? "FunctionCall" - : callType == FuncCallExprNode::MethodCall ? "MethodCall" : "ParentCall" ); - + : callType == FuncCallExprNode::MethodCall ? "MethodCall" : "ParentCall"); + ip += 5; break; } - + case OP_CALLFUNC: { - StringTableEntry fnNamespace = CodeToSTE(code, ip+2); - StringTableEntry fnName = CodeToSTE(code, ip); - U32 callType = code[ip+4]; + StringTableEntry fnNamespace = CodeToSTE(code, ip + 2); + StringTableEntry fnName = CodeToSTE(code, ip); + U32 callType = code[ip + 4]; - Con::printf( "%i: OP_CALLFUNC name=%s nspace=%s callType=%s", ip - 1, fnName, fnNamespace, + Con::printf("%i: OP_CALLFUNC name=%s nspace=%s callType=%s", ip - 1, fnName, fnNamespace, callType == FuncCallExprNode::FunctionCall ? "FunctionCall" - : callType == FuncCallExprNode::MethodCall ? "MethodCall" : "ParentCall" ); - + : callType == FuncCallExprNode::MethodCall ? "MethodCall" : "ParentCall"); + ip += 5; break; } + case OP_CALLFUNC_POINTER: + { + Con::printf("%i: OP_CALLFUNC_POINTER", ip - 1); + break; + } + + case OP_CALLFUNC_THIS: + { + StringTableEntry fnName = CodeToSTE(code, ip); + Con::printf("%i: OP_CALLFUNC_THIS name=%s ", ip - 1, fnName); + + ip += 2; + break; + } + case OP_ADVANCE_STR: { - Con::printf( "%i: OP_ADVANCE_STR", ip - 1 ); + Con::printf("%i: OP_ADVANCE_STR", ip - 1); break; } case OP_ADVANCE_STR_APPENDCHAR: { - char ch = code[ ip ]; - Con::printf( "%i: OP_ADVANCE_STR_APPENDCHAR char=%c", ip - 1, ch ); - ++ ip; + char ch = code[ip]; + Con::printf("%i: OP_ADVANCE_STR_APPENDCHAR char=%c", ip - 1, ch); + ++ip; break; } case OP_ADVANCE_STR_COMMA: { - Con::printf( "%i: OP_ADVANCE_STR_COMMA", ip - 1 ); + Con::printf("%i: OP_ADVANCE_STR_COMMA", ip - 1); break; } case OP_ADVANCE_STR_NUL: { - Con::printf( "%i: OP_ADVANCE_STR_NUL", ip - 1 ); + Con::printf("%i: OP_ADVANCE_STR_NUL", ip - 1); break; } case OP_REWIND_STR: { - Con::printf( "%i: OP_REWIND_STR", ip - 1 ); + Con::printf("%i: OP_REWIND_STR", ip - 1); break; } case OP_TERMINATE_REWIND_STR: { - Con::printf( "%i: OP_TERMINATE_REWIND_STR", ip - 1 ); + Con::printf("%i: OP_TERMINATE_REWIND_STR", ip - 1); break; } case OP_COMPARE_STR: { - Con::printf( "%i: OP_COMPARE_STR", ip - 1 ); + Con::printf("%i: OP_COMPARE_STR", ip - 1); break; } case OP_PUSH: { - Con::printf( "%i: OP_PUSH", ip - 1 ); + Con::printf("%i: OP_PUSH", ip - 1); break; } case OP_PUSH_UINT: { - Con::printf( "%i: OP_PUSH_UINT", ip - 1 ); + Con::printf("%i: OP_PUSH_UINT", ip - 1); break; } case OP_PUSH_FLT: { - Con::printf( "%i: OP_PUSH_FLT", ip - 1 ); + Con::printf("%i: OP_PUSH_FLT", ip - 1); break; } case OP_PUSH_VAR: { - Con::printf( "%i: OP_PUSH_VAR", ip - 1 ); + Con::printf("%i: OP_PUSH_VAR", ip - 1); + break; + } + + case OP_PUSH_THIS: + { + Con::printf("%i: OP_PUSH_THIS varName=%s", ip - 1, CodeToSTE(code, ip)); + ip += 2; break; } case OP_PUSH_FRAME: { - Con::printf( "%i: OP_PUSH_FRAME", ip - 1 ); + Con::printf("%i: OP_PUSH_FRAME", ip - 1); break; } case OP_ASSERT: { - const char* message = (smInFunction ? functionStrings : globalStrings) + code[ ip ]; - Con::printf( "%i: OP_ASSERT message=%s", ip - 1, message ); - ++ ip; + const char* message = (smInFunction ? functionStrings : globalStrings) + code[ip]; + Con::printf("%i: OP_ASSERT message=%s", ip - 1, message); + ++ip; break; } case OP_BREAK: { - Con::printf( "%i: OP_BREAK", ip - 1 ); + Con::printf("%i: OP_BREAK", ip - 1); break; } - + case OP_ITER_BEGIN: { StringTableEntry varName = CodeToSTE(code, ip); - U32 failIp = code[ ip + 2 ]; - - Con::printf( "%i: OP_ITER_BEGIN varName=%s failIp=%i", ip - 1, varName, failIp ); + U32 failIp = code[ip + 2]; + + Con::printf("%i: OP_ITER_BEGIN varName=%s failIp=%i", ip - 1, varName, failIp); ip += 3; break; @@ -1400,35 +1472,35 @@ void CodeBlock::dumpInstructions( U32 startIp, bool upToReturn ) case OP_ITER_BEGIN_STR: { StringTableEntry varName = CodeToSTE(code, ip); - U32 failIp = code[ ip + 2 ]; - - Con::printf( "%i: OP_ITER_BEGIN varName=%s failIp=%i", ip - 1, varName, failIp ); + U32 failIp = code[ip + 2]; + + Con::printf("%i: OP_ITER_BEGIN varName=%s failIp=%i", ip - 1, varName, failIp); ip += 3; break; } - + case OP_ITER: { - U32 breakIp = code[ ip ]; - - Con::printf( "%i: OP_ITER breakIp=%i", ip - 1, breakIp ); + U32 breakIp = code[ip]; - ++ ip; + Con::printf("%i: OP_ITER breakIp=%i", ip - 1, breakIp); + + ++ip; break; } - + case OP_ITER_END: { - Con::printf( "%i: OP_ITER_END", ip - 1 ); + Con::printf("%i: OP_ITER_END", ip - 1); break; } default: - Con::printf( "%i: !!INVALID!!", ip - 1 ); + Con::printf("%i: !!INVALID!!", ip - 1); break; } } - + smInFunction = false; } diff --git a/Engine/source/console/codeBlock.h b/Engine/source/console/codeBlock.h index 71f15c95e..f789f1a92 100644 --- a/Engine/source/console/codeBlock.h +++ b/Engine/source/console/codeBlock.h @@ -35,10 +35,11 @@ class ConsoleValueRef; /// This class represents a block of code, usually mapped directly to a file. class CodeBlock { + friend class CodeInterpreter; private: static CodeBlock* smCodeBlockList; static CodeBlock* smCurrentCodeBlock; - + public: static bool smInFunction; static Compiler::ConsoleParser * smCurrentParser; @@ -89,7 +90,7 @@ public: void calcBreakList(); void clearAllBreaks(); void setAllBreaks(); - void dumpInstructions( U32 startIp = 0, bool upToReturn = false ); + void dumpInstructions(U32 startIp = 0, bool upToReturn = false); /// Returns the first breakable line or 0 if none was found. /// @param lineNumber The one based line number. @@ -106,7 +107,7 @@ public: const char *getFileLine(U32 ip); /// - String getFunctionArgs( U32 offset ); + String getFunctionArgs(U32 offset); bool read(StringTableEntry fileName, Stream &st); bool compile(const char *dsoName, StringTableEntry fileName, const char *script, bool overrideNoDso = false); @@ -129,8 +130,8 @@ public: /// with, zero being the top of the stack. If the the index is /// -1 a new frame is created. If the index is out of range the /// top stack frame is used. - ConsoleValueRef compileExec(StringTableEntry fileName, const char *script, - bool noCalls, S32 setFrame = -1 ); + ConsoleValueRef compileExec(StringTableEntry fileName, const char *script, + bool noCalls, S32 setFrame = -1); /// Executes the existing code in the CodeBlock. The return string is any /// result of the code executed, if any, or an empty string. @@ -147,7 +148,7 @@ public: /// -1 a new frame is created. If the index is out of range the /// top stack frame is used. /// @param packageName The code package name or null. - ConsoleValueRef exec(U32 offset, const char *fnName, Namespace *ns, U32 argc, + ConsoleValueRef exec(U32 offset, const char *fnName, Namespace *ns, U32 argc, ConsoleValueRef *argv, bool noCalls, StringTableEntry packageName, S32 setFrame = -1); }; diff --git a/Engine/source/console/codeInterpreter.cpp b/Engine/source/console/codeInterpreter.cpp new file mode 100644 index 000000000..a0e13502f --- /dev/null +++ b/Engine/source/console/codeInterpreter.cpp @@ -0,0 +1,2979 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// +// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames +// Copyright (C) 2015 Faust Logic, Inc. +//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// + +#include "console/codeInterpreter.h" +#include "console/compiler.h" +#include "console/simBase.h" +#include "console/telnetDebugger.h" +#include "sim/netStringTable.h" +#include "console/ICallMethod.h" +#include "console/stringStack.h" +#include "util/messaging/message.h" +#include "core/strings/findMatch.h" +#include "core/strings/stringUnit.h" +#include "console/console.h" +#include "console/consoleInternal.h" + +//#define TORQUE_VALIDATE_STACK + +using namespace Compiler; + +enum EvalConstants +{ + MaxStackSize = 1024, + FieldBufferSizeString = 2048, + FieldBufferSizeNumeric = 128, + MethodOnComponent = -2 +}; + +namespace Con +{ + // Current script file name and root, these are registered as + // console variables. + extern StringTableEntry gCurrentFile; + extern StringTableEntry gCurrentRoot; + extern S32 gObjectCopyFailures; +} + +// Gets a component of an object's field value or a variable and returns it +// in val. +static void getFieldComponent(SimObject* object, StringTableEntry field, const char* array, StringTableEntry subField, char val[]) +{ + const char* prevVal = NULL; + + // Grab value from object. + if (object && field) + prevVal = object->getDataField(field, array); + + // Otherwise, grab from the string stack. The value coming in will always + // be a string because that is how multicomponent variables are handled. + else + prevVal = STR.getStringValue(); + + // Make sure we got a value. + if (prevVal && *prevVal) + { + static const StringTableEntry xyzw[] = + { + StringTable->insert("x"), + StringTable->insert("y"), + StringTable->insert("z"), + StringTable->insert("w") + }; + + static const StringTableEntry rgba[] = + { + StringTable->insert("r"), + StringTable->insert("g"), + StringTable->insert("b"), + StringTable->insert("a") + }; + + // Translate xyzw and rgba into the indexed component + // of the variable or field. + // + // Review: Should we use strncpy to prevent a buffer overflow? + if (subField == xyzw[0] || subField == rgba[0]) + dStrcpy(val, StringUnit::getUnit(prevVal, 0, " \t\n")); + + else if (subField == xyzw[1] || subField == rgba[1]) + dStrcpy(val, StringUnit::getUnit(prevVal, 1, " \t\n")); + + else if (subField == xyzw[2] || subField == rgba[2]) + dStrcpy(val, StringUnit::getUnit(prevVal, 2, " \t\n")); + + else if (subField == xyzw[3] || subField == rgba[3]) + dStrcpy(val, StringUnit::getUnit(prevVal, 3, " \t\n")); + + else + val[0] = 0; + } + else + val[0] = 0; +} + +// Sets a component of an object's field value based on the sub field. 'x' will +// set the first field, 'y' the second, and 'z' the third. +static void setFieldComponent(SimObject* object, StringTableEntry field, const char* array, StringTableEntry subField) +{ + // Copy the current string value + char strValue[1024]; + dStrncpy(strValue, STR.getStringValue(), 1024); + + char val[1024] = ""; + const char* prevVal = NULL; + + // Set the value on an object field. + if (object && field) + prevVal = object->getDataField(field, array); + + // Set the value on a variable. + else if (gEvalState.currentVariable) + prevVal = gEvalState.getStringVariable(); + + // Ensure that the variable has a value + if (!prevVal) + return; + + static const StringTableEntry xyzw[] = + { + StringTable->insert("x"), + StringTable->insert("y"), + StringTable->insert("z"), + StringTable->insert("w") + }; + + static const StringTableEntry rgba[] = + { + StringTable->insert("r"), + StringTable->insert("g"), + StringTable->insert("b"), + StringTable->insert("a") + }; + + // Insert the value into the specified + // component of the string. + // + // Review: Should we use strncpy to prevent a buffer overflow? + if (subField == xyzw[0] || subField == rgba[0]) + dStrcpy(val, StringUnit::setUnit(prevVal, 0, strValue, " \t\n")); + + else if (subField == xyzw[1] || subField == rgba[1]) + dStrcpy(val, StringUnit::setUnit(prevVal, 1, strValue, " \t\n")); + + else if (subField == xyzw[2] || subField == rgba[2]) + dStrcpy(val, StringUnit::setUnit(prevVal, 2, strValue, " \t\n")); + + else if (subField == xyzw[3] || subField == rgba[3]) + dStrcpy(val, StringUnit::setUnit(prevVal, 3, strValue, " \t\n")); + + if (val[0] != 0) + { + // Update the field or variable. + if (object && field) + object->setDataField(field, 0, val); + else if (gEvalState.currentVariable) + gEvalState.setStringVariable(val); + } +} +extern ExprEvalState gEvalState; + +char sTraceBuffer[1024]; + +StringStack STR; +ConsoleValueStack CSTK; + +U32 _FLT = 0; ///< Stack pointer for floatStack. +U32 _UINT = 0; ///< Stack pointer for intStack. +U32 _ITER = 0; ///< Stack pointer for iterStack. + +IterStackRecord iterStack[MaxStackSize]; + +F64 floatStack[MaxStackSize]; +S64 intStack[MaxStackSize]; + +char curFieldArray[256]; +char prevFieldArray[256]; + +typedef OPCodeReturn(CodeInterpreter::*OpFn)(U32&); + +static OpFn gOpCodeArray[MAX_OP_CODELEN]; + +CodeInterpreter::CodeInterpreter(CodeBlock *cb) : + mCodeBlock(cb), + mIterDepth(0), + mCurFloatTable(nullptr), + mCurStringTable(nullptr), + mThisFunctionName(nullptr), + mPopFrame(false), + mObjectCreationStackIndex(0), + mCurrentNewObject(nullptr), + mFailJump(0), + mPrevField(nullptr), + mCurField(nullptr), + mPrevObject(nullptr), + mCurObject(nullptr), + mSaveObject(nullptr), + mThisObject(nullptr), + mNSEntry(nullptr), + mCurFNDocBlock(nullptr), + mCurNSDocBlock(nullptr), + mCallArgc(0), + mCallArgv(nullptr), + mSaveCodeBlock(nullptr), + mCurrentInstruction(0) +{ +} + +CodeInterpreter::~CodeInterpreter() +{ +} + +void CodeInterpreter::init() +{ + gOpCodeArray[OP_FUNC_DECL] = &CodeInterpreter::op_func_decl; + gOpCodeArray[OP_CREATE_OBJECT] = &CodeInterpreter::op_create_object; + gOpCodeArray[OP_ADD_OBJECT] = &CodeInterpreter::op_add_object; + gOpCodeArray[OP_END_OBJECT] = &CodeInterpreter::op_end_object; + gOpCodeArray[OP_FINISH_OBJECT] = &CodeInterpreter::op_finish_object; + gOpCodeArray[OP_JMPIFFNOT] = &CodeInterpreter::op_jmpiffnot; + gOpCodeArray[OP_JMPIFNOT] = &CodeInterpreter::op_jmpifnot; + gOpCodeArray[OP_JMPIFF] = &CodeInterpreter::op_jmpiff; + gOpCodeArray[OP_JMPIF] = &CodeInterpreter::op_jmpif; + gOpCodeArray[OP_JMPIFNOT_NP] = &CodeInterpreter::op_jmpifnot_np; + gOpCodeArray[OP_JMPIF_NP] = &CodeInterpreter::op_jmpif_np; + gOpCodeArray[OP_JMP] = &CodeInterpreter::op_jmp; + gOpCodeArray[OP_RETURN] = &CodeInterpreter::op_return; + gOpCodeArray[OP_RETURN_VOID] = &CodeInterpreter::op_return_void; + gOpCodeArray[OP_RETURN_FLT] = &CodeInterpreter::op_return_flt; + gOpCodeArray[OP_RETURN_UINT] = &CodeInterpreter::op_return_uint; + gOpCodeArray[OP_CMPEQ] = &CodeInterpreter::op_cmpeq; + gOpCodeArray[OP_CMPGR] = &CodeInterpreter::op_cmpgr; + gOpCodeArray[OP_CMPGE] = &CodeInterpreter::op_cmpge; + gOpCodeArray[OP_CMPLT] = &CodeInterpreter::op_cmplt; + gOpCodeArray[OP_CMPLE] = &CodeInterpreter::op_cmple; + gOpCodeArray[OP_CMPNE] = &CodeInterpreter::op_cmpne; + gOpCodeArray[OP_XOR] = &CodeInterpreter::op_xor; + gOpCodeArray[OP_MOD] = &CodeInterpreter::op_mod; + gOpCodeArray[OP_BITAND] = &CodeInterpreter::op_bitand; + gOpCodeArray[OP_BITOR] = &CodeInterpreter::op_bitor; + gOpCodeArray[OP_NOT] = &CodeInterpreter::op_not; + gOpCodeArray[OP_NOTF] = &CodeInterpreter::op_notf; + gOpCodeArray[OP_ONESCOMPLEMENT] = &CodeInterpreter::op_onescomplement; + gOpCodeArray[OP_SHR] = &CodeInterpreter::op_shr; + gOpCodeArray[OP_SHL] = &CodeInterpreter::op_shl; + gOpCodeArray[OP_AND] = &CodeInterpreter::op_and; + gOpCodeArray[OP_OR] = &CodeInterpreter::op_or; + gOpCodeArray[OP_ADD] = &CodeInterpreter::op_add; + gOpCodeArray[OP_SUB] = &CodeInterpreter::op_sub; + gOpCodeArray[OP_MUL] = &CodeInterpreter::op_mul; + gOpCodeArray[OP_DIV] = &CodeInterpreter::op_div; + gOpCodeArray[OP_NEG] = &CodeInterpreter::op_neg; + gOpCodeArray[OP_INC] = &CodeInterpreter::op_inc; + gOpCodeArray[OP_DEC] = &CodeInterpreter::op_dec; + gOpCodeArray[OP_SETCURVAR] = &CodeInterpreter::op_setcurvar; + gOpCodeArray[OP_SETCURVAR_CREATE] = &CodeInterpreter::op_setcurvar_create; + gOpCodeArray[OP_SETCURVAR_ARRAY] = &CodeInterpreter::op_setcurvar_array; + gOpCodeArray[OP_SETCURVAR_ARRAY_VARLOOKUP] = &CodeInterpreter::op_setcurvar_array_varlookup; + gOpCodeArray[OP_SETCURVAR_ARRAY_CREATE] = &CodeInterpreter::op_setcurvar_array_create; + gOpCodeArray[OP_SETCURVAR_ARRAY_CREATE_VARLOOKUP] = &CodeInterpreter::op_setcurvar_array_create_varlookup; + gOpCodeArray[OP_LOADVAR_UINT] = &CodeInterpreter::op_loadvar_uint; + gOpCodeArray[OP_LOADVAR_FLT] = &CodeInterpreter::op_loadvar_flt; + gOpCodeArray[OP_LOADVAR_STR] = &CodeInterpreter::op_loadvar_str; + gOpCodeArray[OP_LOADVAR_VAR] = &CodeInterpreter::op_loadvar_var; + gOpCodeArray[OP_SAVEVAR_UINT] = &CodeInterpreter::op_savevar_uint; + gOpCodeArray[OP_SAVEVAR_FLT] = &CodeInterpreter::op_savevar_flt; + gOpCodeArray[OP_SAVEVAR_STR] = &CodeInterpreter::op_savevar_str; + gOpCodeArray[OP_SAVEVAR_VAR] = &CodeInterpreter::op_savevar_var; + gOpCodeArray[OP_SETCUROBJECT] = &CodeInterpreter::op_setcurobject; + gOpCodeArray[OP_SETCUROBJECT_INTERNAL] = &CodeInterpreter::op_setcurobject_internal; + gOpCodeArray[OP_SETCUROBJECT_NEW] = &CodeInterpreter::op_setcurobject_new; + gOpCodeArray[OP_SETCURFIELD] = &CodeInterpreter::op_setcurfield; + gOpCodeArray[OP_SETCURFIELD_ARRAY] = &CodeInterpreter::op_setcurfield_array; + gOpCodeArray[OP_SETCURFIELD_TYPE] = &CodeInterpreter::op_setcurfield_type; + gOpCodeArray[OP_SETCURFIELD_ARRAY_VAR] = &CodeInterpreter::op_setcurfield_array_var; + gOpCodeArray[OP_SETCURFIELD_THIS] = &CodeInterpreter::op_setcurfield_this; + gOpCodeArray[OP_LOADFIELD_UINT] = &CodeInterpreter::op_loadfield_uint; + gOpCodeArray[OP_LOADFIELD_FLT] = &CodeInterpreter::op_loadfield_flt; + gOpCodeArray[OP_LOADFIELD_STR] = &CodeInterpreter::op_loadfield_str; + gOpCodeArray[OP_SAVEFIELD_UINT] = &CodeInterpreter::op_savefield_uint; + gOpCodeArray[OP_SAVEFIELD_FLT] = &CodeInterpreter::op_savefield_flt; + gOpCodeArray[OP_SAVEFIELD_STR] = &CodeInterpreter::op_savefield_str; + gOpCodeArray[OP_STR_TO_UINT] = &CodeInterpreter::op_str_to_uint; + gOpCodeArray[OP_STR_TO_FLT] = &CodeInterpreter::op_str_to_flt; + gOpCodeArray[OP_STR_TO_NONE] = &CodeInterpreter::op_str_to_none; + gOpCodeArray[OP_FLT_TO_UINT] = &CodeInterpreter::op_flt_to_uint; + gOpCodeArray[OP_FLT_TO_STR] = &CodeInterpreter::op_flt_to_str; + gOpCodeArray[OP_FLT_TO_NONE] = &CodeInterpreter::op_flt_to_none; + gOpCodeArray[OP_UINT_TO_FLT] = &CodeInterpreter::op_uint_to_flt; + gOpCodeArray[OP_UINT_TO_STR] = &CodeInterpreter::op_uint_to_str; + gOpCodeArray[OP_UINT_TO_NONE] = &CodeInterpreter::op_uint_to_none; + gOpCodeArray[OP_COPYVAR_TO_NONE] = &CodeInterpreter::op_copyvar_to_none; + gOpCodeArray[OP_LOADIMMED_UINT] = &CodeInterpreter::op_loadimmed_uint; + gOpCodeArray[OP_LOADIMMED_FLT] = &CodeInterpreter::op_loadimmed_flt; + gOpCodeArray[OP_TAG_TO_STR] = &CodeInterpreter::op_tag_to_str; + gOpCodeArray[OP_LOADIMMED_STR] = &CodeInterpreter::op_loadimmed_str; + gOpCodeArray[OP_DOCBLOCK_STR] = &CodeInterpreter::op_docblock_str; + gOpCodeArray[OP_LOADIMMED_IDENT] = &CodeInterpreter::op_loadimmed_ident; + gOpCodeArray[OP_CALLFUNC_RESOLVE] = &CodeInterpreter::op_callfunc_resolve; + gOpCodeArray[OP_CALLFUNC] = &CodeInterpreter::op_callfunc; + gOpCodeArray[OP_CALLFUNC_POINTER] = &CodeInterpreter::op_callfunc_pointer; + gOpCodeArray[OP_CALLFUNC_THIS] = &CodeInterpreter::op_callfunc_this; + gOpCodeArray[OP_ADVANCE_STR] = &CodeInterpreter::op_advance_str; + gOpCodeArray[OP_ADVANCE_STR_APPENDCHAR] = &CodeInterpreter::op_advance_str_appendchar; + gOpCodeArray[OP_ADVANCE_STR_COMMA] = &CodeInterpreter::op_advance_str_comma; + gOpCodeArray[OP_ADVANCE_STR_NUL] = &CodeInterpreter::op_advance_str_nul; + gOpCodeArray[OP_REWIND_STR] = &CodeInterpreter::op_rewind_str; + gOpCodeArray[OP_TERMINATE_REWIND_STR] = &CodeInterpreter::op_terminate_rewind_str; + gOpCodeArray[OP_COMPARE_STR] = &CodeInterpreter::op_compare_str; + gOpCodeArray[OP_PUSH] = &CodeInterpreter::op_push; + gOpCodeArray[OP_PUSH_UINT] = &CodeInterpreter::op_push_uint; + gOpCodeArray[OP_PUSH_FLT] = &CodeInterpreter::op_push_flt; + gOpCodeArray[OP_PUSH_VAR] = &CodeInterpreter::op_push_var; + gOpCodeArray[OP_PUSH_THIS] = &CodeInterpreter::op_push_this; + gOpCodeArray[OP_PUSH_FRAME] = &CodeInterpreter::op_push_frame; + gOpCodeArray[OP_ASSERT] = &CodeInterpreter::op_assert; + gOpCodeArray[OP_BREAK] = &CodeInterpreter::op_break; + gOpCodeArray[OP_ITER_BEGIN_STR] = &CodeInterpreter::op_iter_begin_str; + gOpCodeArray[OP_ITER_BEGIN] = &CodeInterpreter::op_iter_begin; + gOpCodeArray[OP_ITER] = &CodeInterpreter::op_iter; + gOpCodeArray[OP_ITER_END] = &CodeInterpreter::op_iter_end; + gOpCodeArray[OP_INVALID] = &CodeInterpreter::op_invalid; +} + +ConsoleValueRef CodeInterpreter::exec(U32 ip, + StringTableEntry functionName, + Namespace *thisNamespace, + U32 argc, + ConsoleValueRef *argv, + bool noCalls, + StringTableEntry packageName, + S32 setFrame) +{ + mExec.functionName = functionName; + mExec.thisNamespace = thisNamespace; + mExec.argc = argc; + mExec.argv = argv; + mExec.noCalls = noCalls; + mExec.packageName = packageName; + mExec.setFrame = setFrame; + + mCodeBlock->incRefCount(); + + mPopFrame = false; + +#ifdef TORQUE_VALIDATE_STACK + U32 stackStart = STR.mStartStackSize; +#endif + + STR.clearFunctionOffset(); // ensures arg buffer offset is back to 0 + + // Lets load up our function arguments. + parseArgs(ip); + + // Grab the state of the telenet debugger here once + // so that the push and pop frames are always balanced. + const bool telDebuggerOn = TelDebugger && TelDebugger->isConnected(); + if (telDebuggerOn && setFrame < 0) + TelDebugger->pushStackFrame(); + + mSaveCodeBlock = CodeBlock::smCurrentCodeBlock; + CodeBlock::smCurrentCodeBlock = mCodeBlock; + if (mCodeBlock->name) + { + Con::gCurrentFile = mCodeBlock->name; + Con::gCurrentRoot = mCodeBlock->modPath; + } + + U32 *code = mCodeBlock->code; + + while (true) + { + mCurrentInstruction = code[ip++]; + mNSEntry = nullptr; + +#ifdef TORQUE_VALIDATE_STACK + // OP Code check. + AssertFatal(mCurrentInstruction < MAX_OP_CODELEN, "Invalid OP code in script interpreter"); +#endif + + breakContinueLabel: + OPCodeReturn ret = (this->*gOpCodeArray[mCurrentInstruction])(ip); + if (ret == OPCodeReturn::exitCode) + goto exitLabel; + else if (ret == OPCodeReturn::breakContinue) + goto breakContinueLabel; + } +exitLabel: + if (telDebuggerOn && setFrame < 0) + TelDebugger->popStackFrame(); + + if (mPopFrame) + gEvalState.popFrame(); + + if (argv) + { + if (gEvalState.traceOn) + { + sTraceBuffer[0] = 0; + dStrcat(sTraceBuffer, "Leaving "); + + if (packageName) + { + dStrcat(sTraceBuffer, "["); + dStrcat(sTraceBuffer, packageName); + dStrcat(sTraceBuffer, "]"); + } + if (thisNamespace && thisNamespace->mName) + { + dSprintf(sTraceBuffer + dStrlen(sTraceBuffer), sizeof(sTraceBuffer) - dStrlen(sTraceBuffer), + "%s::%s() - return %s", thisNamespace->mName, mThisFunctionName, STR.getStringValue()); + } + else + { + dSprintf(sTraceBuffer + dStrlen(sTraceBuffer), sizeof(sTraceBuffer) - dStrlen(sTraceBuffer), + "%s() - return %s", mThisFunctionName, STR.getStringValue()); + } + Con::printf("%s", sTraceBuffer); + } + } + + CodeBlock::smCurrentCodeBlock = mSaveCodeBlock; + if (mSaveCodeBlock && mSaveCodeBlock->name) + { + Con::gCurrentFile = mSaveCodeBlock->name; + Con::gCurrentRoot = mSaveCodeBlock->modPath; + } + + mCodeBlock->decRefCount(); + +#ifdef TORQUE_VALIDATE_STACK + AssertFatal(!(STR.mStartStackSize > stackStart), "String stack not popped enough in script exec"); + AssertFatal(!(STR.mStartStackSize < stackStart), "String stack popped too much in script exec"); +#endif + + return mReturnValue; +} + +void CodeInterpreter::parseArgs(U32 &ip) +{ + U32 *code = mCodeBlock->code; + + if (mExec.argv) + { + U32 fnArgc = code[ip + 2 + 6]; + mThisFunctionName = Compiler::CodeToSTE(code, ip); + S32 wantedArgc = getMin(mExec.argc - 1, fnArgc); // argv[0] is func name + if (gEvalState.traceOn) + { + sTraceBuffer[0] = 0; + dStrcat(sTraceBuffer, "Entering "); + + if (mExec.packageName) + { + dStrcat(sTraceBuffer, "["); + dStrcat(sTraceBuffer, mExec.packageName); + dStrcat(sTraceBuffer, "]"); + } + if (mExec.thisNamespace && mExec.thisNamespace->mName) + { + dSprintf(sTraceBuffer + dStrlen(sTraceBuffer), sizeof(sTraceBuffer) - dStrlen(sTraceBuffer), + "%s::%s(", mExec.thisNamespace->mName, mThisFunctionName); + } + else + { + dSprintf(sTraceBuffer + dStrlen(sTraceBuffer), sizeof(sTraceBuffer) - dStrlen(sTraceBuffer), + "%s(", mThisFunctionName); + } + for (S32 i = 0; i < wantedArgc; i++) + { + dStrcat(sTraceBuffer, mExec.argv[i + 1]); + if (i != wantedArgc - 1) + dStrcat(sTraceBuffer, ", "); + } + dStrcat(sTraceBuffer, ")"); + Con::printf("%s", sTraceBuffer); + } + + gEvalState.pushFrame(mThisFunctionName, mExec.thisNamespace); + mPopFrame = true; + + StringTableEntry thisPointer = StringTable->insert("%this"); + + for (S32 i = 0; i < wantedArgc; i++) + { + StringTableEntry var = Compiler::CodeToSTE(code, ip + (2 + 6 + 1) + (i * 2)); + gEvalState.setCurVarNameCreate(var); + + ConsoleValueRef ref = mExec.argv[i + 1]; + + switch (ref.getType()) + { + case ConsoleValue::TypeInternalInt: + gEvalState.setIntVariable(ref); + break; + case ConsoleValue::TypeInternalFloat: + gEvalState.setFloatVariable(ref); + break; + case ConsoleValue::TypeInternalStringStackPtr: + gEvalState.setStringStackPtrVariable(ref.getStringStackPtrValue()); + break; + case ConsoleValue::TypeInternalStackString: + case ConsoleValue::TypeInternalString: + default: + gEvalState.setStringVariable(ref); + break; + } + + if (var == thisPointer) + { + // %this gets optimized as it is flagged as a constant. + // Since it is guarenteed to be constant, we can then perform optimizations. + gEvalState.currentVariable->mIsConstant = true; + + // Store a reference to the this pointer object. + mThisObject = Sim::findObject(gEvalState.getStringVariable()); + } + } + + ip = ip + (fnArgc * 2) + (2 + 6 + 1); + mCurFloatTable = mCodeBlock->functionFloats; + mCurStringTable = mCodeBlock->functionStrings; + } + else + { + mCurFloatTable = mCodeBlock->globalFloats; + mCurStringTable = mCodeBlock->globalStrings; + + // If requested stack frame isn't available, request a new one + // (this prevents assert failures when creating local + // variables without a stack frame) + if (gEvalState.getStackDepth() <= mExec.setFrame) + mExec.setFrame = -1; + + // Do we want this code to execute using a new stack frame? + if (mExec.setFrame < 0) + { + gEvalState.pushFrame(NULL, NULL); + mPopFrame = true; + } + else + { + // We want to copy a reference to an existing stack frame + // on to the top of the stack. Any change that occurs to + // the locals during this new frame will also occur in the + // original frame. + S32 stackIndex = gEvalState.getStackDepth() - mExec.setFrame - 1; + gEvalState.pushFrameRef(stackIndex); + mPopFrame = true; + } + } +} + +OPCodeReturn CodeInterpreter::op_func_decl(U32 &ip) +{ + U32 *code = mCodeBlock->code; + + if (!mExec.noCalls) + { + StringTableEntry fnName = CodeToSTE(code, ip); + StringTableEntry fnNamespace = CodeToSTE(code, ip + 2); + StringTableEntry fnPackage = CodeToSTE(code, ip + 4); + bool hasBody = (code[ip + 6] & 0x01) != 0; + U32 lineNumber = code[ip + 6] >> 1; + + Namespace::unlinkPackages(); + Namespace *ns = Namespace::find(fnNamespace, fnPackage); + ns->addFunction(fnName, mCodeBlock, hasBody ? ip : 0, mCurFNDocBlock ? dStrdup(mCurFNDocBlock) : NULL, lineNumber);// if no body, set the IP to 0 + if (mCurNSDocBlock) + { + // If we have a docblock before we declare the function in the script file, + // this will attempt to set the doc block to the function. + // See OP_DOCBLOCK_STR + if (fnNamespace == StringTable->lookup(mNSDocBlockClass)) + { + char *usageStr = dStrdup(mCurNSDocBlock); + usageStr[dStrlen(usageStr)] = '\0'; + ns->mUsage = usageStr; + ns->mCleanUpUsage = true; + mCurNSDocBlock = NULL; + } + } + Namespace::relinkPackages(); + + // If we had a docblock, it's definitely not valid anymore, so clear it out. + mCurFNDocBlock = NULL; + + //Con::printf("Adding function %s::%s (%d)", fnNamespace, fnName, ip); + } + ip = code[ip + 7]; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_create_object(U32 &ip) +{ + U32 *code = mCodeBlock->code; + + // Read some useful info. + StringTableEntry objParent = CodeToSTE(code, ip); + bool isDataBlock = code[ip + 2]; + bool isInternal = code[ip + 3]; + bool isSingleton = code[ip + 4]; + U32 lineNumber = code[ip + 5]; + mFailJump = code[ip + 6]; + + // If we don't allow calls, we certainly don't allow creating objects! + // Moved this to after failJump is set. Engine was crashing when + // noCalls = true and an object was being created at the beginning of + // a file. ADL. + if (mExec.noCalls) + { + ip = mFailJump; + return OPCodeReturn::success; + } + + // Push the old info to the stack + //Assert( objectCreationStackIndex < objectCreationStackSize ); + mObjectCreationStack[mObjectCreationStackIndex].newObject = mCurrentNewObject; + mObjectCreationStack[mObjectCreationStackIndex++].failJump = mFailJump; + + // Get the constructor information off the stack. + CSTK.getArgcArgv(NULL, &mCallArgc, &mCallArgv); + const char *objectName = mCallArgv[2]; + + // Con::printf("Creating object..."); + + // objectName = argv[1]... + mCurrentNewObject = NULL; + + // Are we creating a datablock? If so, deal with case where we override + // an old one. + if (isDataBlock) + { + // Con::printf(" - is a datablock"); + + // Find the old one if any. + SimObject *db = Sim::getDataBlockGroup()->findObject(objectName); + + // Make sure we're not changing types on ourselves... + if (db && dStricmp(db->getClassName(), mCallArgv[1])) + { + Con::errorf(ConsoleLogEntry::General, "%s: Cannot re-declare data block %s with a different class.", mCodeBlock->getFileLine(ip), objectName); + ip = mFailJump; + STR.popFrame(); + CSTK.popFrame(); + return OPCodeReturn::success; + } + + // If there was one, set the currentNewObject and move on. + if (db) + mCurrentNewObject = db; + } + else if (!isInternal) + { + // IF we aren't looking at a local/internal object, then check if + // this object already exists in the global space + + AbstractClassRep* rep = AbstractClassRep::findClassRep(objectName); + if (rep != NULL) { + Con::errorf(ConsoleLogEntry::General, "%s: Cannot name object [%s] the same name as a script class.", + mCodeBlock->getFileLine(ip), objectName); + ip = mFailJump; + STR.popFrame(); + CSTK.popFrame(); + return OPCodeReturn::success; + } + + SimObject *obj = Sim::findObject((const char*)objectName); + if (obj /*&& !obj->isLocalName()*/) + { + if (isSingleton) + { + // Make sure we're not trying to change types + if (dStricmp(obj->getClassName(), (const char*)mCallArgv[1]) != 0) + { + Con::errorf(ConsoleLogEntry::General, "%s: Cannot re-declare object [%s] with a different class [%s] - was [%s].", + mCodeBlock->getFileLine(ip), objectName, (const char*)mCallArgv[1], obj->getClassName()); + ip = mFailJump; + STR.popFrame(); + CSTK.popFrame(); + return OPCodeReturn::success; + } + + // We're creating a singleton, so use the found object + // instead of creating a new object. + mCurrentNewObject = obj; + } + else + { + const char* redefineBehavior = Con::getVariable("$Con::redefineBehavior"); + + if (dStricmp(redefineBehavior, "replaceExisting") == 0) + { + // Save our constructor args as the argv vector is stored on the + // string stack and may get stomped if deleteObject triggers + // script execution. + + ConsoleValueRef savedArgv[StringStack::MaxArgs]; + for (int i = 0; i< mCallArgc; i++) { + savedArgv[i] = mCallArgv[i]; + } + //dMemcpy( savedArgv, callArgv, sizeof( savedArgv[ 0 ] ) * callArgc ); + + // Prevent stack value corruption + CSTK.pushFrame(); + STR.pushFrame(); + // -- + + obj->deleteObject(); + obj = NULL; + + // Prevent stack value corruption + CSTK.popFrame(); + STR.popFrame(); + // -- + + //dMemcpy( callArgv, savedArgv, sizeof( callArgv[ 0 ] ) * callArgc ); + for (int i = 0; iinsert(newName); + break; + } + } + } + else if (dStricmp(redefineBehavior, "unnameNew") == 0) + { + objectName = StringTable->insert(""); + } + else if (dStricmp(redefineBehavior, "postfixNew") == 0) + { + const char* postfix = Con::getVariable("$Con::redefineBehaviorPostfix"); + String newName = String::ToString("%s%s", objectName, postfix); + + if (Sim::findObject(newName)) + { + Con::errorf(ConsoleLogEntry::General, "%s: Cannot re-declare object with postfix [%s].", + mCodeBlock->getFileLine(ip), newName.c_str()); + ip = mFailJump; + STR.popFrame(); + CSTK.popFrame(); + return OPCodeReturn::success; + } + else + objectName = StringTable->insert(newName); + } + else + { + Con::errorf(ConsoleLogEntry::General, "%s: Cannot re-declare object [%s].", + mCodeBlock->getFileLine(ip), objectName); + ip = mFailJump; + STR.popFrame(); + CSTK.popFrame(); + return OPCodeReturn::success; + } + } + } + } + + STR.popFrame(); + CSTK.popFrame(); + + if (!mCurrentNewObject) + { + // Well, looks like we have to create a new object. + ConsoleObject *object = ConsoleObject::create((const char*)mCallArgv[1]); + + // Deal with failure! + if (!object) + { + Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-conobject class %s.", mCodeBlock->getFileLine(ip), (const char*)mCallArgv[1]); + ip = mFailJump; + return OPCodeReturn::success; + } + + // Do special datablock init if appropros + if (isDataBlock) + { + SimDataBlock *dataBlock = dynamic_cast(object); + if (dataBlock) + { + dataBlock->assignId(); + } + else + { + // They tried to make a non-datablock with a datablock keyword! + Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-datablock class %s.", mCodeBlock->getFileLine(ip), (const char*)mCallArgv[1]); + // Clean up... + delete object; + mCurrentNewObject = NULL; + ip = mFailJump; + return OPCodeReturn::success; + } + } + + // Finally, set currentNewObject to point to the new one. + mCurrentNewObject = dynamic_cast(object); + + // Deal with the case of a non-SimObject. + if (!mCurrentNewObject) + { + Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-SimObject class %s.", mCodeBlock->getFileLine(ip), (const char*)mCallArgv[1]); + delete object; + mCurrentNewObject = NULL; + ip = mFailJump; + return OPCodeReturn::success; + } + + // Set the declaration line + mCurrentNewObject->setDeclarationLine(lineNumber); + + // Set the file that this object was created in + mCurrentNewObject->setFilename(mCodeBlock->name); + + // Does it have a parent object? (ie, the copy constructor : syntax, not inheriance) + if (*objParent) + { + // Find it! + SimObject *parent; + if (Sim::findObject(objParent, parent)) + { + // Con::printf(" - Parent object found: %s", parent->getClassName()); + + mCurrentNewObject->setCopySource(parent); + mCurrentNewObject->assignFieldsFrom(parent); + + // copy any substitution statements + SimDataBlock* parent_db = dynamic_cast(parent); + if (parent_db) + { + SimDataBlock* currentNewObject_db = dynamic_cast(mCurrentNewObject); + if (currentNewObject_db) + currentNewObject_db->copySubstitutionsFrom(parent_db); + } + } + else + { + if (Con::gObjectCopyFailures == -1) + Con::errorf(ConsoleLogEntry::General, "%s: Unable to find parent object %s for %s.", mCodeBlock->getFileLine(ip), objParent, (const char*)mCallArgv[1]); + else + ++Con::gObjectCopyFailures; + + // Fail to create the object. + delete object; + mCurrentNewObject = NULL; + ip = mFailJump; + return OPCodeReturn::success; + } + } + + // If a name was passed, assign it. + if (objectName[0]) + { + if (!isInternal) + mCurrentNewObject->assignName(objectName); + else + mCurrentNewObject->setInternalName(objectName); + + // Set the original name + mCurrentNewObject->setOriginalName(objectName); + } + + // Prevent stack value corruption + CSTK.pushFrame(); + STR.pushFrame(); + // -- + + // Do the constructor parameters. + if (!mCurrentNewObject->processArguments(mCallArgc - 3, mCallArgv + 3)) + { + delete mCurrentNewObject; + mCurrentNewObject = NULL; + ip = mFailJump; + + // Prevent stack value corruption + CSTK.popFrame(); + STR.popFrame(); + // -- + return OPCodeReturn::success; + } + + // Prevent stack value corruption + CSTK.popFrame(); + STR.popFrame(); + // -- + + // If it's not a datablock, allow people to modify bits of it. + if (!isDataBlock) + { + mCurrentNewObject->setModStaticFields(true); + mCurrentNewObject->setModDynamicFields(true); + } + } + else + { + mCurrentNewObject->reloadReset(); // AFX (reload-reset) + // Does it have a parent object? (ie, the copy constructor : syntax, not inheriance) + if (*objParent) + { + // Find it! + SimObject *parent; + if (Sim::findObject(objParent, parent)) + { + // Con::printf(" - Parent object found: %s", parent->getClassName()); + + // temporarily block name change + SimObject::preventNameChanging = true; + mCurrentNewObject->setCopySource(parent); + mCurrentNewObject->assignFieldsFrom(parent); + // restore name changing + SimObject::preventNameChanging = false; + + // copy any substitution statements + SimDataBlock* parent_db = dynamic_cast(parent); + if (parent_db) + { + SimDataBlock* currentNewObject_db = dynamic_cast(mCurrentNewObject); + if (currentNewObject_db) + currentNewObject_db->copySubstitutionsFrom(parent_db); + } + } + else + Con::errorf(ConsoleLogEntry::General, "%d: Unable to find parent object %s for %s.", lineNumber, objParent, (const char*)mCallArgv[1]); + } + } + + // Advance the IP past the create info... + ip += 7; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_add_object(U32 &ip) +{ + // See OP_SETCURVAR for why we do this. + mCurFNDocBlock = NULL; + mCurNSDocBlock = NULL; + + // Do we place this object at the root? + bool placeAtRoot = mCodeBlock->code[ip++]; + + // Con::printf("Adding object %s", currentNewObject->getName()); + + // Prevent stack value corruption + CSTK.pushFrame(); + STR.pushFrame(); + // -- + + // Make sure it wasn't already added, then add it. + if (mCurrentNewObject->isProperlyAdded() == false) + { + bool ret = false; + + Message *msg = dynamic_cast(mCurrentNewObject); + if (msg) + { + SimObjectId id = Message::getNextMessageID(); + if (id != 0xffffffff) + ret = mCurrentNewObject->registerObject(id); + else + Con::errorf("%s: No more object IDs available for messages", mCodeBlock->getFileLine(ip)); + } + else + ret = mCurrentNewObject->registerObject(); + + if (!ret) + { + // This error is usually caused by failing to call Parent::initPersistFields in the class' initPersistFields(). + Con::warnf(ConsoleLogEntry::General, "%s: Register object failed for object %s of class %s.", mCodeBlock->getFileLine(ip), mCurrentNewObject->getName(), mCurrentNewObject->getClassName()); + delete mCurrentNewObject; + mCurrentNewObject = NULL; + ip = mFailJump; + // Prevent stack value corruption + CSTK.popFrame(); + STR.popFrame(); + // -- + return OPCodeReturn::success; + } + } + + // Are we dealing with a datablock? + SimDataBlock *dataBlock = dynamic_cast(mCurrentNewObject); + static String errorStr; + + // If so, preload it. + if (dataBlock && !dataBlock->preload(true, errorStr)) + { + Con::errorf(ConsoleLogEntry::General, "%s: preload failed for %s: %s.", mCodeBlock->getFileLine(ip), + mCurrentNewObject->getName(), errorStr.c_str()); + dataBlock->deleteObject(); + mCurrentNewObject = NULL; + ip = mFailJump; + + // Prevent stack value corruption + CSTK.popFrame(); + STR.popFrame(); + // -- + return OPCodeReturn::success; + } + + // What group will we be added to, if any? + U32 groupAddId = intStack[_UINT]; + SimGroup *grp = NULL; + SimSet *set = NULL; + bool isMessage = dynamic_cast(mCurrentNewObject) != NULL; + + if (!placeAtRoot || !mCurrentNewObject->getGroup()) + { + if (!isMessage) + { + if (!placeAtRoot) + { + // Otherwise just add to the requested group or set. + if (!Sim::findObject(groupAddId, grp)) + Sim::findObject(groupAddId, set); + } + + if (placeAtRoot) + { + // Deal with the instantGroup if we're being put at the root or we're adding to a component. + if (Con::gInstantGroup.isEmpty() + || !Sim::findObject(Con::gInstantGroup, grp)) + grp = Sim::getRootGroup(); + } + } + + // If we didn't get a group, then make sure we have a pointer to + // the rootgroup. + if (!grp) + grp = Sim::getRootGroup(); + + // add to the parent group + grp->addObject(mCurrentNewObject); + + // If for some reason the add failed, add the object to the + // root group so it won't leak. + if (!mCurrentNewObject->getGroup()) + Sim::getRootGroup()->addObject(mCurrentNewObject); + + // add to any set we might be in + if (set) + set->addObject(mCurrentNewObject); + } + + // store the new object's ID on the stack (overwriting the group/set + // id, if one was given, otherwise getting pushed) + if (placeAtRoot) + intStack[_UINT] = mCurrentNewObject->getId(); + else + intStack[++_UINT] = mCurrentNewObject->getId(); + + // Prevent stack value corruption + CSTK.popFrame(); + STR.popFrame(); + // -- + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_end_object(U32 &ip) +{ + // If we're not to be placed at the root, make sure we clean up + // our group reference. + bool placeAtRoot = mCodeBlock->code[ip++]; + if (!placeAtRoot) + _UINT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_finish_object(U32 &ip) +{ + if (mCurrentNewObject) + mCurrentNewObject->onPostAdd(); + + //Assert( objectCreationStackIndex >= 0 ); + // Restore the object info from the stack [7/9/2007 Black] + mCurrentNewObject = mObjectCreationStack[--mObjectCreationStackIndex].newObject; + mFailJump = mObjectCreationStack[mObjectCreationStackIndex].failJump; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_jmpiffnot(U32 &ip) +{ + if (floatStack[_FLT--]) + { + ip++; + return OPCodeReturn::success; + } + ip = mCodeBlock->code[ip]; + return OPCodeReturn::success; +} + + +OPCodeReturn CodeInterpreter::op_jmpifnot(U32 &ip) +{ + if (intStack[_UINT--]) + { + ip++; + return OPCodeReturn::success; + } + ip = mCodeBlock->code[ip]; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_jmpiff(U32 &ip) +{ + if (!floatStack[_FLT--]) + { + ip++; + return OPCodeReturn::success; + } + ip = mCodeBlock->code[ip]; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_jmpif(U32 &ip) +{ + if (!intStack[_UINT--]) + { + ip++; + return OPCodeReturn::success; + } + ip = mCodeBlock->code[ip]; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_jmpifnot_np(U32 &ip) +{ + if (intStack[_UINT]) + { + _UINT--; + ip++; + return OPCodeReturn::success; + } + ip = mCodeBlock->code[ip]; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_jmpif_np(U32 &ip) +{ + if (!intStack[_UINT]) + { + _UINT--; + ip++; + return OPCodeReturn::success; + } + ip = mCodeBlock->code[ip]; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_jmp(U32 &ip) +{ + ip = mCodeBlock->code[ip]; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_return_void(U32 &ip) +{ + STR.setStringValue(""); + // We're falling thru here on purpose. + + OPCodeReturn ret = op_return(ip); + + return ret; +} + +OPCodeReturn CodeInterpreter::op_return(U32 &ip) +{ + StringStackPtr retValue = STR.getStringValuePtr(); + + if (mIterDepth > 0) + { + // Clear iterator state. + while (mIterDepth > 0) + { + iterStack[--_ITER].mIsStringIter = false; + --mIterDepth; + } + + STR.rewind(); + STR.setStringValue(StringStackPtrRef(retValue).getPtr(&STR)); // Not nice but works. + retValue = STR.getStringValuePtr(); + } + + // Previously the return value was on the stack and would be returned using STR.getStringValue(). + // Now though we need to wrap it in a ConsoleValueRef + mReturnValue.value = CSTK.pushStringStackPtr(retValue); + + return OPCodeReturn::exitCode; +} + +OPCodeReturn CodeInterpreter::op_return_flt(U32 &ip) +{ + if (mIterDepth > 0) + { + // Clear iterator state. + while (mIterDepth > 0) + { + iterStack[--_ITER].mIsStringIter = false; + --mIterDepth; + } + + } + + mReturnValue.value = CSTK.pushFLT(floatStack[_FLT]); + _FLT--; + + return OPCodeReturn::exitCode; +} + +OPCodeReturn CodeInterpreter::op_return_uint(U32 &ip) +{ + if (mIterDepth > 0) + { + // Clear iterator state. + while (mIterDepth > 0) + { + iterStack[--_ITER].mIsStringIter = false; + --mIterDepth; + } + } + + mReturnValue.value = CSTK.pushUINT(intStack[_UINT]); + _UINT--; + + return OPCodeReturn::exitCode; +} + +OPCodeReturn CodeInterpreter::op_cmpeq(U32 &ip) +{ + intStack[_UINT + 1] = bool(floatStack[_FLT] == floatStack[_FLT - 1]); + _UINT++; + _FLT -= 2; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_cmpgr(U32 &ip) +{ + intStack[_UINT + 1] = bool(floatStack[_FLT] > floatStack[_FLT - 1]); + _UINT++; + _FLT -= 2; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_cmpge(U32 &ip) +{ + intStack[_UINT + 1] = bool(floatStack[_FLT] >= floatStack[_FLT - 1]); + _UINT++; + _FLT -= 2; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_cmplt(U32 &ip) +{ + intStack[_UINT + 1] = bool(floatStack[_FLT] < floatStack[_FLT - 1]); + _UINT++; + _FLT -= 2; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_cmple(U32 &ip) +{ + intStack[_UINT + 1] = bool(floatStack[_FLT] <= floatStack[_FLT - 1]); + _UINT++; + _FLT -= 2; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_cmpne(U32 &ip) +{ + intStack[_UINT + 1] = bool(floatStack[_FLT] != floatStack[_FLT - 1]); + _UINT++; + _FLT -= 2; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_xor(U32 &ip) +{ + intStack[_UINT - 1] = intStack[_UINT] ^ intStack[_UINT - 1]; + _UINT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_mod(U32 &ip) +{ + if (intStack[_UINT - 1] != 0) + intStack[_UINT - 1] = intStack[_UINT] % intStack[_UINT - 1]; + else + intStack[_UINT - 1] = 0; + _UINT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_bitand(U32 &ip) +{ + intStack[_UINT - 1] = intStack[_UINT] & intStack[_UINT - 1]; + _UINT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_bitor(U32 &ip) +{ + intStack[_UINT - 1] = intStack[_UINT] | intStack[_UINT - 1]; + _UINT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_not(U32 &ip) +{ + intStack[_UINT] = !intStack[_UINT]; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_notf(U32 &ip) +{ + intStack[_UINT + 1] = !floatStack[_FLT]; + _FLT--; + _UINT++; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_onescomplement(U32 &ip) +{ + intStack[_UINT] = ~intStack[_UINT]; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_shr(U32 &ip) +{ + intStack[_UINT - 1] = intStack[_UINT] >> intStack[_UINT - 1]; + _UINT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_shl(U32 &ip) +{ + intStack[_UINT - 1] = intStack[_UINT] << intStack[_UINT - 1]; + _UINT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_and(U32 &ip) +{ + intStack[_UINT - 1] = intStack[_UINT] && intStack[_UINT - 1]; + _UINT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_or(U32 &ip) +{ + intStack[_UINT - 1] = intStack[_UINT] || intStack[_UINT - 1]; + _UINT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_add(U32 &ip) +{ + floatStack[_FLT - 1] = floatStack[_FLT] + floatStack[_FLT - 1]; + _FLT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_sub(U32 &ip) +{ + floatStack[_FLT - 1] = floatStack[_FLT] - floatStack[_FLT - 1]; + _FLT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_mul(U32 &ip) +{ + floatStack[_FLT - 1] = floatStack[_FLT] * floatStack[_FLT - 1]; + _FLT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_div(U32 &ip) +{ + floatStack[_FLT - 1] = floatStack[_FLT] / floatStack[_FLT - 1]; + _FLT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_neg(U32 &ip) +{ + floatStack[_FLT] = -floatStack[_FLT]; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_inc(U32 &ip) +{ + StringTableEntry var = CodeToSTE(mCodeBlock->code, ip); + ip += 2; + + // If a variable is set, then these must be NULL. It is necessary + // to set this here so that the vector parser can appropriately + // identify whether it's dealing with a vector. + mPrevField = NULL; + mPrevObject = NULL; + mCurObject = NULL; + + gEvalState.setCurVarNameCreate(var); + + // In order to let docblocks work properly with variables, we have + // clear the current docblock when we do an assign. This way it + // won't inappropriately carry forward to following function decls. + mCurFNDocBlock = NULL; + mCurNSDocBlock = NULL; + + F64 val = gEvalState.getFloatVariable() + 1.0; + gEvalState.setFloatVariable(val); + + // We gotta push val onto the stack. What if we have + // more expressions that have to use this. + // If we don't, we send out an op code to pop it. + floatStack[_FLT + 1] = val; + _FLT++; + + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_dec(U32 &ip) +{ + StringTableEntry var = CodeToSTE(mCodeBlock->code, ip); + ip += 2; + + // If a variable is set, then these must be NULL. It is necessary + // to set this here so that the vector parser can appropriately + // identify whether it's dealing with a vector. + mPrevField = NULL; + mPrevObject = NULL; + mCurObject = NULL; + + gEvalState.setCurVarNameCreate(var); + + // In order to let docblocks work properly with variables, we have + // clear the current docblock when we do an assign. This way it + // won't inappropriately carry forward to following function decls. + mCurFNDocBlock = NULL; + mCurNSDocBlock = NULL; + + F64 val = gEvalState.getFloatVariable() - 1.0; + gEvalState.setFloatVariable(val); + + // We gotta push val onto the stack. What if we have + // more expressions that have to use this. + // If we don't, we send out an op code to pop it. + floatStack[_FLT + 1] = val; + _FLT++; + + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_setcurvar(U32 &ip) +{ + StringTableEntry var = CodeToSTE(mCodeBlock->code, ip); + ip += 2; + + // If a variable is set, then these must be NULL. It is necessary + // to set this here so that the vector parser can appropriately + // identify whether it's dealing with a vector. + mPrevField = NULL; + mPrevObject = NULL; + mCurObject = NULL; + + gEvalState.setCurVarName(var); + + // In order to let docblocks work properly with variables, we have + // clear the current docblock when we do an assign. This way it + // won't inappropriately carry forward to following function decls. + mCurFNDocBlock = NULL; + mCurNSDocBlock = NULL; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_setcurvar_create(U32 &ip) +{ + StringTableEntry var = CodeToSTE(mCodeBlock->code, ip); + ip += 2; + + // See OP_SETCURVAR + mPrevField = NULL; + mPrevObject = NULL; + mCurObject = NULL; + + gEvalState.setCurVarNameCreate(var); + + // See OP_SETCURVAR for why we do this. + mCurFNDocBlock = NULL; + mCurNSDocBlock = NULL; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_setcurvar_array(U32 &ip) +{ + StringTableEntry var = STR.getSTValue(); + + // See OP_SETCURVAR + mPrevField = NULL; + mPrevObject = NULL; + mCurObject = NULL; + + gEvalState.setCurVarName(var); + + // See OP_SETCURVAR for why we do this. + mCurFNDocBlock = NULL; + mCurNSDocBlock = NULL; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_setcurvar_array_varlookup(U32 &ip) +{ + StringTableEntry arrayName = CodeToSTE(mCodeBlock->code, ip); + StringTableEntry arrayLookup = CodeToSTE(mCodeBlock->code, ip + 2); + ip += 4; + + STR.setStringValue(arrayName); + STR.advance(); + + // See OP_SETCURVAR + mPrevField = NULL; + mPrevObject = NULL; + mCurObject = NULL; + + // resolve arrayLookup to get the 'value' + // Note: we have to setCurVarNameCreate in case the var doesn't exist. + // this won't cause much of a performance hit since vars are hashed. + gEvalState.setCurVarNameCreate(arrayLookup); + StringTableEntry hash = gEvalState.getStringVariable(); + + STR.setStringValue(hash); + STR.rewind(); + + // Generate new array name. + StringTableEntry var = STR.getSTValue(); + gEvalState.setCurVarName(var); + + // See OP_SETCURVAR for why we do this. + mCurFNDocBlock = NULL; + mCurNSDocBlock = NULL; + + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_setcurvar_array_create(U32 &ip) +{ + StringTableEntry var = STR.getSTValue(); + + // See OP_SETCURVAR + mPrevField = NULL; + mPrevObject = NULL; + mCurObject = NULL; + + gEvalState.setCurVarNameCreate(var); + + // See OP_SETCURVAR for why we do this. + mCurFNDocBlock = NULL; + mCurNSDocBlock = NULL; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_setcurvar_array_create_varlookup(U32 &ip) +{ + StringTableEntry arrayName = CodeToSTE(mCodeBlock->code, ip); + StringTableEntry arrayLookup = CodeToSTE(mCodeBlock->code, ip + 2); + ip += 4; + + // See OP_SETCURVAR + mPrevField = NULL; + mPrevObject = NULL; + mCurObject = NULL; + + STR.setStringValue(arrayName); + STR.advance(); + + // resolve arrayLookup to get the 'value' + // Note: we have to setCurVarNameCreate in case the var doesn't exist. + // this won't cause much of a performance hit since vars are hashed. + gEvalState.setCurVarNameCreate(arrayLookup); + StringTableEntry hash = gEvalState.getStringVariable(); + + STR.setStringValue(hash); + STR.rewind(); + + // Generate new array name. + StringTableEntry var = STR.getSTValue(); + gEvalState.setCurVarNameCreate(var); + + // See OP_SETCURVAR for why we do this. + mCurFNDocBlock = NULL; + mCurNSDocBlock = NULL; + + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_loadvar_uint(U32 &ip) +{ + intStack[_UINT + 1] = gEvalState.getIntVariable(); + _UINT++; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_loadvar_flt(U32 &ip) +{ + floatStack[_FLT + 1] = gEvalState.getFloatVariable(); + _FLT++; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_loadvar_str(U32 &ip) +{ + StringTableEntry val = gEvalState.getStringVariable(); + STR.setStringValue(val); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_loadvar_var(U32 &ip) +{ + // Sets current source of OP_SAVEVAR_VAR + gEvalState.copyVariable = gEvalState.currentVariable; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_savevar_uint(U32 &ip) +{ + gEvalState.setIntVariable(intStack[_UINT]); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_savevar_flt(U32 &ip) +{ + gEvalState.setFloatVariable(floatStack[_FLT]); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_savevar_str(U32 &ip) +{ + gEvalState.setStringVariable(STR.getStringValue()); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_savevar_var(U32 &ip) +{ + // this basically handles %var1 = %var2 + gEvalState.setCopyVariable(); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_setcurobject(U32 &ip) +{ + // Save the previous object for parsing vector fields. + mPrevObject = mCurObject; + StringTableEntry val = STR.getStringValue(); + + // Sim::findObject will sometimes find valid objects from + // multi-component strings. This makes sure that doesn't + // happen. + for (const char* check = val; *check; check++) + { + if (*check == ' ') + { + val = ""; + break; + } + } + mCurObject = Sim::findObject(val); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_setcurobject_internal(U32 &ip) +{ + ++ip; // To skip the recurse flag if the object wasn't found + if (mCurObject) + { + SimSet *set = dynamic_cast(mCurObject); + if (set) + { + StringTableEntry intName = StringTable->insert(STR.getStringValue()); + bool recurse = mCodeBlock->code[ip - 1]; + SimObject *obj = set->findObjectByInternalName(intName, recurse); + intStack[_UINT + 1] = obj ? obj->getId() : 0; + _UINT++; + } + else + { + Con::errorf(ConsoleLogEntry::Script, "%s: Attempt to use -> on non-set %s of class %s.", mCodeBlock->getFileLine(ip - 2), mCurObject->getName(), mCurObject->getClassName()); + intStack[_UINT] = 0; + } + } + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_setcurobject_new(U32 &ip) +{ + mCurObject = mCurrentNewObject; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_setcurfield(U32 &ip) +{ + // Save the previous field for parsing vector fields. + mPrevField = mCurField; + dStrcpy(prevFieldArray, curFieldArray); + mCurField = CodeToSTE(mCodeBlock->code, ip); + curFieldArray[0] = 0; + ip += 2; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_setcurfield_array(U32 &ip) +{ + dStrcpy(curFieldArray, STR.getStringValue()); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_setcurfield_type(U32 &ip) +{ + if (mCurObject) + mCurObject->setDataFieldType(mCodeBlock->code[ip], mCurField, curFieldArray); + ip++; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_setcurfield_array_var(U32 &ip) +{ + StringTableEntry var = CodeToSTE(mCodeBlock->code, ip); + ip += 2; + + // We set the current var name (create it as well in case if it doesn't exist, + // otherwise we will crash). + gEvalState.setCurVarNameCreate(var); + + // Then load the var and copy the contents to the current field array + dStrncpy(curFieldArray, gEvalState.currentVariable->getStringValue(), sizeof(curFieldArray)); + + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_setcurfield_this(U32 &ip) +{ + // set the 'this pointer' as the current object. + mCurObject = mThisObject; + + mPrevField = mCurField; + dStrcpy(prevFieldArray, curFieldArray); + mCurField = CodeToSTE(mCodeBlock->code, ip); + curFieldArray[0] = 0; + ip += 2; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_loadfield_uint(U32 &ip) +{ + if (mCurObject) + intStack[_UINT + 1] = U32(dAtoi(mCurObject->getDataField(mCurField, curFieldArray))); + else + { + // The field is not being retrieved from an object. Maybe it's + // a special accessor? + char buff[FieldBufferSizeNumeric]; + memset(buff, 0, sizeof(buff)); + getFieldComponent(mPrevObject, mPrevField, prevFieldArray, mCurField, buff); + intStack[_UINT + 1] = dAtoi(buff); + } + _UINT++; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_loadfield_flt(U32 &ip) +{ + if (mCurObject) + floatStack[_FLT + 1] = dAtof(mCurObject->getDataField(mCurField, curFieldArray)); + else + { + // The field is not being retrieved from an object. Maybe it's + // a special accessor? + char buff[FieldBufferSizeNumeric]; + memset(buff, 0, sizeof(buff)); + getFieldComponent(mPrevObject, mPrevField, prevFieldArray, mCurField, buff); + floatStack[_FLT + 1] = dAtof(buff); + } + _FLT++; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_loadfield_str(U32 &ip) +{ + if (mCurObject) + { + StringTableEntry val = mCurObject->getDataField(mCurField, curFieldArray); + STR.setStringValue(val); + } + else + { + // The field is not being retrieved from an object. Maybe it's + // a special accessor? + char buff[FieldBufferSizeString]; + memset(buff, 0, sizeof(buff)); + getFieldComponent(mPrevObject, mPrevField, prevFieldArray, mCurField, buff); + STR.setStringValue(buff); + } + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_savefield_uint(U32 &ip) +{ + STR.setIntValue(intStack[_UINT]); + if (mCurObject) + mCurObject->setDataField(mCurField, curFieldArray, STR.getStringValue()); + else + { + // The field is not being set on an object. Maybe it's + // a special accessor? + setFieldComponent(mPrevObject, mPrevField, prevFieldArray, mCurField); + mPrevObject = NULL; + } + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_savefield_flt(U32 &ip) +{ + STR.setFloatValue(floatStack[_FLT]); + if (mCurObject) + mCurObject->setDataField(mCurField, curFieldArray, STR.getStringValue()); + else + { + // The field is not being set on an object. Maybe it's + // a special accessor? + setFieldComponent(mPrevObject, mPrevField, prevFieldArray, mCurField); + mPrevObject = NULL; + } + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_savefield_str(U32 &ip) +{ + if (mCurObject) + mCurObject->setDataField(mCurField, curFieldArray, STR.getStringValue()); + else + { + // The field is not being set on an object. Maybe it's + // a special accessor? + setFieldComponent(mPrevObject, mPrevField, prevFieldArray, mCurField); + mPrevObject = NULL; + } + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_str_to_uint(U32 &ip) +{ + intStack[_UINT + 1] = STR.getIntValue(); + _UINT++; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_str_to_flt(U32 &ip) +{ + floatStack[_FLT + 1] = STR.getFloatValue(); + _FLT++; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_str_to_none(U32 &ip) +{ + // This exists simply to deal with certain typecast situations. + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_flt_to_uint(U32 &ip) +{ + intStack[_UINT + 1] = (S64)floatStack[_FLT]; + _FLT--; + _UINT++; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_flt_to_str(U32 &ip) +{ + STR.setFloatValue(floatStack[_FLT]); + _FLT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_flt_to_none(U32 &ip) +{ + _FLT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_uint_to_flt(U32 &ip) +{ + floatStack[_FLT + 1] = (F32)intStack[_UINT]; + _UINT--; + _FLT++; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_uint_to_str(U32 &ip) +{ + STR.setIntValue(intStack[_UINT]); + _UINT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_uint_to_none(U32 &ip) +{ + _UINT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_copyvar_to_none(U32 &ip) +{ + gEvalState.copyVariable = NULL; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_loadimmed_uint(U32 &ip) +{ + intStack[_UINT + 1] = mCodeBlock->code[ip++]; + _UINT++; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_loadimmed_flt(U32 &ip) +{ + floatStack[_FLT + 1] = mCurFloatTable[mCodeBlock->code[ip]]; + ip++; + _FLT++; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_tag_to_str(U32 &ip) +{ + mCodeBlock->code[ip - 1] = OP_LOADIMMED_STR; + // it's possible the string has already been converted + if (U8(mCurStringTable[mCodeBlock->code[ip]]) != StringTagPrefixByte) + { + U32 id = GameAddTaggedString(mCurStringTable + mCodeBlock->code[ip]); + dSprintf(mCurStringTable + mCodeBlock->code[ip] + 1, 7, "%d", id); + *(mCurStringTable + mCodeBlock->code[ip]) = StringTagPrefixByte; + } + + // Fallthrough + OPCodeReturn ret = op_loadimmed_str(ip); + + return ret; +} + +OPCodeReturn CodeInterpreter::op_loadimmed_str(U32 &ip) +{ + STR.setStringValue(mCurStringTable + mCodeBlock->code[ip++]); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_docblock_str(U32 &ip) +{ + // If the first word of the doc is '\class' or '@class', then this + // is a namespace doc block, otherwise it is a function doc block. + const char* docblock = mCurStringTable + mCodeBlock->code[ip++]; + + const char* sansClass = dStrstr(docblock, "@class"); + if (!sansClass) + sansClass = dStrstr(docblock, "\\class"); + + if (sansClass) + { + // Don't save the class declaration. Scan past the 'class' + // keyword and up to the first whitespace. + sansClass += 7; + S32 index = 0; + while ((*sansClass != ' ') && (*sansClass != '\n') && *sansClass && (index < (nsDocLength - 1))) + { + mNSDocBlockClass[index++] = *sansClass; + sansClass++; + } + mNSDocBlockClass[index] = '\0'; + + mCurNSDocBlock = sansClass + 1; + } + else + mCurFNDocBlock = docblock; + + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_loadimmed_ident(U32 &ip) +{ + STR.setStringValue(CodeToSTE(mCodeBlock->code, ip)); + ip += 2; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_callfunc_resolve(U32 &ip) +{ + // This deals with a function that is potentially living in a namespace. + StringTableEntry fnNamespace = CodeToSTE(mCodeBlock->code, ip + 2); + StringTableEntry fnName = CodeToSTE(mCodeBlock->code, ip); + + // Try to look it up. + mNSEntry = Namespace::find(fnNamespace)->lookup(fnName); + if (!mNSEntry) + { + ip += 5; + Con::warnf(ConsoleLogEntry::General, + "%s: Unable to find function %s%s%s", + mCodeBlock->getFileLine(ip - 7), fnNamespace ? fnNamespace : "", + fnNamespace ? "::" : "", fnName); + STR.popFrame(); + CSTK.popFrame(); + return OPCodeReturn::success; + } + + // Fallthrough to op_callfunc_resolve + OPCodeReturn ret = op_callfunc(ip); + + return ret; +} + +OPCodeReturn CodeInterpreter::op_callfunc(U32 &ip) +{ + // This routingId is set when we query the object as to whether + // it handles this method. It is set to an enum from the table + // above indicating whether it handles it on a component it owns + // or just on the object. + S32 routingId = 0; + + U32 *code = mCodeBlock->code; + + StringTableEntry fnName = CodeToSTE(code, ip); + + //if this is called from inside a function, append the ip and codeptr + if (gEvalState.getStackDepth() > 0) + { + gEvalState.getCurrentFrame().code = mCodeBlock; + gEvalState.getCurrentFrame().ip = ip - 1; + } + + U32 callType = code[ip + 4]; + + ip += 5; + CSTK.getArgcArgv(fnName, &mCallArgc, &mCallArgv); + + const char *componentReturnValue = ""; + Namespace *ns = NULL; + + if (callType == FuncCallExprNode::FunctionCall) + { + if (!mNSEntry) + mNSEntry = Namespace::global()->lookup(fnName); + } + else if (callType == FuncCallExprNode::MethodCall) + { + mSaveObject = gEvalState.thisObject; + gEvalState.thisObject = Sim::findObject((const char*)mCallArgv[1]); + if (!gEvalState.thisObject) + { + // Go back to the previous saved object. + gEvalState.thisObject = mSaveObject; + + Con::warnf(ConsoleLogEntry::General, "%s: Unable to find object: '%s' attempting to call function '%s'", mCodeBlock->getFileLine(ip - 4), (const char*)mCallArgv[1], fnName); + STR.popFrame(); + CSTK.popFrame(); + STR.setStringValue(""); + return OPCodeReturn::success; + } + + bool handlesMethod = gEvalState.thisObject->handlesConsoleMethod(fnName, &routingId); + if (handlesMethod && routingId == MethodOnComponent) + { + ICallMethod *pComponent = dynamic_cast(gEvalState.thisObject); + if (pComponent) + componentReturnValue = pComponent->callMethodArgList(mCallArgc, mCallArgv, false); + } + + ns = gEvalState.thisObject->getNamespace(); + if (ns) + mNSEntry = ns->lookup(fnName); + else + mNSEntry = NULL; + } + else // it's a ParentCall + { + if (mExec.thisNamespace) + { + ns = mExec.thisNamespace->mParent; + if (ns) + mNSEntry = ns->lookup(fnName); + else + mNSEntry = NULL; + } + else + { + ns = NULL; + mNSEntry = NULL; + } + } + + Namespace::Entry::CallbackUnion * nsCb = NULL; + const char * nsUsage = NULL; + if (mNSEntry) + { + nsCb = &mNSEntry->cb; + nsUsage = mNSEntry->mUsage; + routingId = 0; + } + if (!mNSEntry || mExec.noCalls) + { + if (!mExec.noCalls && !(routingId == MethodOnComponent)) + { + Con::warnf(ConsoleLogEntry::General, "%s: Unknown command %s.", mCodeBlock->getFileLine(ip - 6), fnName); + if (callType == FuncCallExprNode::MethodCall) + { + Con::warnf(ConsoleLogEntry::General, " Object %s(%d) %s", + gEvalState.thisObject->getName() ? gEvalState.thisObject->getName() : "", + gEvalState.thisObject->getId(), Con::getNamespaceList(ns)); + } + } + STR.popFrame(); + CSTK.popFrame(); + + if (routingId == MethodOnComponent) + STR.setStringValue(componentReturnValue); + else + STR.setStringValue(""); + return OPCodeReturn::success; + } + + // ConsoleFunctionType is for any function defined by script. + // Any 'callback' type is an engine function that is exposed to script. + if (mNSEntry->mType == Namespace::Entry::ConsoleFunctionType) + { + ConsoleValueRef ret; + if (mNSEntry->mFunctionOffset) + ret = mNSEntry->mCode->exec(mNSEntry->mFunctionOffset, fnName, mNSEntry->mNamespace, mCallArgc, mCallArgv, false, mNSEntry->mPackage); + + STR.popFrame(); + // Functions are assumed to return strings, so look ahead to see if we can skip the conversion + if (code[ip] == OP_STR_TO_UINT) + { + ip++; + intStack[++_UINT] = (U32)((S32)ret); + } + else if (code[ip] == OP_STR_TO_FLT) + { + ip++; + floatStack[++_FLT] = (F32)ret; + } + else if (code[ip] == OP_STR_TO_NONE) + { + STR.setStringValue(ret.getStringValue()); + ip++; + } + else + STR.setStringValue((const char*)ret); + + // This will clear everything including returnValue + CSTK.popFrame(); + //STR.clearFunctionOffset(); + } + else + { + const char* nsName = ns ? ns->mName : ""; +#ifndef TORQUE_DEBUG + // [tom, 12/13/2006] This stops tools functions from working in the console, + // which is useful behavior when debugging so I'm ifdefing this out for debug builds. + if (mNSEntry->mToolOnly && !Con::isCurrentScriptToolScript()) + { + Con::errorf(ConsoleLogEntry::Script, "%s: %s::%s - attempting to call tools only function from outside of tools.", mCodeBlock->getFileLine(ip - 6), nsName, fnName); + } + else +#endif + if ((mNSEntry->mMinArgs && S32(mCallArgc) < mNSEntry->mMinArgs) || (mNSEntry->mMaxArgs && S32(mCallArgc) > mNSEntry->mMaxArgs)) + { + Con::warnf(ConsoleLogEntry::Script, "%s: %s::%s - wrong number of arguments (got %i, expected min %i and max %i).", + mCodeBlock->getFileLine(ip - 6), nsName, fnName, + mCallArgc, mNSEntry->mMinArgs, mNSEntry->mMaxArgs); + Con::warnf(ConsoleLogEntry::Script, "%s: usage: %s", mCodeBlock->getFileLine(ip - 6), mNSEntry->mUsage); + STR.popFrame(); + CSTK.popFrame(); + } + else + { + switch (mNSEntry->mType) + { + case Namespace::Entry::StringCallbackType: + { + const char *ret = mNSEntry->cb.mStringCallbackFunc(gEvalState.thisObject, mCallArgc, mCallArgv); + STR.popFrame(); + CSTK.popFrame(); + if (ret != STR.getStringValue()) + STR.setStringValue(ret); + //else + // sSTR.setLen(dStrlen(ret)); + break; + } + case Namespace::Entry::IntCallbackType: + { + S32 result = mNSEntry->cb.mIntCallbackFunc(gEvalState.thisObject, mCallArgc, mCallArgv); + STR.popFrame(); + CSTK.popFrame(); + if (code[ip] == OP_STR_TO_UINT) + { + ip++; + intStack[++_UINT] = result; + break; + } + else if (code[ip] == OP_STR_TO_FLT) + { + ip++; + floatStack[++_FLT] = result; + break; + } + else if (code[ip] == OP_STR_TO_NONE) + ip++; + else + STR.setIntValue(result); + break; + } + case Namespace::Entry::FloatCallbackType: + { + F64 result = mNSEntry->cb.mFloatCallbackFunc(gEvalState.thisObject, mCallArgc, mCallArgv); + STR.popFrame(); + CSTK.popFrame(); + if (code[ip] == OP_STR_TO_UINT) + { + ip++; + intStack[++_UINT] = (S64)result; + break; + } + else if (code[ip] == OP_STR_TO_FLT) + { + ip++; + floatStack[++_FLT] = result; + break; + } + else if (code[ip] == OP_STR_TO_NONE) + ip++; + else + STR.setFloatValue(result); + break; + } + case Namespace::Entry::VoidCallbackType: + mNSEntry->cb.mVoidCallbackFunc(gEvalState.thisObject, mCallArgc, mCallArgv); + if (code[ip] != OP_STR_TO_NONE && Con::getBoolVariable("$Con::warnVoidAssignment", true)) + Con::warnf(ConsoleLogEntry::General, "%s: Call to %s in %s uses result of void function call.", mCodeBlock->getFileLine(ip - 6), fnName, mExec.functionName); + + STR.popFrame(); + CSTK.popFrame(); + STR.setStringValue(""); + break; + case Namespace::Entry::BoolCallbackType: + { + bool result = mNSEntry->cb.mBoolCallbackFunc(gEvalState.thisObject, mCallArgc, mCallArgv); + STR.popFrame(); + CSTK.popFrame(); + if (code[ip] == OP_STR_TO_UINT) + { + ip++; + intStack[++_UINT] = result; + break; + } + else if (code[ip] == OP_STR_TO_FLT) + { + ip++; + floatStack[++_FLT] = result; + break; + } + else if (code[ip] == OP_STR_TO_NONE) + ip++; + else + STR.setIntValue(result); + break; + } + } + } + } + + if (callType == FuncCallExprNode::MethodCall) + gEvalState.thisObject = mSaveObject; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_callfunc_pointer(U32 &ip) +{ + // get function name. This is the 'function pointer'. + StringTableEntry fnName = StringTable->insert(STR.getStringValue()); + + U32 *code = mCodeBlock->code; + + mNSEntry = Namespace::global()->lookup(fnName); + + //if this is called from inside a function, append the ip and codeptr + if (gEvalState.getStackDepth() > 0) + { + gEvalState.getCurrentFrame().code = mCodeBlock; + gEvalState.getCurrentFrame().ip = ip - 1; + } + + CSTK.getArgcArgv(fnName, &mCallArgc, &mCallArgv); + + + if (!mNSEntry || mExec.noCalls) + { + if (!mExec.noCalls) + { + Con::warnf(ConsoleLogEntry::General, "%s: Unknown command %s.", mCodeBlock->getFileLine(ip - 6), fnName); + } + STR.popFrame(); + CSTK.popFrame(); + + STR.setStringValue(""); + return OPCodeReturn::success; + } + + // ConsoleFunctionType is for any function defined by script. + // Any 'callback' type is an engine function that is exposed to script. + if (mNSEntry->mType == Namespace::Entry::ConsoleFunctionType) + { + ConsoleValueRef ret; + if (mNSEntry->mFunctionOffset) + ret = mNSEntry->mCode->exec(mNSEntry->mFunctionOffset, fnName, mNSEntry->mNamespace, mCallArgc, mCallArgv, false, mNSEntry->mPackage); + + STR.popFrame(); + // Functions are assumed to return strings, so look ahead to see if we can skip the conversion + if (code[ip] == OP_STR_TO_UINT) + { + ip++; + intStack[++_UINT] = (U32)((S32)ret); + } + else if (code[ip] == OP_STR_TO_FLT) + { + ip++; + floatStack[++_FLT] = (F32)ret; + } + else if (code[ip] == OP_STR_TO_NONE) + { + STR.setStringValue(ret.getStringValue()); + ip++; + } + else + STR.setStringValue((const char*)ret); + + // This will clear everything including returnValue + CSTK.popFrame(); + //STR.clearFunctionOffset(); + } + else + { + const char* nsName = ""; + + Namespace::Entry::CallbackUnion * nsCb = &mNSEntry->cb; + const char * nsUsage = mNSEntry->mUsage; + +#ifndef TORQUE_DEBUG + // [tom, 12/13/2006] This stops tools functions from working in the console, + // which is useful behavior when debugging so I'm ifdefing this out for debug builds. + if (mNSEntry->mToolOnly && !Con::isCurrentScriptToolScript()) + { + Con::errorf(ConsoleLogEntry::Script, "%s: %s::%s - attempting to call tools only function from outside of tools.", mCodeBlock->getFileLine(ip - 6), nsName, fnName); + } + else +#endif + if ((mNSEntry->mMinArgs && S32(mCallArgc) < mNSEntry->mMinArgs) || (mNSEntry->mMaxArgs && S32(mCallArgc) > mNSEntry->mMaxArgs)) + { + Con::warnf(ConsoleLogEntry::Script, "%s: %s::%s - wrong number of arguments (got %i, expected min %i and max %i).", + mCodeBlock->getFileLine(ip - 6), nsName, fnName, + mCallArgc, mNSEntry->mMinArgs, mNSEntry->mMaxArgs); + Con::warnf(ConsoleLogEntry::Script, "%s: usage: %s", mCodeBlock->getFileLine(ip - 6), mNSEntry->mUsage); + STR.popFrame(); + CSTK.popFrame(); + } + else + { + switch (mNSEntry->mType) + { + case Namespace::Entry::StringCallbackType: + { + const char *ret = mNSEntry->cb.mStringCallbackFunc(gEvalState.thisObject, mCallArgc, mCallArgv); + STR.popFrame(); + CSTK.popFrame(); + if (ret != STR.getStringValue()) + STR.setStringValue(ret); + //else + // sSTR.setLen(dStrlen(ret)); + break; + } + case Namespace::Entry::IntCallbackType: + { + S32 result = mNSEntry->cb.mIntCallbackFunc(gEvalState.thisObject, mCallArgc, mCallArgv); + STR.popFrame(); + CSTK.popFrame(); + if (code[ip] == OP_STR_TO_UINT) + { + ip++; + intStack[++_UINT] = result; + break; + } + else if (code[ip] == OP_STR_TO_FLT) + { + ip++; + floatStack[++_FLT] = result; + break; + } + else if (code[ip] == OP_STR_TO_NONE) + ip++; + else + STR.setIntValue(result); + break; + } + case Namespace::Entry::FloatCallbackType: + { + F64 result = mNSEntry->cb.mFloatCallbackFunc(gEvalState.thisObject, mCallArgc, mCallArgv); + STR.popFrame(); + CSTK.popFrame(); + if (code[ip] == OP_STR_TO_UINT) + { + ip++; + intStack[++_UINT] = (S64)result; + break; + } + else if (code[ip] == OP_STR_TO_FLT) + { + ip++; + floatStack[++_FLT] = result; + break; + } + else if (code[ip] == OP_STR_TO_NONE) + ip++; + else + STR.setFloatValue(result); + break; + } + case Namespace::Entry::VoidCallbackType: + mNSEntry->cb.mVoidCallbackFunc(gEvalState.thisObject, mCallArgc, mCallArgv); + if (code[ip] != OP_STR_TO_NONE && Con::getBoolVariable("$Con::warnVoidAssignment", true)) + Con::warnf(ConsoleLogEntry::General, "%s: Call to %s in %s uses result of void function call.", mCodeBlock->getFileLine(ip - 6), fnName, mExec.functionName); + + STR.popFrame(); + CSTK.popFrame(); + STR.setStringValue(""); + break; + case Namespace::Entry::BoolCallbackType: + { + bool result = mNSEntry->cb.mBoolCallbackFunc(gEvalState.thisObject, mCallArgc, mCallArgv); + STR.popFrame(); + CSTK.popFrame(); + if (code[ip] == OP_STR_TO_UINT) + { + ip++; + intStack[++_UINT] = result; + break; + } + else if (code[ip] == OP_STR_TO_FLT) + { + ip++; + floatStack[++_FLT] = result; + break; + } + else if (code[ip] == OP_STR_TO_NONE) + ip++; + else + STR.setIntValue(result); + break; + } + } + } + } + + + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_callfunc_this(U32 &ip) +{ + U32 *code = mCodeBlock->code; + + StringTableEntry fnName = CodeToSTE(code, ip); + + //if this is called from inside a function, append the ip and codeptr + if (gEvalState.getStackDepth() > 0) + { + gEvalState.getCurrentFrame().code = mCodeBlock; + gEvalState.getCurrentFrame().ip = ip - 1; + } + + ip += 2; + CSTK.getArgcArgv(fnName, &mCallArgc, &mCallArgv); + + Namespace *ns = mThisObject->getNamespace(); + if (ns) + mNSEntry = ns->lookup(fnName); + else + mNSEntry = NULL; + + if (!mNSEntry || mExec.noCalls) + { + if (!mExec.noCalls) + { + Con::warnf(ConsoleLogEntry::General, "%s: Unknown command %s.", mCodeBlock->getFileLine(ip - 6), fnName); + Con::warnf(ConsoleLogEntry::General, " Object %s(%d) %s", + mThisObject->getName() ? mThisObject->getName() : "", + mThisObject->getId(), Con::getNamespaceList(ns)); + } + STR.popFrame(); + CSTK.popFrame(); + + STR.setStringValue(""); + return OPCodeReturn::success; + } + + // ConsoleFunctionType is for any function defined by script. + // Any 'callback' type is an engine function that is exposed to script. + if (mNSEntry->mType == Namespace::Entry::ConsoleFunctionType) + { + ConsoleValueRef ret; + if (mNSEntry->mFunctionOffset) + ret = mNSEntry->mCode->exec(mNSEntry->mFunctionOffset, fnName, mNSEntry->mNamespace, mCallArgc, mCallArgv, false, mNSEntry->mPackage); + + STR.popFrame(); + // Functions are assumed to return strings, so look ahead to see if we can skip the conversion + if (code[ip] == OP_STR_TO_UINT) + { + ip++; + intStack[++_UINT] = (U32)((S32)ret); + } + else if (code[ip] == OP_STR_TO_FLT) + { + ip++; + floatStack[++_FLT] = (F32)ret; + } + else if (code[ip] == OP_STR_TO_NONE) + { + STR.setStringValue(ret.getStringValue()); + ip++; + } + else + STR.setStringValue((const char*)ret); + + // This will clear everything including returnValue + CSTK.popFrame(); + //STR.clearFunctionOffset(); + } + else + { + Namespace::Entry::CallbackUnion * nsCb = &mNSEntry->cb; + const char * nsUsage = mNSEntry->mUsage; + const char* nsName = ns ? ns->mName : ""; +#ifndef TORQUE_DEBUG + // [tom, 12/13/2006] This stops tools functions from working in the console, + // which is useful behavior when debugging so I'm ifdefing this out for debug builds. + if (mNSEntry->mToolOnly && !Con::isCurrentScriptToolScript()) + { + Con::errorf(ConsoleLogEntry::Script, "%s: %s::%s - attempting to call tools only function from outside of tools.", mCodeBlock->getFileLine(ip - 6), nsName, fnName); + } + else +#endif + if ((mNSEntry->mMinArgs && S32(mCallArgc) < mNSEntry->mMinArgs) || (mNSEntry->mMaxArgs && S32(mCallArgc) > mNSEntry->mMaxArgs)) + { + Con::warnf(ConsoleLogEntry::Script, "%s: %s::%s - wrong number of arguments (got %i, expected min %i and max %i).", + mCodeBlock->getFileLine(ip - 6), nsName, fnName, + mCallArgc, mNSEntry->mMinArgs, mNSEntry->mMaxArgs); + Con::warnf(ConsoleLogEntry::Script, "%s: usage: %s", mCodeBlock->getFileLine(ip - 6), mNSEntry->mUsage); + STR.popFrame(); + CSTK.popFrame(); + } + else + { + switch (mNSEntry->mType) + { + case Namespace::Entry::StringCallbackType: + { + const char *ret = mNSEntry->cb.mStringCallbackFunc(mThisObject, mCallArgc, mCallArgv); + STR.popFrame(); + CSTK.popFrame(); + if (ret != STR.getStringValue()) + STR.setStringValue(ret); + //else + // sSTR.setLen(dStrlen(ret)); + break; + } + case Namespace::Entry::IntCallbackType: + { + S32 result = mNSEntry->cb.mIntCallbackFunc(mThisObject, mCallArgc, mCallArgv); + STR.popFrame(); + CSTK.popFrame(); + if (code[ip] == OP_STR_TO_UINT) + { + ip++; + intStack[++_UINT] = result; + break; + } + else if (code[ip] == OP_STR_TO_FLT) + { + ip++; + floatStack[++_FLT] = result; + break; + } + else if (code[ip] == OP_STR_TO_NONE) + ip++; + else + STR.setIntValue(result); + break; + } + case Namespace::Entry::FloatCallbackType: + { + F64 result = mNSEntry->cb.mFloatCallbackFunc(mThisObject, mCallArgc, mCallArgv); + STR.popFrame(); + CSTK.popFrame(); + if (code[ip] == OP_STR_TO_UINT) + { + ip++; + intStack[++_UINT] = (S64)result; + break; + } + else if (code[ip] == OP_STR_TO_FLT) + { + ip++; + floatStack[++_FLT] = result; + break; + } + else if (code[ip] == OP_STR_TO_NONE) + ip++; + else + STR.setFloatValue(result); + break; + } + case Namespace::Entry::VoidCallbackType: + mNSEntry->cb.mVoidCallbackFunc(mThisObject, mCallArgc, mCallArgv); + if (code[ip] != OP_STR_TO_NONE && Con::getBoolVariable("$Con::warnVoidAssignment", true)) + Con::warnf(ConsoleLogEntry::General, "%s: Call to %s in %s uses result of void function call.", mCodeBlock->getFileLine(ip - 6), fnName, mExec.functionName); + + STR.popFrame(); + CSTK.popFrame(); + STR.setStringValue(""); + break; + case Namespace::Entry::BoolCallbackType: + { + bool result = mNSEntry->cb.mBoolCallbackFunc(mThisObject, mCallArgc, mCallArgv); + STR.popFrame(); + CSTK.popFrame(); + if (code[ip] == OP_STR_TO_UINT) + { + ip++; + intStack[++_UINT] = result; + break; + } + else if (code[ip] == OP_STR_TO_FLT) + { + ip++; + floatStack[++_FLT] = result; + break; + } + else if (code[ip] == OP_STR_TO_NONE) + ip++; + else + STR.setIntValue(result); + break; + } + } + } + } + + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_advance_str(U32 &ip) +{ + STR.advance(); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_advance_str_appendchar(U32 &ip) +{ + STR.advanceChar(mCodeBlock->code[ip++]); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_advance_str_comma(U32 &ip) +{ + STR.advanceChar('_'); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_advance_str_nul(U32 &ip) +{ + STR.advanceChar(0); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_rewind_str(U32 &ip) +{ + STR.rewind(); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_terminate_rewind_str(U32 &ip) +{ + STR.rewindTerminate(); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_compare_str(U32 &ip) +{ + intStack[++_UINT] = STR.compare(); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_push(U32 &ip) +{ + STR.push(); + CSTK.pushStringStackPtr(STR.getPreviousStringValuePtr()); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_push_uint(U32 &ip) +{ + CSTK.pushUINT(intStack[_UINT]); + _UINT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_push_flt(U32 &ip) +{ + CSTK.pushFLT(floatStack[_FLT]); + _FLT--; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_push_var(U32 &ip) +{ + if (gEvalState.currentVariable) + CSTK.pushValue(gEvalState.currentVariable->value); + else + CSTK.pushString(""); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_push_this(U32 &ip) +{ + StringTableEntry varName = CodeToSTE(mCodeBlock->code, ip); + ip += 2; + + // shorthand OP_SETCURVAR + + // If a variable is set, then these must be NULL. It is necessary + // to set this here so that the vector parser can appropriately + // identify whether it's dealing with a vector. + mPrevField = NULL; + mPrevObject = NULL; + mCurObject = NULL; + + gEvalState.setCurVarName(varName); + + // In order to let docblocks work properly with variables, we have + // clear the current docblock when we do an assign. This way it + // won't inappropriately carry forward to following function decls. + mCurFNDocBlock = NULL; + mCurNSDocBlock = NULL; + + // shorthand OP_LOADVAR_STR (since objs can be by name we can't assume uint) + STR.setStringValue(gEvalState.getStringVariable()); + + // shorthand OP_PUSH + STR.push(); + CSTK.pushStringStackPtr(STR.getPreviousStringValuePtr()); + + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_push_frame(U32 &ip) +{ + STR.pushFrame(); + CSTK.pushFrame(); + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_assert(U32 &ip) +{ + if (!intStack[_UINT--]) + { + const char *message = mCurStringTable + mCodeBlock->code[ip]; + + U32 breakLine, inst; + mCodeBlock->findBreakLine(ip - 1, breakLine, inst); + + if (PlatformAssert::processAssert(PlatformAssert::Fatal, + mCodeBlock->name ? mCodeBlock->name : "eval", + breakLine, + message)) + { + if (TelDebugger && TelDebugger->isConnected() && breakLine > 0) + { + TelDebugger->breakProcess(); + } + else + Platform::debugBreak(); + } + } + + ip++; + + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_break(U32 &ip) +{ + //append the ip and codeptr before managing the breakpoint! + AssertFatal(gEvalState.getStackDepth() > 0, "Empty eval stack on break!"); + gEvalState.getCurrentFrame().code = mCodeBlock; + gEvalState.getCurrentFrame().ip = ip - 1; + + U32 breakLine; + mCodeBlock->findBreakLine(ip - 1, breakLine, mCurrentInstruction); + if (!breakLine) + return OPCodeReturn::breakContinue; + TelDebugger->executionStopped(mCodeBlock, breakLine); + return OPCodeReturn::breakContinue; +} + +OPCodeReturn CodeInterpreter::op_iter_begin_str(U32 &ip) +{ + iterStack[_ITER].mIsStringIter = true; + + // Emulate fallthrough: + OPCodeReturn fallthrough = op_iter_begin(ip); + + return fallthrough; +} + +OPCodeReturn CodeInterpreter::op_iter_begin(U32 &ip) +{ + StringTableEntry varName = CodeToSTE(mCodeBlock->code, ip); + U32 failIp = mCodeBlock->code[ip + 2]; + + IterStackRecord& iter = iterStack[_ITER]; + + iter.mVariable = gEvalState.getCurrentFrame().add(varName); + + if (iter.mIsStringIter) + { + iter.mData.mStr.mString = STR.getStringValuePtr(); + iter.mData.mStr.mIndex = 0; + } + else + { + // Look up the object. + + SimSet* set; + if (!Sim::findObject(STR.getStringValue(), set)) + { + Con::errorf(ConsoleLogEntry::General, "No SimSet object '%s'", STR.getStringValue()); + Con::errorf(ConsoleLogEntry::General, "Did you mean to use 'foreach$' instead of 'foreach'?"); + ip = failIp; + return OPCodeReturn::success; + } + + // Set up. + + iter.mData.mObj.mSet = set; + iter.mData.mObj.mIndex = 0; + } + + _ITER++; + mIterDepth++; + + STR.push(); + + ip += 3; + + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_iter(U32 &ip) +{ + U32 breakIp = mCodeBlock->code[ip]; + IterStackRecord& iter = iterStack[_ITER - 1]; + + if (iter.mIsStringIter) + { + const char* str = StringStackPtrRef(iter.mData.mStr.mString).getPtr(&STR); + + U32 startIndex = iter.mData.mStr.mIndex; + U32 endIndex = startIndex; + + // Break if at end. + + if (!str[startIndex]) + { + ip = breakIp; + return OPCodeReturn::success; // continue in old interpreter + } + + // Find right end of current component. + + if (!dIsspace(str[endIndex])) + do ++endIndex; + while (str[endIndex] && !dIsspace(str[endIndex])); + + // Extract component. + + if (endIndex != startIndex) + { + char savedChar = str[endIndex]; + const_cast< char* >(str)[endIndex] = '\0'; // We are on the string stack so this is okay. + iter.mVariable->setStringValue(&str[startIndex]); + const_cast< char* >(str)[endIndex] = savedChar; + } + else + iter.mVariable->setStringValue(""); + + // Skip separator. + if (str[endIndex] != '\0') + ++endIndex; + + iter.mData.mStr.mIndex = endIndex; + } + else + { + U32 index = iter.mData.mObj.mIndex; + SimSet* set = iter.mData.mObj.mSet; + + if (index >= set->size()) + { + ip = breakIp; + return OPCodeReturn::success; // continue in old interpreter + } + + iter.mVariable->setIntValue(set->at(index)->getId()); + iter.mData.mObj.mIndex = index + 1; + } + + ++ip; + + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_iter_end(U32 &ip) +{ + --_ITER; + --mIterDepth; + STR.rewind(); + iterStack[_ITER].mIsStringIter = false; + return OPCodeReturn::success; +} + +OPCodeReturn CodeInterpreter::op_invalid(U32 &ip) +{ + // Invalid does nothing. + return OPCodeReturn::exitCode; +} diff --git a/Engine/source/console/codeInterpreter.h b/Engine/source/console/codeInterpreter.h new file mode 100644 index 000000000..133222726 --- /dev/null +++ b/Engine/source/console/codeInterpreter.h @@ -0,0 +1,262 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef _CODEINTERPRETER_H_ +#define _CODEINTERPRETER_H_ + +#include "console/codeBlock.h" +#include "console/console.h" +#include "console/consoleInternal.h" + +/// Frame data for a foreach/foreach$ loop. +struct IterStackRecord +{ + /// If true, this is a foreach$ loop; if not, it's a foreach loop. + bool mIsStringIter; + + /// The iterator variable. + Dictionary::Entry* mVariable; + + /// Information for an object iterator loop. + struct ObjectPos + { + /// The set being iterated over. + SimSet* mSet; + + /// Current index in the set. + U32 mIndex; + }; + + /// Information for a string iterator loop. + struct StringPos + { + /// The raw string data on the string stack. + StringStackPtr mString; + + /// Current parsing position. + U32 mIndex; + }; + + union + { + ObjectPos mObj; + StringPos mStr; + } mData; +}; + +enum OPCodeReturn +{ + exitCode = -1, + success = 0, + breakContinue = 1 +}; + +class CodeInterpreter +{ +public: + CodeInterpreter(CodeBlock *cb); + ~CodeInterpreter(); + + ConsoleValueRef exec(U32 ip, + StringTableEntry functionName, + Namespace *thisNamespace, + U32 argc, + ConsoleValueRef *argv, + bool noCalls, + StringTableEntry packageName, + S32 setFrame); + + static void init(); + + // Methods +private: + void parseArgs(U32 &ip); + + /// Group op codes + /// @{ + + OPCodeReturn op_func_decl(U32 &ip); + OPCodeReturn op_create_object(U32 &ip); + OPCodeReturn op_add_object(U32 &ip); + OPCodeReturn op_end_object(U32 &ip); + OPCodeReturn op_finish_object(U32 &ip); + OPCodeReturn op_jmpiffnot(U32 &ip); + OPCodeReturn op_jmpifnot(U32 &ip); + OPCodeReturn op_jmpiff(U32 &ip); + OPCodeReturn op_jmpif(U32 &ip); + OPCodeReturn op_jmpifnot_np(U32 &ip); + OPCodeReturn op_jmpif_np(U32 &ip); + OPCodeReturn op_jmp(U32 &ip); + OPCodeReturn op_return_void(U32 &ip); + OPCodeReturn op_return(U32 &ip); + OPCodeReturn op_return_flt(U32 &ip); + OPCodeReturn op_return_uint(U32 &ip); + OPCodeReturn op_cmpeq(U32 &ip); + OPCodeReturn op_cmpgr(U32 &ip); + OPCodeReturn op_cmpge(U32 &ip); + OPCodeReturn op_cmplt(U32 &ip); + OPCodeReturn op_cmple(U32 &ip); + OPCodeReturn op_cmpne(U32 &ip); + OPCodeReturn op_xor(U32 &ip); + OPCodeReturn op_mod(U32 &ip); + OPCodeReturn op_bitand(U32 &ip); + OPCodeReturn op_bitor(U32 &ip); + OPCodeReturn op_not(U32 &ip); + OPCodeReturn op_notf(U32 &ip); + OPCodeReturn op_onescomplement(U32 &ip); + OPCodeReturn op_shr(U32 &ip); + OPCodeReturn op_shl(U32 &ip); + OPCodeReturn op_and(U32 &ip); + OPCodeReturn op_or(U32 &ip); + OPCodeReturn op_add(U32 &ip); + OPCodeReturn op_sub(U32 &ip); + OPCodeReturn op_mul(U32 &ip); + OPCodeReturn op_div(U32 &ip); + OPCodeReturn op_neg(U32 &ip); + OPCodeReturn op_inc(U32 &ip); + OPCodeReturn op_dec(U32 &ip); + OPCodeReturn op_setcurvar(U32 &ip); + OPCodeReturn op_setcurvar_create(U32 &ip); + OPCodeReturn op_setcurvar_array(U32 &ip); + OPCodeReturn op_setcurvar_array_varlookup(U32 &ip); + OPCodeReturn op_setcurvar_array_create(U32 &ip); + OPCodeReturn op_setcurvar_array_create_varlookup(U32 &ip); + OPCodeReturn op_loadvar_uint(U32 &ip); + OPCodeReturn op_loadvar_flt(U32 &ip); + OPCodeReturn op_loadvar_str(U32 &ip); + OPCodeReturn op_loadvar_var(U32 &ip); + OPCodeReturn op_savevar_uint(U32 &ip); + OPCodeReturn op_savevar_flt(U32 &ip); + OPCodeReturn op_savevar_str(U32 &ip); + OPCodeReturn op_savevar_var(U32 &ip); + OPCodeReturn op_setcurobject(U32 &ip); + OPCodeReturn op_setcurobject_internal(U32 &ip); + OPCodeReturn op_setcurobject_new(U32 &ip); + OPCodeReturn op_setcurfield(U32 &ip); + OPCodeReturn op_setcurfield_array(U32 &ip); + OPCodeReturn op_setcurfield_type(U32 &ip); + OPCodeReturn op_setcurfield_this(U32 &ip); + OPCodeReturn op_setcurfield_array_var(U32 &ip); + OPCodeReturn op_loadfield_uint(U32 &ip); + OPCodeReturn op_loadfield_flt(U32 &ip); + OPCodeReturn op_loadfield_str(U32 &ip); + OPCodeReturn op_savefield_uint(U32 &ip); + OPCodeReturn op_savefield_flt(U32 &ip); + OPCodeReturn op_savefield_str(U32 &ip); + OPCodeReturn op_str_to_uint(U32 &ip); + OPCodeReturn op_str_to_flt(U32 &ip); + OPCodeReturn op_str_to_none(U32 &ip); + OPCodeReturn op_flt_to_uint(U32 &ip); + OPCodeReturn op_flt_to_str(U32 &ip); + OPCodeReturn op_flt_to_none(U32 &ip); + OPCodeReturn op_uint_to_flt(U32 &ip); + OPCodeReturn op_uint_to_str(U32 &ip); + OPCodeReturn op_uint_to_none(U32 &ip); + OPCodeReturn op_copyvar_to_none(U32 &ip); + OPCodeReturn op_loadimmed_uint(U32 &ip); + OPCodeReturn op_loadimmed_flt(U32 &ip); + OPCodeReturn op_tag_to_str(U32 &ip); + OPCodeReturn op_loadimmed_str(U32 &ip); + OPCodeReturn op_docblock_str(U32 &ip); + OPCodeReturn op_loadimmed_ident(U32 &ip); + OPCodeReturn op_callfunc_resolve(U32 &ip); + OPCodeReturn op_callfunc(U32 &ip); + OPCodeReturn op_callfunc_pointer(U32 &ip); + OPCodeReturn op_callfunc_this(U32 &ip); + OPCodeReturn op_advance_str(U32 &ip); + OPCodeReturn op_advance_str_appendchar(U32 &ip); + OPCodeReturn op_advance_str_comma(U32 &ip); + OPCodeReturn op_advance_str_nul(U32 &ip); + OPCodeReturn op_rewind_str(U32 &ip); + OPCodeReturn op_terminate_rewind_str(U32 &ip); + OPCodeReturn op_compare_str(U32 &ip); + OPCodeReturn op_push(U32 &ip); + OPCodeReturn op_push_uint(U32 &ip); + OPCodeReturn op_push_flt(U32 &ip); + OPCodeReturn op_push_var(U32 &ip); + OPCodeReturn op_push_this(U32 &ip); + OPCodeReturn op_push_frame(U32 &ip); + OPCodeReturn op_assert(U32 &ip); + OPCodeReturn op_break(U32 &ip); + OPCodeReturn op_iter_begin_str(U32 &ip); + OPCodeReturn op_iter_begin(U32 &ip); + OPCodeReturn op_iter(U32 &ip); + OPCodeReturn op_iter_end(U32 &ip); + OPCodeReturn op_invalid(U32 &ip); + + /// @} + +private: + CodeBlock *mCodeBlock; + + /// Group exec arguments. + struct + { + StringTableEntry functionName; + Namespace *thisNamespace; + U32 argc; + ConsoleValueRef *argv; + bool noCalls; + StringTableEntry packageName; + S32 setFrame; + } mExec; + + U32 mIterDepth; + F64 *mCurFloatTable; + char *mCurStringTable; + StringTableEntry mThisFunctionName; + bool mPopFrame; + + // Add local object creation stack [7/9/2007 Black] + static const U32 objectCreationStackSize = 32; + U32 mObjectCreationStackIndex; + struct + { + SimObject *newObject; + U32 failJump; + } mObjectCreationStack[objectCreationStackSize]; + + SimObject *mCurrentNewObject; + U32 mFailJump; + StringTableEntry mPrevField; + StringTableEntry mCurField; + SimObject *mPrevObject; + SimObject *mCurObject; + SimObject *mSaveObject; + SimObject *mThisObject; + Namespace::Entry *mNSEntry; + StringTableEntry mCurFNDocBlock; + StringTableEntry mCurNSDocBlock; + U32 mCallArgc; + ConsoleValueRef *mCallArgv; + CodeBlock *mSaveCodeBlock; + + // note: anything returned is pushed to CSTK and will be invalidated on the next exec() + ConsoleValueRef mReturnValue; + + U32 mCurrentInstruction; + + static const S32 nsDocLength = 128; + char mNSDocBlockClass[nsDocLength]; +}; + +#endif \ No newline at end of file diff --git a/Engine/source/console/compiledEval.cpp b/Engine/source/console/compiledEval.cpp index 1d872df8a..dc6f8a5f5 100644 --- a/Engine/source/console/compiledEval.cpp +++ b/Engine/source/console/compiledEval.cpp @@ -20,11 +20,6 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// -// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames -// Copyright (C) 2015 Faust Logic, Inc. -//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// - #include "platform/platform.h" #include "console/console.h" @@ -45,95 +40,38 @@ #include "util/messaging/message.h" #include "core/frameAllocator.h" +#include "console/codeInterpreter.h" + #ifndef TORQUE_TGB_ONLY #include "materials/materialDefinition.h" #include "materials/materialManager.h" #endif -// Uncomment to optimize function calls at the expense of potential invalid package lookups -//#define COMPILER_OPTIMIZE_FUNCTION_CALLS - using namespace Compiler; -enum EvalConstants { - MaxStackSize = 1024, - MethodOnComponent = -2 -}; - namespace Con { -// Current script file name and root, these are registered as -// console variables. -extern StringTableEntry gCurrentFile; -extern StringTableEntry gCurrentRoot; -extern S32 gObjectCopyFailures; + // Current script file name and root, these are registered as + // console variables. + extern StringTableEntry gCurrentFile; + extern StringTableEntry gCurrentRoot; + extern S32 gObjectCopyFailures; } -/// Frame data for a foreach/foreach$ loop. -struct IterStackRecord -{ - /// If true, this is a foreach$ loop; if not, it's a foreach loop. - bool mIsStringIter; - - /// The iterator variable. - Dictionary::Entry* mVariable; - - /// Information for an object iterator loop. - struct ObjectPos - { - /// The set being iterated over. - SimSet* mSet; - - /// Current index in the set. - U32 mIndex; - }; - - /// Information for a string iterator loop. - struct StringPos - { - /// The raw string data on the string stack. - StringStackPtr mString; - - /// Current parsing position. - U32 mIndex; - }; - - union - { - ObjectPos mObj; - StringPos mStr; - } mData; -}; - -IterStackRecord iterStack[ MaxStackSize ]; - -F64 floatStack[MaxStackSize]; -S64 intStack[MaxStackSize]; - - - - -StringStack STR; -ConsoleValueStack CSTK; - -U32 _FLT = 0; ///< Stack pointer for floatStack. -U32 _UINT = 0; ///< Stack pointer for intStack. -U32 _ITER = 0; ///< Stack pointer for iterStack. - namespace Con { const char *getNamespaceList(Namespace *ns) { U32 size = 1; Namespace * walk; - for(walk = ns; walk; walk = walk->mParent) + for (walk = ns; walk; walk = walk->mParent) size += dStrlen(walk->mName) + 4; char *ret = Con::getReturnBuffer(size); ret[0] = 0; - for(walk = ns; walk; walk = walk->mParent) + for (walk = ns; walk; walk = walk->mParent) { dStrcat(ret, walk->mName); - if(walk->mParent) + if (walk->mParent) dStrcat(ret, " -> "); } return ret; @@ -145,13 +83,13 @@ namespace Con F64 consoleStringToNumber(const char *str, StringTableEntry file, U32 line) { F64 val = dAtof(str); - if(val != 0) + if (val != 0) return val; - else if(!dStricmp(str, "true")) + else if (!dStricmp(str, "true")) return 1; - else if(!dStricmp(str, "false")) + else if (!dStricmp(str, "false")) return 0; - else if(file) + else if (file) { Con::warnf(ConsoleLogEntry::General, "%s (%d): string always evaluates to 0.", file, line); return 0; @@ -170,28 +108,28 @@ namespace Con return STR.getReturnBuffer(bufferSize); } - char *getReturnBuffer( const char *stringToCopy ) + char *getReturnBuffer(const char *stringToCopy) { - U32 len = dStrlen( stringToCopy ) + 1; - char *ret = STR.getReturnBuffer( len); - dMemcpy( ret, stringToCopy, len ); + U32 len = dStrlen(stringToCopy) + 1; + char *ret = STR.getReturnBuffer(len); + dMemcpy(ret, stringToCopy, len); return ret; } - char* getReturnBuffer( const String& str ) + char* getReturnBuffer(const String& str) { const U32 size = str.size(); - char* ret = STR.getReturnBuffer( size ); - dMemcpy( ret, str.c_str(), size ); + char* ret = STR.getReturnBuffer(size); + dMemcpy(ret, str.c_str(), size); return ret; } - char* getReturnBuffer( const StringBuilder& str ) + char* getReturnBuffer(const StringBuilder& str) { - char* buffer = Con::getReturnBuffer( str.length() + 1 ); - str.copy( buffer ); - buffer[ str.length() ] = '\0'; - + char* buffer = Con::getReturnBuffer(str.length() + 1); + str.copy(buffer); + buffer[str.length()] = '\0'; + return buffer; } @@ -221,40 +159,40 @@ namespace Con return ret; } - char *getStringArg( const char *arg ) + char *getStringArg(const char *arg) { - U32 len = dStrlen( arg ) + 1; - char *ret = STR.getArgBuffer( len ); - dMemcpy( ret, arg, len ); + U32 len = dStrlen(arg) + 1; + char *ret = STR.getArgBuffer(len); + dMemcpy(ret, arg, len); return ret; } - char* getStringArg( const String& arg ) + char* getStringArg(const String& arg) { const U32 size = arg.size(); - char* ret = STR.getArgBuffer( size ); - dMemcpy( ret, arg.c_str(), size ); + char* ret = STR.getArgBuffer(size); + dMemcpy(ret, arg.c_str(), size); return ret; } } //------------------------------------------------------------ -inline void ExprEvalState::setCurVarName(StringTableEntry name) +void ExprEvalState::setCurVarName(StringTableEntry name) { - if(name[0] == '$') + if (name[0] == '$') currentVariable = globalVars.lookup(name); - else if( getStackDepth() > 0 ) + else if (getStackDepth() > 0) currentVariable = getCurrentFrame().lookup(name); - if(!currentVariable && gWarnUndefinedScriptVariables) + if (!currentVariable && gWarnUndefinedScriptVariables) Con::warnf(ConsoleLogEntry::Script, "Variable referenced before assignment: %s", name); } -inline void ExprEvalState::setCurVarNameCreate(StringTableEntry name) +void ExprEvalState::setCurVarNameCreate(StringTableEntry name) { - if(name[0] == '$') + if (name[0] == '$') currentVariable = globalVars.add(name); - else if( getStackDepth() > 0 ) + else if (getStackDepth() > 0) currentVariable = getCurrentFrame().add(name); else { @@ -265,48 +203,48 @@ inline void ExprEvalState::setCurVarNameCreate(StringTableEntry name) //------------------------------------------------------------ -inline S32 ExprEvalState::getIntVariable() +S32 ExprEvalState::getIntVariable() { return currentVariable ? currentVariable->getIntValue() : 0; } -inline F64 ExprEvalState::getFloatVariable() +F64 ExprEvalState::getFloatVariable() { return currentVariable ? currentVariable->getFloatValue() : 0; } -inline const char *ExprEvalState::getStringVariable() +const char *ExprEvalState::getStringVariable() { return currentVariable ? currentVariable->getStringValue() : ""; } //------------------------------------------------------------ -inline void ExprEvalState::setIntVariable(S32 val) +void ExprEvalState::setIntVariable(S32 val) { AssertFatal(currentVariable != NULL, "Invalid evaluator state - trying to set null variable!"); currentVariable->setIntValue(val); } -inline void ExprEvalState::setFloatVariable(F64 val) +void ExprEvalState::setFloatVariable(F64 val) { AssertFatal(currentVariable != NULL, "Invalid evaluator state - trying to set null variable!"); currentVariable->setFloatValue(val); } -inline void ExprEvalState::setStringVariable(const char *val) +void ExprEvalState::setStringVariable(const char *val) { AssertFatal(currentVariable != NULL, "Invalid evaluator state - trying to set null variable!"); currentVariable->setStringValue(val); } -inline void ExprEvalState::setStringStackPtrVariable(StringStackPtr str) +void ExprEvalState::setStringStackPtrVariable(StringStackPtr str) { AssertFatal(currentVariable != NULL, "Invalid evaluator state - trying to set null variable!"); currentVariable->setStringStackPtrValue(str); } -inline void ExprEvalState::setCopyVariable() +void ExprEvalState::setCopyVariable() { if (copyVariable) { @@ -314,2004 +252,24 @@ inline void ExprEvalState::setCopyVariable() { case ConsoleValue::TypeInternalInt: currentVariable->setIntValue(copyVariable->getIntValue()); - break; + break; case ConsoleValue::TypeInternalFloat: currentVariable->setFloatValue(copyVariable->getFloatValue()); - break; + break; default: currentVariable->setStringValue(copyVariable->getStringValue()); - break; + break; } } } //------------------------------------------------------------ -// Gets a component of an object's field value or a variable and returns it -// in val. -static void getFieldComponent( SimObject* object, StringTableEntry field, const char* array, StringTableEntry subField, char val[] ) -{ - const char* prevVal = NULL; - - // Grab value from object. - if( object && field ) - prevVal = object->getDataField( field, array ); - - // Otherwise, grab from the string stack. The value coming in will always - // be a string because that is how multicomponent variables are handled. - else - prevVal = STR.getStringValue(); - - // Make sure we got a value. - if ( prevVal && *prevVal ) - { - static const StringTableEntry xyzw[] = - { - StringTable->insert( "x" ), - StringTable->insert( "y" ), - StringTable->insert( "z" ), - StringTable->insert( "w" ) - }; - - static const StringTableEntry rgba[] = - { - StringTable->insert( "r" ), - StringTable->insert( "g" ), - StringTable->insert( "b" ), - StringTable->insert( "a" ) - }; - - // Translate xyzw and rgba into the indexed component - // of the variable or field. - if ( subField == xyzw[0] || subField == rgba[0] ) - dStrcpy( val, StringUnit::getUnit( prevVal, 0, " \t\n") ); - - else if ( subField == xyzw[1] || subField == rgba[1] ) - dStrcpy( val, StringUnit::getUnit( prevVal, 1, " \t\n") ); - - else if ( subField == xyzw[2] || subField == rgba[2] ) - dStrcpy( val, StringUnit::getUnit( prevVal, 2, " \t\n") ); - - else if ( subField == xyzw[3] || subField == rgba[3] ) - dStrcpy( val, StringUnit::getUnit( prevVal, 3, " \t\n") ); - - else - val[0] = 0; - } - else - val[0] = 0; -} - -// Sets a component of an object's field value based on the sub field. 'x' will -// set the first field, 'y' the second, and 'z' the third. -static void setFieldComponent( SimObject* object, StringTableEntry field, const char* array, StringTableEntry subField ) -{ - // Copy the current string value - char strValue[1024]; - dStrncpy( strValue, STR.getStringValue(), 1024 ); - - char val[1024] = ""; - const char* prevVal = NULL; - - // Set the value on an object field. - if( object && field ) - prevVal = object->getDataField( field, array ); - - // Set the value on a variable. - else if( gEvalState.currentVariable ) - prevVal = gEvalState.getStringVariable(); - - // Ensure that the variable has a value - if (!prevVal) - return; - - static const StringTableEntry xyzw[] = - { - StringTable->insert( "x" ), - StringTable->insert( "y" ), - StringTable->insert( "z" ), - StringTable->insert( "w" ) - }; - - static const StringTableEntry rgba[] = - { - StringTable->insert( "r" ), - StringTable->insert( "g" ), - StringTable->insert( "b" ), - StringTable->insert( "a" ) - }; - - // Insert the value into the specified - // component of the string. - if ( subField == xyzw[0] || subField == rgba[0] ) - dStrcpy( val, StringUnit::setUnit( prevVal, 0, strValue, " \t\n") ); - - else if ( subField == xyzw[1] || subField == rgba[1] ) - dStrcpy( val, StringUnit::setUnit( prevVal, 1, strValue, " \t\n") ); - - else if ( subField == xyzw[2] || subField == rgba[2] ) - dStrcpy( val, StringUnit::setUnit( prevVal, 2, strValue, " \t\n") ); - - else if ( subField == xyzw[3] || subField == rgba[3] ) - dStrcpy( val, StringUnit::setUnit( prevVal, 3, strValue, " \t\n") ); - - if ( val[0] != 0 ) - { - // Update the field or variable. - if( object && field ) - object->setDataField( field, 0, val ); - else if( gEvalState.currentVariable ) - gEvalState.setStringVariable( val ); - } -} ConsoleValueRef CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNamespace, U32 argc, ConsoleValueRef *argv, bool noCalls, StringTableEntry packageName, S32 setFrame) { - -#ifdef TORQUE_VALIDATE_STACK - U32 stackStart = STR.mStartStackSize; - U32 consoleStackStart = CSTK.mStackPos; -#endif - - //Con::printf("CodeBlock::exec(%s,%u)", functionName ? functionName : "??", ip); - - static char traceBuffer[1024]; - S32 i; - - U32 iterDepth = 0; - - incRefCount(); - F64 *curFloatTable; - char *curStringTable; - S32 curStringTableLen = 0; //clint to ensure we dont overwrite it - STR.clearFunctionOffset(); // ensures arg buffer offset is back to 0 - StringTableEntry thisFunctionName = NULL; - bool popFrame = false; - if(argv) - { - // assume this points into a function decl: - U32 fnArgc = code[ip + 2 + 6]; - thisFunctionName = CodeToSTE(code, ip); - S32 wantedArgc = getMin(argc-1, fnArgc); // argv[0] is func name - if(gEvalState.traceOn) - { - traceBuffer[0] = 0; - dStrcat(traceBuffer, "Entering "); - if(packageName) - { - dStrcat(traceBuffer, "["); - dStrcat(traceBuffer, packageName); - dStrcat(traceBuffer, "]"); - } - if(thisNamespace && thisNamespace->mName) - { - dSprintf(traceBuffer + dStrlen(traceBuffer), sizeof(traceBuffer) - dStrlen(traceBuffer), - "%s::%s(", thisNamespace->mName, thisFunctionName); - } - else - { - dSprintf(traceBuffer + dStrlen(traceBuffer), sizeof(traceBuffer) - dStrlen(traceBuffer), - "%s(", thisFunctionName); - } - for(i = 0; i < wantedArgc; i++) - { - dStrcat(traceBuffer, argv[i+1]); - if(i != wantedArgc - 1) - dStrcat(traceBuffer, ", "); - } - dStrcat(traceBuffer, ")"); - Con::printf("%s", traceBuffer); - } - gEvalState.pushFrame(thisFunctionName, thisNamespace); - popFrame = true; - - for(i = 0; i < wantedArgc; i++) - { - StringTableEntry var = CodeToSTE(code, ip + (2 + 6 + 1) + (i * 2)); - gEvalState.setCurVarNameCreate(var); - - ConsoleValueRef ref = argv[i+1]; - - switch(argv[i+1].getType()) - { - case ConsoleValue::TypeInternalInt: - gEvalState.setIntVariable(argv[i+1]); - break; - case ConsoleValue::TypeInternalFloat: - gEvalState.setFloatVariable(argv[i+1]); - break; - case ConsoleValue::TypeInternalStringStackPtr: - gEvalState.setStringStackPtrVariable(argv[i+1].getStringStackPtrValue()); - break; - case ConsoleValue::TypeInternalStackString: - case ConsoleValue::TypeInternalString: - default: - gEvalState.setStringVariable(argv[i+1]); - break; - } - } - - ip = ip + (fnArgc * 2) + (2 + 6 + 1); - curFloatTable = functionFloats; - curStringTable = functionStrings; - curStringTableLen = functionStringsMaxLen; - } - else - { - curFloatTable = globalFloats; - curStringTable = globalStrings; - curStringTableLen = globalStringsMaxLen; - - // If requested stack frame isn't available, request a new one - // (this prevents assert failures when creating local - // variables without a stack frame) - if (gEvalState.getStackDepth() <= setFrame) - setFrame = -1; - - // Do we want this code to execute using a new stack frame? - if (setFrame < 0) - { - gEvalState.pushFrame(NULL, NULL); - popFrame = true; - } - else - { - // We want to copy a reference to an existing stack frame - // on to the top of the stack. Any change that occurs to - // the locals during this new frame will also occur in the - // original frame. - S32 stackIndex = gEvalState.getStackDepth() - setFrame - 1; - gEvalState.pushFrameRef( stackIndex ); - popFrame = true; - } - } - - // Grab the state of the telenet debugger here once - // so that the push and pop frames are always balanced. - const bool telDebuggerOn = TelDebugger && TelDebugger->isConnected(); - if ( telDebuggerOn && setFrame < 0 ) - TelDebugger->pushStackFrame(); - - StringTableEntry var, objParent; - StringTableEntry fnName; - StringTableEntry fnNamespace, fnPackage; - - // Add local object creation stack [7/9/2007 Black] - static const U32 objectCreationStackSize = 32; - U32 objectCreationStackIndex = 0; - struct { - SimObject *newObject; - U32 failJump; - } objectCreationStack[ objectCreationStackSize ]; - - SimObject *currentNewObject = 0; - U32 failJump = 0; - StringTableEntry prevField = NULL; - StringTableEntry curField = NULL; - SimObject *prevObject = NULL; - SimObject *curObject = NULL; - SimObject *saveObject=NULL; - Namespace::Entry *nsEntry; - Namespace *ns; - const char* curFNDocBlock = NULL; - const char* curNSDocBlock = NULL; - const S32 nsDocLength = 128; - char nsDocBlockClass[nsDocLength]; - - U32 callArgc; - ConsoleValueRef *callArgv; - - static char curFieldArray[256]; - static char prevFieldArray[256]; - - CodeBlock *saveCodeBlock = smCurrentCodeBlock; - smCurrentCodeBlock = this; - if(this->name) - { - Con::gCurrentFile = this->name; - Con::gCurrentRoot = this->modPath; - } - const char * val; - StringStackPtr retValue; - - // note: anything returned is pushed to CSTK and will be invalidated on the next exec() - ConsoleValueRef returnValue; - - // The frame temp is used by the variable accessor ops (OP_SAVEFIELD_* and - // OP_LOADFIELD_*) to store temporary values for the fields. - static S32 VAL_BUFFER_SIZE = 1024; - FrameTemp valBuffer( VAL_BUFFER_SIZE ); - - for(;;) - { - U32 instruction = code[ip++]; - nsEntry = NULL; -breakContinue: - switch(instruction) - { - case OP_FUNC_DECL: - if(!noCalls) - { - fnName = CodeToSTE(code, ip); - fnNamespace = CodeToSTE(code, ip+2); - fnPackage = CodeToSTE(code, ip+4); - bool hasBody = ( code[ ip + 6 ] & 0x01 ) != 0; - U32 lineNumber = code[ ip + 6 ] >> 1; - - Namespace::unlinkPackages(); - ns = Namespace::find(fnNamespace, fnPackage); - ns->addFunction(fnName, this, hasBody ? ip : 0, curFNDocBlock ? dStrdup( curFNDocBlock ) : NULL, lineNumber );// if no body, set the IP to 0 - if( curNSDocBlock ) - { - if( fnNamespace == StringTable->lookup( nsDocBlockClass ) ) - { - char *usageStr = dStrdup( curNSDocBlock ); - usageStr[dStrlen(usageStr)] = '\0'; - ns->mUsage = usageStr; - ns->mCleanUpUsage = true; - curNSDocBlock = NULL; - } - } - Namespace::relinkPackages(); - - // If we had a docblock, it's definitely not valid anymore, so clear it out. - curFNDocBlock = NULL; - - //Con::printf("Adding function %s::%s (%d)", fnNamespace, fnName, ip); - } - ip = code[ip + 7]; - break; - - case OP_CREATE_OBJECT: - { - // Read some useful info. - objParent = CodeToSTE(code, ip); - bool isDataBlock = code[ip + 2]; - bool isInternal = code[ip + 3]; - bool isSingleton = code[ip + 4]; - U32 lineNumber = code[ip + 5]; - failJump = code[ip + 6]; - - // If we don't allow calls, we certainly don't allow creating objects! - // Moved this to after failJump is set. Engine was crashing when - // noCalls = true and an object was being created at the beginning of - // a file. ADL. - if(noCalls) - { - ip = failJump; - break; - } - - // Push the old info to the stack - //Assert( objectCreationStackIndex < objectCreationStackSize ); - objectCreationStack[ objectCreationStackIndex ].newObject = currentNewObject; - objectCreationStack[ objectCreationStackIndex++ ].failJump = failJump; - - // Get the constructor information off the stack. - CSTK.getArgcArgv(NULL, &callArgc, &callArgv); - const char *objectName = callArgv[ 2 ]; - - // Con::printf("Creating object..."); - - // objectName = argv[1]... - currentNewObject = NULL; - - // Are we creating a datablock? If so, deal with case where we override - // an old one. - if(isDataBlock) - { - // Con::printf(" - is a datablock"); - - // Find the old one if any. - SimObject *db = Sim::getDataBlockGroup()->findObject( objectName ); - - // Make sure we're not changing types on ourselves... - if(db && dStricmp(db->getClassName(), callArgv[1])) - { - Con::errorf(ConsoleLogEntry::General, "%s: Cannot re-declare data block %s with a different class.", getFileLine(ip), objectName); - ip = failJump; - STR.popFrame(); - CSTK.popFrame(); - break; - } - - // If there was one, set the currentNewObject and move on. - if(db) - currentNewObject = db; - } - else if (!isInternal) - { - // IF we aren't looking at a local/internal object, then check if - // this object already exists in the global space - - AbstractClassRep* rep = AbstractClassRep::findClassRep( objectName ); - if (rep != NULL) { - Con::errorf(ConsoleLogEntry::General, "%s: Cannot name object [%s] the same name as a script class.", - getFileLine(ip), objectName); - ip = failJump; - STR.popFrame(); - break; - } - - SimObject *obj = Sim::findObject( (const char*)objectName ); - if (obj /*&& !obj->isLocalName()*/) - { - if ( isSingleton ) - { - // Make sure we're not trying to change types - if ( dStricmp( obj->getClassName(), (const char*)callArgv[1] ) != 0 ) - { - Con::errorf(ConsoleLogEntry::General, "%s: Cannot re-declare object [%s] with a different class [%s] - was [%s].", - getFileLine(ip), objectName, (const char*)callArgv[1], obj->getClassName()); - ip = failJump; - STR.popFrame(); - CSTK.popFrame(); - break; - } - - // We're creating a singleton, so use the found object - // instead of creating a new object. - currentNewObject = obj; - } - else - { - const char* redefineBehavior = Con::getVariable( "$Con::redefineBehavior" ); - - if( dStricmp( redefineBehavior, "replaceExisting" ) == 0 ) - { - // Save our constructor args as the argv vector is stored on the - // string stack and may get stomped if deleteObject triggers - // script execution. - - ConsoleValueRef savedArgv[ StringStack::MaxArgs ]; - for (int i=0; ideleteObject(); - obj = NULL; - - // Prevent stack value corruption - CSTK.popFrame(); - STR.popFrame(); - // -- - - //dMemcpy( callArgv, savedArgv, sizeof( callArgv[ 0 ] ) * callArgc ); - for (int i=0; iinsert( newName ); - break; - } - } - } - else if( dStricmp( redefineBehavior, "unnameNew" ) == 0 ) - { - objectName = StringTable->insert( "" ); - } - else if( dStricmp( redefineBehavior, "postfixNew" ) == 0 ) - { - const char* postfix = Con::getVariable( "$Con::redefineBehaviorPostfix" ); - String newName = String::ToString( "%s%s", objectName, postfix ); - - if( Sim::findObject( newName ) ) - { - Con::errorf( ConsoleLogEntry::General, "%s: Cannot re-declare object with postfix [%s].", - getFileLine(ip), newName.c_str() ); - ip = failJump; - STR.popFrame(); - CSTK.popFrame(); - break; - } - else - objectName = StringTable->insert( newName ); - } - else - { - Con::errorf(ConsoleLogEntry::General, "%s: Cannot re-declare object [%s].", - getFileLine(ip), objectName); - ip = failJump; - STR.popFrame(); - CSTK.popFrame(); - break; - } - } - } - } - - STR.popFrame(); - CSTK.popFrame(); - - if(!currentNewObject) - { - // Well, looks like we have to create a new object. - ConsoleObject *object = ConsoleObject::create((const char*)callArgv[1]); - - // Deal with failure! - if(!object) - { - Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-conobject class %s.", getFileLine(ip), (const char*)callArgv[1]); - ip = failJump; - break; - } - - // Do special datablock init if appropros - if(isDataBlock) - { - SimDataBlock *dataBlock = dynamic_cast(object); - if(dataBlock) - { - dataBlock->assignId(); - } - else - { - // They tried to make a non-datablock with a datablock keyword! - Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-datablock class %s.", getFileLine(ip), (const char*)callArgv[1]); - // Clean up... - delete object; - currentNewObject = NULL; - ip = failJump; - break; - } - } - - // Finally, set currentNewObject to point to the new one. - currentNewObject = dynamic_cast(object); - - // Deal with the case of a non-SimObject. - if(!currentNewObject) - { - Con::errorf(ConsoleLogEntry::General, "%s: Unable to instantiate non-SimObject class %s.", getFileLine(ip), (const char*)callArgv[1]); - delete object; - currentNewObject = NULL; - ip = failJump; - break; - } - - // Set the declaration line - currentNewObject->setDeclarationLine(lineNumber); - - // Set the file that this object was created in - currentNewObject->setFilename(name); - - // Does it have a parent object? (ie, the copy constructor : syntax, not inheriance) - if(*objParent) - { - // Find it! - SimObject *parent; - if(Sim::findObject(objParent, parent)) - { - // Con::printf(" - Parent object found: %s", parent->getClassName()); - - currentNewObject->setCopySource( parent ); - currentNewObject->assignFieldsFrom( parent ); - // copy any substitution statements - SimDataBlock* parent_db = dynamic_cast(parent); - if (parent_db) - { - SimDataBlock* currentNewObject_db = dynamic_cast(currentNewObject); - if (currentNewObject_db) - currentNewObject_db->copySubstitutionsFrom(parent_db); - } - } - else - { - if ( Con::gObjectCopyFailures == -1 ) - Con::errorf(ConsoleLogEntry::General, "%s: Unable to find parent object %s for %s.", getFileLine(ip), objParent, (const char*)callArgv[1]); - else - ++Con::gObjectCopyFailures; - - // Fail to create the object. - delete object; - currentNewObject = NULL; - ip = failJump; - break; - } - } - - // If a name was passed, assign it. - if( objectName[ 0 ] ) - { - if( !isInternal ) - currentNewObject->assignName( objectName ); - else - currentNewObject->setInternalName( objectName ); - - // Set the original name - currentNewObject->setOriginalName( objectName ); - } - - // Prevent stack value corruption - CSTK.pushFrame(); - STR.pushFrame(); - // -- - - // Do the constructor parameters. - if(!currentNewObject->processArguments(callArgc-3, callArgv+3)) - { - delete currentNewObject; - currentNewObject = NULL; - ip = failJump; - - // Prevent stack value corruption - CSTK.popFrame(); - STR.popFrame(); - // -- - break; - } - - // Prevent stack value corruption - CSTK.popFrame(); - STR.popFrame(); - // -- - - // If it's not a datablock, allow people to modify bits of it. - if(!isDataBlock) - { - currentNewObject->setModStaticFields(true); - currentNewObject->setModDynamicFields(true); - } - } - else - { - currentNewObject->reloadReset(); // AFX (reload-reset) - // Does it have a parent object? (ie, the copy constructor : syntax, not inheriance) - if(*objParent) - { - // Find it! - SimObject *parent; - if(Sim::findObject(objParent, parent)) - { - // Con::printf(" - Parent object found: %s", parent->getClassName()); - - // temporarily block name change - SimObject::preventNameChanging = true; - currentNewObject->setCopySource( parent ); - currentNewObject->assignFieldsFrom(parent); - // restore name changing - SimObject::preventNameChanging = false; - - // copy any substitution statements - SimDataBlock* parent_db = dynamic_cast(parent); - if (parent_db) - { - SimDataBlock* currentNewObject_db = dynamic_cast(currentNewObject); - if (currentNewObject_db) - currentNewObject_db->copySubstitutionsFrom(parent_db); - } - } - else - Con::errorf(ConsoleLogEntry::General, "%d: Unable to find parent object %s for %s.", lineNumber, objParent, (const char*)callArgv[1]); - } - } - - // Advance the IP past the create info... - ip += 7; - break; - } - - case OP_ADD_OBJECT: - { - // See OP_SETCURVAR for why we do this. - curFNDocBlock = NULL; - curNSDocBlock = NULL; - - // Do we place this object at the root? - bool placeAtRoot = code[ip++]; - - // Con::printf("Adding object %s", currentNewObject->getName()); - - // Prevent stack value corruption - CSTK.pushFrame(); - STR.pushFrame(); - // -- - - // Make sure it wasn't already added, then add it. - if(currentNewObject->isProperlyAdded() == false) - { - bool ret = false; - - Message *msg = dynamic_cast(currentNewObject); - if(msg) - { - SimObjectId id = Message::getNextMessageID(); - if(id != 0xffffffff) - ret = currentNewObject->registerObject(id); - else - Con::errorf("%s: No more object IDs available for messages", getFileLine(ip)); - } - else - ret = currentNewObject->registerObject(); - - if(! ret) - { - // This error is usually caused by failing to call Parent::initPersistFields in the class' initPersistFields(). - Con::warnf(ConsoleLogEntry::General, "%s: Register object failed for object %s of class %s.", getFileLine(ip), currentNewObject->getName(), currentNewObject->getClassName()); - delete currentNewObject; - currentNewObject = NULL; - ip = failJump; - // Prevent stack value corruption - CSTK.popFrame(); - STR.popFrame(); - // -- - break; - } - } - - // Are we dealing with a datablock? - SimDataBlock *dataBlock = dynamic_cast(currentNewObject); - static String errorStr; - - - - // If so, preload it. - if(dataBlock && !dataBlock->preload(true, errorStr)) - { - Con::errorf(ConsoleLogEntry::General, "%s: preload failed for %s: %s.", getFileLine(ip), - currentNewObject->getName(), errorStr.c_str()); - dataBlock->deleteObject(); - currentNewObject = NULL; - ip = failJump; - - // Prevent stack value corruption - CSTK.popFrame(); - STR.popFrame(); - // -- - break; - } - - // What group will we be added to, if any? - U32 groupAddId = intStack[_UINT]; - SimGroup *grp = NULL; - SimSet *set = NULL; - bool isMessage = dynamic_cast(currentNewObject) != NULL; - - if(!placeAtRoot || !currentNewObject->getGroup()) - { - if(! isMessage) - { - if(! placeAtRoot) - { - // Otherwise just add to the requested group or set. - if(!Sim::findObject(groupAddId, grp)) - Sim::findObject(groupAddId, set); - } - - if(placeAtRoot) - { - // Deal with the instantGroup if we're being put at the root or we're adding to a component. - if( Con::gInstantGroup.isEmpty() - || !Sim::findObject( Con::gInstantGroup, grp ) ) - grp = Sim::getRootGroup(); - } - } - - // If we didn't get a group, then make sure we have a pointer to - // the rootgroup. - if(!grp) - grp = Sim::getRootGroup(); - - // add to the parent group - grp->addObject(currentNewObject); - - // If for some reason the add failed, add the object to the - // root group so it won't leak. - if( !currentNewObject->getGroup() ) - Sim::getRootGroup()->addObject( currentNewObject ); - - // add to any set we might be in - if(set) - set->addObject(currentNewObject); - } - - // store the new object's ID on the stack (overwriting the group/set - // id, if one was given, otherwise getting pushed) - if(placeAtRoot) - intStack[_UINT] = currentNewObject->getId(); - else - intStack[++_UINT] = currentNewObject->getId(); - - // Prevent stack value corruption - CSTK.popFrame(); - STR.popFrame(); - // -- - break; - } - - case OP_END_OBJECT: - { - // If we're not to be placed at the root, make sure we clean up - // our group reference. - bool placeAtRoot = code[ip++]; - if(!placeAtRoot) - _UINT--; - break; - } - - case OP_FINISH_OBJECT: - { - if (currentNewObject) - currentNewObject->onPostAdd(); - - //Assert( objectCreationStackIndex >= 0 ); - // Restore the object info from the stack [7/9/2007 Black] - currentNewObject = objectCreationStack[ --objectCreationStackIndex ].newObject; - failJump = objectCreationStack[ objectCreationStackIndex ].failJump; - break; - } - - case OP_JMPIFFNOT: - if(floatStack[_FLT--]) - { - ip++; - break; - } - ip = code[ip]; - break; - case OP_JMPIFNOT: - if(intStack[_UINT--]) - { - ip++; - break; - } - ip = code[ip]; - break; - case OP_JMPIFF: - if(!floatStack[_FLT--]) - { - ip++; - break; - } - ip = code[ip]; - break; - case OP_JMPIF: - if(!intStack[_UINT--]) - { - ip ++; - break; - } - ip = code[ip]; - break; - case OP_JMPIFNOT_NP: - if(intStack[_UINT]) - { - _UINT--; - ip++; - break; - } - ip = code[ip]; - break; - case OP_JMPIF_NP: - if(!intStack[_UINT]) - { - _UINT--; - ip++; - break; - } - ip = code[ip]; - break; - case OP_JMP: - ip = code[ip]; - break; - - // This fixes a bug when not explicitly returning a value. - case OP_RETURN_VOID: - STR.setStringValue(""); - // We're falling thru here on purpose. - - case OP_RETURN: - retValue = STR.getStringValuePtr(); - - if( iterDepth > 0 ) - { - // Clear iterator state. - while( iterDepth > 0 ) - { - iterStack[ -- _ITER ].mIsStringIter = false; - -- iterDepth; - } - - STR.rewind(); - STR.setStringValue( StringStackPtrRef(retValue).getPtr(&STR) ); // Not nice but works. - retValue = STR.getStringValuePtr(); - } - - // Previously the return value was on the stack and would be returned using STR.getStringValue(). - // Now though we need to wrap it in a ConsoleValueRef - returnValue.value = CSTK.pushStringStackPtr(retValue); - - goto execFinished; - - case OP_RETURN_FLT: - - if( iterDepth > 0 ) - { - // Clear iterator state. - while( iterDepth > 0 ) - { - iterStack[ -- _ITER ].mIsStringIter = false; - -- iterDepth; - } - - } - - returnValue.value = CSTK.pushFLT(floatStack[_FLT]); - _FLT--; - - goto execFinished; - - case OP_RETURN_UINT: - - if( iterDepth > 0 ) - { - // Clear iterator state. - while( iterDepth > 0 ) - { - iterStack[ -- _ITER ].mIsStringIter = false; - -- iterDepth; - } - } - - returnValue.value = CSTK.pushUINT(intStack[_UINT]); - _UINT--; - - goto execFinished; - - case OP_CMPEQ: - intStack[_UINT+1] = bool(floatStack[_FLT] == floatStack[_FLT-1]); - _UINT++; - _FLT -= 2; - break; - - case OP_CMPGR: - intStack[_UINT+1] = bool(floatStack[_FLT] > floatStack[_FLT-1]); - _UINT++; - _FLT -= 2; - break; - - case OP_CMPGE: - intStack[_UINT+1] = bool(floatStack[_FLT] >= floatStack[_FLT-1]); - _UINT++; - _FLT -= 2; - break; - - case OP_CMPLT: - intStack[_UINT+1] = bool(floatStack[_FLT] < floatStack[_FLT-1]); - _UINT++; - _FLT -= 2; - break; - - case OP_CMPLE: - intStack[_UINT+1] = bool(floatStack[_FLT] <= floatStack[_FLT-1]); - _UINT++; - _FLT -= 2; - break; - - case OP_CMPNE: - intStack[_UINT+1] = bool(floatStack[_FLT] != floatStack[_FLT-1]); - _UINT++; - _FLT -= 2; - break; - - case OP_XOR: - intStack[_UINT-1] = intStack[_UINT] ^ intStack[_UINT-1]; - _UINT--; - break; - - case OP_MOD: - if( intStack[_UINT-1] != 0 ) - intStack[_UINT-1] = intStack[_UINT] % intStack[_UINT-1]; - else - intStack[_UINT-1] = 0; - _UINT--; - break; - - case OP_BITAND: - intStack[_UINT-1] = intStack[_UINT] & intStack[_UINT-1]; - _UINT--; - break; - - case OP_BITOR: - intStack[_UINT-1] = intStack[_UINT] | intStack[_UINT-1]; - _UINT--; - break; - - case OP_NOT: - intStack[_UINT] = !intStack[_UINT]; - break; - - case OP_NOTF: - intStack[_UINT+1] = !floatStack[_FLT]; - _FLT--; - _UINT++; - break; - - case OP_ONESCOMPLEMENT: - intStack[_UINT] = ~intStack[_UINT]; - break; - - case OP_SHR: - intStack[_UINT-1] = intStack[_UINT] >> intStack[_UINT-1]; - _UINT--; - break; - - case OP_SHL: - intStack[_UINT-1] = intStack[_UINT] << intStack[_UINT-1]; - _UINT--; - break; - - case OP_AND: - intStack[_UINT-1] = intStack[_UINT] && intStack[_UINT-1]; - _UINT--; - break; - - case OP_OR: - intStack[_UINT-1] = intStack[_UINT] || intStack[_UINT-1]; - _UINT--; - break; - - case OP_ADD: - floatStack[_FLT-1] = floatStack[_FLT] + floatStack[_FLT-1]; - _FLT--; - break; - - case OP_SUB: - floatStack[_FLT-1] = floatStack[_FLT] - floatStack[_FLT-1]; - _FLT--; - break; - - case OP_MUL: - floatStack[_FLT-1] = floatStack[_FLT] * floatStack[_FLT-1]; - _FLT--; - break; - case OP_DIV: - floatStack[_FLT-1] = floatStack[_FLT] / floatStack[_FLT-1]; - _FLT--; - break; - case OP_NEG: - floatStack[_FLT] = -floatStack[_FLT]; - break; - - case OP_SETCURVAR: - var = CodeToSTE(code, ip); - ip += 2; - - // If a variable is set, then these must be NULL. It is necessary - // to set this here so that the vector parser can appropriately - // identify whether it's dealing with a vector. - prevField = NULL; - prevObject = NULL; - curObject = NULL; - - gEvalState.setCurVarName(var); - - // In order to let docblocks work properly with variables, we have - // clear the current docblock when we do an assign. This way it - // won't inappropriately carry forward to following function decls. - curFNDocBlock = NULL; - curNSDocBlock = NULL; - break; - - case OP_SETCURVAR_CREATE: - var = CodeToSTE(code, ip); - ip += 2; - - // See OP_SETCURVAR - prevField = NULL; - prevObject = NULL; - curObject = NULL; - - gEvalState.setCurVarNameCreate(var); - - // See OP_SETCURVAR for why we do this. - curFNDocBlock = NULL; - curNSDocBlock = NULL; - break; - - case OP_SETCURVAR_ARRAY: - var = STR.getSTValue(); - - // See OP_SETCURVAR - prevField = NULL; - prevObject = NULL; - curObject = NULL; - - gEvalState.setCurVarName(var); - - // See OP_SETCURVAR for why we do this. - curFNDocBlock = NULL; - curNSDocBlock = NULL; - break; - - case OP_SETCURVAR_ARRAY_CREATE: - var = STR.getSTValue(); - - // See OP_SETCURVAR - prevField = NULL; - prevObject = NULL; - curObject = NULL; - - gEvalState.setCurVarNameCreate(var); - - // See OP_SETCURVAR for why we do this. - curFNDocBlock = NULL; - curNSDocBlock = NULL; - break; - - case OP_LOADVAR_UINT: - intStack[_UINT+1] = gEvalState.getIntVariable(); - _UINT++; - break; - - case OP_LOADVAR_FLT: - floatStack[_FLT+1] = gEvalState.getFloatVariable(); - _FLT++; - break; - - case OP_LOADVAR_STR: - val = gEvalState.getStringVariable(); - STR.setStringValue(val); - break; - - case OP_LOADVAR_VAR: - // Sets current source of OP_SAVEVAR_VAR - gEvalState.copyVariable = gEvalState.currentVariable; - break; - - case OP_SAVEVAR_UINT: - gEvalState.setIntVariable(intStack[_UINT]); - break; - - case OP_SAVEVAR_FLT: - gEvalState.setFloatVariable(floatStack[_FLT]); - break; - - case OP_SAVEVAR_STR: - gEvalState.setStringVariable(STR.getStringValue()); - break; - - case OP_SAVEVAR_VAR: - // this basically handles %var1 = %var2 - gEvalState.setCopyVariable(); - break; - - case OP_SETCUROBJECT: - // Save the previous object for parsing vector fields. - prevObject = curObject; - val = STR.getStringValue(); - - // Sim::findObject will sometimes find valid objects from - // multi-component strings. This makes sure that doesn't - // happen. - for( const char* check = val; *check; check++ ) - { - if( *check == ' ' ) - { - val = ""; - break; - } - } - curObject = Sim::findObject(val); - break; - - case OP_SETCUROBJECT_INTERNAL: - ++ip; // To skip the recurse flag if the object wasn't found - if(curObject) - { - SimSet *set = dynamic_cast(curObject); - if(set) - { - StringTableEntry intName = StringTable->insert(STR.getStringValue()); - bool recurse = code[ip-1]; - SimObject *obj = set->findObjectByInternalName(intName, recurse); - intStack[_UINT+1] = obj ? obj->getId() : 0; - _UINT++; - } - else - { - Con::errorf(ConsoleLogEntry::Script, "%s: Attempt to use -> on non-set %s of class %s.", getFileLine(ip-2), curObject->getName(), curObject->getClassName()); - intStack[_UINT] = 0; - } - } - break; - - case OP_SETCUROBJECT_NEW: - curObject = currentNewObject; - break; - - case OP_SETCURFIELD: - // Save the previous field for parsing vector fields. - prevField = curField; - dStrcpy( prevFieldArray, curFieldArray ); - curField = CodeToSTE(code, ip); - curFieldArray[0] = 0; - ip += 2; - break; - - case OP_SETCURFIELD_ARRAY: - dStrcpy(curFieldArray, STR.getStringValue()); - break; - - case OP_SETCURFIELD_TYPE: - if(curObject) - curObject->setDataFieldType(code[ip], curField, curFieldArray); - ip++; - break; - - case OP_LOADFIELD_UINT: - if(curObject) - intStack[_UINT+1] = U32(dAtoi(curObject->getDataField(curField, curFieldArray))); - else - { - // The field is not being retrieved from an object. Maybe it's - // a special accessor? - getFieldComponent( prevObject, prevField, prevFieldArray, curField, valBuffer ); - intStack[_UINT+1] = dAtoi( valBuffer ); - } - _UINT++; - break; - - case OP_LOADFIELD_FLT: - if(curObject) - floatStack[_FLT+1] = dAtof(curObject->getDataField(curField, curFieldArray)); - else - { - // The field is not being retrieved from an object. Maybe it's - // a special accessor? - getFieldComponent( prevObject, prevField, prevFieldArray, curField, valBuffer ); - floatStack[_FLT+1] = dAtof( valBuffer ); - } - _FLT++; - break; - - case OP_LOADFIELD_STR: - if(curObject) - { - val = curObject->getDataField(curField, curFieldArray); - STR.setStringValue( val ); - } - else - { - // The field is not being retrieved from an object. Maybe it's - // a special accessor? - getFieldComponent( prevObject, prevField, prevFieldArray, curField, valBuffer ); - STR.setStringValue( valBuffer ); - } - break; - - case OP_SAVEFIELD_UINT: - STR.setIntValue(intStack[_UINT]); - if(curObject) - curObject->setDataField(curField, curFieldArray, STR.getStringValue()); - else - { - // The field is not being set on an object. Maybe it's - // a special accessor? - setFieldComponent( prevObject, prevField, prevFieldArray, curField ); - prevObject = NULL; - } - break; - - case OP_SAVEFIELD_FLT: - STR.setFloatValue(floatStack[_FLT]); - if(curObject) - curObject->setDataField(curField, curFieldArray, STR.getStringValue()); - else - { - // The field is not being set on an object. Maybe it's - // a special accessor? - setFieldComponent( prevObject, prevField, prevFieldArray, curField ); - prevObject = NULL; - } - break; - - case OP_SAVEFIELD_STR: - if(curObject) - curObject->setDataField(curField, curFieldArray, STR.getStringValue()); - else - { - // The field is not being set on an object. Maybe it's - // a special accessor? - setFieldComponent( prevObject, prevField, prevFieldArray, curField ); - prevObject = NULL; - } - break; - - case OP_STR_TO_UINT: - intStack[_UINT+1] = STR.getIntValue(); - _UINT++; - break; - - case OP_STR_TO_FLT: - floatStack[_FLT+1] = STR.getFloatValue(); - _FLT++; - break; - - case OP_STR_TO_NONE: - // This exists simply to deal with certain typecast situations. - break; - - case OP_FLT_TO_UINT: - intStack[_UINT+1] = (S64)floatStack[_FLT]; - _FLT--; - _UINT++; - break; - - case OP_FLT_TO_STR: - STR.setFloatValue(floatStack[_FLT]); - _FLT--; - break; - - case OP_FLT_TO_NONE: - _FLT--; - break; - - case OP_UINT_TO_FLT: - floatStack[_FLT+1] = (F32)intStack[_UINT]; - _UINT--; - _FLT++; - break; - - case OP_UINT_TO_STR: - STR.setIntValue(intStack[_UINT]); - _UINT--; - break; - - case OP_UINT_TO_NONE: - _UINT--; - break; - - case OP_COPYVAR_TO_NONE: - gEvalState.copyVariable = NULL; - break; - - case OP_LOADIMMED_UINT: - intStack[_UINT+1] = code[ip++]; - _UINT++; - break; - - case OP_LOADIMMED_FLT: - floatStack[_FLT+1] = curFloatTable[code[ip]]; - ip++; - _FLT++; - break; - - case OP_TAG_TO_STR: - code[ip-1] = OP_LOADIMMED_STR; - // it's possible the string has already been converted - if(U8(curStringTable[code[ip]]) != StringTagPrefixByte) - { - U32 id = GameAddTaggedString(curStringTable + code[ip]); - dSprintf(curStringTable + code[ip] + 1, 7, "%d", id); - *(curStringTable + code[ip]) = StringTagPrefixByte; - } - case OP_LOADIMMED_STR: - STR.setStringValue(curStringTable + code[ip++]); - break; - - case OP_DOCBLOCK_STR: - { - // If the first word of the doc is '\class' or '@class', then this - // is a namespace doc block, otherwise it is a function doc block. - const char* docblock = curStringTable + code[ip++]; - - const char* sansClass = dStrstr( docblock, "@class" ); - if( !sansClass ) - sansClass = dStrstr( docblock, "\\class" ); - - if( sansClass ) - { - // Don't save the class declaration. Scan past the 'class' - // keyword and up to the first whitespace. - sansClass += 7; - S32 index = 0; - while( ( *sansClass != ' ' ) && ( *sansClass != '\n' ) && *sansClass && ( index < ( nsDocLength - 1 ) ) ) - { - nsDocBlockClass[index++] = *sansClass; - sansClass++; - } - nsDocBlockClass[index] = '\0'; - - curNSDocBlock = sansClass + 1; - } - else - curFNDocBlock = docblock; - } - - break; - - case OP_LOADIMMED_IDENT: - STR.setStringValue(CodeToSTE(code, ip)); - ip += 2; - break; - - case OP_CALLFUNC_RESOLVE: - // This deals with a function that is potentially living in a namespace. - fnNamespace = CodeToSTE(code, ip+2); - fnName = CodeToSTE(code, ip); - - // Try to look it up. - ns = Namespace::find(fnNamespace); - nsEntry = ns->lookup(fnName); - if(!nsEntry) - { - ip+= 5; - Con::warnf(ConsoleLogEntry::General, - "%s: Unable to find function %s%s%s", - getFileLine(ip-7), fnNamespace ? fnNamespace : "", - fnNamespace ? "::" : "", fnName); - STR.popFrame(); - CSTK.popFrame(); - break; - } - -#ifdef COMPILER_OPTIMIZE_FUNCTION_CALLS - // Now fall through to OP_CALLFUNC... - // Now, rewrite our code a bit (ie, avoid future lookups) and fall - // through to OP_CALLFUNC -#ifdef TORQUE_CPU_X64 - *((U64*)(code+ip+2)) = ((U64)nsEntry); -#else - code[ip+2] = ((U32)nsEntry); -#endif - code[ip-1] = OP_CALLFUNC; -#endif - - case OP_CALLFUNC: - { - // This routingId is set when we query the object as to whether - // it handles this method. It is set to an enum from the table - // above indicating whether it handles it on a component it owns - // or just on the object. - S32 routingId = 0; - - fnName = CodeToSTE(code, ip); - - //if this is called from inside a function, append the ip and codeptr - if( gEvalState.getStackDepth() > 0 ) - { - gEvalState.getCurrentFrame().code = this; - gEvalState.getCurrentFrame().ip = ip - 1; - } - - U32 callType = code[ip+4]; - - ip += 5; - CSTK.getArgcArgv(fnName, &callArgc, &callArgv); - - const char *componentReturnValue = ""; - - if(callType == FuncCallExprNode::FunctionCall) - { - if( !nsEntry ) - { -#ifdef COMPILER_OPTIMIZE_FUNCTION_CALLS -#ifdef TORQUE_CPU_X64 - nsEntry = ((Namespace::Entry *) *((U64*)(code+ip-3))); -#else - nsEntry = ((Namespace::Entry *) *(code+ip-3)); -#endif -#else - nsEntry = Namespace::global()->lookup( fnName ); -#endif - ns = NULL; - } - ns = NULL; - } - else if(callType == FuncCallExprNode::MethodCall) - { - saveObject = gEvalState.thisObject; - gEvalState.thisObject = Sim::findObject((const char*)callArgv[1]); - if(!gEvalState.thisObject) - { - // Go back to the previous saved object. - gEvalState.thisObject = saveObject; - - Con::warnf(ConsoleLogEntry::General,"%s: Unable to find object: '%s' attempting to call function '%s'", getFileLine(ip-4), (const char*)callArgv[1], fnName); - STR.popFrame(); - CSTK.popFrame(); - STR.setStringValue(""); - break; - } - - bool handlesMethod = gEvalState.thisObject->handlesConsoleMethod(fnName,&routingId); - if( handlesMethod && routingId == MethodOnComponent ) - { - ICallMethod *pComponent = dynamic_cast( gEvalState.thisObject ); - if( pComponent ) - componentReturnValue = pComponent->callMethodArgList( callArgc, callArgv, false ); - } - - ns = gEvalState.thisObject->getNamespace(); - if(ns) - nsEntry = ns->lookup(fnName); - else - nsEntry = NULL; - } - else // it's a ParentCall - { - if(thisNamespace) - { - ns = thisNamespace->mParent; - if(ns) - nsEntry = ns->lookup(fnName); - else - nsEntry = NULL; - } - else - { - ns = NULL; - nsEntry = NULL; - } - } - - Namespace::Entry::CallbackUnion * nsCb = NULL; - const char * nsUsage = NULL; - if (nsEntry) - { - nsCb = &nsEntry->cb; - nsUsage = nsEntry->mUsage; - routingId = 0; - } - if(!nsEntry || noCalls) - { - if(!noCalls && !( routingId == MethodOnComponent ) ) - { - Con::warnf(ConsoleLogEntry::General,"%s: Unknown command %s.", getFileLine(ip-6), fnName); - if(callType == FuncCallExprNode::MethodCall) - { - Con::warnf(ConsoleLogEntry::General, " Object %s(%d) %s", - gEvalState.thisObject->getName() ? gEvalState.thisObject->getName() : "", - gEvalState.thisObject->getId(), Con::getNamespaceList(ns) ); - } - } - STR.popFrame(); - CSTK.popFrame(); - - if( routingId == MethodOnComponent ) - STR.setStringValue( componentReturnValue ); - else - STR.setStringValue( "" ); - - break; - } - if(nsEntry->mType == Namespace::Entry::ConsoleFunctionType) - { - ConsoleValueRef ret; - if(nsEntry->mFunctionOffset) - ret = nsEntry->mCode->exec(nsEntry->mFunctionOffset, fnName, nsEntry->mNamespace, callArgc, callArgv, false, nsEntry->mPackage); - - STR.popFrame(); - // Functions are assumed to return strings, so look ahead to see if we can skip the conversion - if(code[ip] == OP_STR_TO_UINT) - { - ip++; - intStack[++_UINT] = (U32)((S32)ret); - } - else if(code[ip] == OP_STR_TO_FLT) - { - ip++; - floatStack[++_FLT] = (F32)ret; - } - else if(code[ip] == OP_STR_TO_NONE) - { - STR.setStringValue(ret.getStringValue()); - ip++; - } - else - STR.setStringValue((const char*)ret); - - // This will clear everything including returnValue - CSTK.popFrame(); - //STR.clearFunctionOffset(); - } - else - { - const char* nsName = ns? ns->mName: ""; -#ifndef TORQUE_DEBUG - // [tom, 12/13/2006] This stops tools functions from working in the console, - // which is useful behavior when debugging so I'm ifdefing this out for debug builds. - if(nsEntry->mToolOnly && ! Con::isCurrentScriptToolScript()) - { - Con::errorf(ConsoleLogEntry::Script, "%s: %s::%s - attempting to call tools only function from outside of tools.", getFileLine(ip-6), nsName, fnName); - } - else -#endif - if((nsEntry->mMinArgs && S32(callArgc) < nsEntry->mMinArgs) || (nsEntry->mMaxArgs && S32(callArgc) > nsEntry->mMaxArgs)) - { - Con::warnf(ConsoleLogEntry::Script, "%s: %s::%s - wrong number of arguments (got %i, expected min %i and max %i).", - getFileLine(ip-6), nsName, fnName, - callArgc, nsEntry->mMinArgs, nsEntry->mMaxArgs); - Con::warnf(ConsoleLogEntry::Script, "%s: usage: %s", getFileLine(ip-6), nsEntry->mUsage); - STR.popFrame(); - CSTK.popFrame(); - } - else - { - switch(nsEntry->mType) - { - case Namespace::Entry::StringCallbackType: - { - const char *ret = nsEntry->cb.mStringCallbackFunc(gEvalState.thisObject, callArgc, callArgv); - STR.popFrame(); - CSTK.popFrame(); - if(ret != STR.getStringValue()) - STR.setStringValue(ret); - //else - // STR.setLen(dStrlen(ret)); - break; - } - case Namespace::Entry::IntCallbackType: - { - S32 result = nsEntry->cb.mIntCallbackFunc(gEvalState.thisObject, callArgc, callArgv); - STR.popFrame(); - CSTK.popFrame(); - if(code[ip] == OP_STR_TO_UINT) - { - ip++; - intStack[++_UINT] = result; - break; - } - else if(code[ip] == OP_STR_TO_FLT) - { - ip++; - floatStack[++_FLT] = result; - break; - } - else if(code[ip] == OP_STR_TO_NONE) - ip++; - else - STR.setIntValue(result); - break; - } - case Namespace::Entry::FloatCallbackType: - { - F64 result = nsEntry->cb.mFloatCallbackFunc(gEvalState.thisObject, callArgc, callArgv); - STR.popFrame(); - CSTK.popFrame(); - if(code[ip] == OP_STR_TO_UINT) - { - ip++; - intStack[++_UINT] = (S64)result; - break; - } - else if(code[ip] == OP_STR_TO_FLT) - { - ip++; - floatStack[++_FLT] = result; - break; - } - else if(code[ip] == OP_STR_TO_NONE) - ip++; - else - STR.setFloatValue(result); - break; - } - case Namespace::Entry::VoidCallbackType: - nsEntry->cb.mVoidCallbackFunc(gEvalState.thisObject, callArgc, callArgv); - if( code[ ip ] != OP_STR_TO_NONE && Con::getBoolVariable( "$Con::warnVoidAssignment", true ) ) - Con::warnf(ConsoleLogEntry::General, "%s: Call to %s in %s uses result of void function call.", getFileLine(ip-6), fnName, functionName); - - STR.popFrame(); - CSTK.popFrame(); - STR.setStringValue(""); - break; - case Namespace::Entry::BoolCallbackType: - { - bool result = nsEntry->cb.mBoolCallbackFunc(gEvalState.thisObject, callArgc, callArgv); - STR.popFrame(); - CSTK.popFrame(); - if(code[ip] == OP_STR_TO_UINT) - { - ip++; - intStack[++_UINT] = result; - break; - } - else if(code[ip] == OP_STR_TO_FLT) - { - ip++; - floatStack[++_FLT] = result; - break; - } - else if(code[ip] == OP_STR_TO_NONE) - ip++; - else - STR.setIntValue(result); - break; - } - } - } - } - - if(callType == FuncCallExprNode::MethodCall) - gEvalState.thisObject = saveObject; - break; - } - case OP_ADVANCE_STR: - STR.advance(); - break; - case OP_ADVANCE_STR_APPENDCHAR: - STR.advanceChar(code[ip++]); - break; - - case OP_ADVANCE_STR_COMMA: - STR.advanceChar('_'); - break; - - case OP_ADVANCE_STR_NUL: - STR.advanceChar(0); - break; - - case OP_REWIND_STR: - STR.rewind(); - break; - - case OP_TERMINATE_REWIND_STR: - STR.rewindTerminate(); - break; - - case OP_COMPARE_STR: - intStack[++_UINT] = STR.compare(); - break; - case OP_PUSH: - STR.push(); - CSTK.pushStringStackPtr(STR.getPreviousStringValuePtr()); - break; - case OP_PUSH_UINT: - CSTK.pushUINT(intStack[_UINT]); - _UINT--; - break; - case OP_PUSH_FLT: - CSTK.pushFLT(floatStack[_FLT]); - _FLT--; - break; - case OP_PUSH_VAR: - if (gEvalState.currentVariable) - CSTK.pushValue(gEvalState.currentVariable->value); - else - CSTK.pushString(""); - break; - - case OP_PUSH_FRAME: - STR.pushFrame(); - CSTK.pushFrame(); - break; - - case OP_ASSERT: - { - if( !intStack[_UINT--] ) - { - const char *message = curStringTable + code[ip]; - - U32 breakLine, inst; - findBreakLine( ip - 1, breakLine, inst ); - - if ( PlatformAssert::processAssert( PlatformAssert::Fatal, - name ? name : "eval", - breakLine, - message ) ) - { - if ( TelDebugger && TelDebugger->isConnected() && breakLine > 0 ) - { - TelDebugger->breakProcess(); - } - else - Platform::debugBreak(); - } - } - - ip++; - break; - } - - case OP_BREAK: - { - //append the ip and codeptr before managing the breakpoint! - AssertFatal( gEvalState.getStackDepth() > 0, "Empty eval stack on break!"); - gEvalState.getCurrentFrame().code = this; - gEvalState.getCurrentFrame().ip = ip - 1; - - U32 breakLine; - findBreakLine(ip-1, breakLine, instruction); - if(!breakLine) - goto breakContinue; - TelDebugger->executionStopped(this, breakLine); - goto breakContinue; - } - - case OP_ITER_BEGIN_STR: - { - iterStack[ _ITER ].mIsStringIter = true; - /* fallthrough */ - } - - case OP_ITER_BEGIN: - { - StringTableEntry varName = CodeToSTE(code, ip); - U32 failIp = code[ ip + 2 ]; - - IterStackRecord& iter = iterStack[ _ITER ]; - - iter.mVariable = gEvalState.getCurrentFrame().add( varName ); - - if( iter.mIsStringIter ) - { - iter.mData.mStr.mString = STR.getStringValuePtr(); - iter.mData.mStr.mIndex = 0; - } - else - { - // Look up the object. - - SimSet* set; - if( !Sim::findObject( STR.getStringValue(), set ) ) - { - Con::errorf( ConsoleLogEntry::General, "No SimSet object '%s'", STR.getStringValue() ); - Con::errorf( ConsoleLogEntry::General, "Did you mean to use 'foreach$' instead of 'foreach'?" ); - ip = failIp; - continue; - } - - // Set up. - - iter.mData.mObj.mSet = set; - iter.mData.mObj.mIndex = 0; - } - - _ITER ++; - iterDepth ++; - - STR.push(); - - ip += 3; - break; - } - - case OP_ITER: - { - U32 breakIp = code[ ip ]; - IterStackRecord& iter = iterStack[ _ITER - 1 ]; - - if( iter.mIsStringIter ) - { - const char* str = StringStackPtrRef(iter.mData.mStr.mString).getPtr(&STR); - - U32 startIndex = iter.mData.mStr.mIndex; - U32 endIndex = startIndex; - - // Break if at end. - - if( !str[ startIndex ] ) - { - ip = breakIp; - continue; - } - - // Find right end of current component. - - if( !dIsspace( str[ endIndex ] ) ) - do ++ endIndex; - while( str[ endIndex ] && !dIsspace( str[ endIndex ] ) ); - - // Extract component. - - if( endIndex != startIndex ) - { - char savedChar = str[ endIndex ]; - const_cast< char* >( str )[ endIndex ] = '\0'; // We are on the string stack so this is okay. - iter.mVariable->setStringValue( &str[ startIndex ] ); - const_cast< char* >( str )[ endIndex ] = savedChar; - } - else - iter.mVariable->setStringValue( "" ); - - // Skip separator. - if( str[ endIndex ] != '\0' ) - ++ endIndex; - - iter.mData.mStr.mIndex = endIndex; - } - else - { - U32 index = iter.mData.mObj.mIndex; - SimSet* set = iter.mData.mObj.mSet; - - if( index >= set->size() ) - { - ip = breakIp; - continue; - } - - iter.mVariable->setIntValue( set->at( index )->getId() ); - iter.mData.mObj.mIndex = index + 1; - } - - ++ ip; - break; - } - - case OP_ITER_END: - { - -- _ITER; - -- iterDepth; - - STR.rewind(); - - iterStack[ _ITER ].mIsStringIter = false; - break; - } - - case OP_INVALID: - - default: - // error! - goto execFinished; - } - } -execFinished: - - if ( telDebuggerOn && setFrame < 0 ) - TelDebugger->popStackFrame(); - - if ( popFrame ) - gEvalState.popFrame(); - - if(argv) - { - if(gEvalState.traceOn) - { - traceBuffer[0] = 0; - dStrcat(traceBuffer, "Leaving "); - - if(packageName) - { - dStrcat(traceBuffer, "["); - dStrcat(traceBuffer, packageName); - dStrcat(traceBuffer, "]"); - } - if(thisNamespace && thisNamespace->mName) - { - dSprintf(traceBuffer + dStrlen(traceBuffer), sizeof(traceBuffer) - dStrlen(traceBuffer), - "%s::%s() - return %s", thisNamespace->mName, thisFunctionName, STR.getStringValue()); - } - else - { - dSprintf(traceBuffer + dStrlen(traceBuffer), sizeof(traceBuffer) - dStrlen(traceBuffer), - "%s() - return %s", thisFunctionName, STR.getStringValue()); - } - Con::printf("%s", traceBuffer); - } - } - - smCurrentCodeBlock = saveCodeBlock; - if(saveCodeBlock && saveCodeBlock->name) - { - Con::gCurrentFile = saveCodeBlock->name; - Con::gCurrentRoot = saveCodeBlock->modPath; - } - - decRefCount(); - -#ifdef TORQUE_VALIDATE_STACK - AssertFatal(!(STR.mStartStackSize > stackStart), "String stack not popped enough in script exec"); - AssertFatal(!(STR.mStartStackSize < stackStart), "String stack popped too much in script exec"); -#endif - - return returnValue; + CodeInterpreter interpreter(this); + return interpreter.exec(ip, functionName, thisNamespace, argc, argv, noCalls, packageName, setFrame); } //------------------------------------------------------------ diff --git a/Engine/source/console/compiler.cpp b/Engine/source/console/compiler.cpp index fd871c036..0330f4d59 100644 --- a/Engine/source/console/compiler.cpp +++ b/Engine/source/console/compiler.cpp @@ -40,13 +40,13 @@ namespace Compiler F64 consoleStringToNumber(const char *str, StringTableEntry file, U32 line) { F64 val = dAtof(str); - if(val != 0) + if (val != 0) return val; - else if(!dStricmp(str, "true")) + else if (!dStricmp(str, "true")) return 1; - else if(!dStricmp(str, "false")) + else if (!dStricmp(str, "false")) return 0; - else if(file) + else if (file) { Con::warnf(ConsoleLogEntry::General, "%s (%d): string always evaluates to 0.", file, line); return 0; @@ -57,7 +57,7 @@ namespace Compiler //------------------------------------------------------------ CompilerStringTable *gCurrentStringTable, gGlobalStringTable, gFunctionStringTable; - CompilerFloatTable *gCurrentFloatTable, gGlobalFloatTable, gFunctionFloatTable; + CompilerFloatTable *gCurrentFloatTable, gGlobalFloatTable, gFunctionFloatTable; DataChunker gConsoleAllocator; CompilerIdentTable gIdentTable; @@ -71,16 +71,16 @@ namespace Compiler *ptr = (U32)ste; #endif } - + void compileSTEtoCode(StringTableEntry ste, U32 ip, U32 *ptr) { - if(ste) + if (ste) getIdentTable().add(ste, ip); *ptr = 0; - *(ptr+1) = 0; + *(ptr + 1) = 0; } - - void (*STEtoCode)(StringTableEntry ste, U32 ip, U32 *ptr) = evalSTEtoCode; + + void(*STEtoCode)(StringTableEntry ste, U32 ip, U32 *ptr) = evalSTEtoCode; //------------------------------------------------------------ @@ -88,23 +88,23 @@ namespace Compiler //------------------------------------------------------------ - CompilerStringTable *getCurrentStringTable() { return gCurrentStringTable; } - CompilerStringTable &getGlobalStringTable() { return gGlobalStringTable; } + CompilerStringTable *getCurrentStringTable() { return gCurrentStringTable; } + CompilerStringTable &getGlobalStringTable() { return gGlobalStringTable; } CompilerStringTable &getFunctionStringTable() { return gFunctionStringTable; } - void setCurrentStringTable (CompilerStringTable* cst) { gCurrentStringTable = cst; } + void setCurrentStringTable(CompilerStringTable* cst) { gCurrentStringTable = cst; } - CompilerFloatTable *getCurrentFloatTable() { return gCurrentFloatTable; } - CompilerFloatTable &getGlobalFloatTable() { return gGlobalFloatTable; } - CompilerFloatTable &getFunctionFloatTable() { return gFunctionFloatTable; } + CompilerFloatTable *getCurrentFloatTable() { return gCurrentFloatTable; } + CompilerFloatTable &getGlobalFloatTable() { return gGlobalFloatTable; } + CompilerFloatTable &getFunctionFloatTable() { return gFunctionFloatTable; } - void setCurrentFloatTable (CompilerFloatTable* cst) { gCurrentFloatTable = cst; } + void setCurrentFloatTable(CompilerFloatTable* cst) { gCurrentFloatTable = cst; } CompilerIdentTable &getIdentTable() { return gIdentTable; } void precompileIdent(StringTableEntry ident) { - if(ident) + if (ident) gGlobalStringTable.add(ident); } @@ -119,8 +119,8 @@ namespace Compiler getIdentTable().reset(); } - void *consoleAlloc(U32 size) { return gConsoleAllocator.alloc(size); } - void consoleAllocReset() { gConsoleAllocator.freeBlocks(); } + void *consoleAlloc(U32 size) { return gConsoleAllocator.alloc(size); } + void consoleAllocReset() { gConsoleAllocator.freeBlocks(); } } @@ -135,36 +135,40 @@ U32 CompilerStringTable::add(const char *str, bool caseSens, bool tag) { // Is it already in? Entry **walk; - for(walk = &list; *walk; walk = &((*walk)->next)) + for (walk = &list; *walk; walk = &((*walk)->next)) { - if((*walk)->tag != tag) + if ((*walk)->tag != tag) continue; - if(caseSens) + if (caseSens) { - if(!dStrcmp((*walk)->string, str)) + if (!dStrcmp((*walk)->string, str)) return (*walk)->start; } else { - if(!dStricmp((*walk)->string, str)) + if (!dStricmp((*walk)->string, str)) return (*walk)->start; } } // Write it out. - Entry *newStr = (Entry *) consoleAlloc(sizeof(Entry)); + Entry *newStr = (Entry *)consoleAlloc(sizeof(Entry)); *walk = newStr; newStr->next = NULL; newStr->start = totalLen; U32 len = dStrlen(str) + 1; - if(tag && len < 7) // alloc space for the numeric tag 1 for tag, 5 for # and 1 for nul + if (tag && len < 7) // alloc space for the numeric tag 1 for tag, 5 for # and 1 for nul len = 7; totalLen += len; - newStr->string = (char *) consoleAlloc(len); + newStr->string = (char *)consoleAlloc(len); newStr->len = len; newStr->tag = tag; dStrcpy(newStr->string, str); + + // Put into the hash table. + hashTable[str] = newStr; + return newStr->start; } @@ -189,7 +193,8 @@ void CompilerStringTable::reset() char *CompilerStringTable::build() { char *ret = new char[totalLen]; - for(Entry *walk = list; walk; walk = walk->next) + dMemset(ret, 0, totalLen); + for (Entry *walk = list; walk; walk = walk->next) dStrcpy(ret + walk->start, walk->string); return ret; } @@ -197,7 +202,7 @@ char *CompilerStringTable::build() void CompilerStringTable::write(Stream &st) { st.write(totalLen); - for(Entry *walk = list; walk; walk = walk->next) + for (Entry *walk = list; walk; walk = walk->next) st.write(walk->len, walk->string); } @@ -207,15 +212,15 @@ U32 CompilerFloatTable::add(F64 value) { Entry **walk; U32 i = 0; - for(walk = &list; *walk; walk = &((*walk)->next), i++) - if(value == (*walk)->val) + for (walk = &list; *walk; walk = &((*walk)->next), i++) + if (value == (*walk)->val) return i; - Entry *newFloat = (Entry *) consoleAlloc(sizeof(Entry)); + Entry *newFloat = (Entry *)consoleAlloc(sizeof(Entry)); newFloat->val = value; newFloat->next = NULL; count++; *walk = newFloat; - return count-1; + return count - 1; } void CompilerFloatTable::reset() { @@ -226,7 +231,7 @@ F64 *CompilerFloatTable::build() { F64 *ret = new F64[count]; U32 i = 0; - for(Entry *walk = list; walk; walk = walk->next, i++) + for (Entry *walk = list; walk; walk = walk->next, i++) ret[i] = walk->val; return ret; } @@ -234,7 +239,7 @@ F64 *CompilerFloatTable::build() void CompilerFloatTable::write(Stream &st) { st.write(count); - for(Entry *walk = list; walk; walk = walk->next) + for (Entry *walk = list; walk; walk = walk->next) st.write(walk->val); } @@ -248,12 +253,12 @@ void CompilerIdentTable::reset() void CompilerIdentTable::add(StringTableEntry ste, U32 ip) { U32 index = gGlobalStringTable.add(ste, false); - Entry *newEntry = (Entry *) consoleAlloc(sizeof(Entry)); + Entry *newEntry = (Entry *)consoleAlloc(sizeof(Entry)); newEntry->offset = index; newEntry->ip = ip; - for(Entry *walk = list; walk; walk = walk->next) + for (Entry *walk = list; walk; walk = walk->next) { - if(walk->offset == index) + if (walk->offset == index) { newEntry->nextIdent = walk->nextIdent; walk->nextIdent = newEntry; @@ -269,24 +274,24 @@ void CompilerIdentTable::write(Stream &st) { U32 count = 0; Entry * walk; - for(walk = list; walk; walk = walk->next) + for (walk = list; walk; walk = walk->next) count++; st.write(count); - for(walk = list; walk; walk = walk->next) + for (walk = list; walk; walk = walk->next) { U32 ec = 0; Entry * el; - for(el = walk; el; el = el->nextIdent) + for (el = walk; el; el = el->nextIdent) ec++; st.write(walk->offset); st.write(ec); - for(el = walk; el; el = el->nextIdent) + for (el = walk; el; el = el->nextIdent) st.write(el->ip); } } //------------------------------------------------------------------------- - + U8 *CodeStream::allocCode(U32 sz) { U8 *ptr = NULL; @@ -300,12 +305,12 @@ U8 *CodeStream::allocCode(U32 sz) return ptr; } } - + CodeData *data = new CodeData; data->data = (U8*)dMalloc(BlockSize); data->size = sz; data->next = NULL; - + if (mCodeHead) mCodeHead->next = data; mCodeHead = data; @@ -313,21 +318,21 @@ U8 *CodeStream::allocCode(U32 sz) mCode = data; return data->data; } - + //------------------------------------------------------------------------- - + void CodeStream::fixLoop(U32 loopBlockStart, U32 breakPoint, U32 continuePoint) { AssertFatal(mFixStack.size() > 0, "Fix stack mismatch"); - - U32 fixStart = mFixStack[mFixStack.size()-1]; - for (U32 i=fixStart; inext : NULL; while (itr != NULL) @@ -403,7 +408,7 @@ void CodeStream::reset() delete(itr); itr = next; } - + if (mCode) { mCode->size = 0; diff --git a/Engine/source/console/compiler.h b/Engine/source/console/compiler.h index 3f1fb5339..df69d0819 100644 --- a/Engine/source/console/compiler.h +++ b/Engine/source/console/compiler.h @@ -30,6 +30,9 @@ #include #endif +#include +#include + class Stream; class DataChunker; @@ -91,10 +94,15 @@ namespace Compiler OP_DIV, OP_NEG, + OP_INC, + OP_DEC, + OP_SETCURVAR, OP_SETCURVAR_CREATE, OP_SETCURVAR_ARRAY, + OP_SETCURVAR_ARRAY_VARLOOKUP, OP_SETCURVAR_ARRAY_CREATE, + OP_SETCURVAR_ARRAY_CREATE_VARLOOKUP, OP_LOADVAR_UINT,// 40 OP_LOADVAR_FLT, @@ -113,6 +121,8 @@ namespace Compiler OP_SETCURFIELD, OP_SETCURFIELD_ARRAY, // 50 OP_SETCURFIELD_TYPE, + OP_SETCURFIELD_ARRAY_VAR, + OP_SETCURFIELD_THIS, OP_LOADFIELD_UINT, OP_LOADFIELD_FLT, @@ -142,6 +152,8 @@ namespace Compiler OP_CALLFUNC_RESOLVE, OP_CALLFUNC, + OP_CALLFUNC_POINTER, + OP_CALLFUNC_THIS, OP_ADVANCE_STR, OP_ADVANCE_STR_APPENDCHAR, @@ -155,23 +167,26 @@ namespace Compiler OP_PUSH_UINT, // Integer OP_PUSH_FLT, // Float OP_PUSH_VAR, // Variable + OP_PUSH_THIS, // This pointer OP_PUSH_FRAME, // Frame OP_ASSERT, OP_BREAK, - + OP_ITER_BEGIN, ///< Prepare foreach iterator. OP_ITER_BEGIN_STR, ///< Prepare foreach$ iterator. OP_ITER, ///< Enter foreach loop. OP_ITER_END, ///< End foreach loop. - OP_INVALID // 90 + OP_INVALID, // 90 + + MAX_OP_CODELEN ///< The amount of op codes. }; //------------------------------------------------------------ F64 consoleStringToNumber(const char *str, StringTableEntry file = 0, U32 line = 0); - + U32 compileBlock(StmtNode *block, CodeStream &codeStream, U32 ip); //------------------------------------------------------------ @@ -207,6 +222,7 @@ namespace Compiler Entry *list; char buf[256]; + std::unordered_map hashTable; U32 add(const char *str, bool caseSens = true, bool tag = false); U32 addIntString(U32 value); @@ -239,14 +255,14 @@ namespace Compiler inline StringTableEntry CodeToSTE(U32 *code, U32 ip) { #ifdef TORQUE_CPU_X64 - return (StringTableEntry)(*((U64*)(code+ip))); + return (StringTableEntry)(*((U64*)(code + ip))); #else - return (StringTableEntry)(*(code+ip)); + return (StringTableEntry)(*(code + ip)); #endif } - extern void (*STEtoCode)(StringTableEntry ste, U32 ip, U32 *ptr); - + extern void(*STEtoCode)(StringTableEntry ste, U32 ip, U32 *ptr); + void evalSTEtoCode(StringTableEntry ste, U32 ip, U32 *ptr); void compileSTEtoCode(StringTableEntry ste, U32 ip, U32 *ptr); @@ -254,13 +270,13 @@ namespace Compiler CompilerStringTable &getGlobalStringTable(); CompilerStringTable &getFunctionStringTable(); - void setCurrentStringTable (CompilerStringTable* cst); + void setCurrentStringTable(CompilerStringTable* cst); CompilerFloatTable *getCurrentFloatTable(); CompilerFloatTable &getGlobalFloatTable(); CompilerFloatTable &getFunctionFloatTable(); - void setCurrentFloatTable (CompilerFloatTable* cst); + void setCurrentFloatTable(CompilerFloatTable* cst); CompilerIdentTable &getIdentTable(); @@ -280,7 +296,7 @@ namespace Compiler class CodeStream { public: - + enum FixType { // For loops @@ -288,37 +304,37 @@ public: FIXTYPE_BREAK, FIXTYPE_CONTINUE }; - + enum Constants { BlockSize = 16384, }; - + protected: - + typedef struct PatchEntry { U32 addr; ///< Address to patch U32 value; ///< Value to place at addr - - PatchEntry() {;} - PatchEntry(U32 a, U32 v) : addr(a), value(v) {;} + + PatchEntry() { ; } + PatchEntry(U32 a, U32 v) : addr(a), value(v) { ; } } PatchEntry; - + typedef struct CodeData { U8 *data; ///< Allocated data (size is BlockSize) U32 size; ///< Bytes used in data CodeData *next; ///< Next block } CodeData; - + /// @name Emitted code /// { CodeData *mCode; CodeData *mCodeHead; U32 mCodePos; /// } - + /// @name Code fixing stacks /// { Vector mFixList; @@ -326,28 +342,28 @@ protected: Vector mFixLoopStack; Vector mPatchList; /// } - + Vector mBreakLines; ///< Line numbers - + public: CodeStream() : mCode(0), mCodeHead(NULL), mCodePos(0) { } - + ~CodeStream() { reset(); - + if (mCode) { dFree(mCode->data); delete mCode; } } - + U8 *allocCode(U32 sz); - + inline U32 emit(U32 code) { U32 *ptr = (U32*)allocCode(4); @@ -357,7 +373,7 @@ public: #endif return mCodePos++; } - + inline void patch(U32 addr, U32 code) { #ifdef DEBUG_CODESTREAM @@ -365,7 +381,7 @@ public: #endif mPatchList.push_back(PatchEntry(addr, code)); } - + inline U32 emitSTE(const char *code) { U64 *ptr = (U64*)allocCode(8); @@ -375,70 +391,70 @@ public: printf("code[%u] = %s\n", mCodePos, code); #endif mCodePos += 2; - return mCodePos-2; + return mCodePos - 2; } - + inline U32 tell() { return mCodePos; } - + inline bool inLoop() { - for (U32 i=0; i 0, "Fix stack mismatch"); - - U32 newSize = mFixStack[mFixStack.size()-1]; + + U32 newSize = mFixStack[mFixStack.size() - 1]; while (mFixList.size() > newSize) mFixList.pop_back(); mFixStack.pop_back(); mFixLoopStack.pop_back(); } - + void fixLoop(U32 loopBlockStart, U32 breakPoint, U32 continuePoint); - + inline void addBreakLine(U32 lineNumber, U32 ip) { mBreakLines.push_back(lineNumber); mBreakLines.push_back(ip); } - + inline U32 getNumLineBreaks() { return mBreakLines.size() / 2; } - + void emitCodeStream(U32 *size, U32 **stream, U32 **lineBreaks); - + void reset(); }; diff --git a/Engine/source/console/console.h b/Engine/source/console/console.h index 303c19fed..4009a5393 100644 --- a/Engine/source/console/console.h +++ b/Engine/source/console/console.h @@ -24,13 +24,13 @@ #define _CONSOLE_H_ #ifndef _PLATFORM_H_ - #include "platform/platform.h" +#include "platform/platform.h" #endif #ifndef _BITSET_H_ - #include "core/bitSet.h" +#include "core/bitSet.h" #endif #ifndef _REFBASE_H_ - #include "core/util/refBase.h" +#include "core/util/refBase.h" #endif #include @@ -95,8 +95,8 @@ struct ConsoleLogEntry Script, GUI, Network, - GGConnect, - NUM_TYPE + GGConnect, + NUM_TYPE } mType; /// Indicates the actual log entry. @@ -120,7 +120,7 @@ extern char *typeValueEmpty; class ConsoleValue { public: - + enum { TypeInternalInt = -5, @@ -129,17 +129,17 @@ public: TypeInternalStackString = -2, TypeInternalString = -1, }; - + S32 type; - + public: - + // NOTE: This is protected to ensure no one outside // of this structure is messing with it. - + #pragma warning( push ) #pragma warning( disable : 4201 ) // warning C4201: nonstandard extension used : nameless struct/union - + // An variable is either a real dynamic type or // its one exposed from C++ using a data pointer. // @@ -154,24 +154,24 @@ public: F32 fval; U32 bufferLen; }; - + struct { /// The real data pointer. void *dataPtr; - + /// The enum lookup table for enumerated types. const EnumTable *enumTable; }; }; - + U32 getIntValue(); S32 getSignedIntValue(); F32 getFloatValue(); const char *getStringValue(); StringStackPtr getStringStackPtr(); bool getBoolValue(); - + void setIntValue(U32 val); void setIntValue(S32 val); void setFloatValue(F32 val); @@ -179,7 +179,7 @@ public: void setStackStringValue(const char *value); void setStringStackPtrValue(StringStackPtr ptr); void setBoolValue(bool val); - + void init() { ival = 0; @@ -188,7 +188,7 @@ public: bufferLen = 0; type = TypeInternalString; } - + void cleanup() { if ((type <= TypeInternalString) && (bufferLen > 0)) @@ -201,8 +201,8 @@ public: ival = 0; fval = 0; } - ConsoleValue(){ init(); }; - ~ConsoleValue(){ cleanup(); }; + ConsoleValue() { init(); }; + ~ConsoleValue() { cleanup(); }; }; // Proxy class for console variables @@ -234,7 +234,7 @@ public: inline operator S32() { return getSignedIntValue(); } inline operator F32() { return getFloatValue(); } inline operator bool() { return getBoolValue(); } - + inline bool isStringStackPtr() { return value ? value->type == ConsoleValue::TypeInternalStringStackPtr : false; } inline bool isString() { return value ? value->type >= ConsoleValue::TypeInternalStringStackPtr : true; } inline bool isInt() { return value ? value->type == ConsoleValue::TypeInternalInt : false; } @@ -320,12 +320,12 @@ public: /// typedef const char * (*StringCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]); -typedef S32 (*IntCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]); -typedef F32 (*FloatCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]); -typedef void (*VoidCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]); // We have it return a value so things don't break.. -typedef bool (*BoolCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]); +typedef S32(*IntCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]); +typedef F32(*FloatCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]); +typedef void(*VoidCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]); // We have it return a value so things don't break.. +typedef bool(*BoolCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]); -typedef void (*ConsumerCallback)(U32 level, const char *consoleLine); +typedef void(*ConsumerCallback)(U32 level, const char *consoleLine); /// @} /// @defgroup console_types Scripting Engine Type Functions @@ -333,7 +333,7 @@ typedef void (*ConsumerCallback)(U32 level, const char *consoleLine); /// @see Con::registerType /// @{ typedef const char* (*GetDataFunction)(void *dptr, EnumTable *tbl, BitSet32 flag); -typedef void (*SetDataFunction)(void *dptr, S32 argc, const char **argv, EnumTable *tbl, BitSet32 flag); +typedef void(*SetDataFunction)(void *dptr, S32 argc, const char **argv, EnumTable *tbl, BitSet32 flag); /// @} /// This namespace contains the core of the console functionality. @@ -347,7 +347,7 @@ typedef void (*SetDataFunction)(void *dptr, S32 argc, const char **argv, namespace Con { /// Various configuration constants. - enum Constants + enum Constants { /// This is the version number associated with DSO files. /// @@ -361,20 +361,22 @@ namespace Con /// 12/29/04 - BJG - 33->34 Removed some opcodes, part of namespace upgrade. /// 12/30/04 - BJG - 34->35 Reordered some things, further general shuffling. /// 11/03/05 - BJG - 35->36 Integrated new debugger code. - // 09/08/06 - THB - 36->37 New opcode for internal names - // 09/15/06 - THB - 37->38 Added unit conversions - // 11/23/06 - THB - 38->39 Added recursive internal name operator - // 02/15/07 - THB - 39->40 Bumping to 40 for TGB since the console has been - // majorly hacked without the version number being bumped - // 02/16/07 - THB - 40->41 newmsg operator - // 06/15/07 - THB - 41->42 script types + /// 09/08/06 - THB - 36->37 New opcode for internal names + /// 09/15/06 - THB - 37->38 Added unit conversions + /// 11/23/06 - THB - 38->39 Added recursive internal name operator + /// 02/15/07 - THB - 39->40 Bumping to 40 for TGB since the console has been + /// majorly hacked without the version number being bumped + /// 02/16/07 - THB - 40->41 newmsg operator + /// 06/15/07 - THB - 41->42 script types /// 07/31/07 - THB - 42->43 Patch from Andreas Kirsch: Added opcode to support nested new declarations. /// 09/12/07 - CAF - 43->44 remove newmsg operator /// 09/27/07 - RDB - 44->45 Patch from Andreas Kirsch: Added opcode to support correct void return /// 01/13/09 - TMS - 45->46 Added script assert /// 09/07/14 - jamesu - 46->47 64bit support /// 10/14/14 - jamesu - 47->48 Added opcodes to reduce reliance on strings in function calls - DSOVersion = 48, + /// 10/07/17 - JTH - 48->49 Added opcode for function pointers and revamp of interpreter + /// from switch to function calls. + DSOVersion = 49, MaxLineLength = 512, ///< Maximum length of a line of console input. MaxDataTypes = 256 ///< Maximum number of registered data types. @@ -552,11 +554,11 @@ namespace Con /// @param usage Documentation string. /// /// @see ConsoleDynamicTypes - void addVariable( const char *name, - S32 type, - void *pointer, - const char* usage = NULL ); - + void addVariable(const char *name, + S32 type, + void *pointer, + const char* usage = NULL); + /// Add a console constant that references the value of a constant in C++ code. /// /// @param name Global console constant name to create. @@ -565,11 +567,11 @@ namespace Con /// @param usage Documentation string. /// /// @see ConsoleDynamicTypes - void addConstant( const char *name, - S32 type, - const void *pointer, - const char* usage = NULL ); - + void addConstant(const char *name, + S32 type, + const void *pointer, + const char* usage = NULL); + /// Remove a console variable. /// /// @param name Global console variable name to remove @@ -582,14 +584,14 @@ namespace Con /// @param name An existing global console variable name. /// @param callback The notification delegate function. /// - void addVariableNotify( const char *name, const NotifyDelegate &callback ); + void addVariableNotify(const char *name, const NotifyDelegate &callback); /// Remove an existing variable assignment notification callback. /// /// @param name An existing global console variable name. /// @param callback The notification delegate function. /// - void removeVariableNotify( const char *name, const NotifyDelegate &callback ); + void removeVariableNotify(const char *name, const NotifyDelegate &callback); /// Assign a string value to a locally scoped console variable /// @@ -628,31 +630,31 @@ namespace Con const char* getObjectField(const char* name); /// Same as setVariable(), but for bools. - void setBoolVariable (const char* name,bool var); + void setBoolVariable(const char* name, bool var); /// Same as getVariable(), but for bools. /// /// @param name Name of the variable. /// @param def Default value to supply if no matching variable is found. - bool getBoolVariable (const char* name,bool def = false); + bool getBoolVariable(const char* name, bool def = false); /// Same as setVariable(), but for ints. - void setIntVariable (const char* name,S32 var); + void setIntVariable(const char* name, S32 var); /// Same as getVariable(), but for ints. /// /// @param name Name of the variable. /// @param def Default value to supply if no matching variable is found. - S32 getIntVariable (const char* name,S32 def = 0); + S32 getIntVariable(const char* name, S32 def = 0); /// Same as setVariable(), but for floats. - void setFloatVariable(const char* name,F32 var); + void setFloatVariable(const char* name, F32 var); /// Same as getVariable(), but for floats. /// /// @param name Name of the variable. /// @param def Default value to supply if no matching variable is found. - F32 getFloatVariable(const char* name,F32 def = .0f); + F32 getFloatVariable(const char* name, F32 def = .0f); /// @} @@ -668,52 +670,52 @@ namespace Con /// @param maxArgs Maximum number of arguments this function accepts /// @param toolOnly Wether this is a TORQUE_TOOLS only function. /// @param header The extended function header. - void addCommand( const char* name, StringCallback cb, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); + void addCommand(const char* name, StringCallback cb, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); - void addCommand( const char* name, IntCallback cb, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); ///< @copydoc addCommand( const char *, StringCallback, const char *, S32, S32, bool, ConsoleFunctionHeader* ) - void addCommand( const char* name, FloatCallback cb, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); ///< @copydoc addCommand( const char *, StringCallback, const char *, S32, S32, bool, ConsoleFunctionHeader* ) - void addCommand( const char* name, VoidCallback cb, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); ///< @copydoc addCommand( const char *, StringCallback, const char *, S32, S32, bool, ConsoleFunctionHeader* ) - void addCommand( const char* name, BoolCallback cb, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); ///< @copydoc addCommand( const char *, StringCallback, const char *, S32, S32, bool, ConsoleFunctionHeader* ) - - /// @} + void addCommand(const char* name, IntCallback cb, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); ///< @copydoc addCommand( const char *, StringCallback, const char *, S32, S32, bool, ConsoleFunctionHeader* ) + void addCommand(const char* name, FloatCallback cb, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); ///< @copydoc addCommand( const char *, StringCallback, const char *, S32, S32, bool, ConsoleFunctionHeader* ) + void addCommand(const char* name, VoidCallback cb, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); ///< @copydoc addCommand( const char *, StringCallback, const char *, S32, S32, bool, ConsoleFunctionHeader* ) + void addCommand(const char* name, BoolCallback cb, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); ///< @copydoc addCommand( const char *, StringCallback, const char *, S32, S32, bool, ConsoleFunctionHeader* ) - /// @name Namespace Function Registration - /// @{ + /// @} - /// Register a C++ function with the console making it callable - /// as a method of the given namespace from the scripting engine. - /// - /// @param nameSpace Name of the namespace to associate the new function with; this is usually the name of a class. - /// @param name Name of the new function. - /// @param cb Pointer to the function implementing the scripting call; a console callback function returning a specific type value. - /// @param usage Documentation for this function. @ref console_autodoc - /// @param minArgs Minimum number of arguments this function accepts - /// @param maxArgs Maximum number of arguments this function accepts - /// @param toolOnly Wether this is a TORQUE_TOOLS only function. - /// @param header The extended function header. - void addCommand(const char *nameSpace, const char *name,StringCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); + /// @name Namespace Function Registration + /// @{ - void addCommand(const char *nameSpace, const char *name,IntCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); ///< @copydoc addCommand( const char*, const char *, StringCallback, const char *, S32, S32, bool, ConsoleFunctionHeader* ) - void addCommand(const char *nameSpace, const char *name,FloatCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); ///< @copydoc addCommand( const char*, const char *, StringCallback, const char *, S32, S32, bool, ConsoleFunctionHeader* ) - void addCommand(const char *nameSpace, const char *name,VoidCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); ///< @copydoc addCommand( const char*, const char *, StringCallback, const char *, S32, S32, bool, ConsoleFunctionHeader* ) - void addCommand(const char *nameSpace, const char *name,BoolCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); ///< @copydoc addCommand( const char*, const char *, StringCallback, const char *, S32, S32, bool, ConsoleFunctionHeader* ) + /// Register a C++ function with the console making it callable + /// as a method of the given namespace from the scripting engine. + /// + /// @param nameSpace Name of the namespace to associate the new function with; this is usually the name of a class. + /// @param name Name of the new function. + /// @param cb Pointer to the function implementing the scripting call; a console callback function returning a specific type value. + /// @param usage Documentation for this function. @ref console_autodoc + /// @param minArgs Minimum number of arguments this function accepts + /// @param maxArgs Maximum number of arguments this function accepts + /// @param toolOnly Wether this is a TORQUE_TOOLS only function. + /// @param header The extended function header. + void addCommand(const char *nameSpace, const char *name, StringCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); - /// @} + void addCommand(const char *nameSpace, const char *name, IntCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); ///< @copydoc addCommand( const char*, const char *, StringCallback, const char *, S32, S32, bool, ConsoleFunctionHeader* ) + void addCommand(const char *nameSpace, const char *name, FloatCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); ///< @copydoc addCommand( const char*, const char *, StringCallback, const char *, S32, S32, bool, ConsoleFunctionHeader* ) + void addCommand(const char *nameSpace, const char *name, VoidCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); ///< @copydoc addCommand( const char*, const char *, StringCallback, const char *, S32, S32, bool, ConsoleFunctionHeader* ) + void addCommand(const char *nameSpace, const char *name, BoolCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); ///< @copydoc addCommand( const char*, const char *, StringCallback, const char *, S32, S32, bool, ConsoleFunctionHeader* ) - /// @name Special Purpose Registration - /// - /// These are special-purpose functions that exist to allow commands to be grouped, so - /// that when we generate console docs, they can be more meaningfully presented. - /// - /// @ref console_autodoc "Click here for more information about console docs and grouping." - /// - /// @{ + /// @} - void markCommandGroup (const char * nsName, const char *name, const char* usage=NULL); + /// @name Special Purpose Registration + /// + /// These are special-purpose functions that exist to allow commands to be grouped, so + /// that when we generate console docs, they can be more meaningfully presented. + /// + /// @ref console_autodoc "Click here for more information about console docs and grouping." + /// + /// @{ + + void markCommandGroup(const char * nsName, const char *name, const char* usage = NULL); void beginCommandGroup(const char * nsName, const char *name, const char* usage); - void endCommandGroup (const char * nsName, const char *name); + void endCommandGroup(const char * nsName, const char *name); - void noteScriptCallback( const char *className, const char *funcName, const char *usage, ConsoleFunctionHeader* header = NULL ); + void noteScriptCallback(const char *className, const char *funcName, const char *usage, ConsoleFunctionHeader* header = NULL); /// @} @@ -841,15 +843,15 @@ namespace Con /// char* getReturnBuffer(U32 bufferSize); char* getReturnBuffer(const char *stringToCopy); - char* getReturnBuffer( const String& str ); - char* getReturnBuffer( const StringBuilder& str ); + char* getReturnBuffer(const String& str); + char* getReturnBuffer(const StringBuilder& str); char* getArgBuffer(U32 bufferSize); char* getFloatArg(F64 arg); - char* getIntArg (S32 arg); + char* getIntArg(S32 arg); char* getBoolArg(bool arg); - char* getStringArg( const char* arg ); - char* getStringArg( const String& arg ); + char* getStringArg(const char* arg); + char* getStringArg(const String& arg); /// @} /// @name Namespaces @@ -877,7 +879,7 @@ namespace Con /// @name Instant Group /// @{ - void pushInstantGroup( String name = String() ); + void pushInstantGroup(String name = String()); void popInstantGroup(); /// @} @@ -915,7 +917,7 @@ namespace Con template ConsoleValueRef executef(R r, ArgTs ...argTs) { - _EngineConsoleExecCallbackHelper callback( r ); + _EngineConsoleExecCallbackHelper callback(r); return callback.template call(argTs...); } /// } @@ -931,25 +933,25 @@ struct ConsoleFunctionHeader { /// Return type string. const char* mReturnString; - + /// List of arguments taken by the function. Used for documentation. const char* mArgString; - + /// List of default argument values. Used for documentation. const char* mDefaultArgString; - + /// Whether this is a static method in a class. bool mIsStatic; - + ConsoleFunctionHeader( const char* returnString, const char* argString, const char* defaultArgString, - bool isStatic = false ) - : mReturnString( returnString ), - mArgString( argString ), - mDefaultArgString( defaultArgString ), - mIsStatic( isStatic ) {} + bool isStatic = false) + : mReturnString(returnString), + mArgString(argString), + mDefaultArgString(defaultArgString), + mIsStatic(isStatic) {} }; @@ -969,7 +971,7 @@ public: /// /// @ref console_autodoc /// @{ - + StringCallback sc; ///< A function/method that returns a string. IntCallback ic; ///< A function/method that returns an int. FloatCallback fc; ///< A function/method that returns a float. @@ -979,18 +981,18 @@ public: bool ns; ///< Indicates that this is a namespace marker. /// @deprecated Unused. bool callback; ///< Is this a callback into script? - - /// @} - /// Minimum number of arguments expected by the function. + /// @} + + /// Minimum number of arguments expected by the function. S32 mina; - + /// Maximum number of arguments accepted by the funtion. Zero for varargs. S32 maxa; - + /// Name of the function/method. const char* funcName; - + /// Name of the class namespace to which to add the method. const char* className; @@ -999,10 +1001,10 @@ public: /// Whether this is a TORQUE_TOOLS only function. bool toolOnly; - + /// The extended function header. ConsoleFunctionHeader* header; - + /// @name ConsoleConstructor Innards /// /// The ConsoleConstructor class is used as the backend for the ConsoleFunction() and @@ -1067,7 +1069,7 @@ public: ConsoleConstructor *next; static ConsoleConstructor *first; - void init( const char* cName, const char* fName, const char *usg, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); + void init(const char* cName, const char* fName, const char *usg, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); static void setup(); @@ -1079,12 +1081,12 @@ public: /// @name Basic Console Constructors /// @{ - ConsoleConstructor( const char* className, const char* funcName, StringCallback sfunc, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); - ConsoleConstructor( const char* className, const char* funcName, IntCallback ifunc, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); - ConsoleConstructor( const char* className, const char* funcName, FloatCallback ffunc, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); - ConsoleConstructor( const char* className, const char* funcName, VoidCallback vfunc, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); - ConsoleConstructor( const char* className, const char* funcName, BoolCallback bfunc, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); - + ConsoleConstructor(const char* className, const char* funcName, StringCallback sfunc, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); + ConsoleConstructor(const char* className, const char* funcName, IntCallback ifunc, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); + ConsoleConstructor(const char* className, const char* funcName, FloatCallback ffunc, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); + ConsoleConstructor(const char* className, const char* funcName, VoidCallback vfunc, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); + ConsoleConstructor(const char* className, const char* funcName, BoolCallback bfunc, const char* usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); + /// @} /// @name Magic Console Constructors @@ -1097,10 +1099,10 @@ public: /// /// @see Con::markCommandGroup /// @ref console_autodoc - ConsoleConstructor( const char *className, const char *groupName, const char* usage ); + ConsoleConstructor(const char *className, const char *groupName, const char* usage); /// Indicates a callback declared with the DECLARE_SCRIPT_CALLBACK macro and friends. - ConsoleConstructor( const char *className, const char *callbackName, const char *usage, ConsoleFunctionHeader* header ); + ConsoleConstructor(const char *className, const char *callbackName, const char *usage, ConsoleFunctionHeader* header); /// @} }; @@ -1112,25 +1114,25 @@ struct ConsoleDocFragment /// The class in which to put the fragment. If NULL, the fragment /// will be placed globally. const char* mClass; - + /// The definition to output for this fragment. NULL for fragments /// not associated with a definition. const char* mDefinition; - + /// The documentation text. const char* mText; - + /// Next fragment in the global link chain. ConsoleDocFragment* mNext; - + /// First fragment in the global link chain. static ConsoleDocFragment* smFirst; - - ConsoleDocFragment( const char* text, const char* inClass = NULL, const char* definition = NULL ) - : mClass( inClass ), - mDefinition( definition ), - mText( text ), - mNext( smFirst ) + + ConsoleDocFragment(const char* text, const char* inClass = NULL, const char* definition = NULL) + : mClass(inClass), + mDefinition(definition), + mText(text), + mNext(smFirst) { smFirst = this; } @@ -1229,7 +1231,7 @@ public: # define ConsoleMethodGroupEnd(className, groupName) \ static ConsoleConstructor cc_##className##_##groupName##_GroupEnd(#className,#groupName,NULL) - + /// Add a fragment of auto-doc text to the console API reference. /// @note There can only be one ConsoleDoc per source file. # define ConsoleDoc( text ) \ diff --git a/Engine/source/console/consoleInternal.cpp b/Engine/source/console/consoleInternal.cpp index c9016e8dc..1d1477325 100644 --- a/Engine/source/console/consoleInternal.cpp +++ b/Engine/source/console/consoleInternal.cpp @@ -20,6 +20,8 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include + #include "platform/platform.h" #include "console/console.h" @@ -43,28 +45,42 @@ DataChunker Namespace::mAllocator; Namespace *Namespace::mNamespaceList = NULL; Namespace *Namespace::mGlobalNamespace = NULL; +namespace std +{ + template<> struct hash> + { + typedef std::pair argument_type; + typedef size_t result_type; + result_type operator()(argument_type const& s) const + { + return HashPointer(s.first) ^ (HashPointer(s.second) << 1); + } + }; +}; + +std::unordered_map, Namespace*> gNamespaceCache; bool canTabComplete(const char *prevText, const char *bestMatch, - const char *newText, S32 baseLen, bool fForward) + const char *newText, S32 baseLen, bool fForward) { // test if it matches the first baseLen chars: - if(dStrnicmp(newText, prevText, baseLen)) + if (dStrnicmp(newText, prevText, baseLen)) return false; if (fForward) { - if(!bestMatch) + if (!bestMatch) return dStricmp(newText, prevText) > 0; else return (dStricmp(newText, prevText) > 0) && - (dStricmp(newText, bestMatch) < 0); + (dStricmp(newText, bestMatch) < 0); } else { - if (dStrlen(prevText) == (U32) baseLen) + if (dStrlen(prevText) == (U32)baseLen) { // look for the 'worst match' - if(!bestMatch) + if (!bestMatch) return dStricmp(newText, prevText) > 0; else return dStricmp(newText, bestMatch) > 0; @@ -75,7 +91,7 @@ bool canTabComplete(const char *prevText, const char *bestMatch, return (dStricmp(newText, prevText) < 0); else return (dStricmp(newText, prevText) < 0) && - (dStricmp(newText, bestMatch) > 0); + (dStricmp(newText, bestMatch) > 0); } } } @@ -100,7 +116,7 @@ struct StringValue StringValue & StringValue::operator=(const char *string) { - if(!val) + if (!val) { val = dStrdup(string); size = dStrlen(val); @@ -108,7 +124,7 @@ StringValue & StringValue::operator=(const char *string) else { S32 len = dStrlen(string); - if(len < size) + if (len < size) dStrcpy(val, string); else { @@ -120,9 +136,9 @@ StringValue & StringValue::operator=(const char *string) return *this; } -static S32 QSORT_CALLBACK varCompare(const void* a,const void* b) +static S32 QSORT_CALLBACK varCompare(const void* a, const void* b) { - return dStricmp( (*((Dictionary::Entry **) a))->name, (*((Dictionary::Entry **) b))->name ); + return dStricmp((*((Dictionary::Entry **) a))->name, (*((Dictionary::Entry **) b))->name); } void Dictionary::exportVariables(const char *varString, const char *fileName, bool append) @@ -130,44 +146,44 @@ void Dictionary::exportVariables(const char *varString, const char *fileName, bo const char *searchStr = varString; Vector sortList(__FILE__, __LINE__); - for(S32 i = 0; i < hashTable->size;i ++) + for (S32 i = 0; i < hashTable->size; i++) { Entry *walk = hashTable->data[i]; - while(walk) + while (walk) { - if(FindMatch::isMatch((char *) searchStr, (char *) walk->name)) + if (FindMatch::isMatch((char *)searchStr, (char *)walk->name)) sortList.push_back(walk); walk = walk->nextEntry; } } - if(!sortList.size()) + if (!sortList.size()) return; - dQsort((void *) &sortList[0], sortList.size(), sizeof(Entry *), varCompare); + dQsort((void *)&sortList[0], sortList.size(), sizeof(Entry *), varCompare); Vector::iterator s; char expandBuffer[1024]; FileStream *strm = NULL; - if(fileName) + if (fileName) { - if((strm = FileStream::createAndOpen( fileName, append ? Torque::FS::File::ReadWrite : Torque::FS::File::Write )) == NULL) + if ((strm = FileStream::createAndOpen(fileName, append ? Torque::FS::File::ReadWrite : Torque::FS::File::Write)) == NULL) { Con::errorf(ConsoleLogEntry::General, "Unable to open file '%s for writing.", fileName); return; } - if(append) + if (append) strm->setPosition(strm->getStreamSize()); } char buffer[1024]; const char *cat = fileName ? "\r\n" : ""; - for(s = sortList.begin(); s != sortList.end(); s++) + for (s = sortList.begin(); s != sortList.end(); s++) { - switch((*s)->value.type) + switch ((*s)->value.type) { case ConsoleValue::TypeInternalInt: dSprintf(buffer, sizeof(buffer), "%s = %d;%s", (*s)->name, (*s)->value.ival, cat); @@ -180,65 +196,65 @@ void Dictionary::exportVariables(const char *varString, const char *fileName, bo dSprintf(buffer, sizeof(buffer), "%s = \"%s\";%s", (*s)->name, expandBuffer, cat); break; } - if(strm) + if (strm) strm->write(dStrlen(buffer), buffer); else Con::printf("%s", buffer); } - if(strm) + if (strm) delete strm; } -void Dictionary::exportVariables( const char *varString, Vector *names, Vector *values ) +void Dictionary::exportVariables(const char *varString, Vector *names, Vector *values) { const char *searchStr = varString; Vector sortList(__FILE__, __LINE__); - for ( S32 i = 0; i < hashTable->size; i++ ) + for (S32 i = 0; i < hashTable->size; i++) { Entry *walk = hashTable->data[i]; - while ( walk ) + while (walk) { - if ( FindMatch::isMatch( (char*)searchStr, (char*)walk->name ) ) - sortList.push_back( walk ); + if (FindMatch::isMatch((char*)searchStr, (char*)walk->name)) + sortList.push_back(walk); walk = walk->nextEntry; } } - if ( !sortList.size() ) + if (!sortList.size()) return; - dQsort((void *) &sortList[0], sortList.size(), sizeof(Entry *), varCompare); + dQsort((void *)&sortList[0], sortList.size(), sizeof(Entry *), varCompare); - if ( names ) - names->reserve( sortList.size() ); - if ( values ) - values->reserve( sortList.size() ); + if (names) + names->reserve(sortList.size()); + if (values) + values->reserve(sortList.size()); char expandBuffer[1024]; Vector::iterator s; - for ( s = sortList.begin(); s != sortList.end(); s++ ) + for (s = sortList.begin(); s != sortList.end(); s++) { - if ( names ) - names->push_back( String( (*s)->name ) ); + if (names) + names->push_back(String((*s)->name)); - if ( values ) + if (values) { - switch ( (*s)->value.type ) + switch ((*s)->value.type) { - case ConsoleValue::TypeInternalInt: - values->push_back( String::ToString( (*s)->value.ival ) ); - break; - case ConsoleValue::TypeInternalFloat: - values->push_back( String::ToString( (*s)->value.fval ) ); - break; - default: - expandEscape( expandBuffer, (*s)->getStringValue() ); - values->push_back( expandBuffer ); - break; + case ConsoleValue::TypeInternalInt: + values->push_back(String::ToString((*s)->value.ival)); + break; + case ConsoleValue::TypeInternalFloat: + values->push_back(String::ToString((*s)->value.fval)); + break; + default: + expandEscape(expandBuffer, (*s)->getStringValue()); + values->push_back(expandBuffer); + break; } } } @@ -248,12 +264,12 @@ void Dictionary::deleteVariables(const char *varString) { const char *searchStr = varString; - for(S32 i = 0; i < hashTable->size; i++) + for (S32 i = 0; i < hashTable->size; i++) { Entry *walk = hashTable->data[i]; - while(walk) + while (walk) { - Entry *matchedEntry = (FindMatch::isMatch((char *) searchStr, (char *) walk->name)) ? walk : NULL; + Entry *matchedEntry = (FindMatch::isMatch((char *)searchStr, (char *)walk->name)) ? walk : NULL; walk = walk->nextEntry; if (matchedEntry) remove(matchedEntry); // assumes remove() is a stable remove (will not reorder entries on remove) @@ -269,9 +285,9 @@ U32 HashPointer(StringTableEntry ptr) Dictionary::Entry *Dictionary::lookup(StringTableEntry name) { Entry *walk = hashTable->data[HashPointer(name) % hashTable->size]; - while(walk) + while (walk) { - if(walk->name == name) + if (walk->name == name) return walk; else walk = walk->nextEntry; @@ -284,56 +300,56 @@ Dictionary::Entry *Dictionary::add(StringTableEntry name) { // Try to find an existing match. //printf("Add Variable %s\n", name); - - Entry* ret = lookup( name ); - if( ret ) + + Entry* ret = lookup(name); + if (ret) return ret; - + // Rehash if the table get's too crowded. Be aware that this might // modify a table that we don't own. - hashTable->count ++; - if( hashTable->count > hashTable->size * 2 ) + hashTable->count++; + if (hashTable->count > hashTable->size * 2) { // Allocate a new table. - + const U32 newTableSize = hashTable->size * 4 - 1; - Entry** newTableData = new Entry*[ newTableSize ]; - dMemset( newTableData, 0, newTableSize * sizeof( Entry* ) ); - + Entry** newTableData = new Entry*[newTableSize]; + dMemset(newTableData, 0, newTableSize * sizeof(Entry*)); + // Move the entries over. - - for( U32 i = 0; i < hashTable->size; ++ i ) - for( Entry* entry = hashTable->data[ i ]; entry != NULL; ) + + for (U32 i = 0; i < hashTable->size; ++i) + for (Entry* entry = hashTable->data[i]; entry != NULL; ) { Entry* next = entry->nextEntry; - U32 index = HashPointer( entry->name ) % newTableSize; - - entry->nextEntry = newTableData[ index ]; - newTableData[ index ] = entry; - + U32 index = HashPointer(entry->name) % newTableSize; + + entry->nextEntry = newTableData[index]; + newTableData[index] = entry; + entry = next; } - + // Switch the tables. - + delete[] hashTable->data; hashTable->data = newTableData; hashTable->size = newTableSize; } - - #ifdef DEBUG_SPEW - Platform::outputDebugString( "[ConsoleInternal] Adding entry '%s'", name ); - #endif - + +#ifdef DEBUG_SPEW + Platform::outputDebugString("[ConsoleInternal] Adding entry '%s'", name); +#endif + // Add the new entry. ret = hashTable->mChunker.alloc(); - constructInPlace( ret, name ); + constructInPlace(ret, name); U32 idx = HashPointer(name) % hashTable->size; ret->nextEntry = hashTable->data[idx]; hashTable->data[idx] = ret; - + return ret; } @@ -341,88 +357,88 @@ Dictionary::Entry *Dictionary::add(StringTableEntry name) void Dictionary::remove(Dictionary::Entry *ent) { Entry **walk = &hashTable->data[HashPointer(ent->name) % hashTable->size]; - while(*walk != ent) + while (*walk != ent) walk = &((*walk)->nextEntry); - - #ifdef DEBUG_SPEW - Platform::outputDebugString( "[ConsoleInternal] Removing entry '%s'", ent->name ); - #endif + +#ifdef DEBUG_SPEW + Platform::outputDebugString("[ConsoleInternal] Removing entry '%s'", ent->name); +#endif *walk = (ent->nextEntry); - destructInPlace( ent ); - hashTable->mChunker.free( ent ); + destructInPlace(ent); + hashTable->mChunker.free(ent); hashTable->count--; } Dictionary::Dictionary() - : hashTable( NULL ), + : hashTable(NULL), #pragma warning( disable : 4355 ) - ownHashTable( this ), // Warning with VC++ but this is safe. + ownHashTable(this), // Warning with VC++ but this is safe. #pragma warning( default : 4355 ) - exprState( NULL ), - scopeName( NULL ), - scopeNamespace( NULL ), - code( NULL ), - ip( 0 ) + exprState(NULL), + scopeName(NULL), + scopeNamespace(NULL), + code(NULL), + ip(0) { } void Dictionary::setState(ExprEvalState *state, Dictionary* ref) { exprState = state; - - if( ref ) + + if (ref) { hashTable = ref->hashTable; return; } - if( !ownHashTable.data ) + if (!ownHashTable.data) { ownHashTable.count = 0; ownHashTable.size = ST_INIT_SIZE; - ownHashTable.data = new Entry *[ ownHashTable.size ]; - - dMemset( ownHashTable.data, 0, ownHashTable.size * sizeof( Entry* ) ); + ownHashTable.data = new Entry *[ownHashTable.size]; + + dMemset(ownHashTable.data, 0, ownHashTable.size * sizeof(Entry*)); } - + hashTable = &ownHashTable; } Dictionary::~Dictionary() { reset(); - if( ownHashTable.data ) - delete [] ownHashTable.data; + if (ownHashTable.data) + delete[] ownHashTable.data; } void Dictionary::reset() { - if( hashTable && hashTable->owner != this ) + if (hashTable && hashTable->owner != this) { hashTable = NULL; return; } - - for( U32 i = 0; i < ownHashTable.size; ++ i ) + + for (U32 i = 0; i < ownHashTable.size; ++i) { Entry* walk = ownHashTable.data[i]; - while( walk ) + while (walk) { Entry* temp = walk->nextEntry; - destructInPlace( walk ); + destructInPlace(walk); walk = temp; } } - dMemset( ownHashTable.data, 0, ownHashTable.size * sizeof( Entry* ) ); - ownHashTable.mChunker.freeBlocks( true ); - + dMemset(ownHashTable.data, 0, ownHashTable.size * sizeof(Entry*)); + ownHashTable.mChunker.freeBlocks(true); + ownHashTable.count = 0; hashTable = NULL; - + scopeName = NULL; scopeNamespace = NULL; code = NULL; @@ -435,12 +451,12 @@ const char *Dictionary::tabComplete(const char *prevText, S32 baseLen, bool fFor S32 i; const char *bestMatch = NULL; - for(i = 0; i < hashTable->size; i++) + for (i = 0; i < hashTable->size; i++) { Entry *walk = hashTable->data[i]; - while(walk) + while (walk) { - if(canTabComplete(prevText, bestMatch, walk->name, baseLen, fForward)) + if (canTabComplete(prevText, bestMatch, walk->name, baseLen, fForward)) bestMatch = walk->name; walk = walk->nextEntry; } @@ -469,24 +485,24 @@ Dictionary::Entry::~Entry() { value.cleanup(); - if ( notify ) + if (notify) delete notify; } const char *Dictionary::getVariable(StringTableEntry name, bool *entValid) { Entry *ent = lookup(name); - if(ent) + if (ent) { - if(entValid) + if (entValid) *entValid = true; return ent->getStringValue(); } - if(entValid) + if (entValid) *entValid = false; // Warn users when they access a variable that isn't defined. - if(gWarnUndefinedScriptVariables) + if (gWarnUndefinedScriptVariables) Con::warnf(" *** Accessed undefined variable '%s'", name); return ""; @@ -496,20 +512,20 @@ void ConsoleValue::setStringValue(const char * value) { if (value == NULL) value = typeValueEmpty; - if(type <= ConsoleValue::TypeInternalString) + if (type <= ConsoleValue::TypeInternalString) { // Let's not remove empty-string-valued global vars from the dict. // If we remove them, then they won't be exported, and sometimes // it could be necessary to export such a global. There are very // few empty-string global vars so there's no performance-related // need to remove them from the dict. -/* + /* if(!value[0] && name[0] == '$') { - gEvalState.globalVars.remove(this); - return; + gEvalState.globalVars.remove(this); + return; } -*/ + */ if (value == typeValueEmpty) { if (bufferLen > 0) @@ -531,7 +547,7 @@ void ConsoleValue::setStringValue(const char * value) // // (This decision may come back to haunt you. Shame on you if it // does.) - if(stringLen < 256) + if (stringLen < 256) { fval = dAtof(value); ival = dAtoi(value); @@ -544,11 +560,11 @@ void ConsoleValue::setStringValue(const char * value) // may as well pad to the next cache line U32 newLen = ((stringLen + 1) + 15) & ~15; - - if(bufferLen == 0) - sval = (char *) dMalloc(newLen); - else if(newLen > bufferLen) - sval = (char *) dRealloc(sval, newLen); + + if (bufferLen == 0) + sval = (char *)dMalloc(newLen); + else if (newLen > bufferLen) + sval = (char *)dRealloc(sval, newLen); type = TypeInternalString; @@ -556,7 +572,7 @@ void ConsoleValue::setStringValue(const char * value) dStrcpy(sval, value); } else - Con::setData(type, dataPtr, 0, 1, &value, enumTable); + Con::setData(type, dataPtr, 0, 1, &value, enumTable); } @@ -564,7 +580,7 @@ void ConsoleValue::setStackStringValue(const char *value) { if (value == NULL) value = typeValueEmpty; - if(type <= ConsoleValue::TypeInternalString) + if (type <= ConsoleValue::TypeInternalString) { // sval might still be temporarily present so we need to check and free it if (bufferLen > 0) @@ -583,7 +599,7 @@ void ConsoleValue::setStackStringValue(const char *value) } U32 stringLen = dStrlen(value); - if(stringLen < 256) + if (stringLen < 256) { fval = dAtof(value); ival = dAtoi(value); @@ -599,12 +615,12 @@ void ConsoleValue::setStackStringValue(const char *value) bufferLen = 0; } else - Con::setData(type, dataPtr, 0, 1, &value, enumTable); + Con::setData(type, dataPtr, 0, 1, &value, enumTable); } void ConsoleValue::setStringStackPtrValue(StringStackPtr ptrValue) { - if(type <= ConsoleValue::TypeInternalString) + if (type <= ConsoleValue::TypeInternalString) { const char *value = StringStackPtrRef(ptrValue).getPtr(&STR); if (bufferLen > 0) @@ -614,7 +630,7 @@ void ConsoleValue::setStringStackPtrValue(StringStackPtr ptrValue) } U32 stringLen = dStrlen(value); - if(stringLen < 256) + if (stringLen < 256) { fval = dAtof(value); ival = dAtoi(value); @@ -632,37 +648,37 @@ void ConsoleValue::setStringStackPtrValue(StringStackPtr ptrValue) else { const char *value = StringStackPtrRef(ptrValue).getPtr(&STR); - Con::setData(type, dataPtr, 0, 1, &value, enumTable); + Con::setData(type, dataPtr, 0, 1, &value, enumTable); } } S32 Dictionary::getIntVariable(StringTableEntry name, bool *entValid) { Entry *ent = lookup(name); - if(ent) + if (ent) { - if(entValid) + if (entValid) *entValid = true; return ent->getIntValue(); } - if(entValid) + if (entValid) *entValid = false; - return 0; + return 0; } F32 Dictionary::getFloatVariable(StringTableEntry name, bool *entValid) { Entry *ent = lookup(name); - if(ent) + if (ent) { - if(entValid) + if (entValid) *entValid = true; return ent->getFloatValue(); } - if(entValid) + if (entValid) *entValid = false; return 0; @@ -671,19 +687,19 @@ F32 Dictionary::getFloatVariable(StringTableEntry name, bool *entValid) void Dictionary::setVariable(StringTableEntry name, const char *value) { Entry *ent = add(name); - if(!value) + if (!value) value = ""; ent->setStringValue(value); } -Dictionary::Entry* Dictionary::addVariable( const char *name, - S32 type, - void *dataPtr, - const char* usage ) +Dictionary::Entry* Dictionary::addVariable(const char *name, + S32 type, + void *dataPtr, + const char* usage) { - AssertFatal( type >= 0, "Dictionary::addVariable - Got bad type!" ); + AssertFatal(type >= 0, "Dictionary::addVariable - Got bad type!"); - if(name[0] != '$') + if (name[0] != '$') { scratchBuffer[0] = '$'; dStrcpy(scratchBuffer + 1, name); @@ -691,142 +707,142 @@ Dictionary::Entry* Dictionary::addVariable( const char *name, } Entry *ent = add(StringTable->insert(name)); - - if ( ent->value.type <= ConsoleValue::TypeInternalString && - ent->value.bufferLen > 0 ) + + if (ent->value.type <= ConsoleValue::TypeInternalString && + ent->value.bufferLen > 0) dFree(ent->value.sval); ent->value.type = type; ent->value.dataPtr = dataPtr; ent->mUsage = usage; - + // Fetch enum table, if any. - - ConsoleBaseType* conType = ConsoleBaseType::getType( type ); - AssertFatal( conType, "Dictionary::addVariable - invalid console type" ); + + ConsoleBaseType* conType = ConsoleBaseType::getType(type); + AssertFatal(conType, "Dictionary::addVariable - invalid console type"); ent->value.enumTable = conType->getEnumTable(); - + return ent; } bool Dictionary::removeVariable(StringTableEntry name) { - if( Entry *ent = lookup(name) ) + if (Entry *ent = lookup(name)) { - remove( ent ); + remove(ent); return true; } return false; } -void Dictionary::addVariableNotify( const char *name, const Con::NotifyDelegate &callback ) +void Dictionary::addVariableNotify(const char *name, const Con::NotifyDelegate &callback) { Entry *ent = lookup(StringTable->insert(name)); - if ( !ent ) - return; + if (!ent) + return; - if ( !ent->notify ) + if (!ent->notify) ent->notify = new Entry::NotifySignal(); - ent->notify->notify( callback ); + ent->notify->notify(callback); } -void Dictionary::removeVariableNotify( const char *name, const Con::NotifyDelegate &callback ) +void Dictionary::removeVariableNotify(const char *name, const Con::NotifyDelegate &callback) { Entry *ent = lookup(StringTable->insert(name)); - if ( ent && ent->notify ) - ent->notify->remove( callback ); + if (ent && ent->notify) + ent->notify->remove(callback); } void Dictionary::validate() { - AssertFatal( ownHashTable.owner == this, - "Dictionary::validate() - Dictionary not owner of own hashtable!" ); + AssertFatal(ownHashTable.owner == this, + "Dictionary::validate() - Dictionary not owner of own hashtable!"); } void ExprEvalState::pushFrame(StringTableEntry frameName, Namespace *ns) -{ - #ifdef DEBUG_SPEW +{ +#ifdef DEBUG_SPEW validate(); - Platform::outputDebugString( "[ConsoleInternal] Pushing new frame for '%s' at %i", - frameName, mStackDepth ); - #endif - - if( mStackDepth + 1 > stack.size() ) + Platform::outputDebugString("[ConsoleInternal] Pushing new frame for '%s' at %i", + frameName, mStackDepth); +#endif + + if (mStackDepth + 1 > stack.size()) { - #ifdef DEBUG_SPEW - Platform::outputDebugString( "[ConsoleInternal] Growing stack by one frame" ); - #endif - - stack.push_back( new Dictionary ); +#ifdef DEBUG_SPEW + Platform::outputDebugString("[ConsoleInternal] Growing stack by one frame"); +#endif + + stack.push_back(new Dictionary); } - - Dictionary& newFrame = *( stack[ mStackDepth ] ); - newFrame.setState( this ); - + + Dictionary& newFrame = *(stack[mStackDepth]); + newFrame.setState(this); + newFrame.scopeName = frameName; newFrame.scopeNamespace = ns; - mStackDepth ++; + mStackDepth++; currentVariable = NULL; - - AssertFatal( !newFrame.getCount(), "ExprEvalState::pushFrame - Dictionary not empty!" ); - - #ifdef DEBUG_SPEW + + AssertFatal(!newFrame.getCount(), "ExprEvalState::pushFrame - Dictionary not empty!"); + +#ifdef DEBUG_SPEW validate(); - #endif +#endif } void ExprEvalState::popFrame() { - AssertFatal( mStackDepth > 0, "ExprEvalState::popFrame - Stack Underflow!" ); - - #ifdef DEBUG_SPEW - validate(); - - Platform::outputDebugString( "[ConsoleInternal] Popping %sframe at %i", - getCurrentFrame().isOwner() ? "" : "shared ", mStackDepth - 1 ); - #endif + AssertFatal(mStackDepth > 0, "ExprEvalState::popFrame - Stack Underflow!"); - mStackDepth --; - stack[ mStackDepth ]->reset(); +#ifdef DEBUG_SPEW + validate(); + + Platform::outputDebugString("[ConsoleInternal] Popping %sframe at %i", + getCurrentFrame().isOwner() ? "" : "shared ", mStackDepth - 1); +#endif + + mStackDepth--; + stack[mStackDepth]->reset(); currentVariable = NULL; - #ifdef DEBUG_SPEW +#ifdef DEBUG_SPEW validate(); - #endif +#endif } void ExprEvalState::pushFrameRef(S32 stackIndex) { - AssertFatal( stackIndex >= 0 && stackIndex < stack.size(), "You must be asking for a valid frame!" ); + AssertFatal(stackIndex >= 0 && stackIndex < stack.size(), "You must be asking for a valid frame!"); - #ifdef DEBUG_SPEW +#ifdef DEBUG_SPEW validate(); - - Platform::outputDebugString( "[ConsoleInternal] Cloning frame from %i to %i", - stackIndex, mStackDepth ); - #endif - if( mStackDepth + 1 > stack.size() ) + Platform::outputDebugString("[ConsoleInternal] Cloning frame from %i to %i", + stackIndex, mStackDepth); +#endif + + if (mStackDepth + 1 > stack.size()) { - #ifdef DEBUG_SPEW - Platform::outputDebugString( "[ConsoleInternal] Growing stack by one frame" ); - #endif - - stack.push_back( new Dictionary ); +#ifdef DEBUG_SPEW + Platform::outputDebugString("[ConsoleInternal] Growing stack by one frame"); +#endif + + stack.push_back(new Dictionary); } - Dictionary& newFrame = *( stack[ mStackDepth ] ); - newFrame.setState( this, stack[ stackIndex ] ); - - mStackDepth ++; + Dictionary& newFrame = *(stack[mStackDepth]); + newFrame.setState(this, stack[stackIndex]); + + mStackDepth++; currentVariable = NULL; - - #ifdef DEBUG_SPEW + +#ifdef DEBUG_SPEW validate(); - #endif +#endif } ExprEvalState::ExprEvalState() @@ -837,7 +853,7 @@ ExprEvalState::ExprEvalState() traceOn = false; currentVariable = NULL; mStackDepth = 0; - stack.reserve( 64 ); + stack.reserve(64); mShouldReset = false; mResetLocked = false; } @@ -845,8 +861,8 @@ ExprEvalState::ExprEvalState() ExprEvalState::~ExprEvalState() { // Delete callframes. - - while( !stack.empty() ) + + while (!stack.empty()) { delete stack.last(); stack.decrement(); @@ -855,14 +871,14 @@ ExprEvalState::~ExprEvalState() void ExprEvalState::validate() { - AssertFatal( mStackDepth <= stack.size(), - "ExprEvalState::validate() - Stack depth pointing beyond last stack frame!" ); - - for( U32 i = 0; i < stack.size(); ++ i ) - stack[ i ]->validate(); + AssertFatal(mStackDepth <= stack.size(), + "ExprEvalState::validate() - Stack depth pointing beyond last stack frame!"); + + for (U32 i = 0; i < stack.size(); ++i) + stack[i]->validate(); } -DefineEngineFunction(backtrace, void, ( ),, +DefineEngineFunction(backtrace, void, (), , "@brief Prints the scripting call stack to the console log.\n\n" "Used to trace functions called from within functions. Can help discover what functions were called " "(and not yet exited) before the current point in scripts.\n\n" @@ -870,34 +886,34 @@ DefineEngineFunction(backtrace, void, ( ),, { U32 totalSize = 1; - for(U32 i = 0; i < gEvalState.getStackDepth(); i++) + for (U32 i = 0; i < gEvalState.getStackDepth(); i++) { - if(gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage) - totalSize += dStrlen(gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage) + 2; - if(gEvalState.stack[i]->scopeName) - totalSize += dStrlen(gEvalState.stack[i]->scopeName) + 3; - if(gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mName) + if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage) + totalSize += dStrlen(gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage) + 2; + if (gEvalState.stack[i]->scopeName) + totalSize += dStrlen(gEvalState.stack[i]->scopeName) + 3; + if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mName) totalSize += dStrlen(gEvalState.stack[i]->scopeNamespace->mName) + 2; } char *buf = Con::getReturnBuffer(totalSize); buf[0] = 0; - for(U32 i = 0; i < gEvalState.getStackDepth(); i++) + for (U32 i = 0; i < gEvalState.getStackDepth(); i++) { dStrcat(buf, "->"); - - if(gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage) - { - dStrcat(buf, "["); - dStrcat(buf, gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage); - dStrcat(buf, "]"); - } - if(gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mName) + + if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage) + { + dStrcat(buf, "["); + dStrcat(buf, gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage); + dStrcat(buf, "]"); + } + if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mName) { dStrcat(buf, gEvalState.stack[i]->scopeNamespace->mName); dStrcat(buf, "::"); } - if(gEvalState.stack[i]->scopeName) + if (gEvalState.stack[i]->scopeName) dStrcat(buf, gEvalState.stack[i]->scopeName); } @@ -915,14 +931,14 @@ Namespace::Entry::Entry() void Namespace::Entry::clear() { - if(mCode) + if (mCode) { mCode->decRefCount(); mCode = NULL; } // Clean up usage strings generated for script functions. - if( ( mType == Namespace::Entry::ConsoleFunctionType ) && mUsage ) + if ((mType == Namespace::Entry::ConsoleFunctionType) && mUsage) { dFree(mUsage); mUsage = NULL; @@ -948,7 +964,7 @@ Namespace::Namespace() Namespace::~Namespace() { clearEntries(); - if( mUsage && mCleanUpUsage ) + if (mUsage && mCleanUpUsage) { dFree(mUsage); mUsage = NULL; @@ -958,33 +974,36 @@ Namespace::~Namespace() void Namespace::clearEntries() { - for(Entry *walk = mEntryList; walk; walk = walk->mNext) + for (Entry *walk = mEntryList; walk; walk = walk->mNext) walk->clear(); } Namespace *Namespace::find(StringTableEntry name, StringTableEntry package) { - if ( name == NULL && package == NULL ) + if (name == NULL && package == NULL) return mGlobalNamespace; - for(Namespace *walk = mNamespaceList; walk; walk = walk->mNext) - { - if(walk->mName == name && walk->mPackage == package) - return walk; - } + auto pair = std::make_pair(name, package); + auto pos = gNamespaceCache.find(pair); + if (pos != gNamespaceCache.end()) + return pos->second; - Namespace *ret = (Namespace *) mAllocator.alloc(sizeof(Namespace)); + Namespace *ret = (Namespace *)mAllocator.alloc(sizeof(Namespace)); constructInPlace(ret); ret->mPackage = package; ret->mName = name; ret->mNext = mNamespaceList; mNamespaceList = ret; + + // insert into namespace cache. + gNamespaceCache[pair] = ret; + return ret; } -bool Namespace::unlinkClass( Namespace *parent ) +bool Namespace::unlinkClass(Namespace *parent) { - AssertFatal( mPackage == NULL, "Namespace::unlinkClass - Must not be called on a namespace coming from a package!" ); + AssertFatal(mPackage == NULL, "Namespace::unlinkClass - Must not be called on a namespace coming from a package!"); // Skip additions to this namespace coming from packages. @@ -992,7 +1011,7 @@ bool Namespace::unlinkClass( Namespace *parent ) // Make sure "parent" is the direct parent namespace. - if( parent != NULL && walk->mParent && walk->mParent != parent ) + if (parent != NULL && walk->mParent && walk->mParent != parent) { Con::errorf(ConsoleLogEntry::General, "Namespace::unlinkClass - cannot unlink namespace parent linkage for %s for %s.", walk->mName, walk->mParent->mName); @@ -1003,12 +1022,12 @@ bool Namespace::unlinkClass( Namespace *parent ) // the bottom-most namespace, i.e. the one guaranteed not // to come from a package. - mRefCountToParent --; - AssertFatal( mRefCountToParent >= 0, "Namespace::unlinkClass - reference count to parent is less than 0" ); + mRefCountToParent--; + AssertFatal(mRefCountToParent >= 0, "Namespace::unlinkClass - reference count to parent is less than 0"); // Unlink if the count dropped to zero. - if( mRefCountToParent == 0 ) + if (mRefCountToParent == 0) { walk->mParent = NULL; trashCache(); @@ -1022,7 +1041,7 @@ bool Namespace::classLinkTo(Namespace *parent) { Namespace* walk = getPackageRoot(); - if(walk->mParent && walk->mParent != parent) + if (walk->mParent && walk->mParent != parent) { Con::errorf(ConsoleLogEntry::General, "Error: cannot change namespace parent linkage of %s from %s to %s.", walk->mName, walk->mParent->mName, parent->mName); @@ -1039,10 +1058,10 @@ bool Namespace::classLinkTo(Namespace *parent) void Namespace::buildHashTable() { - if(mHashSequence == mCacheSequence) + if (mHashSequence == mCacheSequence) return; - if(!mEntryList && mParent) + if (!mEntryList && mParent) { mParent->buildHashTable(); mHashTable = mParent->mHashTable; @@ -1053,33 +1072,33 @@ void Namespace::buildHashTable() U32 entryCount = 0; Namespace * ns; - for(ns = this; ns; ns = ns->mParent) - for(Entry *walk = ns->mEntryList; walk; walk = walk->mNext) - if(lookupRecursive(walk->mFunctionName) == walk) + for (ns = this; ns; ns = ns->mParent) + for (Entry *walk = ns->mEntryList; walk; walk = walk->mNext) + if (lookupRecursive(walk->mFunctionName) == walk) entryCount++; mHashSize = entryCount + (entryCount >> 1) + 1; - if(!(mHashSize & 1)) + if (!(mHashSize & 1)) mHashSize++; - mHashTable = (Entry **) mCacheAllocator.alloc(sizeof(Entry *) * mHashSize); - for(U32 i = 0; i < mHashSize; i++) + mHashTable = (Entry **)mCacheAllocator.alloc(sizeof(Entry *) * mHashSize); + for (U32 i = 0; i < mHashSize; i++) mHashTable[i] = NULL; - for(ns = this; ns; ns = ns->mParent) + for (ns = this; ns; ns = ns->mParent) { - for(Entry *walk = ns->mEntryList; walk; walk = walk->mNext) + for (Entry *walk = ns->mEntryList; walk; walk = walk->mNext) { U32 index = HashPointer(walk->mFunctionName) % mHashSize; - while(mHashTable[index] && mHashTable[index]->mFunctionName != walk->mFunctionName) + while (mHashTable[index] && mHashTable[index]->mFunctionName != walk->mFunctionName) { index++; - if(index >= mHashSize) + if (index >= mHashSize) index = 0; } - if(!mHashTable[index]) + if (!mHashTable[index]) mHashTable[index] = walk; } } @@ -1087,15 +1106,15 @@ void Namespace::buildHashTable() mHashSequence = mCacheSequence; } -void Namespace::getUniqueEntryLists( Namespace *other, VectorPtr *outThisList, VectorPtr *outOtherList ) +void Namespace::getUniqueEntryLists(Namespace *other, VectorPtr *outThisList, VectorPtr *outOtherList) { // All namespace entries in the common ACR should be // ignored when checking for duplicate entry names. static VectorPtr commonEntries; commonEntries.clear(); - AbstractClassRep *commonACR = mClassRep->getCommonParent( other->mClassRep ); - commonACR->getNameSpace()->getEntryList( &commonEntries ); + AbstractClassRep *commonACR = mClassRep->getCommonParent(other->mClassRep); + commonACR->getNameSpace()->getEntryList(&commonEntries); // Make life easier VectorPtr &thisEntries = *outThisList; @@ -1105,29 +1124,29 @@ void Namespace::getUniqueEntryLists( Namespace *other, VectorPtr *outTh thisEntries.clear(); compEntries.clear(); - getEntryList( &thisEntries ); - other->getEntryList( &compEntries ); + getEntryList(&thisEntries); + other->getEntryList(&compEntries); // Run through all of the entries in the common ACR, and remove them from // the other two entry lists - for( NamespaceEntryListIterator itr = commonEntries.begin(); itr != commonEntries.end(); itr++ ) + for (NamespaceEntryListIterator itr = commonEntries.begin(); itr != commonEntries.end(); itr++) { // Check this entry list - for( NamespaceEntryListIterator thisItr = thisEntries.begin(); thisItr != thisEntries.end(); thisItr++ ) + for (NamespaceEntryListIterator thisItr = thisEntries.begin(); thisItr != thisEntries.end(); thisItr++) { - if( *thisItr == *itr ) + if (*thisItr == *itr) { - thisEntries.erase( thisItr ); + thisEntries.erase(thisItr); break; } } // Same check for component entry list - for( NamespaceEntryListIterator compItr = compEntries.begin(); compItr != compEntries.end(); compItr++ ) + for (NamespaceEntryListIterator compItr = compEntries.begin(); compItr != compEntries.end(); compItr++) { - if( *compItr == *itr ) + if (*compItr == *itr) { - compEntries.erase( compItr ); + compEntries.erase(compItr); break; } } @@ -1137,12 +1156,15 @@ void Namespace::getUniqueEntryLists( Namespace *other, VectorPtr *outTh void Namespace::init() { // create the global namespace - mGlobalNamespace = (Namespace *) mAllocator.alloc(sizeof(Namespace)); + mGlobalNamespace = (Namespace *)mAllocator.alloc(sizeof(Namespace)); constructInPlace(mGlobalNamespace); mGlobalNamespace->mPackage = NULL; mGlobalNamespace->mName = NULL; mGlobalNamespace->mNext = NULL; mNamespaceList = mGlobalNamespace; + + // Insert into namespace cache. + gNamespaceCache[std::make_pair(mGlobalNamespace->mName, mGlobalNamespace->mPackage)] = mGlobalNamespace; } Namespace *Namespace::global() @@ -1155,7 +1177,7 @@ void Namespace::shutdown() // The data chunker will release all memory in one go // without calling destructors, so we do this manually here. - for(Namespace *walk = mNamespaceList; walk; walk = walk->mNext) + for (Namespace *walk = mNamespaceList; walk; walk = walk->mNext) walk->~Namespace(); } @@ -1167,21 +1189,21 @@ void Namespace::trashCache() const char *Namespace::tabComplete(const char *prevText, S32 baseLen, bool fForward) { - if(mHashSequence != mCacheSequence) + if (mHashSequence != mCacheSequence) buildHashTable(); const char *bestMatch = NULL; - for(U32 i = 0; i < mHashSize; i++) - if(mHashTable[i] && canTabComplete(prevText, bestMatch, mHashTable[i]->mFunctionName, baseLen, fForward)) + for (U32 i = 0; i < mHashSize; i++) + if (mHashTable[i] && canTabComplete(prevText, bestMatch, mHashTable[i]->mFunctionName, baseLen, fForward)) bestMatch = mHashTable[i]->mFunctionName; return bestMatch; } Namespace::Entry *Namespace::lookupRecursive(StringTableEntry name) { - for(Namespace *ns = this; ns; ns = ns->mParent) - for(Entry *walk = ns->mEntryList; walk; walk = walk->mNext) - if(walk->mFunctionName == name) + for (Namespace *ns = this; ns; ns = ns->mParent) + for (Entry *walk = ns->mEntryList; walk; walk = walk->mNext) + if (walk->mFunctionName == name) return walk; return NULL; @@ -1189,20 +1211,20 @@ Namespace::Entry *Namespace::lookupRecursive(StringTableEntry name) Namespace::Entry *Namespace::lookup(StringTableEntry name) { - if(mHashSequence != mCacheSequence) + if (mHashSequence != mCacheSequence) buildHashTable(); U32 index = HashPointer(name) % mHashSize; - while(mHashTable[index] && mHashTable[index]->mFunctionName != name) + while (mHashTable[index] && mHashTable[index]->mFunctionName != name) { index++; - if(index >= mHashSize) + if (index >= mHashSize) index = 0; } return mHashTable[index]; } -static S32 QSORT_CALLBACK compareEntries(const void* a,const void* b) +static S32 QSORT_CALLBACK compareEntries(const void* a, const void* b) { const Namespace::Entry* fa = *((Namespace::Entry**)a); const Namespace::Entry* fb = *((Namespace::Entry**)b); @@ -1212,28 +1234,28 @@ static S32 QSORT_CALLBACK compareEntries(const void* a,const void* b) void Namespace::getEntryList(VectorPtr *vec) { - if(mHashSequence != mCacheSequence) + if (mHashSequence != mCacheSequence) buildHashTable(); - for(U32 i = 0; i < mHashSize; i++) - if(mHashTable[i]) + for (U32 i = 0; i < mHashSize; i++) + if (mHashTable[i]) vec->push_back(mHashTable[i]); - dQsort(vec->address(),vec->size(),sizeof(Namespace::Entry *),compareEntries); + dQsort(vec->address(), vec->size(), sizeof(Namespace::Entry *), compareEntries); } Namespace::Entry *Namespace::createLocalEntry(StringTableEntry name) { - for(Entry *walk = mEntryList; walk; walk = walk->mNext) + for (Entry *walk = mEntryList; walk; walk = walk->mNext) { - if(walk->mFunctionName == name) + if (walk->mFunctionName == name) { walk->clear(); return walk; } } - Entry *ent = (Entry *) mAllocator.alloc(sizeof(Entry)); + Entry *ent = (Entry *)mAllocator.alloc(sizeof(Entry)); constructInPlace(ent); ent->mNamespace = this; @@ -1245,7 +1267,7 @@ Namespace::Entry *Namespace::createLocalEntry(StringTableEntry name) return ent; } -void Namespace::addFunction( StringTableEntry name, CodeBlock *cb, U32 functionOffset, const char* usage, U32 lineNumber ) +void Namespace::addFunction(StringTableEntry name, CodeBlock *cb, U32 functionOffset, const char* usage, U32 lineNumber) { Entry *ent = createLocalEntry(name); trashCache(); @@ -1255,10 +1277,10 @@ void Namespace::addFunction( StringTableEntry name, CodeBlock *cb, U32 functionO ent->mFunctionOffset = functionOffset; ent->mCode->incRefCount(); ent->mType = Entry::ConsoleFunctionType; - ent->mFunctionLineNumber = lineNumber; + ent->mFunctionLineNumber = lineNumber; } -void Namespace::addCommand( StringTableEntry name, StringCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool isToolOnly, ConsoleFunctionHeader* header ) +void Namespace::addCommand(StringTableEntry name, StringCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool isToolOnly, ConsoleFunctionHeader* header) { Entry *ent = createLocalEntry(name); trashCache(); @@ -1273,7 +1295,7 @@ void Namespace::addCommand( StringTableEntry name, StringCallback cb, const char ent->cb.mStringCallbackFunc = cb; } -void Namespace::addCommand( StringTableEntry name, IntCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool isToolOnly, ConsoleFunctionHeader* header ) +void Namespace::addCommand(StringTableEntry name, IntCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool isToolOnly, ConsoleFunctionHeader* header) { Entry *ent = createLocalEntry(name); trashCache(); @@ -1288,7 +1310,7 @@ void Namespace::addCommand( StringTableEntry name, IntCallback cb, const char *u ent->cb.mIntCallbackFunc = cb; } -void Namespace::addCommand( StringTableEntry name, VoidCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool isToolOnly, ConsoleFunctionHeader* header ) +void Namespace::addCommand(StringTableEntry name, VoidCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool isToolOnly, ConsoleFunctionHeader* header) { Entry *ent = createLocalEntry(name); trashCache(); @@ -1303,7 +1325,7 @@ void Namespace::addCommand( StringTableEntry name, VoidCallback cb, const char * ent->cb.mVoidCallbackFunc = cb; } -void Namespace::addCommand( StringTableEntry name, FloatCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool isToolOnly, ConsoleFunctionHeader* header ) +void Namespace::addCommand(StringTableEntry name, FloatCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool isToolOnly, ConsoleFunctionHeader* header) { Entry *ent = createLocalEntry(name); trashCache(); @@ -1318,7 +1340,7 @@ void Namespace::addCommand( StringTableEntry name, FloatCallback cb, const char ent->cb.mFloatCallbackFunc = cb; } -void Namespace::addCommand( StringTableEntry name, BoolCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool isToolOnly, ConsoleFunctionHeader* header ) +void Namespace::addCommand(StringTableEntry name, BoolCallback cb, const char *usage, S32 minArgs, S32 maxArgs, bool isToolOnly, ConsoleFunctionHeader* header) { Entry *ent = createLocalEntry(name); trashCache(); @@ -1333,16 +1355,16 @@ void Namespace::addCommand( StringTableEntry name, BoolCallback cb, const char * ent->cb.mBoolCallbackFunc = cb; } -void Namespace::addScriptCallback( const char *funcName, const char *usage, ConsoleFunctionHeader* header ) +void Namespace::addScriptCallback(const char *funcName, const char *usage, ConsoleFunctionHeader* header) { - static U32 uid=0; + static U32 uid = 0; char buffer[1024]; char lilBuffer[32]; dStrcpy(buffer, funcName); dSprintf(lilBuffer, 32, "_%d_cb", uid++); dStrcat(buffer, lilBuffer); - Entry *ent = createLocalEntry(StringTable->insert( buffer )); + Entry *ent = createLocalEntry(StringTable->insert(buffer)); trashCache(); ent->mUsage = usage; @@ -1356,17 +1378,17 @@ void Namespace::addScriptCallback( const char *funcName, const char *usage, Cons void Namespace::markGroup(const char* name, const char* usage) { - static U32 uid=0; + static U32 uid = 0; char buffer[1024]; char lilBuffer[32]; dStrcpy(buffer, name); dSprintf(lilBuffer, 32, "_%d", uid++); dStrcat(buffer, lilBuffer); - Entry *ent = createLocalEntry(StringTable->insert( buffer )); + Entry *ent = createLocalEntry(StringTable->insert(buffer)); trashCache(); - if(usage != NULL) + if (usage != NULL) lastUsage = (char*)(ent->mUsage = usage); else ent->mUsage = lastUsage; @@ -1384,9 +1406,9 @@ ConsoleValueRef Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprE { STR.clearFunctionOffset(); - if(mType == ConsoleFunctionType) + if (mType == ConsoleFunctionType) { - if(mFunctionOffset) + if (mFunctionOffset) { return mCode->exec(mFunctionOffset, argv[0], mNamespace, argc, argv, false, mPackage); } @@ -1399,35 +1421,35 @@ ConsoleValueRef Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprE #ifndef TORQUE_DEBUG // [tom, 12/13/2006] This stops tools functions from working in the console, // which is useful behavior when debugging so I'm ifdefing this out for debug builds. - if(mToolOnly && ! Con::isCurrentScriptToolScript()) + if (mToolOnly && !Con::isCurrentScriptToolScript()) { Con::errorf(ConsoleLogEntry::Script, "%s::%s - attempting to call tools only function from outside of tools", mNamespace->mName, mFunctionName); return ConsoleValueRef(); } #endif - if((mMinArgs && argc < mMinArgs) || (mMaxArgs && argc > mMaxArgs)) + if ((mMinArgs && argc < mMinArgs) || (mMaxArgs && argc > mMaxArgs)) { Con::warnf(ConsoleLogEntry::Script, "%s::%s - wrong number of arguments.", mNamespace->mName, mFunctionName); Con::warnf(ConsoleLogEntry::Script, "usage: %s", mUsage); return ConsoleValueRef(); } - switch(mType) + switch (mType) { case StringCallbackType: return ConsoleValueRef::fromValue(CSTK.pushStackString(cb.mStringCallbackFunc(state->thisObject, argc, argv))); case IntCallbackType: - return ConsoleValueRef::fromValue(CSTK.pushUINT((U32)cb.mBoolCallbackFunc(state->thisObject, argc, argv))); + return ConsoleValueRef::fromValue(CSTK.pushUINT((U32)cb.mBoolCallbackFunc(state->thisObject, argc, argv))); case FloatCallbackType: - return ConsoleValueRef::fromValue(CSTK.pushFLT((U32)cb.mBoolCallbackFunc(state->thisObject, argc, argv))); + return ConsoleValueRef::fromValue(CSTK.pushFLT((U32)cb.mBoolCallbackFunc(state->thisObject, argc, argv))); case VoidCallbackType: cb.mVoidCallbackFunc(state->thisObject, argc, argv); return ConsoleValueRef(); case BoolCallbackType: - return ConsoleValueRef::fromValue(CSTK.pushUINT((U32)cb.mBoolCallbackFunc(state->thisObject, argc, argv))); + return ConsoleValueRef::fromValue(CSTK.pushUINT((U32)cb.mBoolCallbackFunc(state->thisObject, argc, argv))); } - + return ConsoleValueRef(); } @@ -1439,181 +1461,181 @@ namespace { /// Scan the given usage string for an argument list description. With the /// old console macros, these were usually included as the first part of the /// usage string. - bool sFindArgumentListSubstring( const char* usage, const char*& start, const char*& end ) + bool sFindArgumentListSubstring(const char* usage, const char*& start, const char*& end) { - if( !usage ) + if (!usage) return false; - + const char* ptr = usage; - while( *ptr && *ptr != '(' && *ptr != '\n' ) // Only scan first line of usage string. + while (*ptr && *ptr != '(' && *ptr != '\n') // Only scan first line of usage string. { // Stop on the first alphanumeric character as we expect // argument lists to precede descriptions. - if( dIsalnum( *ptr ) ) + if (dIsalnum(*ptr)) return false; - - ptr ++; + + ptr++; } - - if( *ptr != '(' ) + + if (*ptr != '(') return false; start = ptr; - ptr ++; - + ptr++; + bool inString = false; U32 nestingCount = 0; - - while( *ptr && ( *ptr != ')' || nestingCount > 0 || inString ) ) + + while (*ptr && (*ptr != ')' || nestingCount > 0 || inString)) { - if( *ptr == '(' ) - nestingCount ++; - else if( *ptr == ')' ) - nestingCount --; - else if( *ptr == '"' ) + if (*ptr == '(') + nestingCount++; + else if (*ptr == ')') + nestingCount--; + else if (*ptr == '"') inString = !inString; - else if( *ptr == '\\' && ptr[ 1 ] == '"' ) - ptr ++; - ptr ++; + else if (*ptr == '\\' && ptr[1] == '"') + ptr++; + ptr++; } - - if( *ptr ) - ptr ++; + + if (*ptr) + ptr++; end = ptr; - + return true; } - + /// - void sParseList( const char* str, Vector< String >& outList ) + void sParseList(const char* str, Vector< String >& outList) { // Skip the initial '( '. - + const char* ptr = str; - while( *ptr && dIsspace( *ptr ) ) - ptr ++; - - if( *ptr == '(' ) + while (*ptr && dIsspace(*ptr)) + ptr++; + + if (*ptr == '(') { - ptr ++; - while( *ptr && dIsspace( *ptr ) ) - ptr ++; + ptr++; + while (*ptr && dIsspace(*ptr)) + ptr++; } - + // Parse out list items. - - while( *ptr && *ptr != ')' ) + + while (*ptr && *ptr != ')') { // Find end of element. - + const char* start = ptr; bool inString = false; U32 nestingCount = 0; - while( *ptr && ( ( *ptr != ')' && *ptr != ',' ) || nestingCount > 0 || inString ) ) + while (*ptr && ((*ptr != ')' && *ptr != ',') || nestingCount > 0 || inString)) { - if( *ptr == '(' ) - nestingCount ++; - else if( *ptr == ')' ) - nestingCount --; - else if( *ptr == '"' ) + if (*ptr == '(') + nestingCount++; + else if (*ptr == ')') + nestingCount--; + else if (*ptr == '"') inString = !inString; - else if( *ptr == '\\' && ptr[ 1 ] == '"' ) - ptr ++; - ptr ++; + else if (*ptr == '\\' && ptr[1] == '"') + ptr++; + ptr++; } - + // Backtrack to remove trailing whitespace. - + const char* end = ptr; - if( *end == ',' || *end == ')' ) - end --; - while( end > start && dIsspace( *end ) ) - end --; - if( *end ) - end ++; - + if (*end == ',' || *end == ')') + end--; + while (end > start && dIsspace(*end)) + end--; + if (*end) + end++; + // Add to list. - - if( start != end ) - outList.push_back( String( start, end - start ) ); - + + if (start != end) + outList.push_back(String(start, end - start)); + // Skip comma and whitespace. - - if( *ptr == ',' ) - ptr ++; - while( *ptr && dIsspace( *ptr ) ) - ptr ++; + + if (*ptr == ',') + ptr++; + while (*ptr && dIsspace(*ptr)) + ptr++; } } - + /// - void sGetArgNameAndType( const String& str, String& outType, String& outName ) + void sGetArgNameAndType(const String& str, String& outType, String& outName) { - if( !str.length() ) + if (!str.length()) { outType = String::EmptyString; outName = String::EmptyString; return; } - + // Find first non-ID character from right. - + S32 index = str.length() - 1; - while( index >= 0 && ( dIsalnum( str[ index ] ) || str[ index ] == '_' ) ) - index --; - + while (index >= 0 && (dIsalnum(str[index]) || str[index] == '_')) + index--; + const U32 nameStartIndex = index + 1; - + // Find end of type name by skipping rightmost whitespace inwards. - - while( index >= 0 && dIsspace( str[ index ] ) ) - index --; - + + while (index >= 0 && dIsspace(str[index])) + index--; + // - - outName = String( &( ( const char* ) str )[ nameStartIndex ] ); - outType = String( str, index + 1 ); + + outName = String(&((const char*)str)[nameStartIndex]); + outType = String(str, index + 1); } - + /// Return the type name to show in documentation for the given C++ type. - const char* sGetDocTypeString( const char* nativeType ) + const char* sGetDocTypeString(const char* nativeType) { - if( dStrncmp( nativeType, "const ", 6 ) == 0 ) + if (dStrncmp(nativeType, "const ", 6) == 0) nativeType += 6; - if( dStrcmp( nativeType, "char*" ) == 0 || dStrcmp( nativeType, "char *" ) == 0 ) + if (dStrcmp(nativeType, "char*") == 0 || dStrcmp(nativeType, "char *") == 0) return "string"; - else if( dStrcmp( nativeType, "S32" ) == 0 || dStrcmp( nativeType, "U32" ) == 0 ) + else if (dStrcmp(nativeType, "S32") == 0 || dStrcmp(nativeType, "U32") == 0) return "int"; - else if( dStrcmp( nativeType, "F32" ) == 0 ) + else if (dStrcmp(nativeType, "F32") == 0) return "float"; - - const U32 length = dStrlen( nativeType ); - if( nativeType[ length - 1 ] == '&' || nativeType[ length - 1 ] == '*' ) - return StringTable->insertn( nativeType, length - 1 ); - + + const U32 length = dStrlen(nativeType); + if (nativeType[length - 1] == '&' || nativeType[length - 1] == '*') + return StringTable->insertn(nativeType, length - 1); + return nativeType; } } -String Namespace::Entry::getBriefDescription( String* outRemainingDocText ) const +String Namespace::Entry::getBriefDescription(String* outRemainingDocText) const { String docString = getDocString(); - - S32 newline = docString.find( '\n' ); - if( newline == -1 ) + + S32 newline = docString.find('\n'); + if (newline == -1) { - if( outRemainingDocText ) + if (outRemainingDocText) *outRemainingDocText = String(); return docString; } - - String brief = docString.substr( 0, newline ); - if( outRemainingDocText ) - *outRemainingDocText = docString.substr( newline + 1 ); - + + String brief = docString.substr(0, newline); + if (outRemainingDocText) + *outRemainingDocText = docString.substr(newline + 1); + return brief; } @@ -1621,92 +1643,92 @@ String Namespace::Entry::getDocString() const { const char* argListStart; const char* argListEnd; - - if( sFindArgumentListSubstring( mUsage, argListStart, argListEnd ) ) + + if (sFindArgumentListSubstring(mUsage, argListStart, argListEnd)) { // Skip the " - " part present in some old doc strings. - + const char* ptr = argListEnd; - while( *ptr && dIsspace( *ptr ) ) - ptr ++; - - if( *ptr == '-' ) + while (*ptr && dIsspace(*ptr)) + ptr++; + + if (*ptr == '-') { - ptr ++; - while( *ptr && dIsspace( *ptr ) ) - ptr ++; + ptr++; + while (*ptr && dIsspace(*ptr)) + ptr++; } - + return ptr; } - + return mUsage; } String Namespace::Entry::getArgumentsString() const { StringBuilder str; - - if( mHeader ) + + if (mHeader) { // Parse out the argument list string supplied with the extended // function header and add default arguments as we go. - + Vector< String > argList; Vector< String > defaultArgList; - - sParseList( mHeader->mArgString, argList ); - sParseList( mHeader->mDefaultArgString, defaultArgList ); - - str.append( '(' ); - + + sParseList(mHeader->mArgString, argList); + sParseList(mHeader->mDefaultArgString, defaultArgList); + + str.append('('); + const U32 numArgs = argList.size(); const U32 numDefaultArgs = defaultArgList.size(); const U32 firstDefaultArgIndex = numArgs - numDefaultArgs; - - for( U32 i = 0; i < numArgs; ++ i ) + + for (U32 i = 0; i < numArgs; ++i) { // Add separator if not first arg. - - if( i > 0 ) - str.append( ',' ); - + + if (i > 0) + str.append(','); + // Add type and name. - + String name; String type; - - sGetArgNameAndType( argList[ i ], type, name ); - - str.append( ' ' ); - str.append( sGetDocTypeString( type ) ); - str.append( ' ' ); - str.append( name ); - + + sGetArgNameAndType(argList[i], type, name); + + str.append(' '); + str.append(sGetDocTypeString(type)); + str.append(' '); + str.append(name); + // Add default value, if any. - - if( i >= firstDefaultArgIndex ) + + if (i >= firstDefaultArgIndex) { - str.append( '=' ); - str.append( defaultArgList[ i - firstDefaultArgIndex ] ); + str.append('='); + str.append(defaultArgList[i - firstDefaultArgIndex]); } } - - if( numArgs > 0 ) - str.append( ' ' ); - str.append( ')' ); + + if (numArgs > 0) + str.append(' '); + str.append(')'); } else { // No extended function header. Try to parse out the argument // list from the usage string. - + const char* argListStart; const char* argListEnd; - - if( sFindArgumentListSubstring( mUsage, argListStart, argListEnd ) ) - str.append( argListStart, argListEnd - argListStart ); - else if( mType == ConsoleFunctionType && mCode ) + + if (sFindArgumentListSubstring(mUsage, argListStart, argListEnd)) + str.append(argListStart, argListEnd - argListStart); + else if (mType == ConsoleFunctionType && mCode) { // This isn't correct but the nonsense console stuff is set up such that all // functions that have no function bodies are keyed to offset 0 to indicate "no code." @@ -1714,70 +1736,70 @@ String Namespace::Entry::getArgumentsString() const // tell here what the actual prototype is except if we searched though the entire opcode // stream for the corresponding OP_FUNC_DECL (which would require dealing with the // variable-size instructions). - - if( !mFunctionOffset ) + + if (!mFunctionOffset) return "()"; - - String args = mCode->getFunctionArgs( mFunctionOffset ); - if( args.isEmpty() ) + + String args = mCode->getFunctionArgs(mFunctionOffset); + if (args.isEmpty()) return "()"; - - str.append( "( " ); - str.append( args ); - str.append( " )" ); + + str.append("( "); + str.append(args); + str.append(" )"); } } - + return str.end(); } String Namespace::Entry::getPrototypeString() const { StringBuilder str; - + // Start with return type. - - if( mHeader && mHeader->mReturnString ) + + if (mHeader && mHeader->mReturnString) { - str.append( sGetDocTypeString( mHeader->mReturnString ) ); - str.append( ' ' ); + str.append(sGetDocTypeString(mHeader->mReturnString)); + str.append(' '); } else - switch( mType ) + switch (mType) { case StringCallbackType: - str.append( "string " ); + str.append("string "); break; - + case IntCallbackType: - str.append( "int " ); + str.append("int "); break; case FloatCallbackType: - str.append( "float " ); + str.append("float "); break; case VoidCallbackType: - str.append( "void " ); + str.append("void "); break; case BoolCallbackType: - str.append( "bool " ); + str.append("bool "); break; - + case ScriptCallbackType: break; } - + // Add function name and arguments. - if( mType == ScriptCallbackType ) - str.append( cb.mCallbackName ); + if (mType == ScriptCallbackType) + str.append(cb.mCallbackName); else - str.append( mFunctionName ); - - str.append( getArgumentsString() ); - + str.append(mFunctionName); + + str.append(getArgumentsString()); + return str.end(); } @@ -1789,8 +1811,8 @@ U32 Namespace::mOldNumActivePackages = 0; bool Namespace::isPackage(StringTableEntry name) { - for(Namespace *walk = mNamespaceList; walk; walk = walk->mNext) - if(walk->mPackage == name) + for (Namespace *walk = mNamespaceList; walk; walk = walk->mNext) + if (walk->mPackage == name) return true; return false; } @@ -1802,7 +1824,7 @@ U32 Namespace::getActivePackagesCount() StringTableEntry Namespace::getActivePackage(U32 index) { - if( index >= mNumActivePackages ) + if (index >= mNumActivePackages) return StringTable->EmptyString(); return mActivePackages[index]; @@ -1810,26 +1832,26 @@ StringTableEntry Namespace::getActivePackage(U32 index) void Namespace::activatePackage(StringTableEntry name) { - if(mNumActivePackages == MaxActivePackages) + if (mNumActivePackages == MaxActivePackages) { Con::printf("ActivatePackage(%s) failed - Max package limit reached: %d", name, MaxActivePackages); return; } - if(!name) + if (!name) return; // see if this one's already active - for(U32 i = 0; i < mNumActivePackages; i++) - if(mActivePackages[i] == name) + for (U32 i = 0; i < mNumActivePackages; i++) + if (mActivePackages[i] == name) return; // kill the cache trashCache(); // find all the package namespaces... - for(Namespace *walk = mNamespaceList; walk; walk = walk->mNext) + for (Namespace *walk = mNamespaceList; walk; walk = walk->mNext) { - if(walk->mPackage == name) + if (walk->mPackage == name) { Namespace *parent = Namespace::find(walk->mName); // hook the parent @@ -1838,10 +1860,10 @@ void Namespace::activatePackage(StringTableEntry name) // now swap the entries: Entry *ew; - for(ew = parent->mEntryList; ew; ew = ew->mNext) + for (ew = parent->mEntryList; ew; ew = ew->mNext) ew->mNamespace = walk; - for(ew = walk->mEntryList; ew; ew = ew->mNext) + for (ew = walk->mEntryList; ew; ew = ew->mNext) ew->mNamespace = parent; ew = walk->mEntryList; @@ -1857,33 +1879,33 @@ void Namespace::deactivatePackage(StringTableEntry name) U32 oldNumActivePackages = mNumActivePackages; // Remove all packages down to the given one - deactivatePackageStack( name ); + deactivatePackageStack(name); // Now add back all packages that followed the given one - if(!oldNumActivePackages) + if (!oldNumActivePackages) return; - for(U32 i = mNumActivePackages+1; i < oldNumActivePackages; i++) + for (U32 i = mNumActivePackages + 1; i < oldNumActivePackages; i++) activatePackage(mActivePackages[i]); } void Namespace::deactivatePackageStack(StringTableEntry name) { S32 i, j; - for(i = 0; i < mNumActivePackages; i++) - if(mActivePackages[i] == name) + for (i = 0; i < mNumActivePackages; i++) + if (mActivePackages[i] == name) break; - if(i == mNumActivePackages) + if (i == mNumActivePackages) return; trashCache(); // Remove all packages down to the given one - for(j = mNumActivePackages - 1; j >= i; j--) + for (j = mNumActivePackages - 1; j >= i; j--) { // gotta unlink em in reverse order... - for(Namespace *walk = mNamespaceList; walk; walk = walk->mNext) + for (Namespace *walk = mNamespaceList; walk; walk = walk->mNext) { - if(walk->mPackage == mActivePackages[j]) + if (walk->mPackage == mActivePackages[j]) { Namespace *parent = Namespace::find(walk->mName); // hook the parent @@ -1892,10 +1914,10 @@ void Namespace::deactivatePackageStack(StringTableEntry name) // now swap the entries: Entry *ew; - for(ew = parent->mEntryList; ew; ew = ew->mNext) + for (ew = parent->mEntryList; ew; ew = ew->mNext) ew->mNamespace = walk; - for(ew = walk->mEntryList; ew; ew = ew->mNext) + for (ew = walk->mEntryList; ew; ew = ew->mNext) ew->mNamespace = parent; ew = walk->mEntryList; @@ -1910,21 +1932,21 @@ void Namespace::deactivatePackageStack(StringTableEntry name) void Namespace::unlinkPackages() { mOldNumActivePackages = mNumActivePackages; - if(!mNumActivePackages) + if (!mNumActivePackages) return; deactivatePackageStack(mActivePackages[0]); } void Namespace::relinkPackages() { - if(!mOldNumActivePackages) + if (!mOldNumActivePackages) return; - for(U32 i = 0; i < mOldNumActivePackages; i++) + for (U32 i = 0; i < mOldNumActivePackages; i++) activatePackage(mActivePackages[i]); } -DefineEngineFunction(isPackage, bool, ( String identifier ),, +DefineEngineFunction(isPackage, bool, (String identifier), , "@brief Returns true if the identifier is the name of a declared package.\n\n" "@ingroup Packages\n") { @@ -1932,7 +1954,7 @@ DefineEngineFunction(isPackage, bool, ( String identifier ),, return Namespace::isPackage(name); } -DefineEngineFunction(activatePackage, void, ( String packageName ),, +DefineEngineFunction(activatePackage, void, (String packageName), , "@brief Activates an existing package.\n\n" "The activation occurs by updating the namespace linkage of existing functions and methods. " "If the package is already activated the function does nothing.\n" @@ -1942,7 +1964,7 @@ DefineEngineFunction(activatePackage, void, ( String packageName ),, Namespace::activatePackage(name); } -DefineEngineFunction(deactivatePackage, void, ( String packageName ),, +DefineEngineFunction(deactivatePackage, void, (String packageName), , "@brief Deactivates a previously activated package.\n\n" "The package is deactivated by removing its namespace linkages to any function or method. " "If there are any packages above this one in the stack they are deactivated as well. " @@ -1953,16 +1975,16 @@ DefineEngineFunction(deactivatePackage, void, ( String packageName ),, Namespace::deactivatePackage(name); } -DefineEngineFunction(getPackageList, const char*, (),, +DefineEngineFunction(getPackageList, const char*, (), , "@brief Returns a space delimited list of the active packages in stack order.\n\n" "@ingroup Packages\n") { - if( Namespace::getActivePackagesCount() == 0 ) + if (Namespace::getActivePackagesCount() == 0) return ""; // Determine size of return buffer dsize_t buffersize = 0; - for( U32 i = 0; i < Namespace::getActivePackagesCount(); ++i ) + for (U32 i = 0; i < Namespace::getActivePackagesCount(); ++i) { buffersize += dStrlen(Namespace::getActivePackage(i)) + 1; } @@ -1970,7 +1992,7 @@ DefineEngineFunction(getPackageList, const char*, (),, U32 maxBufferSize = buffersize + 1; char* returnBuffer = Con::getReturnBuffer(maxBufferSize); U32 returnLen = 0; - for( U32 i = 0; i < Namespace::getActivePackagesCount(); ++i ) + for (U32 i = 0; i < Namespace::getActivePackagesCount(); ++i) { dSprintf(returnBuffer + returnLen, maxBufferSize - returnLen, "%s ", Namespace::getActivePackage(i)); returnLen = dStrlen(returnBuffer); diff --git a/Engine/source/console/consoleInternal.h b/Engine/source/console/consoleInternal.h index 35ebff800..d673bb39c 100644 --- a/Engine/source/console/consoleInternal.h +++ b/Engine/source/console/consoleInternal.h @@ -24,22 +24,21 @@ #define _CONSOLEINTERNAL_H_ #ifndef _STRINGFUNCTIONS_H_ - #include "core/strings/stringFunctions.h" +#include "core/strings/stringFunctions.h" #endif #ifndef _STRINGTABLE_H_ - #include "core/stringTable.h" +#include "core/stringTable.h" #endif #ifndef _CONSOLETYPES_H - #include "console/consoleTypes.h" +#include "console/consoleTypes.h" #endif #ifndef _CONSOLEOBJECT_H_ - #include "console/simObject.h" +#include "console/simObject.h" #endif #ifndef _DATACHUNKER_H_ - #include "core/dataChunker.h" +#include "core/dataChunker.h" #endif - /// @ingroup console_system Console System /// @{ @@ -55,222 +54,222 @@ class AbstractClassRep; /// Namespaces are used for dispatching calls in the console system. class Namespace { - enum { - MaxActivePackages = 512, + enum { + MaxActivePackages = 512, + }; + + static U32 mNumActivePackages; + static U32 mOldNumActivePackages; + static StringTableEntry mActivePackages[MaxActivePackages]; + +public: + StringTableEntry mName; + StringTableEntry mPackage; + + Namespace *mParent; + Namespace *mNext; + AbstractClassRep *mClassRep; + U32 mRefCountToParent; + + const char* mUsage; + + /// Script defined usage strings need to be cleaned up. This + /// field indicates whether or not the usage was set from script. + bool mCleanUpUsage; + + /// A function entry in the namespace. + struct Entry + { + enum + { + ScriptCallbackType = -3, + GroupMarker = -2, + InvalidFunctionType = -1, + ConsoleFunctionType, + StringCallbackType, + IntCallbackType, + FloatCallbackType, + VoidCallbackType, + BoolCallbackType }; - static U32 mNumActivePackages; - static U32 mOldNumActivePackages; - static StringTableEntry mActivePackages[MaxActivePackages]; + /// Link back to the namespace to which the entry belongs. + Namespace* mNamespace; - public: - StringTableEntry mName; + /// Next function entry in the hashtable link chain of the namespace. + Entry* mNext; + + /// Name of this function. + StringTableEntry mFunctionName; + + /// + S32 mType; + + /// Min number of arguments expected by this function. + S32 mMinArgs; + + /// Max number of arguments expected by this function. If zero, + /// function takes an arbitrary number of arguments. + S32 mMaxArgs; + + /// Name of the package to which this function belongs. StringTableEntry mPackage; - Namespace *mParent; - Namespace *mNext; - AbstractClassRep *mClassRep; - U32 mRefCountToParent; - + /// Whether this function is included only in TORQUE_TOOLS builds. + bool mToolOnly; + + /// Usage string for documentation. const char* mUsage; - - /// Script defined usage strings need to be cleaned up. This - /// field indicates whether or not the usage was set from script. - bool mCleanUpUsage; - /// A function entry in the namespace. - struct Entry - { - enum - { - ScriptCallbackType = -3, - GroupMarker = -2, - InvalidFunctionType = -1, - ConsoleFunctionType, - StringCallbackType, - IntCallbackType, - FloatCallbackType, - VoidCallbackType, - BoolCallbackType - }; + /// Extended console function information. + ConsoleFunctionHeader* mHeader; - /// Link back to the namespace to which the entry belongs. - Namespace* mNamespace; - - /// Next function entry in the hashtable link chain of the namespace. - Entry* mNext; - - /// Name of this function. - StringTableEntry mFunctionName; - - /// - S32 mType; - - /// Min number of arguments expected by this function. - S32 mMinArgs; - - /// Max number of arguments expected by this function. If zero, - /// function takes an arbitrary number of arguments. - S32 mMaxArgs; - - /// Name of the package to which this function belongs. - StringTableEntry mPackage; - - /// Whether this function is included only in TORQUE_TOOLS builds. - bool mToolOnly; + /// The compiled script code if this is a script function. + CodeBlock* mCode; - /// Usage string for documentation. - const char* mUsage; - - /// Extended console function information. - ConsoleFunctionHeader* mHeader; + /// The offset in the compiled script code at which this function begins. + U32 mFunctionOffset; - /// The compiled script code if this is a script function. - CodeBlock* mCode; - - /// The offset in the compiled script code at which this function begins. - U32 mFunctionOffset; + /// If it's a script function, this is the line of the declaration in code. + /// @note 0 for functions read from legacy DSOs that have no line number information. + U32 mFunctionLineNumber; - /// If it's a script function, this is the line of the declaration in code. - /// @note 0 for functions read from legacy DSOs that have no line number information. - U32 mFunctionLineNumber; - - union CallbackUnion { - StringCallback mStringCallbackFunc; - IntCallback mIntCallbackFunc; - VoidCallback mVoidCallbackFunc; - FloatCallback mFloatCallbackFunc; - BoolCallback mBoolCallbackFunc; - const char *mGroupName; - const char *mCallbackName; - } cb; - - Entry(); - - /// - void clear(); + union CallbackUnion { + StringCallback mStringCallbackFunc; + IntCallback mIntCallbackFunc; + VoidCallback mVoidCallbackFunc; + FloatCallback mFloatCallbackFunc; + BoolCallback mBoolCallbackFunc; + const char *mGroupName; + const char *mCallbackName; + } cb; - /// - ConsoleValueRef execute( S32 argc, ConsoleValueRef* argv, ExprEvalState* state ); - - /// Return a one-line documentation text string for the function. - String getBriefDescription( String* outRemainingDocText = NULL ) const; - - /// Get the auto-doc string for this function. This string does not included prototype information. - String getDocString() const; - - /// Return a string describing the arguments the function takes including default argument values. - String getArgumentsString() const; + Entry(); - /// Return a full prototype string for the function including return type, function name, - /// and arguments. - String getPrototypeString() const; - }; - - Entry* mEntryList; + /// + void clear(); - Entry** mHashTable; - - U32 mHashSize; - U32 mHashSequence; ///< @note The hash sequence is used by the autodoc console facility - /// as a means of testing reference state. + /// + ConsoleValueRef execute(S32 argc, ConsoleValueRef* argv, ExprEvalState* state); - Namespace(); - ~Namespace(); + /// Return a one-line documentation text string for the function. + String getBriefDescription(String* outRemainingDocText = NULL) const; - void addFunction( StringTableEntry name, CodeBlock* cb, U32 functionOffset, const char* usage = NULL, U32 lineNumber = 0 ); - void addCommand( StringTableEntry name, StringCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); - void addCommand( StringTableEntry name, IntCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); - void addCommand( StringTableEntry name, FloatCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); - void addCommand( StringTableEntry name, VoidCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); - void addCommand( StringTableEntry name, BoolCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); + /// Get the auto-doc string for this function. This string does not included prototype information. + String getDocString() const; - void addScriptCallback( const char *funcName, const char *usage, ConsoleFunctionHeader* header = NULL ); + /// Return a string describing the arguments the function takes including default argument values. + String getArgumentsString() const; - void markGroup(const char* name, const char* usage); - char * lastUsage; + /// Return a full prototype string for the function including return type, function name, + /// and arguments. + String getPrototypeString() const; + }; - /// Returns true if this namespace represents an engine defined - /// class and is not just a script defined class namespace. - bool isClass() const { return mClassRep && mClassRep->getNameSpace() == this; } + Entry* mEntryList; - void getEntryList(VectorPtr *); + Entry** mHashTable; - /// Return the name of this namespace. - StringTableEntry getName() const { return mName; } + U32 mHashSize; + U32 mHashSequence; ///< @note The hash sequence is used by the autodoc console facility + /// as a means of testing reference state. - /// Return the superordinate namespace to this namespace. Symbols are inherited from - /// this namespace. - Namespace* getParent() const { return mParent; } + Namespace(); + ~Namespace(); - /// Return the topmost package in the parent hierarchy of this namespace - /// that still refers to the same namespace. If packages are active and - /// adding to this namespace, then they will be linked in-between the namespace - /// they are adding to and its real parent namespace. - Namespace* getPackageRoot() - { - Namespace* walk = this; - while( walk->mParent && walk->mParent->mName == mName ) - walk = walk->mParent; + void addFunction(StringTableEntry name, CodeBlock* cb, U32 functionOffset, const char* usage = NULL, U32 lineNumber = 0); + void addCommand(StringTableEntry name, StringCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); + void addCommand(StringTableEntry name, IntCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); + void addCommand(StringTableEntry name, FloatCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); + void addCommand(StringTableEntry name, VoidCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); + void addCommand(StringTableEntry name, BoolCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL); - return walk; - } + void addScriptCallback(const char *funcName, const char *usage, ConsoleFunctionHeader* header = NULL); - /// Return the package in which this namespace is defined. - StringTableEntry getPackage() const { return mPackage; } + void markGroup(const char* name, const char* usage); + char * lastUsage; - /// Increase the count on the reference that this namespace - /// holds to its parent. - /// @note Must not be called on namespaces coming from packages. - void incRefCountToParent() - { - AssertFatal( mPackage == NULL, "Namespace::incRefCountToParent - Must not be called on a namespace coming from a package!" ); - mRefCountToParent ++; - } + /// Returns true if this namespace represents an engine defined + /// class and is not just a script defined class namespace. + bool isClass() const { return mClassRep && mClassRep->getNameSpace() == this; } - /// Decrease the count on the reference that this namespace - /// holds to its parent. - /// @note Must not be called on namespaces coming from packages. - void decRefCountToParent() - { - unlinkClass( NULL ); - } + void getEntryList(VectorPtr *); - Entry *lookup(StringTableEntry name); - Entry *lookupRecursive(StringTableEntry name); - Entry *createLocalEntry(StringTableEntry name); - void buildHashTable(); - void clearEntries(); - bool classLinkTo(Namespace *parent); - bool unlinkClass(Namespace *parent); - void getUniqueEntryLists( Namespace *other, VectorPtr *outThisList, VectorPtr *outOtherList ); + /// Return the name of this namespace. + StringTableEntry getName() const { return mName; } - const char *tabComplete(const char *prevText, S32 baseLen, bool fForward); + /// Return the superordinate namespace to this namespace. Symbols are inherited from + /// this namespace. + Namespace* getParent() const { return mParent; } - static U32 mCacheSequence; - static DataChunker mCacheAllocator; - static DataChunker mAllocator; - static void trashCache(); - static Namespace *mNamespaceList; - static Namespace *mGlobalNamespace; + /// Return the topmost package in the parent hierarchy of this namespace + /// that still refers to the same namespace. If packages are active and + /// adding to this namespace, then they will be linked in-between the namespace + /// they are adding to and its real parent namespace. + Namespace* getPackageRoot() + { + Namespace* walk = this; + while (walk->mParent && walk->mParent->mName == mName) + walk = walk->mParent; - static void init(); - static void shutdown(); - static Namespace *global(); + return walk; + } - static Namespace *find(StringTableEntry name, StringTableEntry package=NULL); + /// Return the package in which this namespace is defined. + StringTableEntry getPackage() const { return mPackage; } - static void activatePackage(StringTableEntry name); - static void deactivatePackage(StringTableEntry name); - static void deactivatePackageStack(StringTableEntry name); - static void dumpClasses( bool dumpScript = true, bool dumpEngine = true ); - static void dumpFunctions( bool dumpScript = true, bool dumpEngine = true ); - static void printNamespaceEntries(Namespace * g, bool dumpScript = true, bool dumpEngine = true); - static void unlinkPackages(); - static void relinkPackages(); - static bool isPackage(StringTableEntry name); - static U32 getActivePackagesCount(); - static StringTableEntry getActivePackage(U32 index); + /// Increase the count on the reference that this namespace + /// holds to its parent. + /// @note Must not be called on namespaces coming from packages. + void incRefCountToParent() + { + AssertFatal(mPackage == NULL, "Namespace::incRefCountToParent - Must not be called on a namespace coming from a package!"); + mRefCountToParent++; + } + + /// Decrease the count on the reference that this namespace + /// holds to its parent. + /// @note Must not be called on namespaces coming from packages. + void decRefCountToParent() + { + unlinkClass(NULL); + } + + Entry *lookup(StringTableEntry name); + Entry *lookupRecursive(StringTableEntry name); + Entry *createLocalEntry(StringTableEntry name); + void buildHashTable(); + void clearEntries(); + bool classLinkTo(Namespace *parent); + bool unlinkClass(Namespace *parent); + void getUniqueEntryLists(Namespace *other, VectorPtr *outThisList, VectorPtr *outOtherList); + + const char *tabComplete(const char *prevText, S32 baseLen, bool fForward); + + static U32 mCacheSequence; + static DataChunker mCacheAllocator; + static DataChunker mAllocator; + static void trashCache(); + static Namespace *mNamespaceList; + static Namespace *mGlobalNamespace; + + static void init(); + static void shutdown(); + static Namespace *global(); + + static Namespace *find(StringTableEntry name, StringTableEntry package = NULL); + + static void activatePackage(StringTableEntry name); + static void deactivatePackage(StringTableEntry name); + static void deactivatePackageStack(StringTableEntry name); + static void dumpClasses(bool dumpScript = true, bool dumpEngine = true); + static void dumpFunctions(bool dumpScript = true, bool dumpEngine = true); + static void printNamespaceEntries(Namespace * g, bool dumpScript = true, bool dumpEngine = true); + static void unlinkPackages(); + static void relinkPackages(); + static bool isPackage(StringTableEntry name); + static U32 getActivePackagesCount(); + static StringTableEntry getActivePackage(U32 index); }; typedef VectorPtr::iterator NamespaceEntryListIterator; @@ -292,10 +291,10 @@ public: /// The optional notification signal called when /// a value is assigned to this variable. NotifySignal *notify; - + /// Usage doc string. const char* mUsage; - + /// Whether this is a constant that cannot be assigned to. bool mIsConstant; @@ -309,16 +308,16 @@ public: mIsConstant = false; value.init(); } - + Entry(StringTableEntry name); ~Entry(); - + Entry *mNext; - + void reset() { name = NULL; value.cleanup(); - if ( notify ) + if (notify) delete notify; } @@ -339,63 +338,63 @@ public: void setIntValue(U32 val) { - if( mIsConstant ) + if (mIsConstant) { - Con::errorf( "Cannot assign value to constant '%s'.", name ); + Con::errorf("Cannot assign value to constant '%s'.", name); return; } - + value.setIntValue(val); // Fire off the notification if we have one. - if ( notify ) + if (notify) notify->trigger(); } void setFloatValue(F32 val) { - if( mIsConstant ) + if (mIsConstant) { - Con::errorf( "Cannot assign value to constant '%s'.", name ); + Con::errorf("Cannot assign value to constant '%s'.", name); return; } - + value.setFloatValue(val); // Fire off the notification if we have one. - if ( notify ) + if (notify) notify->trigger(); } void setStringStackPtrValue(StringStackPtr newValue) { - if( mIsConstant ) + if (mIsConstant) { - Con::errorf( "Cannot assign value to constant '%s'.", name ); + Con::errorf("Cannot assign value to constant '%s'.", name); return; } - + value.setStringStackPtrValue(newValue); - - + + // Fire off the notification if we have one. - if ( notify ) + if (notify) notify->trigger(); } void setStringValue(const char *newValue) { - if( mIsConstant ) + if (mIsConstant) { - Con::errorf( "Cannot assign value to constant '%s'.", name ); + Con::errorf("Cannot assign value to constant '%s'.", name); return; } - + value.setStringValue(newValue); - - + + // Fire off the notification if we have one. - if ( notify ) + if (notify) notify->trigger(); } }; @@ -407,9 +406,9 @@ public: S32 count; Entry **data; FreeListChunker< Entry > mChunker; - - HashTableData( Dictionary* owner ) - : owner( owner ), size( 0 ), count( 0 ), data( NULL ) {} + + HashTableData(Dictionary* owner) + : owner(owner), size(0), count(0), data(NULL) {} }; HashTableData* hashTable; @@ -426,13 +425,13 @@ public: Entry *lookup(StringTableEntry name); Entry *add(StringTableEntry name); - void setState(ExprEvalState *state, Dictionary* ref=NULL); + void setState(ExprEvalState *state, Dictionary* ref = NULL); void remove(Entry *); void reset(); - void exportVariables( const char *varString, const char *fileName, bool append ); - void exportVariables( const char *varString, Vector *names, Vector *values ); - void deleteVariables( const char *varString ); + void exportVariables(const char *varString, const char *fileName, bool append); + void exportVariables(const char *varString, Vector *names, Vector *values); + void deleteVariables(const char *varString); void setVariable(StringTableEntry name, const char *value); const char *getVariable(StringTableEntry name, bool *valid = NULL); @@ -449,19 +448,19 @@ public: } /// @see Con::addVariable - Entry* addVariable( const char *name, - S32 type, - void *dataPtr, - const char* usage ); + Entry* addVariable(const char *name, + S32 type, + void *dataPtr, + const char* usage); /// @see Con::removeVariable bool removeVariable(StringTableEntry name); /// @see Con::addVariableNotify - void addVariableNotify( const char *name, const Con::NotifyDelegate &callback ); + void addVariableNotify(const char *name, const Con::NotifyDelegate &callback); /// @see Con::removeVariableNotify - void removeVariableNotify( const char *name, const Con::NotifyDelegate &callback ); + void removeVariableNotify(const char *name, const Con::NotifyDelegate &callback); /// Return the best tab completion for prevText, with the length /// of the pre-tab string in baseLen. @@ -520,15 +519,15 @@ public: /// Puts a reference to an existing stack frame /// on the top of the stack. void pushFrameRef(S32 stackIndex); - + U32 getStackDepth() const { return mStackDepth; } - + Dictionary& getCurrentFrame() { - return *( stack[ mStackDepth - 1 ] ); + return *(stack[mStackDepth - 1]); } /// @} diff --git a/Engine/source/console/simDictionary.cpp b/Engine/source/console/simDictionary.cpp index ce923ac49..b733d9fcc 100644 --- a/Engine/source/console/simDictionary.cpp +++ b/Engine/source/console/simDictionary.cpp @@ -45,7 +45,7 @@ SimNameDictionary::~SimNameDictionary() void SimNameDictionary::insert(SimObject* obj) { - if(!obj || !obj->objectName) + if (!obj || !obj->objectName) return; SimObject* checkForDup = find(obj->objectName); @@ -55,47 +55,47 @@ void SimNameDictionary::insert(SimObject* obj) Mutex::lockMutex(mutex); #ifndef USE_NEW_SIMDICTIONARY - if(!hashTable) + if (!hashTable) { hashTable = new SimObject *[DefaultTableSize]; hashTableSize = DefaultTableSize; hashEntryCount = 0; - - dMemset( hashTable, 0, sizeof( *hashTable ) * DefaultTableSize ); + + dMemset(hashTable, 0, sizeof(*hashTable) * DefaultTableSize); } - + S32 idx = HashPointer(obj->objectName) % hashTableSize; obj->nextNameObject = hashTable[idx]; hashTable[idx] = obj; hashEntryCount++; - + // Rehash if necessary. - if( hashEntryCount > hashTableSize ) + if (hashEntryCount > hashTableSize) { // Allocate new table. - + U32 newHashTableSize = hashTableSize * 2 + 1; - SimObject** newHashTable = new SimObject *[ newHashTableSize ]; - dMemset( newHashTable, 0, sizeof( newHashTable[ 0 ] ) * newHashTableSize ); - + SimObject** newHashTable = new SimObject *[newHashTableSize]; + dMemset(newHashTable, 0, sizeof(newHashTable[0]) * newHashTableSize); + // Move entries over. - for( U32 i = 0; i < hashTableSize; ++ i ) - for( SimObject* object = hashTable[ i ]; object != NULL; ) + for (U32 i = 0; i < hashTableSize; ++i) + for (SimObject* object = hashTable[i]; object != NULL; ) { SimObject* next = object->nextNameObject; - idx = HashPointer( object->objectName ) % newHashTableSize; - object->nextNameObject = newHashTable[ idx ]; - newHashTable[ idx ] = object; - + idx = HashPointer(object->objectName) % newHashTableSize; + object->nextNameObject = newHashTable[idx]; + newHashTable[idx] = object; + object = next; } - + // Switch tables. - - delete [] hashTable; + + delete[] hashTable; hashTable = newHashTable; hashTableSize = newHashTableSize; } @@ -109,16 +109,16 @@ SimObject* SimNameDictionary::find(StringTableEntry name) { #ifndef USE_NEW_SIMDICTIONARY // NULL is a valid lookup - it will always return NULL - if(!hashTable) + if (!hashTable) return NULL; - + Mutex::lockMutex(mutex); S32 idx = HashPointer(name) % hashTableSize; SimObject *walk = hashTable[idx]; - while(walk) + while (walk) { - if(walk->objectName == name) + if (walk->objectName == name) { Mutex::unlockMutex(mutex); return walk; @@ -129,28 +129,28 @@ SimObject* SimNameDictionary::find(StringTableEntry name) Mutex::unlockMutex(mutex); return NULL; #else - Mutex::lockMutex(mutex); - StringDictDef::iterator it = root.find(name); - SimObject* f = (it == root.end() ? NULL : it->second); - Mutex::unlockMutex(mutex); - return f; + Mutex::lockMutex(mutex); + StringDictDef::iterator it = root.find(name); + SimObject* f = (it == root.end() ? NULL : it->second); + Mutex::unlockMutex(mutex); + return f; #endif } void SimNameDictionary::remove(SimObject* obj) { - if(!obj || !obj->objectName) + if (!obj || !obj->objectName) return; Mutex::lockMutex(mutex); #ifndef USE_NEW_SIMDICTIONARY SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize]; - while(*walk) + while (*walk) { - if(*walk == obj) + if (*walk == obj) { *walk = obj->nextNameObject; - obj->nextNameObject = (SimObject*)-1; + obj->nextNameObject = nullptr; hashEntryCount--; Mutex::unlockMutex(mutex); @@ -164,7 +164,7 @@ void SimNameDictionary::remove(SimObject* obj) root.erase(name); #endif Mutex::unlockMutex(mutex); -} +} //---------------------------------------------------------------------------- @@ -174,8 +174,8 @@ SimManagerNameDictionary::SimManagerNameDictionary() hashTable = new SimObject *[DefaultTableSize]; hashTableSize = DefaultTableSize; hashEntryCount = 0; - - dMemset( hashTable, 0, sizeof( hashTable[ 0 ] ) * hashTableSize ); + + dMemset(hashTable, 0, sizeof(hashTable[0]) * hashTableSize); #endif mutex = Mutex::createMutex(); } @@ -190,7 +190,7 @@ SimManagerNameDictionary::~SimManagerNameDictionary() void SimManagerNameDictionary::insert(SimObject* obj) { - if(!obj || !obj->objectName) + if (!obj || !obj->objectName) return; Mutex::lockMutex(mutex); @@ -199,34 +199,34 @@ void SimManagerNameDictionary::insert(SimObject* obj) obj->nextManagerNameObject = hashTable[idx]; hashTable[idx] = obj; hashEntryCount++; - + // Rehash if necessary. - if( hashEntryCount > hashTableSize ) + if (hashEntryCount > hashTableSize) { // Allocate new table. - + U32 newHashTableSize = hashTableSize * 2 + 1; - SimObject** newHashTable = new SimObject *[ newHashTableSize ]; - dMemset( newHashTable, 0, sizeof( newHashTable[ 0 ] ) * newHashTableSize ); - + SimObject** newHashTable = new SimObject *[newHashTableSize]; + dMemset(newHashTable, 0, sizeof(newHashTable[0]) * newHashTableSize); + // Move entries over. - for( U32 i = 0; i < hashTableSize; ++ i ) - for( SimObject* object = hashTable[ i ]; object != NULL; ) + for (U32 i = 0; i < hashTableSize; ++i) + for (SimObject* object = hashTable[i]; object != NULL; ) { SimObject* next = object->nextManagerNameObject; - idx = HashPointer( object->objectName ) % newHashTableSize; - object->nextManagerNameObject = newHashTable[ idx ]; - newHashTable[ idx ] = object; - + idx = HashPointer(object->objectName) % newHashTableSize; + object->nextManagerNameObject = newHashTable[idx]; + newHashTable[idx] = object; + object = next; } - + // Switch tables. - - delete [] hashTable; + + delete[] hashTable; hashTable = newHashTable; hashTableSize = newHashTableSize; } @@ -245,9 +245,9 @@ SimObject* SimManagerNameDictionary::find(StringTableEntry name) #ifndef USE_NEW_SIMDICTIONARY S32 idx = HashPointer(name) % hashTableSize; SimObject *walk = hashTable[idx]; - while(walk) + while (walk) { - if(walk->objectName == name) + if (walk->objectName == name) { Mutex::unlockMutex(mutex); return walk; @@ -267,19 +267,19 @@ SimObject* SimManagerNameDictionary::find(StringTableEntry name) void SimManagerNameDictionary::remove(SimObject* obj) { - if(!obj || !obj->objectName) + if (!obj || !obj->objectName) return; #ifndef USE_NEW_SIMDICTIONARY Mutex::lockMutex(mutex); SimObject **walk = &hashTable[HashPointer(obj->objectName) % hashTableSize]; - while(*walk) + while (*walk) { - if(*walk == obj) + if (*walk == obj) { *walk = obj->nextManagerNameObject; - obj->nextManagerNameObject = (SimObject*)-1; + obj->nextManagerNameObject = nullptr; hashEntryCount--; Mutex::unlockMutex(mutex); @@ -293,7 +293,7 @@ void SimManagerNameDictionary::remove(SimObject* obj) root.erase(name); #endif Mutex::unlockMutex(mutex); -} +} //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- @@ -301,7 +301,7 @@ void SimManagerNameDictionary::remove(SimObject* obj) SimIdDictionary::SimIdDictionary() { #ifndef USE_NEW_SIMDICTIONARY - dMemset( table, 0, sizeof( table[ 0 ] ) * DefaultTableSize ); + dMemset(table, 0, sizeof(table[0]) * DefaultTableSize); #endif mutex = Mutex::createMutex(); } @@ -322,7 +322,7 @@ void SimIdDictionary::insert(SimObject* obj) #ifndef USE_NEW_SIMDICTIONARY S32 idx = obj->getId() & TableBitMask; obj->nextIdObject = table[idx]; - AssertFatal( obj->nextIdObject != obj, "SimIdDictionary::insert - Creating Infinite Loop linking to self!" ); + AssertFatal(obj->nextIdObject != obj, "SimIdDictionary::insert - Creating Infinite Loop linking to self!"); table[idx] = obj; #else root[obj->getId()] = obj; @@ -336,9 +336,9 @@ SimObject* SimIdDictionary::find(S32 id) #ifndef USE_NEW_SIMDICTIONARY S32 idx = id & TableBitMask; SimObject *walk = table[idx]; - while(walk) + while (walk) { - if(walk->getId() == U32(id)) + if (walk->getId() == U32(id)) { Mutex::unlockMutex(mutex); return walk; @@ -364,9 +364,9 @@ void SimIdDictionary::remove(SimObject* obj) Mutex::lockMutex(mutex); #ifndef USE_NEW_SIMDICTIONARY SimObject **walk = &table[obj->getId() & TableBitMask]; - while(*walk && *walk != obj) + while (*walk && *walk != obj) walk = &((*walk)->nextIdObject); - if(*walk) + if (*walk) *walk = obj->nextIdObject; #else root.erase(obj->getId()); diff --git a/Engine/source/console/simFieldDictionary.cpp b/Engine/source/console/simFieldDictionary.cpp index 7cf3deb94..f68a8689b 100644 --- a/Engine/source/console/simFieldDictionary.cpp +++ b/Engine/source/console/simFieldDictionary.cpp @@ -36,20 +36,20 @@ SimFieldDictionary::Entry *SimFieldDictionary::smFreeList = NULL; static Chunker fieldChunker; -U32 SimFieldDictionary::getHashValue( StringTableEntry slotName ) +U32 SimFieldDictionary::getHashValue(StringTableEntry slotName) { - return HashPointer( slotName ) % HashTableSize; + return HashPointer(slotName) % HashTableSize; } -U32 SimFieldDictionary::getHashValue( const String& fieldName ) +U32 SimFieldDictionary::getHashValue(const String& fieldName) { - return getHashValue( StringTable->insert( fieldName ) ); + return getHashValue(StringTable->insert(fieldName)); } -SimFieldDictionary::Entry *SimFieldDictionary::addEntry( U32 bucket, StringTableEntry slotName, ConsoleBaseType* type, char* value ) +SimFieldDictionary::Entry *SimFieldDictionary::addEntry(U32 bucket, StringTableEntry slotName, ConsoleBaseType* type, char* value) { Entry* ret; - if(smFreeList) + if (smFreeList) { ret = smFreeList; smFreeList = ret->next; @@ -57,14 +57,14 @@ SimFieldDictionary::Entry *SimFieldDictionary::addEntry( U32 bucket, StringTable else ret = fieldChunker.alloc(); - ret->next = mHashTable[ bucket ]; - ret->slotName = slotName; - ret->type = type; - ret->value = value; + ret->next = mHashTable[bucket]; + ret->slotName = slotName; + ret->type = type; + ret->value = value; - mHashTable[ bucket ] = ret; - mNumFields ++; - mVersion ++; + mHashTable[bucket] = ret; + mNumFields++; + mVersion++; return ret; } @@ -74,37 +74,37 @@ void SimFieldDictionary::freeEntry(SimFieldDictionary::Entry *ent) ent->next = smFreeList; smFreeList = ent; - mNumFields --; + mNumFields--; } SimFieldDictionary::SimFieldDictionary() -: mNumFields( 0 ), - mVersion( 0 ) + : mNumFields(0), + mVersion(0) { - dMemset( mHashTable, 0, sizeof( mHashTable ) ); + dMemset(mHashTable, 0, sizeof(mHashTable)); } SimFieldDictionary::~SimFieldDictionary() { - for(U32 i = 0; i < HashTableSize; i++) + for (U32 i = 0; i < HashTableSize; i++) { - for(Entry *walk = mHashTable[i]; walk;) + for (Entry *walk = mHashTable[i]; walk;) { Entry *temp = walk; walk = temp->next; - if( temp->value ) + if (temp->value) dFree(temp->value); freeEntry(temp); } } - AssertFatal( mNumFields == 0, "Incorrect count on field dictionary" ); + AssertFatal(mNumFields == 0, "Incorrect count on field dictionary"); } void SimFieldDictionary::setFieldType(StringTableEntry slotName, const char *typeString) { - ConsoleBaseType *cbt = ConsoleBaseType::getTypeByName( typeString ); + ConsoleBaseType *cbt = ConsoleBaseType::getTypeByName(typeString); setFieldType(slotName, cbt); } @@ -117,11 +117,11 @@ void SimFieldDictionary::setFieldType(StringTableEntry slotName, const U32 typeI void SimFieldDictionary::setFieldType(StringTableEntry slotName, ConsoleBaseType *type) { // If the field exists on the object, set the type - U32 bucket = getHashValue( slotName ); + U32 bucket = getHashValue(slotName); - for( Entry *walk = mHashTable[bucket]; walk; walk = walk->next ) + for (Entry *walk = mHashTable[bucket]; walk; walk = walk->next) { - if( walk->slotName == slotName ) + if (walk->slotName == slotName) { // Found and type assigned, let's bail walk->type = type; @@ -130,15 +130,15 @@ void SimFieldDictionary::setFieldType(StringTableEntry slotName, ConsoleBaseType } // Otherwise create the field, and set the type. Assign a null value. - addEntry( bucket, slotName, type ); + addEntry(bucket, slotName, type); } U32 SimFieldDictionary::getFieldType(StringTableEntry slotName) const { - U32 bucket = getHashValue( slotName ); + U32 bucket = getHashValue(slotName); - for( Entry *walk = mHashTable[bucket]; walk; walk = walk->next ) - if( walk->slotName == slotName ) + for (Entry *walk = mHashTable[bucket]; walk; walk = walk->next) + if (walk->slotName == slotName) return walk->type ? walk->type->getTypeID() : TypeString; return TypeString; @@ -146,27 +146,27 @@ U32 SimFieldDictionary::getFieldType(StringTableEntry slotName) const SimFieldDictionary::Entry *SimFieldDictionary::findDynamicField(const String &fieldName) const { - U32 bucket = getHashValue( fieldName ); + U32 bucket = getHashValue(fieldName); - for( Entry *walk = mHashTable[bucket]; walk; walk = walk->next ) + for (Entry *walk = mHashTable[bucket]; walk; walk = walk->next) { - if( fieldName.equal(walk->slotName, String::NoCase) ) + if (fieldName.equal(walk->slotName, String::NoCase)) return walk; } return NULL; } -SimFieldDictionary::Entry *SimFieldDictionary::findDynamicField( StringTableEntry fieldName) const +SimFieldDictionary::Entry *SimFieldDictionary::findDynamicField(StringTableEntry fieldName) const { - U32 bucket = getHashValue( fieldName ); + U32 bucket = getHashValue(fieldName); - for( Entry *walk = mHashTable[bucket]; walk; walk = walk->next ) + for (Entry *walk = mHashTable[bucket]; walk; walk = walk->next) { - if( walk->slotName == fieldName ) - { - return walk; - } + if (walk->slotName == fieldName) + { + return walk; + } } return NULL; @@ -177,17 +177,17 @@ void SimFieldDictionary::setFieldValue(StringTableEntry slotName, const char *va { U32 bucket = getHashValue(slotName); Entry **walk = &mHashTable[bucket]; - while(*walk && (*walk)->slotName != slotName) + while (*walk && (*walk)->slotName != slotName) walk = &((*walk)->next); Entry *field = *walk; - if( !value || !*value ) + if (!value || !*value) { - if(field) + if (field) { mVersion++; - if( field->value ) + if (field->value) dFree(field->value); *walk = field->next; @@ -196,15 +196,15 @@ void SimFieldDictionary::setFieldValue(StringTableEntry slotName, const char *va } else { - if(field) + if (field) { - if( field->value ) + if (field->value) dFree(field->value); field->value = dStrdup(value); } else - addEntry( bucket, slotName, 0, dStrdup( value ) ); + addEntry(bucket, slotName, 0, dStrdup(value)); } } @@ -212,8 +212,8 @@ const char *SimFieldDictionary::getFieldValue(StringTableEntry slotName) { U32 bucket = getHashValue(slotName); - for(Entry *walk = mHashTable[bucket];walk;walk = walk->next) - if(walk->slotName == slotName) + for (Entry *walk = mHashTable[bucket]; walk; walk = walk->next) + if (walk->slotName == slotName) return walk->value; return NULL; @@ -223,9 +223,9 @@ void SimFieldDictionary::assignFrom(SimFieldDictionary *dict) { mVersion++; - for(U32 i = 0; i < HashTableSize; i++) + for (U32 i = 0; i < HashTableSize; i++) { - for(Entry *walk = dict->mHashTable[i];walk; walk = walk->next) + for (Entry *walk = dict->mHashTable[i]; walk; walk = walk->next) { setFieldValue(walk->slotName, walk->value); setFieldType(walk->slotName, walk->type); @@ -233,7 +233,7 @@ void SimFieldDictionary::assignFrom(SimFieldDictionary *dict) } } -static S32 QSORT_CALLBACK compareEntries(const void* a,const void* b) +static S32 QSORT_CALLBACK compareEntries(const void* a, const void* b) { SimFieldDictionary::Entry *fa = *((SimFieldDictionary::Entry **)a); SimFieldDictionary::Entry *fb = *((SimFieldDictionary::Entry **)b); @@ -245,17 +245,17 @@ void SimFieldDictionary::writeFields(SimObject *obj, Stream &stream, U32 tabStop const AbstractClassRep::FieldList &list = obj->getFieldList(); Vector flist(__FILE__, __LINE__); - for(U32 i = 0; i < HashTableSize; i++) + for (U32 i = 0; i < HashTableSize; i++) { - for(Entry *walk = mHashTable[i];walk; walk = walk->next) + for (Entry *walk = mHashTable[i]; walk; walk = walk->next) { // make sure we haven't written this out yet: U32 i; - for(i = 0; i < list.size(); i++) - if(list[i].pFieldname == walk->slotName) + for (i = 0; i < list.size(); i++) + if (list[i].pFieldname == walk->slotName) break; - if(i != list.size()) + if (i != list.size()) continue; @@ -267,23 +267,23 @@ void SimFieldDictionary::writeFields(SimObject *obj, Stream &stream, U32 tabStop } // Sort Entries to prevent version control conflicts - dQsort(flist.address(),flist.size(),sizeof(Entry *),compareEntries); + dQsort(flist.address(), flist.size(), sizeof(Entry *), compareEntries); // Save them out - for(Vector::iterator itr = flist.begin(); itr != flist.end(); itr++) + for (Vector::iterator itr = flist.begin(); itr != flist.end(); itr++) { - U32 nBufferSize = (dStrlen( (*itr)->value ) * 2) + dStrlen( (*itr)->slotName ) + 16; - FrameTemp expandedBuffer( nBufferSize ); + U32 nBufferSize = (dStrlen((*itr)->value) * 2) + dStrlen((*itr)->slotName) + 16; + FrameTemp expandedBuffer(nBufferSize); - stream.writeTabs(tabStop+1); + stream.writeTabs(tabStop + 1); const char *typeName = (*itr)->type && (*itr)->type->getTypeID() != TypeString ? (*itr)->type->getTypeName() : ""; dSprintf(expandedBuffer, nBufferSize, "%s%s%s = \"", typeName, *typeName ? " " : "", (*itr)->slotName); - if ( (*itr)->value ) + if ((*itr)->value) expandEscape((char*)expandedBuffer + dStrlen(expandedBuffer), (*itr)->value); dStrcat(expandedBuffer, "\";\r\n"); - stream.write(dStrlen(expandedBuffer),expandedBuffer); + stream.write(dStrlen(expandedBuffer), expandedBuffer); } } @@ -293,32 +293,32 @@ void SimFieldDictionary::printFields(SimObject *obj) char expandedBuffer[4096]; Vector flist(__FILE__, __LINE__); - for(U32 i = 0; i < HashTableSize; i++) + for (U32 i = 0; i < HashTableSize; i++) { - for(Entry *walk = mHashTable[i];walk; walk = walk->next) + for (Entry *walk = mHashTable[i]; walk; walk = walk->next) { // make sure we haven't written this out yet: U32 i; - for(i = 0; i < list.size(); i++) - if(list[i].pFieldname == walk->slotName) + for (i = 0; i < list.size(); i++) + if (list[i].pFieldname == walk->slotName) break; - if(i != list.size()) + if (i != list.size()) continue; flist.push_back(walk); } } - dQsort(flist.address(),flist.size(),sizeof(Entry *),compareEntries); + dQsort(flist.address(), flist.size(), sizeof(Entry *), compareEntries); - for(Vector::iterator itr = flist.begin(); itr != flist.end(); itr++) + for (Vector::iterator itr = flist.begin(); itr != flist.end(); itr++) { const char* type = "string"; - if( ( *itr )->type ) - type = ( *itr )->type->getTypeClassName(); - - dSprintf( expandedBuffer, sizeof( expandedBuffer ), " %s %s = \"", type, ( *itr )->slotName ); - if ( (*itr)->value ) + if ((*itr)->type) + type = (*itr)->type->getTypeClassName(); + + dSprintf(expandedBuffer, sizeof(expandedBuffer), " %s %s = \"", type, (*itr)->slotName); + if ((*itr)->value) expandEscape(expandedBuffer + dStrlen(expandedBuffer), (*itr)->value); Con::printf("%s\"", expandedBuffer); } @@ -326,9 +326,9 @@ void SimFieldDictionary::printFields(SimObject *obj) SimFieldDictionary::Entry *SimFieldDictionary::operator[](U32 index) { - AssertFatal ( index < mNumFields, "out of range" ); + AssertFatal(index < mNumFields, "out of range"); - if ( index > mNumFields ) + if (index > mNumFields) return NULL; SimFieldDictionaryIterator itr(this); @@ -350,13 +350,13 @@ SimFieldDictionaryIterator::SimFieldDictionaryIterator(SimFieldDictionary * dict SimFieldDictionary::Entry* SimFieldDictionaryIterator::operator++() { - if(!mDictionary) + if (!mDictionary) return(mEntry); - if(mEntry) + if (mEntry) mEntry = mEntry->next; - while(!mEntry && (mHashIndex < (SimFieldDictionary::HashTableSize-1))) + while (!mEntry && (mHashIndex < (SimFieldDictionary::HashTableSize - 1))) mEntry = mDictionary->mHashTable[++mHashIndex]; return(mEntry); @@ -386,14 +386,14 @@ void SimFieldDictionary::setFieldValue(StringTableEntry slotName, const char *va U32 bucket = getHashValue(slotName); Entry **walk = &mHashTable[bucket]; - while(*walk && (*walk)->slotName != slotName) + while (*walk && (*walk)->slotName != slotName) walk = &((*walk)->next); Entry *field = *walk; if (field) return; - addEntry( bucket, slotName, type, dStrdup( value ) ); + addEntry(bucket, slotName, type, dStrdup(value)); } // A variation of the stock SimFieldDictionary::assignFrom(), this method adds // and arguments. When true, prohibits the replacement of fields that already @@ -412,15 +412,15 @@ void SimFieldDictionary::assignFrom(SimFieldDictionary *dict, const char* filter if (filter_len == 0) { - for(U32 i = 0; i < HashTableSize; i++) - for(Entry *walk = dict->mHashTable[i];walk; walk = walk->next) + for (U32 i = 0; i < HashTableSize; i++) + for (Entry *walk = dict->mHashTable[i]; walk; walk = walk->next) setFieldValue(walk->slotName, walk->value, walk->type, no_replace); } else { - for(U32 i = 0; i < HashTableSize; i++) - for(Entry *walk = dict->mHashTable[i];walk; walk = walk->next) + for (U32 i = 0; i < HashTableSize; i++) + for (Entry *walk = dict->mHashTable[i]; walk; walk = walk->next) if (dStrncmp(walk->slotName, filter, filter_len) == 0) setFieldValue(walk->slotName, walk->value, walk->type, no_replace); } -} +} \ No newline at end of file diff --git a/Engine/source/console/simFieldDictionary.h b/Engine/source/console/simFieldDictionary.h index 4849be563..c89bd5b57 100644 --- a/Engine/source/console/simFieldDictionary.h +++ b/Engine/source/console/simFieldDictionary.h @@ -47,7 +47,7 @@ class SimFieldDictionary public: struct Entry { - Entry() : type( NULL ) {}; + Entry() : type(NULL) {}; StringTableEntry slotName; char *value; @@ -64,10 +64,10 @@ private: static Entry *smFreeList; void freeEntry(Entry *entry); - Entry* addEntry( U32 bucket, StringTableEntry slotName, ConsoleBaseType* type, char* value = 0 ); + Entry* addEntry(U32 bucket, StringTableEntry slotName, ConsoleBaseType* type, char* value = 0); - static U32 getHashValue( StringTableEntry slotName ); - static U32 getHashValue( const String& fieldName ); + static U32 getHashValue(StringTableEntry slotName); + static U32 getHashValue(const String& fieldName); U32 mNumFields; @@ -88,7 +88,7 @@ public: const char *getFieldValue(StringTableEntry slotName); U32 getFieldType(StringTableEntry slotName) const; Entry *findDynamicField(const String &fieldName) const; - Entry *findDynamicField( StringTableEntry fieldName) const; + Entry *findDynamicField(StringTableEntry fieldName) const; void writeFields(SimObject *obj, Stream &strem, U32 tabStop); void printFields(SimObject *obj); void assignFrom(SimFieldDictionary *dict); @@ -112,4 +112,4 @@ public: }; -#endif // _SIMFIELDDICTIONARY_H_ +#endif // _SIMFIELDDICTIONARY_H_ \ No newline at end of file diff --git a/Engine/source/console/simObject.cpp b/Engine/source/console/simObject.cpp index c12a12f19..0583606b0 100644 --- a/Engine/source/console/simObject.cpp +++ b/Engine/source/console/simObject.cpp @@ -72,8 +72,8 @@ SimObject::SimObject() objectName = NULL; mOriginalName = NULL; mInternalName = NULL; - nextNameObject = (SimObject*)-1; - nextManagerNameObject = (SimObject*)-1; + nextNameObject = nullptr; + nextManagerNameObject = nullptr; nextIdObject = NULL; mFilename = NULL; @@ -86,6 +86,8 @@ SimObject::SimObject() mNotifyList = NULL; mFlags.set( ModStaticFields | ModDynamicFields ); + mProgenitorFile = StringTable->EmptyString(); + mFieldDictionary = NULL; mCanSaveFieldDictionary = true; @@ -122,10 +124,10 @@ SimObject::~SimObject() if( mCopySource ) mCopySource->unregisterReference( &mCopySource ); - AssertFatal(nextNameObject == (SimObject*)-1,avar( + AssertFatal(nextNameObject == nullptr,avar( "SimObject::~SimObject: Not removed from dictionary: name %s, id %i", objectName, mId)); - AssertFatal(nextManagerNameObject == (SimObject*)-1,avar( + AssertFatal(nextManagerNameObject == nullptr,avar( "SimObject::~SimObject: Not removed from manager dictionary: name %s, id %i", objectName,mId)); AssertFatal(mFlags.test(Added) == 0, "SimObject::object " diff --git a/Engine/source/persistence/taml/taml.cpp b/Engine/source/persistence/taml/taml.cpp index 21e1e3d0b..f364ed0ce 100644 --- a/Engine/source/persistence/taml/taml.cpp +++ b/Engine/source/persistence/taml/taml.cpp @@ -82,635 +82,637 @@ //----------------------------------------------------------------------------- -IMPLEMENT_CONOBJECT( Taml ); +IMPLEMENT_CONOBJECT(Taml); //----------------------------------------------------------------------------- -StringTableEntry tamlRefIdName = StringTable->insert( "TamlId" ); -StringTableEntry tamlRefToIdName = StringTable->insert( "TamlRefId" ); -StringTableEntry tamlNamedObjectName = StringTable->insert( "Name" ); +StringTableEntry tamlRefIdName = StringTable->insert("TamlId"); +StringTableEntry tamlRefToIdName = StringTable->insert("TamlRefId"); +StringTableEntry tamlNamedObjectName = StringTable->insert("Name"); //----------------------------------------------------------------------------- typedef Taml::TamlFormatMode _TamlFormatMode; -ImplementEnumType( _TamlFormatMode, +ImplementEnumType(_TamlFormatMode, "") - { Taml::XmlFormat, "xml" }, - { Taml::BinaryFormat, "binary" }//, - //{ Taml::JSONFormat, "json" } -EndImplementEnumType; - -//----------------------------------------------------------------------------- - -Taml::TamlFormatMode Taml::getFormatModeEnum(const char* label) { - // Search for Mnemonic. - for (U32 i = 0; i < (sizeof(__TamlFormatMode::_sEnums) / sizeof(EnumTable::Value)); i++) - { - if( dStricmp(__TamlFormatMode::_sEnumTable[i].getName(), label) == 0) - return (TamlFormatMode)__TamlFormatMode::_sEnumTable[i].getInt(); - } + Taml::XmlFormat, "xml" +}, +{ Taml::BinaryFormat, "binary" }//, + //{ Taml::JSONFormat, "json" } + EndImplementEnumType; - // Warn. - Con::warnf( "Taml::getFormatModeEnum() - Invalid format of '%s'.", label ); + //----------------------------------------------------------------------------- - return Taml::InvalidFormat; -} + Taml::TamlFormatMode Taml::getFormatModeEnum(const char* label) + { + // Search for Mnemonic. + for (U32 i = 0; i < (sizeof(__TamlFormatMode::_sEnums) / sizeof(EnumTable::Value)); i++) + { + if (dStricmp(__TamlFormatMode::_sEnumTable[i].getName(), label) == 0) + return (TamlFormatMode)__TamlFormatMode::_sEnumTable[i].getInt(); + } -//----------------------------------------------------------------------------- + // Warn. + Con::warnf("Taml::getFormatModeEnum() - Invalid format of '%s'.", label); -const char* Taml::getFormatModeDescription(const Taml::TamlFormatMode formatMode) -{ - // Search for Mnemonic. - for (U32 i = 0; i < (sizeof(__TamlFormatMode::_sEnums) / sizeof(EnumTable::Value)); i++) - { - if( __TamlFormatMode::_sEnumTable[i].getInt() == (S32)formatMode ) - return __TamlFormatMode::_sEnumTable[i].getName(); - } + return Taml::InvalidFormat; + } - // Warn. - Con::warnf( "Taml::getFormatModeDescription() - Invalid format mode." ); + //----------------------------------------------------------------------------- - return StringTable->EmptyString(); -} + const char* Taml::getFormatModeDescription(const Taml::TamlFormatMode formatMode) + { + // Search for Mnemonic. + for (U32 i = 0; i < (sizeof(__TamlFormatMode::_sEnums) / sizeof(EnumTable::Value)); i++) + { + if (__TamlFormatMode::_sEnumTable[i].getInt() == (S32)formatMode) + return __TamlFormatMode::_sEnumTable[i].getName(); + } -//----------------------------------------------------------------------------- + // Warn. + Con::warnf("Taml::getFormatModeDescription() - Invalid format mode."); -// The string-table-entries are set to string literals below because Taml is used in a static scope and the string-table cannot currently be used like that. -Taml::Taml() : - mFormatMode(XmlFormat), - mJSONStrict( true ), - mBinaryCompression(true), - mWriteDefaults(false), - mAutoFormatXmlExtension("taml"), - mAutoFormat(true), - mProgenitorUpdate(true), - mAutoFormatBinaryExtension("baml"), - mAutoFormatJSONExtension("json") -{ - // Reset the file-path buffer. - mFilePathBuffer[0] = 0; -} + return StringTable->EmptyString(); + } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -void Taml::initPersistFields() -{ - // Call parent. - Parent::initPersistFields(); + // The string-table-entries are set to string literals below because Taml is used in a static scope and the string-table cannot currently be used like that. + Taml::Taml() : + mFormatMode(XmlFormat), + mJSONStrict(true), + mBinaryCompression(true), + mWriteDefaults(false), + mAutoFormatXmlExtension("taml"), + mAutoFormat(true), + mProgenitorUpdate(true), + mAutoFormatBinaryExtension("baml"), + mAutoFormatJSONExtension("json") + { + // Reset the file-path buffer. + mFilePathBuffer[0] = 0; + } - addField("Format", TYPEID<_TamlFormatMode>(), Offset(mFormatMode, Taml), "The read/write format that should be used."); - addField("JSONStrict", TypeBool, Offset(mBinaryCompression, Taml), "Whether to write JSON that is strictly compatible with RFC4627 or not.\n"); - addField("BinaryCompression", TypeBool, Offset(mBinaryCompression, Taml), "Whether ZIP compression is used on binary formatting or not.\n"); - addField("WriteDefaults", TypeBool, Offset(mWriteDefaults, Taml), "Whether to write static fields that are at their default or not.\n"); - addField("ProgenitorUpdate", TypeBool, Offset(mProgenitorUpdate, Taml), "Whether to update each type instances file-progenitor or not.\n"); - addField("AutoFormat", TypeBool, Offset(mAutoFormat, Taml), "Whether the format type is automatically determined by the filename extension or not.\n"); - addField("AutoFormatXmlExtension", TypeString, Offset(mAutoFormatXmlExtension, Taml), "When using auto-format, this is the extension (end of filename) used to detect the XML format.\n"); - addField("AutoFormatBinaryExtension", TypeString, Offset(mAutoFormatBinaryExtension, Taml), "When using auto-format, this is the extension (end of filename) used to detect the BINARY format.\n"); - addField("AutoFormatJSONExtension", TypeString, Offset(mAutoFormatJSONExtension, Taml), "When using auto-format, this is the extension (end of filename) used to detect the JSON format.\n"); -} + //----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- + void Taml::initPersistFields() + { + // Call parent. + Parent::initPersistFields(); -bool Taml::onAdd() -{ - // Call parent. - if ( !Parent::onAdd() ) - return false; + addField("Format", TYPEID<_TamlFormatMode>(), Offset(mFormatMode, Taml), "The read/write format that should be used."); + addField("JSONStrict", TypeBool, Offset(mBinaryCompression, Taml), "Whether to write JSON that is strictly compatible with RFC4627 or not.\n"); + addField("BinaryCompression", TypeBool, Offset(mBinaryCompression, Taml), "Whether ZIP compression is used on binary formatting or not.\n"); + addField("WriteDefaults", TypeBool, Offset(mWriteDefaults, Taml), "Whether to write static fields that are at their default or not.\n"); + addField("ProgenitorUpdate", TypeBool, Offset(mProgenitorUpdate, Taml), "Whether to update each type instances file-progenitor or not.\n"); + addField("AutoFormat", TypeBool, Offset(mAutoFormat, Taml), "Whether the format type is automatically determined by the filename extension or not.\n"); + addField("AutoFormatXmlExtension", TypeString, Offset(mAutoFormatXmlExtension, Taml), "When using auto-format, this is the extension (end of filename) used to detect the XML format.\n"); + addField("AutoFormatBinaryExtension", TypeString, Offset(mAutoFormatBinaryExtension, Taml), "When using auto-format, this is the extension (end of filename) used to detect the BINARY format.\n"); + addField("AutoFormatJSONExtension", TypeString, Offset(mAutoFormatJSONExtension, Taml), "When using auto-format, this is the extension (end of filename) used to detect the JSON format.\n"); + } - // Set JSON strict mode. - mJSONStrict = Con::getBoolVariable( TAML_JSON_STRICT_VARIBLE, true ); + //----------------------------------------------------------------------------- - // Reset the compilation. - resetCompilation(); + bool Taml::onAdd() + { + // Call parent. + if (!Parent::onAdd()) + return false; - return true; -} + // Set JSON strict mode. + mJSONStrict = Con::getBoolVariable(TAML_JSON_STRICT_VARIBLE, true); -//----------------------------------------------------------------------------- + // Reset the compilation. + resetCompilation(); -void Taml::onRemove() -{ - // Reset the compilation. - resetCompilation(); + return true; + } - // Call parent. - Parent::onRemove(); -} + //----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- + void Taml::onRemove() + { + // Reset the compilation. + resetCompilation(); -bool Taml::write( SimObject* pSimObject, const char* pFilename ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_Write); + // Call parent. + Parent::onRemove(); + } - // Sanity! - AssertFatal( pSimObject != NULL, "Cannot write a NULL object." ); - AssertFatal( pFilename != NULL, "Cannot write to a NULL filename." ); + //----------------------------------------------------------------------------- - // Expand the file-name into the file-path buffer. - Con::expandToolScriptFilename( mFilePathBuffer, sizeof(mFilePathBuffer), pFilename ); + bool Taml::write(SimObject* pSimObject, const char* pFilename) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_Write); - FileStream stream; + // Sanity! + AssertFatal(pSimObject != NULL, "Cannot write a NULL object."); + AssertFatal(pFilename != NULL, "Cannot write to a NULL filename."); - // File opened? - if ( !stream.open( mFilePathBuffer, Torque::FS::File::Write ) ) - { - // No, so warn. - Con::warnf("Taml::writeFile() - Could not open filename '%s' for write.", mFilePathBuffer ); - return false; - } + // Expand the file-name into the file-path buffer. + Con::expandToolScriptFilename(mFilePathBuffer, sizeof(mFilePathBuffer), pFilename); - // Get the file auto-format mode. - const TamlFormatMode formatMode = getFileAutoFormatMode( mFilePathBuffer ); + FileStream stream; - // Reset the compilation. - resetCompilation(); + // File opened? + if (!stream.open(mFilePathBuffer, Torque::FS::File::Write)) + { + // No, so warn. + Con::warnf("Taml::writeFile() - Could not open filename '%s' for write.", mFilePathBuffer); + return false; + } - // Write object. - const bool status = write( stream, pSimObject, formatMode ); + // Get the file auto-format mode. + const TamlFormatMode formatMode = getFileAutoFormatMode(mFilePathBuffer); - // Close file. - stream.close(); + // Reset the compilation. + resetCompilation(); - // Reset the compilation. - resetCompilation(); + // Write object. + const bool status = write(stream, pSimObject, formatMode); - return status; -} + // Close file. + stream.close(); -//----------------------------------------------------------------------------- + // Reset the compilation. + resetCompilation(); -SimObject* Taml::read( const char* pFilename ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_Read); + return status; + } - // Sanity! - AssertFatal( pFilename != NULL, "Cannot read from a NULL filename." ); + //----------------------------------------------------------------------------- - // Expand the file-name into the file-path buffer. - Con::expandToolScriptFilename( mFilePathBuffer, sizeof(mFilePathBuffer), pFilename ); + SimObject* Taml::read(const char* pFilename) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_Read); - FileStream stream; + // Sanity! + AssertFatal(pFilename != NULL, "Cannot read from a NULL filename."); - // File opened? - if ( !stream.open( mFilePathBuffer, Torque::FS::File::Read ) ) - { - // No, so warn. - Con::warnf("Taml::read() - Could not open filename '%s' for read.", mFilePathBuffer ); - return NULL; - } + // Expand the file-name into the file-path buffer. + Con::expandToolScriptFilename(mFilePathBuffer, sizeof(mFilePathBuffer), pFilename); - // Get the file auto-format mode. - const TamlFormatMode formatMode = getFileAutoFormatMode( mFilePathBuffer ); + FileStream stream; - // Reset the compilation. - resetCompilation(); + // File opened? + if (!stream.open(mFilePathBuffer, Torque::FS::File::Read)) + { + // No, so warn. + Con::warnf("Taml::read() - Could not open filename '%s' for read.", mFilePathBuffer); + return NULL; + } - // Write object. - SimObject* pSimObject = read( stream, formatMode ); + // Get the file auto-format mode. + const TamlFormatMode formatMode = getFileAutoFormatMode(mFilePathBuffer); - // Close file. - stream.close(); + // Reset the compilation. + resetCompilation(); - // Reset the compilation. - resetCompilation(); + // Write object. + SimObject* pSimObject = read(stream, formatMode); - // Did we generate an object? - if ( pSimObject == NULL ) - { - // No, so warn. - Con::warnf( "Taml::read() - Failed to load an object from the file '%s'.", mFilePathBuffer ); - } - else - { - pSimObject->onPostAdd(); - } + // Close file. + stream.close(); - return pSimObject; -} + // Reset the compilation. + resetCompilation(); -//----------------------------------------------------------------------------- + // Did we generate an object? + if (pSimObject == NULL) + { + // No, so warn. + Con::warnf("Taml::read() - Failed to load an object from the file '%s'.", mFilePathBuffer); + } + else + { + pSimObject->onPostAdd(); + } -bool Taml::write( FileStream& stream, SimObject* pSimObject, const TamlFormatMode formatMode ) -{ - // Sanity! - AssertFatal( pSimObject != NULL, "Cannot write a NULL object." ); + return pSimObject; + } - // Compile nodes. - TamlWriteNode* pRootNode = compileObject( pSimObject ); + //----------------------------------------------------------------------------- - // Format appropriately. - switch( formatMode ) - { - /// Xml. - case XmlFormat: - { - // Create writer. - TamlXmlWriter writer( this ); - // Write. - return writer.write( stream, pRootNode ); - } + bool Taml::write(FileStream& stream, SimObject* pSimObject, const TamlFormatMode formatMode) + { + // Sanity! + AssertFatal(pSimObject != NULL, "Cannot write a NULL object."); - /// Binary. - case BinaryFormat: - { - // Create writer. - TamlBinaryWriter writer( this ); + // Compile nodes. + TamlWriteNode* pRootNode = compileObject(pSimObject); - // Write. - return writer.write( stream, pRootNode, mBinaryCompression ); - } + // Format appropriately. + switch (formatMode) + { + /// Xml. + case XmlFormat: + { + // Create writer. + TamlXmlWriter writer(this); + // Write. + return writer.write(stream, pRootNode); + } - /// JSON. - case JSONFormat: - { - // Create writer. - //TamlJSONWriter writer( this ); + /// Binary. + case BinaryFormat: + { + // Create writer. + TamlBinaryWriter writer(this); - // Write. - //return writer.write( stream, pRootNode ); - return NULL; - } + // Write. + return writer.write(stream, pRootNode, mBinaryCompression); + } - /// Invalid. - case InvalidFormat: - { - // Warn. - Con::warnf("Taml::write() - Cannot write, invalid format."); + /// JSON. + case JSONFormat: + { + // Create writer. + //TamlJSONWriter writer( this ); + + // Write. + //return writer.write( stream, pRootNode ); + return NULL; + } + + /// Invalid. + case InvalidFormat: + { + // Warn. + Con::warnf("Taml::write() - Cannot write, invalid format."); + return false; + } + } + + // Warn. + Con::warnf("Taml::write() - Unknown format."); + return false; + } + + //----------------------------------------------------------------------------- + + SimObject* Taml::read(FileStream& stream, const TamlFormatMode formatMode) + { + // Format appropriately. + switch (formatMode) + { + /// Xml. + case XmlFormat: + { + // Create reader. + TamlXmlReader reader(this); + + // Read. + return reader.read(stream); + } + + /// Binary. + case BinaryFormat: + { + // Create reader. + TamlBinaryReader reader(this); + + // Read. + return reader.read(stream); + } + + /// JSON. + case JSONFormat: + { + // Create reader. + //TamlJSONReader reader( this ); + + // Read. + //return reader.read( stream ); + return NULL; + } + + /// Invalid. + case InvalidFormat: + { + // Warn. + Con::warnf("Taml::read() - Cannot read, invalid format."); + return NULL; + } + } + + // Warn. + Con::warnf("Taml::read() - Unknown format."); + return NULL; + } + + //----------------------------------------------------------------------------- + + bool Taml::parse(const char* pFilename, TamlVisitor& visitor) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_Parse); + + // Sanity! + AssertFatal(pFilename != NULL, "Taml::parse() - Cannot parse a NULL filename."); + + // Fetch format mode. + const TamlFormatMode formatMode = getFileAutoFormatMode(pFilename); + + // Handle format mode appropriately. + switch (formatMode) + { + case XmlFormat: + { + // Parse with the visitor. + TamlXmlParser parser; + + // Are property changes needed but not supported? + if (visitor.wantsPropertyChanges() && !parser.canChangeProperty()) + { + // Yes, so warn. + Con::warnf("Taml::parse() - Cannot parse '%s' file-type for filename '%s' as a specified visitor requires property changes which are not supported by the parser.", getFormatModeDescription(formatMode), pFilename); return false; - } - } + } - // Warn. - Con::warnf("Taml::write() - Unknown format."); - return false; -} + return parser.accept(pFilename, visitor); + } -//----------------------------------------------------------------------------- + case JSONFormat: + { + // Parse with the visitor. + /*TamlJSONParser parser; -SimObject* Taml::read( FileStream& stream, const TamlFormatMode formatMode ) -{ - // Format appropriately. - switch( formatMode ) - { - /// Xml. - case XmlFormat: - { - // Create reader. - TamlXmlReader reader( this ); + // Are property changes needed but not supported? + if ( visitor.wantsPropertyChanges() && !parser.canChangeProperty() ) + { + // Yes, so warn. + Con::warnf( "Taml::parse() - Cannot parse '%s' file-type for filename '%s' as a specified visitor requires property changes which are not supported by the parser.", getFormatModeDescription(formatMode), pFilename ); + return false; + } - // Read. - return reader.read( stream ); - } + return parser.accept( pFilename, visitor ); */ + return false; + } - /// Binary. - case BinaryFormat: - { - // Create reader. - TamlBinaryReader reader( this ); + case BinaryFormat: + default: + break; + } - // Read. - return reader.read( stream ); - } + // Warn. + Con::warnf("Taml::parse() - Cannot parse '%s' file-type for filename '%s' as a required parser is not available.", getFormatModeDescription(formatMode), pFilename); + return false; + } - /// JSON. - case JSONFormat: - { - // Create reader. - //TamlJSONReader reader( this ); + //----------------------------------------------------------------------------- - // Read. - //return reader.read( stream ); - return NULL; - } - - /// Invalid. - case InvalidFormat: - { - // Warn. - Con::warnf("Taml::read() - Cannot read, invalid format."); - return NULL; - } - } + void Taml::resetCompilation(void) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_ResetCompilation); - // Warn. - Con::warnf("Taml::read() - Unknown format."); - return NULL; -} + // Clear compiled nodes. + for (typeNodeVector::iterator itr = mCompiledNodes.begin(); itr != mCompiledNodes.end(); ++itr) + { + // Fetch node. + TamlWriteNode* pNode = (*itr); -//----------------------------------------------------------------------------- + // Reset node. + pNode->resetNode(); -bool Taml::parse( const char* pFilename, TamlVisitor& visitor ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_Parse); + // Delete node. + delete pNode; + } + mCompiledNodes.clear(); - // Sanity! - AssertFatal( pFilename != NULL, "Taml::parse() - Cannot parse a NULL filename." ); + // Clear compiled objects. + mCompiledObjects.clear(); - // Fetch format mode. - const TamlFormatMode formatMode = getFileAutoFormatMode( pFilename ); + // Reset master node Id. + mMasterNodeId = 0; + } - // Handle format mode appropriately. - switch( formatMode ) - { - case XmlFormat: - { - // Parse with the visitor. - TamlXmlParser parser; + //----------------------------------------------------------------------------- - // Are property changes needed but not supported? - if ( visitor.wantsPropertyChanges() && !parser.canChangeProperty() ) - { - // Yes, so warn. - Con::warnf( "Taml::parse() - Cannot parse '%s' file-type for filename '%s' as a specified visitor requires property changes which are not supported by the parser.", getFormatModeDescription(formatMode), pFilename ); - return false; - } + Taml::TamlFormatMode Taml::getFileAutoFormatMode(const char* pFilename) + { + // Sanity! + AssertFatal(pFilename != NULL, "Taml::getFileAutoFormatMode() - Cannot auto-format using a NULL filename."); - return parser.accept( pFilename, visitor ); - } + // Is auto-format active? + if (mAutoFormat) + { + // Yes, so fetch the extension lengths. + const U32 xmlExtensionLength = dStrlen(mAutoFormatXmlExtension); + const U32 binaryExtensionLength = dStrlen(mAutoFormatBinaryExtension); + const U32 jsonExtensionLength = dStrlen(mAutoFormatJSONExtension); - case JSONFormat: - { - // Parse with the visitor. - /*TamlJSONParser parser; + // Fetch filename length. + const U32 filenameLength = dStrlen(pFilename); - // Are property changes needed but not supported? - if ( visitor.wantsPropertyChanges() && !parser.canChangeProperty() ) - { - // Yes, so warn. - Con::warnf( "Taml::parse() - Cannot parse '%s' file-type for filename '%s' as a specified visitor requires property changes which are not supported by the parser.", getFormatModeDescription(formatMode), pFilename ); - return false; - } + // Fetch end of filename, + const char* pEndOfFilename = pFilename + filenameLength; - return parser.accept( pFilename, visitor ); */ - return false; - } - - case BinaryFormat: - default: - break; - } - - // Warn. - Con::warnf( "Taml::parse() - Cannot parse '%s' file-type for filename '%s' as a required parser is not available.", getFormatModeDescription(formatMode), pFilename ); - return false; -} - -//----------------------------------------------------------------------------- - -void Taml::resetCompilation( void ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_ResetCompilation); - - // Clear compiled nodes. - for( typeNodeVector::iterator itr = mCompiledNodes.begin(); itr != mCompiledNodes.end(); ++itr ) - { - // Fetch node. - TamlWriteNode* pNode = (*itr); - - // Reset node. - pNode->resetNode(); - - // Delete node. - delete pNode; - } - mCompiledNodes.clear(); - - // Clear compiled objects. - mCompiledObjects.clear(); - - // Reset master node Id. - mMasterNodeId = 0; -} - -//----------------------------------------------------------------------------- - -Taml::TamlFormatMode Taml::getFileAutoFormatMode( const char* pFilename ) -{ - // Sanity! - AssertFatal( pFilename != NULL, "Taml::getFileAutoFormatMode() - Cannot auto-format using a NULL filename." ); - - // Is auto-format active? - if ( mAutoFormat ) - { - // Yes, so fetch the extension lengths. - const U32 xmlExtensionLength = dStrlen( mAutoFormatXmlExtension ); - const U32 binaryExtensionLength = dStrlen( mAutoFormatBinaryExtension ); - const U32 jsonExtensionLength = dStrlen( mAutoFormatJSONExtension ); - - // Fetch filename length. - const U32 filenameLength = dStrlen( pFilename ); - - // Fetch end of filename, - const char* pEndOfFilename = pFilename + filenameLength; - - // Check for the XML format. - if ( xmlExtensionLength <= filenameLength && dStricmp( pEndOfFilename - xmlExtensionLength, mAutoFormatXmlExtension ) == 0 ) + // Check for the XML format. + if (xmlExtensionLength <= filenameLength && dStricmp(pEndOfFilename - xmlExtensionLength, mAutoFormatXmlExtension) == 0) return Taml::XmlFormat; - // Check for the Binary format. - if ( binaryExtensionLength <= filenameLength && dStricmp( pEndOfFilename - xmlExtensionLength, mAutoFormatBinaryExtension ) == 0 ) - return Taml::BinaryFormat; + // Check for the Binary format. + if (binaryExtensionLength <= filenameLength && dStricmp(pEndOfFilename - xmlExtensionLength, mAutoFormatBinaryExtension) == 0) + return Taml::BinaryFormat; - // Check for the XML format. - if ( jsonExtensionLength <= filenameLength && dStricmp( pEndOfFilename - jsonExtensionLength, mAutoFormatJSONExtension ) == 0 ) + // Check for the XML format. + if (jsonExtensionLength <= filenameLength && dStricmp(pEndOfFilename - jsonExtensionLength, mAutoFormatJSONExtension) == 0) return Taml::JSONFormat; - } + } - // Use the explicitly specified format mode. - return mFormatMode; -} + // Use the explicitly specified format mode. + return mFormatMode; + } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -TamlWriteNode* Taml::compileObject( SimObject* pSimObject, const bool forceId ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_CompileObject); + TamlWriteNode* Taml::compileObject(SimObject* pSimObject, const bool forceId) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_CompileObject); - // Sanity! - AssertFatal( pSimObject != NULL, "Taml::compileObject() - Cannot compile a NULL object." ); + // Sanity! + AssertFatal(pSimObject != NULL, "Taml::compileObject() - Cannot compile a NULL object."); - // Fetch object Id. - const SimObjectId objectId = pSimObject->getId(); + // Fetch object Id. + const SimObjectId objectId = pSimObject->getId(); - // Find a previously compiled node. - typeCompiledHash::Iterator compiledItr = mCompiledObjects.find( objectId ); + // Find a previously compiled node. + typeCompiledHash::Iterator compiledItr = mCompiledObjects.find(objectId); - // Have we already compiled this? - if ( compiledItr != mCompiledObjects.end() ) - { - // Yes, so sanity! - AssertFatal( mCompiledNodes.size() != 0, "Taml::compileObject() - Found a compiled node at the root." ); + // Have we already compiled this? + if (compiledItr != mCompiledObjects.end()) + { + // Yes, so sanity! + AssertFatal(mCompiledNodes.size() != 0, "Taml::compileObject() - Found a compiled node at the root."); - // Yes, so fetch node. - TamlWriteNode* compiledNode = compiledItr->value; + // Yes, so fetch node. + TamlWriteNode* compiledNode = compiledItr->value; - // Is a reference Id already present? - if ( compiledNode->mRefId == 0 ) - { + // Is a reference Id already present? + if (compiledNode->mRefId == 0) + { // No, so allocate one. compiledNode->mRefId = ++mMasterNodeId; - } + } - // Create write node. - TamlWriteNode* pNewNode = new TamlWriteNode(); - pNewNode->set( pSimObject ); + // Create write node. + TamlWriteNode* pNewNode = new TamlWriteNode(); + pNewNode->set(pSimObject); - // Set reference node. - pNewNode->mRefToNode = compiledNode; + // Set reference node. + pNewNode->mRefToNode = compiledNode; - // Push new node. - mCompiledNodes.push_back( pNewNode ); + // Push new node. + mCompiledNodes.push_back(pNewNode); - return pNewNode; - } + return pNewNode; + } - // No, so create write node. - TamlWriteNode* pNewNode = new TamlWriteNode(); - pNewNode->set( pSimObject ); + // No, so create write node. + TamlWriteNode* pNewNode = new TamlWriteNode(); + pNewNode->set(pSimObject); - // Is an Id being forced for this object? - if ( forceId ) - { - // Yes, so allocate one. - pNewNode->mRefId = ++mMasterNodeId; - } + // Is an Id being forced for this object? + if (forceId) + { + // Yes, so allocate one. + pNewNode->mRefId = ++mMasterNodeId; + } - // Push new node. - mCompiledNodes.push_back( pNewNode ); + // Push new node. + mCompiledNodes.push_back(pNewNode); - // Insert compiled object. - mCompiledObjects.insertUnique( objectId, pNewNode ); + // Insert compiled object. + mCompiledObjects.insertUnique(objectId, pNewNode); - // Are there any Taml callbacks? - if ( pNewNode->mpTamlCallbacks != NULL ) - { - // Yes, so call it. - tamlPreWrite( pNewNode->mpTamlCallbacks ); - } + // Are there any Taml callbacks? + if (pNewNode->mpTamlCallbacks != NULL) + { + // Yes, so call it. + tamlPreWrite(pNewNode->mpTamlCallbacks); + } - // Compile static and dynamic fields. - compileStaticFields( pNewNode ); - compileDynamicFields( pNewNode ); + // Compile static and dynamic fields. + compileStaticFields(pNewNode); + compileDynamicFields(pNewNode); - // Compile children. - compileChildren( pNewNode ); + // Compile children. + compileChildren(pNewNode); - // Compile custom state. - compileCustomState( pNewNode ); + // Compile custom state. + compileCustomState(pNewNode); - // Are there any Taml callbacks? - if ( pNewNode->mpTamlCallbacks != NULL ) - { - // Yes, so call it. - tamlPostWrite( pNewNode->mpTamlCallbacks ); - } + // Are there any Taml callbacks? + if (pNewNode->mpTamlCallbacks != NULL) + { + // Yes, so call it. + tamlPostWrite(pNewNode->mpTamlCallbacks); + } - return pNewNode; -} + return pNewNode; + } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -void Taml::compileStaticFields( TamlWriteNode* pTamlWriteNode ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_CompileStaticFields); + void Taml::compileStaticFields(TamlWriteNode* pTamlWriteNode) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_CompileStaticFields); - // Sanity! - AssertFatal( pTamlWriteNode != NULL, "Cannot compile static fields on a NULL node." ); - AssertFatal( pTamlWriteNode->mpSimObject != NULL, "Cannot compile static fields on a node with no object." ); + // Sanity! + AssertFatal(pTamlWriteNode != NULL, "Cannot compile static fields on a NULL node."); + AssertFatal(pTamlWriteNode->mpSimObject != NULL, "Cannot compile static fields on a node with no object."); - // Fetch object. - SimObject* pSimObject = pTamlWriteNode->mpSimObject; + // Fetch object. + SimObject* pSimObject = pTamlWriteNode->mpSimObject; - // Fetch field list. - const AbstractClassRep::FieldList& fieldList = pSimObject->getFieldList(); + // Fetch field list. + const AbstractClassRep::FieldList& fieldList = pSimObject->getFieldList(); - // Fetch field count. - const U32 fieldCount = fieldList.size(); + // Fetch field count. + const U32 fieldCount = fieldList.size(); - // Iterate fields. - U8 arrayDepth = 0; - TamlCustomNode* currentArrayNode; - for( U32 index = 0; index < fieldCount; ++index ) - { - // Fetch field. - const AbstractClassRep::Field* pField = &fieldList[index]; + // Iterate fields. + U8 arrayDepth = 0; + TamlCustomNode* currentArrayNode; + for (U32 index = 0; index < fieldCount; ++index) + { + // Fetch field. + const AbstractClassRep::Field* pField = &fieldList[index]; - // Ignore if field not appropriate. - if( pField->type == AbstractClassRep::DeprecatedFieldType || + // Ignore if field not appropriate. + if (pField->type == AbstractClassRep::DeprecatedFieldType || pField->type == AbstractClassRep::StartGroupFieldType || - pField->type == AbstractClassRep::EndGroupFieldType ) + pField->type == AbstractClassRep::EndGroupFieldType) continue; - if( pField->type == AbstractClassRep::StartArrayFieldType ) - { - TamlCustomNodes& pCustomNodes = pTamlWriteNode->mCustomNodes; - currentArrayNode = pCustomNodes.addNode(pField->pGroupname); - for(U16 idx = 0; idx < pField->elementCount; idx++) - currentArrayNode->addNode(pField->pFieldname); - arrayDepth++; - continue; - } + if (pField->type == AbstractClassRep::StartArrayFieldType) + { + TamlCustomNodes& pCustomNodes = pTamlWriteNode->mCustomNodes; + currentArrayNode = pCustomNodes.addNode(pField->pGroupname); + for (U16 idx = 0; idx < pField->elementCount; idx++) + currentArrayNode->addNode(pField->pFieldname); + arrayDepth++; + continue; + } - if( pField->type == AbstractClassRep::EndArrayFieldType ) - { - arrayDepth--; - continue; - } + if (pField->type == AbstractClassRep::EndArrayFieldType) + { + arrayDepth--; + continue; + } - if(arrayDepth == 0 && pField->elementCount > 1) - { - TamlCustomNodes& pCustomNodes = pTamlWriteNode->mCustomNodes; - char* niceFieldName = const_cast(pField->pFieldname); - niceFieldName[0] = dToupper(niceFieldName[0]); - String str_niceFieldName = String(niceFieldName); - currentArrayNode = pCustomNodes.addNode(str_niceFieldName + "s"); - for(U16 idx = 0; idx < pField->elementCount; idx++) - currentArrayNode->addNode(str_niceFieldName); - } + if (arrayDepth == 0 && pField->elementCount > 1) + { + TamlCustomNodes& pCustomNodes = pTamlWriteNode->mCustomNodes; + char* niceFieldName = const_cast(pField->pFieldname); + niceFieldName[0] = dToupper(niceFieldName[0]); + String str_niceFieldName = String(niceFieldName); + currentArrayNode = pCustomNodes.addNode(str_niceFieldName + "s"); + for (U16 idx = 0; idx < pField->elementCount; idx++) + currentArrayNode->addNode(str_niceFieldName); + } - // Fetch fieldname. - StringTableEntry fieldName = StringTable->insert( pField->pFieldname ); + // Fetch fieldname. + StringTableEntry fieldName = StringTable->insert(pField->pFieldname); - // Fetch element count. - const U32 elementCount = pField->elementCount; + // Fetch element count. + const U32 elementCount = pField->elementCount; - // Skip if the field should not be written. - // For now, we only deal with non-array fields. - if ( elementCount == 1 && - pField->setDataFn != NULL && - ( !getWriteDefaults() && pField->writeDataFn( pSimObject, fieldName ) == false) ) + // Skip if the field should not be written. + // For now, we only deal with non-array fields. + if (elementCount == 1 && + pField->setDataFn != NULL && + (!getWriteDefaults() && pField->writeDataFn(pSimObject, fieldName) == false)) continue; - // Iterate elements. - for( U32 elementIndex = 0; elementIndex < elementCount; ++elementIndex ) - { + // Iterate elements. + for (U32 elementIndex = 0; elementIndex < elementCount; ++elementIndex) + { char indexBuffer[8]; - dSprintf( indexBuffer, 8, "%d", elementIndex ); + dSprintf(indexBuffer, 8, "%d", elementIndex); // Fetch object field value. const char* pFieldValue = pSimObject->getPrefixedDataField(fieldName, indexBuffer); - if(!pFieldValue) + if (!pFieldValue) pFieldValue = StringTable->EmptyString(); - if(pField->type == TypeBool) + if (pField->type == TypeBool) pFieldValue = dAtob(pFieldValue) ? "true" : "false"; - U32 nBufferSize = dStrlen( pFieldValue ) + 1; - FrameTemp valueCopy( nBufferSize ); - dStrcpy( (char *)valueCopy, pFieldValue ); + U32 nBufferSize = dStrlen(pFieldValue) + 1; + FrameTemp valueCopy(nBufferSize); + dStrcpy((char *)valueCopy, pFieldValue); // Skip if field should not be written. if (!pSimObject->writeField(fieldName, valueCopy)) - continue; + continue; // Reassign field value. pFieldValue = valueCopy; @@ -719,660 +721,660 @@ void Taml::compileStaticFields( TamlWriteNode* pTamlWriteNode ) char fnBuf[1024]; if ((S32)pField->type == TypeFilename) { - Con::collapseScriptFilename( fnBuf, 1024, pFieldValue ); - pFieldValue = fnBuf; + Con::collapseScriptFilename(fnBuf, 1024, pFieldValue); + pFieldValue = fnBuf; } // Save field/value. - if(arrayDepth > 0 || pField->elementCount > 1) + if (arrayDepth > 0 || pField->elementCount > 1) currentArrayNode->getChildren()[elementIndex]->addField(fieldName, pFieldValue); else { - TamlWriteNode::FieldValuePair* pFieldValuePair = new TamlWriteNode::FieldValuePair( fieldName, pFieldValue ); - pTamlWriteNode->mFields.push_back( pFieldValuePair ); + TamlWriteNode::FieldValuePair* pFieldValuePair = new TamlWriteNode::FieldValuePair(fieldName, pFieldValue); + pTamlWriteNode->mFields.push_back(pFieldValuePair); } - } - } -} + } + } + } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -static S32 QSORT_CALLBACK compareFieldEntries(const void* a,const void* b) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_CompareFieldEntries); + static S32 QSORT_CALLBACK compareFieldEntries(const void* a, const void* b) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_CompareFieldEntries); - SimFieldDictionary::Entry *fa = *((SimFieldDictionary::Entry **)a); - SimFieldDictionary::Entry *fb = *((SimFieldDictionary::Entry **)b); - return dStricmp(fa->slotName, fb->slotName); -} + SimFieldDictionary::Entry *fa = *((SimFieldDictionary::Entry **)a); + SimFieldDictionary::Entry *fb = *((SimFieldDictionary::Entry **)b); + return dStricmp(fa->slotName, fb->slotName); + } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -void Taml::compileDynamicFields( TamlWriteNode* pTamlWriteNode ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_CompileDynamicFields); + void Taml::compileDynamicFields(TamlWriteNode* pTamlWriteNode) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_CompileDynamicFields); - // Sanity! - AssertFatal( pTamlWriteNode != NULL, "Cannot compile dynamic fields on a NULL node." ); - AssertFatal( pTamlWriteNode->mpSimObject != NULL, "Cannot compile dynamic fields on a node with no object." ); + // Sanity! + AssertFatal(pTamlWriteNode != NULL, "Cannot compile dynamic fields on a NULL node."); + AssertFatal(pTamlWriteNode->mpSimObject != NULL, "Cannot compile dynamic fields on a node with no object."); - // Fetch object. - SimObject* pSimObject = pTamlWriteNode->mpSimObject; + // Fetch object. + SimObject* pSimObject = pTamlWriteNode->mpSimObject; - // Fetch field dictionary. - SimFieldDictionary* pFieldDictionary = pSimObject->getFieldDictionary(); + // Fetch field dictionary. + SimFieldDictionary* pFieldDictionary = pSimObject->getFieldDictionary(); - // Ignore if not writing dynamic fields. - if ( !pFieldDictionary || !pSimObject->getCanSaveDynamicFields() ) - return; + // Ignore if not writing dynamic fields. + if (!pFieldDictionary || !pSimObject->getCanSaveDynamicFields()) + return; - // Fetch field list. - const AbstractClassRep::FieldList& fieldList = pSimObject->getFieldList(); + // Fetch field list. + const AbstractClassRep::FieldList& fieldList = pSimObject->getFieldList(); - // Fetch field count. - const U32 fieldCount = fieldList.size(); + // Fetch field count. + const U32 fieldCount = fieldList.size(); - Vector dynamicFieldList(__FILE__, __LINE__); + Vector dynamicFieldList(__FILE__, __LINE__); - // Ensure the dynamic field doesn't conflict with static field. - for( U32 hashIndex = 0; hashIndex < SimFieldDictionary::HashTableSize; ++hashIndex ) - { - for( SimFieldDictionary::Entry* pEntry = pFieldDictionary->mHashTable[hashIndex]; pEntry; pEntry = pEntry->next ) - { + // Ensure the dynamic field doesn't conflict with static field. + for (U32 hashIndex = 0; hashIndex < SimFieldDictionary::HashTableSize; ++hashIndex) + { + for (SimFieldDictionary::Entry* pEntry = pFieldDictionary->mHashTable[hashIndex]; pEntry; pEntry = pEntry->next) + { // Iterate static fields. U32 fieldIndex; - for( fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex ) + for (fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex) { - if( fieldList[fieldIndex].pFieldname == pEntry->slotName) - break; + if (fieldList[fieldIndex].pFieldname == pEntry->slotName) + break; } // Skip if found. - if( fieldIndex != (U32)fieldList.size() ) - continue; + if (fieldIndex != (U32)fieldList.size()) + continue; // Skip if not writing field. - if ( !pSimObject->writeField( pEntry->slotName, pEntry->value) ) - continue; + if (!pSimObject->writeField(pEntry->slotName, pEntry->value)) + continue; - dynamicFieldList.push_back( pEntry ); - } - } + dynamicFieldList.push_back(pEntry); + } + } - // Sort Entries to prevent version control conflicts - if ( dynamicFieldList.size() > 1 ) - dQsort(dynamicFieldList.address(), dynamicFieldList.size(), sizeof(SimFieldDictionary::Entry*), compareFieldEntries); + // Sort Entries to prevent version control conflicts + if (dynamicFieldList.size() > 1) + dQsort(dynamicFieldList.address(), dynamicFieldList.size(), sizeof(SimFieldDictionary::Entry*), compareFieldEntries); - // Save the fields. - for( Vector::iterator entryItr = dynamicFieldList.begin(); entryItr != dynamicFieldList.end(); ++entryItr ) - { - // Fetch entry. - SimFieldDictionary::Entry* pEntry = *entryItr; + // Save the fields. + for (Vector::iterator entryItr = dynamicFieldList.begin(); entryItr != dynamicFieldList.end(); ++entryItr) + { + // Fetch entry. + SimFieldDictionary::Entry* pEntry = *entryItr; - // Save field/value. - TamlWriteNode::FieldValuePair* pFieldValuePair = new TamlWriteNode::FieldValuePair( pEntry->slotName, pEntry->value ); - pTamlWriteNode->mFields.push_back( pFieldValuePair ); - } -} + // Save field/value. + TamlWriteNode::FieldValuePair* pFieldValuePair = new TamlWriteNode::FieldValuePair(pEntry->slotName, pEntry->value); + pTamlWriteNode->mFields.push_back(pFieldValuePair); + } + } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -void Taml::compileChildren( TamlWriteNode* pTamlWriteNode ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_CompileChildren); + void Taml::compileChildren(TamlWriteNode* pTamlWriteNode) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_CompileChildren); - // Sanity! - AssertFatal( pTamlWriteNode != NULL, "Cannot compile children on a NULL node." ); - AssertFatal( pTamlWriteNode->mpSimObject != NULL, "Cannot compile children on a node with no object." ); + // Sanity! + AssertFatal(pTamlWriteNode != NULL, "Cannot compile children on a NULL node."); + AssertFatal(pTamlWriteNode->mpSimObject != NULL, "Cannot compile children on a node with no object."); - // Fetch object. - SimObject* pSimObject = pTamlWriteNode->mpSimObject; + // Fetch object. + SimObject* pSimObject = pTamlWriteNode->mpSimObject; - // Fetch the Taml children. - TamlChildren* pChildren = dynamic_cast( pSimObject ); + // Fetch the Taml children. + TamlChildren* pChildren = dynamic_cast(pSimObject); - // Finish if object does not contain Taml children. - if ( pChildren == NULL || pChildren->getTamlChildCount() == 0 ) - return; + // Finish if object does not contain Taml children. + if (pChildren == NULL || pChildren->getTamlChildCount() == 0) + return; - // Create children vector. - pTamlWriteNode->mChildren = new typeNodeVector(); + // Create children vector. + pTamlWriteNode->mChildren = new typeNodeVector(); - // Fetch the child count. - const U32 childCount = pChildren->getTamlChildCount(); + // Fetch the child count. + const U32 childCount = pChildren->getTamlChildCount(); - // Iterate children. - for ( U32 childIndex = 0; childIndex < childCount; childIndex++ ) - { - // Compile object. - TamlWriteNode* pChildTamlWriteNode = compileObject( pChildren->getTamlChild(childIndex) ); + // Iterate children. + for (U32 childIndex = 0; childIndex < childCount; childIndex++) + { + // Compile object. + TamlWriteNode* pChildTamlWriteNode = compileObject(pChildren->getTamlChild(childIndex)); - // Save node. - pTamlWriteNode->mChildren->push_back( pChildTamlWriteNode ); - } -} + // Save node. + pTamlWriteNode->mChildren->push_back(pChildTamlWriteNode); + } + } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -void Taml::compileCustomState( TamlWriteNode* pTamlWriteNode ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_CompileCustomProperties); + void Taml::compileCustomState(TamlWriteNode* pTamlWriteNode) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_CompileCustomProperties); - // Sanity! - AssertFatal( pTamlWriteNode != NULL, "Cannot compile custom state on a NULL node." ); - AssertFatal( pTamlWriteNode->mpSimObject != NULL, "Cannot compile custom state on a node with no object." ); + // Sanity! + AssertFatal(pTamlWriteNode != NULL, "Cannot compile custom state on a NULL node."); + AssertFatal(pTamlWriteNode->mpSimObject != NULL, "Cannot compile custom state on a node with no object."); - // Fetch the custom node on the write node. - TamlCustomNodes& customNodes = pTamlWriteNode->mCustomNodes; + // Fetch the custom node on the write node. + TamlCustomNodes& customNodes = pTamlWriteNode->mCustomNodes; - // Are there any Taml callbacks? - if ( pTamlWriteNode->mpTamlCallbacks != NULL ) - { - // Yes, so call it. - tamlCustomWrite( pTamlWriteNode->mpTamlCallbacks, customNodes ); - } + // Are there any Taml callbacks? + if (pTamlWriteNode->mpTamlCallbacks != NULL) + { + // Yes, so call it. + tamlCustomWrite(pTamlWriteNode->mpTamlCallbacks, customNodes); + } - // Fetch custom nodes. - const TamlCustomNodeVector& nodes = customNodes.getNodes(); + // Fetch custom nodes. + const TamlCustomNodeVector& nodes = customNodes.getNodes(); - // Finish if no custom nodes to process. - if ( nodes.size() == 0 ) - return; - - // Iterate custom properties. - for( TamlCustomNodeVector::const_iterator customNodesItr = nodes.begin(); customNodesItr != nodes.end(); ++customNodesItr ) - { - // Fetch the custom node. - TamlCustomNode* pCustomNode = *customNodesItr; + // Finish if no custom nodes to process. + if (nodes.size() == 0) + return; - // Compile custom node state. - compileCustomNodeState( pCustomNode ); - } -} + // Iterate custom properties. + for (TamlCustomNodeVector::const_iterator customNodesItr = nodes.begin(); customNodesItr != nodes.end(); ++customNodesItr) + { + // Fetch the custom node. + TamlCustomNode* pCustomNode = *customNodesItr; -//----------------------------------------------------------------------------- + // Compile custom node state. + compileCustomNodeState(pCustomNode); + } + } -void Taml::compileCustomNodeState( TamlCustomNode* pCustomNode ) -{ - // Sanity! - AssertFatal( pCustomNode != NULL, "Taml: Cannot compile NULL custom node state." ); + //----------------------------------------------------------------------------- - // Fetch children. - const TamlCustomNodeVector& children = pCustomNode->getChildren(); + void Taml::compileCustomNodeState(TamlCustomNode* pCustomNode) + { + // Sanity! + AssertFatal(pCustomNode != NULL, "Taml: Cannot compile NULL custom node state."); - // Fetch proxy object. - SimObject* pProxyObject = pCustomNode->getProxyObject(false); + // Fetch children. + const TamlCustomNodeVector& children = pCustomNode->getChildren(); - // Do we have a proxy object? - if ( pProxyObject != NULL ) - { - // Yes, so sanity! - AssertFatal( children.size() == 0, "Taml: Cannot compile a proxy object on a custom node that has children." ); + // Fetch proxy object. + SimObject* pProxyObject = pCustomNode->getProxyObject(false); - // Yes, so compile it. - // NOTE: We force an Id for custom compiled objects so we guarantee an Id. The reason for this is fairly - // weak in that the XML parser currently has no way of distinguishing between a compiled object node - // and a custom node. If the node has an Id or an Id-Ref then it's obviously an object and should be parsed as such. - pCustomNode->setWriteNode( compileObject( pProxyObject, true ) ); - return; - } + // Do we have a proxy object? + if (pProxyObject != NULL) + { + // Yes, so sanity! + AssertFatal(children.size() == 0, "Taml: Cannot compile a proxy object on a custom node that has children."); - // Finish if no children. - if ( children.size() == 0 ) - return; + // Yes, so compile it. + // NOTE: We force an Id for custom compiled objects so we guarantee an Id. The reason for this is fairly + // weak in that the XML parser currently has no way of distinguishing between a compiled object node + // and a custom node. If the node has an Id or an Id-Ref then it's obviously an object and should be parsed as such. + pCustomNode->setWriteNode(compileObject(pProxyObject, true)); + return; + } - // Iterate children. - for( TamlCustomNodeVector::const_iterator childItr = children.begin(); childItr != children.end(); ++childItr ) - { - // Fetch shape node. - TamlCustomNode* pChildNode = *childItr; + // Finish if no children. + if (children.size() == 0) + return; - // Compile the child. - compileCustomNodeState( pChildNode ); - } -} + // Iterate children. + for (TamlCustomNodeVector::const_iterator childItr = children.begin(); childItr != children.end(); ++childItr) + { + // Fetch shape node. + TamlCustomNode* pChildNode = *childItr; -//----------------------------------------------------------------------------- + // Compile the child. + compileCustomNodeState(pChildNode); + } + } -SimObject* Taml::createType( StringTableEntry typeName, const Taml* pTaml, const char* pProgenitorSuffix ) -{ - // Debug Profiling. - PROFILE_SCOPE(Taml_CreateType); + //----------------------------------------------------------------------------- - typedef HashTable typeClassHash; - static typeClassHash mClassMap; + SimObject* Taml::createType(StringTableEntry typeName, const Taml* pTaml, const char* pProgenitorSuffix) + { + // Debug Profiling. + PROFILE_SCOPE(Taml_CreateType); - // Sanity! - AssertFatal( typeName != NULL, "Taml: Type cannot be NULL" ); + typedef HashTable typeClassHash; + static typeClassHash mClassMap; - // Find type. - typeClassHash::Iterator typeItr = mClassMap.find( typeName ); + // Sanity! + AssertFatal(typeName != NULL, "Taml: Type cannot be NULL"); - // Found type? - if ( typeItr == mClassMap.end() ) - { - // No, so find type. - AbstractClassRep* pClassRep = AbstractClassRep::getClassList(); - while( pClassRep ) - { + // Find type. + typeClassHash::Iterator typeItr = mClassMap.find(typeName); + + // Found type? + if (typeItr == mClassMap.end()) + { + // No, so find type. + AbstractClassRep* pClassRep = AbstractClassRep::getClassList(); + while (pClassRep) + { // Is this the type? - if( dStricmp( pClassRep->getClassName(), typeName ) == 0 ) + if (dStricmp(pClassRep->getClassName(), typeName) == 0) { - // Yes, so insert it. - typeItr = mClassMap.insertUnique( typeName, pClassRep ); - break; + // Yes, so insert it. + typeItr = mClassMap.insertUnique(typeName, pClassRep); + break; } // Next type. pClassRep = pClassRep->getNextClass(); - } + } - // Did we find the type? - if ( typeItr == mClassMap.end() ) - { + // Did we find the type? + if (typeItr == mClassMap.end()) + { // No, so warn and fail. - Con::warnf( "Taml: Failed to create type '%s' as such a registered type could not be found.", typeName ); + Con::warnf("Taml: Failed to create type '%s' as such a registered type could not be found.", typeName); return NULL; - } - } + } + } - // Create the object. - ConsoleObject* pConsoleObject = typeItr->value->create(); + // Create the object. + ConsoleObject* pConsoleObject = typeItr->value->create(); - // NOTE: It is important that we don't register the object here as many objects rely on the fact that - // fields are set prior to the object being registered. Registering here will invalid those assumptions. + // NOTE: It is important that we don't register the object here as many objects rely on the fact that + // fields are set prior to the object being registered. Registering here will invalid those assumptions. - // Fetch the SimObject. - SimObject* pSimObject = dynamic_cast( pConsoleObject ); + // Fetch the SimObject. + SimObject* pSimObject = dynamic_cast(pConsoleObject); - // Was it a SimObject? - if ( pSimObject == NULL ) - { - // No, so warn. - Con::warnf( "Taml: Failed to create type '%s' as it is not a SimObject.", typeName ); + // Was it a SimObject? + if (pSimObject == NULL) + { + // No, so warn. + Con::warnf("Taml: Failed to create type '%s' as it is not a SimObject.", typeName); - // Destroy object and fail. - delete pConsoleObject; - return NULL; - } + // Destroy object and fail. + delete pConsoleObject; + return NULL; + } - // Are we updating the file-progenitor? - if ( pTaml->getProgenitorUpdate() ) - { - // Yes, so do we have a progenitor suffix? - if ( pProgenitorSuffix == NULL ) - { + // Are we updating the file-progenitor? + if (pTaml->getProgenitorUpdate()) + { + // Yes, so do we have a progenitor suffix? + if (pProgenitorSuffix == NULL) + { // No, so just set it to the progenitor file. - pSimObject->setProgenitorFile( pTaml->getFilePathBuffer() ); - } - else - { + pSimObject->setProgenitorFile(pTaml->getFilePathBuffer()); + } + else + { // Yes, so format the progenitor buffer. char progenitorBuffer[2048]; - dSprintf( progenitorBuffer, sizeof(progenitorBuffer), "%s,%s", pTaml->getFilePathBuffer(), pProgenitorSuffix ); + dSprintf(progenitorBuffer, sizeof(progenitorBuffer), "%s,%s", pTaml->getFilePathBuffer(), pProgenitorSuffix); // Set the progenitor file. - pSimObject->setProgenitorFile( progenitorBuffer ); - } - } + pSimObject->setProgenitorFile(progenitorBuffer); + } + } - return pSimObject; -} + return pSimObject; + } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -bool Taml::generateTamlSchema() -{ - // Fetch any TAML Schema file reference. - const char* pTamlSchemaFile = Con::getVariable( TAML_SCHEMA_VARIABLE ); + bool Taml::generateTamlSchema() + { + // Fetch any TAML Schema file reference. + const char* pTamlSchemaFile = Con::getVariable(TAML_SCHEMA_VARIABLE); - // Do we have a schema file reference? - if ( pTamlSchemaFile == NULL || *pTamlSchemaFile == 0 ) - { - // No, so warn. - Con::warnf( "Taml::generateTamlSchema() - Cannot write a TAML schema as no schema variable is set ('%s').", TAML_SCHEMA_VARIABLE ); - return false; - } + // Do we have a schema file reference? + if (pTamlSchemaFile == NULL || *pTamlSchemaFile == 0) + { + // No, so warn. + Con::warnf("Taml::generateTamlSchema() - Cannot write a TAML schema as no schema variable is set ('%s').", TAML_SCHEMA_VARIABLE); + return false; + } - // Expand the file-name into the file-path buffer. - char filePathBuffer[1024]; - Con::expandToolScriptFilename( filePathBuffer, sizeof(filePathBuffer), pTamlSchemaFile ); + // Expand the file-name into the file-path buffer. + char filePathBuffer[1024]; + Con::expandToolScriptFilename(filePathBuffer, sizeof(filePathBuffer), pTamlSchemaFile); - FileStream stream; + FileStream stream; - // File opened? - /*if ( !stream.open( filePathBuffer, Torque::FS::File::Write ) ) - { - // No, so warn. - Con::warnf("Taml::GenerateTamlSchema() - Could not open filename '%s' for write.", filePathBuffer ); - return false; - }*/ + // File opened? + /*if ( !stream.open( filePathBuffer, Torque::FS::File::Write ) ) + { + // No, so warn. + Con::warnf("Taml::GenerateTamlSchema() - Could not open filename '%s' for write.", filePathBuffer ); + return false; + }*/ - // Create document. - TiXmlDocument schemaDocument; + // Create document. + TiXmlDocument schemaDocument; - // Add declaration. - TiXmlDeclaration schemaDeclaration( "1.0", "iso-8859-1", "no" ); - schemaDocument.InsertEndChild( schemaDeclaration ); + // Add declaration. + TiXmlDeclaration schemaDeclaration("1.0", "iso-8859-1", "no"); + schemaDocument.InsertEndChild(schemaDeclaration); - // Add schema element. - TiXmlElement* pSchemaElement = new TiXmlElement( "xs:schema" ); - pSchemaElement->SetAttribute( "xmlns:xs", "http://www.w3.org/2001/XMLSchema" ); - schemaDocument.LinkEndChild( pSchemaElement ); + // Add schema element. + TiXmlElement* pSchemaElement = new TiXmlElement("xs:schema"); + pSchemaElement->SetAttribute("xmlns:xs", "http://www.w3.org/2001/XMLSchema"); + schemaDocument.LinkEndChild(pSchemaElement); - // Fetch class-rep root. - AbstractClassRep* pRootType = AbstractClassRep::getClassList(); + // Fetch class-rep root. + AbstractClassRep* pRootType = AbstractClassRep::getClassList(); - // Fetch SimObject class rep. - AbstractClassRep* pSimObjectType = AbstractClassRep::findClassRep( "SimObject" ); - // Sanity! - AssertFatal( pSimObjectType != NULL, "Taml::GenerateTamlSchema() - Could not find SimObject class rep." ); + // Fetch SimObject class rep. + AbstractClassRep* pSimObjectType = AbstractClassRep::findClassRep("SimObject"); + // Sanity! + AssertFatal(pSimObjectType != NULL, "Taml::GenerateTamlSchema() - Could not find SimObject class rep."); - // Reset scratch state. - char buffer[1024]; - HashTable childGroups; + // Reset scratch state. + char buffer[1024]; + HashTable childGroups; - // ************************************************************* - // Generate console type elements. - // ************************************************************* + // ************************************************************* + // Generate console type elements. + // ************************************************************* - // Vector2. - TiXmlComment* pVector2Comment = new TiXmlComment( "Vector2 Console Type" ); - pSchemaElement->LinkEndChild( pVector2Comment ); - TiXmlElement* pVector2TypeElement = new TiXmlElement( "xs:simpleType" ); - pVector2TypeElement->SetAttribute( "name", "Vector2_ConsoleType" ); - pSchemaElement->LinkEndChild( pVector2TypeElement ); - TiXmlElement* pVector2ElementA = new TiXmlElement( "xs:restriction" ); - pVector2ElementA->SetAttribute( "base", "xs:string" ); - pVector2TypeElement->LinkEndChild( pVector2ElementA ); - TiXmlElement* pVector2ElementB = new TiXmlElement( "xs:pattern" ); - pVector2ElementB->SetAttribute( "value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b" ); - pVector2ElementA->LinkEndChild( pVector2ElementB ); + // Vector2. + TiXmlComment* pVector2Comment = new TiXmlComment("Vector2 Console Type"); + pSchemaElement->LinkEndChild(pVector2Comment); + TiXmlElement* pVector2TypeElement = new TiXmlElement("xs:simpleType"); + pVector2TypeElement->SetAttribute("name", "Vector2_ConsoleType"); + pSchemaElement->LinkEndChild(pVector2TypeElement); + TiXmlElement* pVector2ElementA = new TiXmlElement("xs:restriction"); + pVector2ElementA->SetAttribute("base", "xs:string"); + pVector2TypeElement->LinkEndChild(pVector2ElementA); + TiXmlElement* pVector2ElementB = new TiXmlElement("xs:pattern"); + pVector2ElementB->SetAttribute("value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b"); + pVector2ElementA->LinkEndChild(pVector2ElementB); - // Point2F. - TiXmlComment* pPoint2FComment = new TiXmlComment( "Point2F Console Type" ); - pSchemaElement->LinkEndChild( pPoint2FComment ); - TiXmlElement* pPoint2FTypeElement = new TiXmlElement( "xs:simpleType" ); - pPoint2FTypeElement->SetAttribute( "name", "Point2F_ConsoleType" ); - pSchemaElement->LinkEndChild( pPoint2FTypeElement ); - TiXmlElement* pPoint2FElementA = new TiXmlElement( "xs:restriction" ); - pPoint2FElementA->SetAttribute( "base", "xs:string" ); - pPoint2FTypeElement->LinkEndChild( pPoint2FElementA ); - TiXmlElement* pPoint2FElementB = new TiXmlElement( "xs:pattern" ); - pPoint2FElementB->SetAttribute( "value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b" ); - pPoint2FElementA->LinkEndChild( pPoint2FElementB ); + // Point2F. + TiXmlComment* pPoint2FComment = new TiXmlComment("Point2F Console Type"); + pSchemaElement->LinkEndChild(pPoint2FComment); + TiXmlElement* pPoint2FTypeElement = new TiXmlElement("xs:simpleType"); + pPoint2FTypeElement->SetAttribute("name", "Point2F_ConsoleType"); + pSchemaElement->LinkEndChild(pPoint2FTypeElement); + TiXmlElement* pPoint2FElementA = new TiXmlElement("xs:restriction"); + pPoint2FElementA->SetAttribute("base", "xs:string"); + pPoint2FTypeElement->LinkEndChild(pPoint2FElementA); + TiXmlElement* pPoint2FElementB = new TiXmlElement("xs:pattern"); + pPoint2FElementB->SetAttribute("value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b"); + pPoint2FElementA->LinkEndChild(pPoint2FElementB); - // Point2I. - TiXmlComment* pPoint2IComment = new TiXmlComment( "Point2I Console Type" ); - pSchemaElement->LinkEndChild( pPoint2IComment ); - TiXmlElement* pPoint2ITypeElement = new TiXmlElement( "xs:simpleType" ); - pPoint2ITypeElement->SetAttribute( "name", "Point2I_ConsoleType" ); - pSchemaElement->LinkEndChild( pPoint2ITypeElement ); - TiXmlElement* pPoint2IElementA = new TiXmlElement( "xs:restriction" ); - pPoint2IElementA->SetAttribute( "base", "xs:string" ); - pPoint2ITypeElement->LinkEndChild( pPoint2IElementA ); - TiXmlElement* pPoint2IElementB = new TiXmlElement( "xs:pattern" ); - pPoint2IElementB->SetAttribute( "value", "[-]?[0-9]* [-]?[0-9]*" ); - pPoint2IElementA->LinkEndChild( pPoint2IElementB ); + // Point2I. + TiXmlComment* pPoint2IComment = new TiXmlComment("Point2I Console Type"); + pSchemaElement->LinkEndChild(pPoint2IComment); + TiXmlElement* pPoint2ITypeElement = new TiXmlElement("xs:simpleType"); + pPoint2ITypeElement->SetAttribute("name", "Point2I_ConsoleType"); + pSchemaElement->LinkEndChild(pPoint2ITypeElement); + TiXmlElement* pPoint2IElementA = new TiXmlElement("xs:restriction"); + pPoint2IElementA->SetAttribute("base", "xs:string"); + pPoint2ITypeElement->LinkEndChild(pPoint2IElementA); + TiXmlElement* pPoint2IElementB = new TiXmlElement("xs:pattern"); + pPoint2IElementB->SetAttribute("value", "[-]?[0-9]* [-]?[0-9]*"); + pPoint2IElementA->LinkEndChild(pPoint2IElementB); - // b2AABB. - TiXmlComment* pb2AABBComment = new TiXmlComment( "b2AABB Console Type" ); - pSchemaElement->LinkEndChild( pb2AABBComment ); - TiXmlElement* pb2AABBTypeElement = new TiXmlElement( "xs:simpleType" ); - pb2AABBTypeElement->SetAttribute( "name", "b2AABB_ConsoleType" ); - pSchemaElement->LinkEndChild( pb2AABBTypeElement ); - TiXmlElement* pb2AABBElementA = new TiXmlElement( "xs:restriction" ); - pb2AABBElementA->SetAttribute( "base", "xs:string" ); - pb2AABBTypeElement->LinkEndChild( pb2AABBElementA ); - TiXmlElement* pb2AABBElementB = new TiXmlElement( "xs:pattern" ); - pb2AABBElementB->SetAttribute( "value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b" ); - pb2AABBElementA->LinkEndChild( pb2AABBElementB ); + // b2AABB. + TiXmlComment* pb2AABBComment = new TiXmlComment("b2AABB Console Type"); + pSchemaElement->LinkEndChild(pb2AABBComment); + TiXmlElement* pb2AABBTypeElement = new TiXmlElement("xs:simpleType"); + pb2AABBTypeElement->SetAttribute("name", "b2AABB_ConsoleType"); + pSchemaElement->LinkEndChild(pb2AABBTypeElement); + TiXmlElement* pb2AABBElementA = new TiXmlElement("xs:restriction"); + pb2AABBElementA->SetAttribute("base", "xs:string"); + pb2AABBTypeElement->LinkEndChild(pb2AABBElementA); + TiXmlElement* pb2AABBElementB = new TiXmlElement("xs:pattern"); + pb2AABBElementB->SetAttribute("value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b"); + pb2AABBElementA->LinkEndChild(pb2AABBElementB); - // RectI. - TiXmlComment* pRectIComment = new TiXmlComment( "RectI Console Type" ); - pSchemaElement->LinkEndChild( pRectIComment ); - TiXmlElement* pRectITypeElement = new TiXmlElement( "xs:simpleType" ); - pRectITypeElement->SetAttribute( "name", "RectI_ConsoleType" ); - pSchemaElement->LinkEndChild( pRectITypeElement ); - TiXmlElement* pRectIElementA = new TiXmlElement( "xs:restriction" ); - pRectIElementA->SetAttribute( "base", "xs:string" ); - pRectITypeElement->LinkEndChild( pRectIElementA ); - TiXmlElement* pRectIElementB = new TiXmlElement( "xs:pattern" ); - pRectIElementB->SetAttribute( "value", "[-]?[0-9]* [-]?[0-9]* [-]?[0-9]* [-]?[0-9]*" ); - pRectIElementA->LinkEndChild( pRectIElementB ); + // RectI. + TiXmlComment* pRectIComment = new TiXmlComment("RectI Console Type"); + pSchemaElement->LinkEndChild(pRectIComment); + TiXmlElement* pRectITypeElement = new TiXmlElement("xs:simpleType"); + pRectITypeElement->SetAttribute("name", "RectI_ConsoleType"); + pSchemaElement->LinkEndChild(pRectITypeElement); + TiXmlElement* pRectIElementA = new TiXmlElement("xs:restriction"); + pRectIElementA->SetAttribute("base", "xs:string"); + pRectITypeElement->LinkEndChild(pRectIElementA); + TiXmlElement* pRectIElementB = new TiXmlElement("xs:pattern"); + pRectIElementB->SetAttribute("value", "[-]?[0-9]* [-]?[0-9]* [-]?[0-9]* [-]?[0-9]*"); + pRectIElementA->LinkEndChild(pRectIElementB); - // RectF. - TiXmlComment* pRectFComment = new TiXmlComment( "RectF Console Type" ); - pSchemaElement->LinkEndChild( pRectFComment ); - TiXmlElement* pRectFTypeElement = new TiXmlElement( "xs:simpleType" ); - pRectFTypeElement->SetAttribute( "name", "RectF_ConsoleType" ); - pSchemaElement->LinkEndChild( pRectFTypeElement ); - TiXmlElement* pRectFElementA = new TiXmlElement( "xs:restriction" ); - pRectFElementA->SetAttribute( "base", "xs:string" ); - pRectFTypeElement->LinkEndChild( pRectFElementA ); - TiXmlElement* pRectFElementB = new TiXmlElement( "xs:pattern" ); - pRectFElementB->SetAttribute( "value", "(\\b[-]?(b[0-9]+)?\\.)?[0-9]+\\b" ); - pRectFElementA->LinkEndChild( pRectFElementB ); + // RectF. + TiXmlComment* pRectFComment = new TiXmlComment("RectF Console Type"); + pSchemaElement->LinkEndChild(pRectFComment); + TiXmlElement* pRectFTypeElement = new TiXmlElement("xs:simpleType"); + pRectFTypeElement->SetAttribute("name", "RectF_ConsoleType"); + pSchemaElement->LinkEndChild(pRectFTypeElement); + TiXmlElement* pRectFElementA = new TiXmlElement("xs:restriction"); + pRectFElementA->SetAttribute("base", "xs:string"); + pRectFTypeElement->LinkEndChild(pRectFElementA); + TiXmlElement* pRectFElementB = new TiXmlElement("xs:pattern"); + pRectFElementB->SetAttribute("value", "(\\b[-]?(b[0-9]+)?\\.)?[0-9]+\\b"); + pRectFElementA->LinkEndChild(pRectFElementB); - // AssetId. - TiXmlComment* pAssetIdComment = new TiXmlComment("AssetId Console Type"); - pSchemaElement->LinkEndChild(pAssetIdComment); - TiXmlElement* pAssetIdTypeElement = new TiXmlElement("xs:simpleType"); - pAssetIdTypeElement->SetAttribute("name", "AssetId_ConsoleType"); - pSchemaElement->LinkEndChild(pAssetIdTypeElement); - TiXmlElement* pAssetIdElementA = new TiXmlElement("xs:restriction"); - pAssetIdElementA->SetAttribute("base", "xs:string"); - pAssetIdTypeElement->LinkEndChild(pAssetIdElementA); - TiXmlElement* pAssetIdElementB = new TiXmlElement("xs:pattern"); - dSprintf(buffer, sizeof(buffer), "(%s)?\\b[a-zA-Z0-9]+\\b%s\\b[a-zA-Z0-9]+\\b", ASSET_ID_FIELD_PREFIX, ASSET_SCOPE_TOKEN); - pAssetIdElementB->SetAttribute("value", buffer); - pAssetIdElementA->LinkEndChild(pAssetIdElementB); + // AssetId. + TiXmlComment* pAssetIdComment = new TiXmlComment("AssetId Console Type"); + pSchemaElement->LinkEndChild(pAssetIdComment); + TiXmlElement* pAssetIdTypeElement = new TiXmlElement("xs:simpleType"); + pAssetIdTypeElement->SetAttribute("name", "AssetId_ConsoleType"); + pSchemaElement->LinkEndChild(pAssetIdTypeElement); + TiXmlElement* pAssetIdElementA = new TiXmlElement("xs:restriction"); + pAssetIdElementA->SetAttribute("base", "xs:string"); + pAssetIdTypeElement->LinkEndChild(pAssetIdElementA); + TiXmlElement* pAssetIdElementB = new TiXmlElement("xs:pattern"); + dSprintf(buffer, sizeof(buffer), "(%s)?\\b[a-zA-Z0-9]+\\b%s\\b[a-zA-Z0-9]+\\b", ASSET_ID_FIELD_PREFIX, ASSET_SCOPE_TOKEN); + pAssetIdElementB->SetAttribute("value", buffer); + pAssetIdElementA->LinkEndChild(pAssetIdElementB); - // Color Enums. - TiXmlComment* pColorEnumsComment = new TiXmlComment( "Color Enums" ); - pSchemaElement->LinkEndChild( pColorEnumsComment ); - TiXmlElement* pColorEnumsTypeElement = new TiXmlElement( "xs:simpleType" ); - pColorEnumsTypeElement->SetAttribute( "name", "Color_Enums" ); - pSchemaElement->LinkEndChild( pColorEnumsTypeElement ); - TiXmlElement* pColorEnumsRestrictionElement = new TiXmlElement( "xs:restriction" ); - pColorEnumsRestrictionElement->SetAttribute( "base", "xs:string" ); - pColorEnumsTypeElement->LinkEndChild( pColorEnumsRestrictionElement ); - const S32 ColorEnumsCount = StockColor::getCount(); - for( S32 index = 0; index < ColorEnumsCount; ++index ) - { - // Add enumeration element. - TiXmlElement* pColorEnumsAttributeEnumerationElement = new TiXmlElement( "xs:enumeration" ); - pColorEnumsAttributeEnumerationElement->SetAttribute( "value", StockColor::getColorItem(index)->getColorName() ); - pColorEnumsRestrictionElement->LinkEndChild( pColorEnumsAttributeEnumerationElement ); - } + // Color Enums. + TiXmlComment* pColorEnumsComment = new TiXmlComment("Color Enums"); + pSchemaElement->LinkEndChild(pColorEnumsComment); + TiXmlElement* pColorEnumsTypeElement = new TiXmlElement("xs:simpleType"); + pColorEnumsTypeElement->SetAttribute("name", "Color_Enums"); + pSchemaElement->LinkEndChild(pColorEnumsTypeElement); + TiXmlElement* pColorEnumsRestrictionElement = new TiXmlElement("xs:restriction"); + pColorEnumsRestrictionElement->SetAttribute("base", "xs:string"); + pColorEnumsTypeElement->LinkEndChild(pColorEnumsRestrictionElement); + const S32 ColorEnumsCount = StockColor::getCount(); + for (S32 index = 0; index < ColorEnumsCount; ++index) + { + // Add enumeration element. + TiXmlElement* pColorEnumsAttributeEnumerationElement = new TiXmlElement("xs:enumeration"); + pColorEnumsAttributeEnumerationElement->SetAttribute("value", StockColor::getColorItem(index)->getColorName()); + pColorEnumsRestrictionElement->LinkEndChild(pColorEnumsAttributeEnumerationElement); + } - // LinearColorF. - TiXmlComment* pColorFValuesComment = new TiXmlComment( "LinearColorF Values" ); - pSchemaElement->LinkEndChild( pColorFValuesComment ); - TiXmlElement* pColorFValuesTypeElement = new TiXmlElement( "xs:simpleType" ); - pColorFValuesTypeElement->SetAttribute( "name", "ColorF_Values" ); - pSchemaElement->LinkEndChild( pColorFValuesTypeElement ); - TiXmlElement* pColorFValuesElementA = new TiXmlElement( "xs:restriction" ); - pColorFValuesElementA->SetAttribute( "base", "xs:string" ); - pColorFValuesTypeElement->LinkEndChild( pColorFValuesElementA ); - TiXmlElement* pColorFValuesElementB = new TiXmlElement( "xs:pattern" ); - pColorFValuesElementB->SetAttribute( "value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b" ); - pColorFValuesElementA->LinkEndChild( pColorFValuesElementB ); + // LinearColorF. + TiXmlComment* pColorFValuesComment = new TiXmlComment("LinearColorF Values"); + pSchemaElement->LinkEndChild(pColorFValuesComment); + TiXmlElement* pColorFValuesTypeElement = new TiXmlElement("xs:simpleType"); + pColorFValuesTypeElement->SetAttribute("name", "ColorF_Values"); + pSchemaElement->LinkEndChild(pColorFValuesTypeElement); + TiXmlElement* pColorFValuesElementA = new TiXmlElement("xs:restriction"); + pColorFValuesElementA->SetAttribute("base", "xs:string"); + pColorFValuesTypeElement->LinkEndChild(pColorFValuesElementA); + TiXmlElement* pColorFValuesElementB = new TiXmlElement("xs:pattern"); + pColorFValuesElementB->SetAttribute("value", "([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b ([-]?(\\b[0-9]+)?\\.)?[0-9]+\\b"); + pColorFValuesElementA->LinkEndChild(pColorFValuesElementB); - TiXmlComment* pColorFComment = new TiXmlComment( "LinearColorF Console Type" ); - pSchemaElement->LinkEndChild( pColorFComment ); - TiXmlElement* pColorFTypeElement = new TiXmlElement( "xs:simpleType" ); - pColorFTypeElement->SetAttribute( "name", "ColorF_ConsoleType" ); - pSchemaElement->LinkEndChild( pColorFTypeElement ); - TiXmlElement* pColorFUnionElement = new TiXmlElement( "xs:union" ); - pColorFUnionElement->SetAttribute( "memberTypes", "ColorF_Values Color_Enums" ); - pColorFTypeElement->LinkEndChild( pColorFUnionElement ); + TiXmlComment* pColorFComment = new TiXmlComment("LinearColorF Console Type"); + pSchemaElement->LinkEndChild(pColorFComment); + TiXmlElement* pColorFTypeElement = new TiXmlElement("xs:simpleType"); + pColorFTypeElement->SetAttribute("name", "ColorF_ConsoleType"); + pSchemaElement->LinkEndChild(pColorFTypeElement); + TiXmlElement* pColorFUnionElement = new TiXmlElement("xs:union"); + pColorFUnionElement->SetAttribute("memberTypes", "ColorF_Values Color_Enums"); + pColorFTypeElement->LinkEndChild(pColorFUnionElement); - // ColorI. - TiXmlComment* pColorIValuesComment = new TiXmlComment( "ColorI Values" ); - pSchemaElement->LinkEndChild( pColorIValuesComment ); - TiXmlElement* pColorIValuesTypeElement = new TiXmlElement( "xs:simpleType" ); - pColorIValuesTypeElement->SetAttribute( "name", "ColorI_Values" ); - pSchemaElement->LinkEndChild( pColorIValuesTypeElement ); - TiXmlElement* pColorIValuesElementA = new TiXmlElement( "xs:restriction" ); - pColorIValuesElementA->SetAttribute( "base", "xs:string" ); - pColorIValuesTypeElement->LinkEndChild( pColorIValuesElementA ); - TiXmlElement* pColorIValuesElementB = new TiXmlElement( "xs:pattern" ); - pColorIValuesElementB->SetAttribute( "value", "[-]?[0-9]* [-]?[0-9]* [-]?[0-9]* [-]?[0-9]*" ); - pColorIValuesElementA->LinkEndChild( pColorIValuesElementB ); + // ColorI. + TiXmlComment* pColorIValuesComment = new TiXmlComment("ColorI Values"); + pSchemaElement->LinkEndChild(pColorIValuesComment); + TiXmlElement* pColorIValuesTypeElement = new TiXmlElement("xs:simpleType"); + pColorIValuesTypeElement->SetAttribute("name", "ColorI_Values"); + pSchemaElement->LinkEndChild(pColorIValuesTypeElement); + TiXmlElement* pColorIValuesElementA = new TiXmlElement("xs:restriction"); + pColorIValuesElementA->SetAttribute("base", "xs:string"); + pColorIValuesTypeElement->LinkEndChild(pColorIValuesElementA); + TiXmlElement* pColorIValuesElementB = new TiXmlElement("xs:pattern"); + pColorIValuesElementB->SetAttribute("value", "[-]?[0-9]* [-]?[0-9]* [-]?[0-9]* [-]?[0-9]*"); + pColorIValuesElementA->LinkEndChild(pColorIValuesElementB); - TiXmlComment* pColorIComment = new TiXmlComment( "ColorI Console Type" ); - pSchemaElement->LinkEndChild( pColorIComment ); - TiXmlElement* pColorITypeElement = new TiXmlElement( "xs:simpleType" ); - pColorITypeElement->SetAttribute( "name", "ColorI_ConsoleType" ); - pSchemaElement->LinkEndChild( pColorITypeElement ); - TiXmlElement* pColorIUnionElement = new TiXmlElement( "xs:union" ); - pColorIUnionElement->SetAttribute( "memberTypes", "ColorI_Values Color_Enums" ); - pColorITypeElement->LinkEndChild( pColorIUnionElement ); + TiXmlComment* pColorIComment = new TiXmlComment("ColorI Console Type"); + pSchemaElement->LinkEndChild(pColorIComment); + TiXmlElement* pColorITypeElement = new TiXmlElement("xs:simpleType"); + pColorITypeElement->SetAttribute("name", "ColorI_ConsoleType"); + pSchemaElement->LinkEndChild(pColorITypeElement); + TiXmlElement* pColorIUnionElement = new TiXmlElement("xs:union"); + pColorIUnionElement->SetAttribute("memberTypes", "ColorI_Values Color_Enums"); + pColorITypeElement->LinkEndChild(pColorIUnionElement); - // ************************************************************* - // Generate engine type elements. - // ************************************************************* + // ************************************************************* + // Generate engine type elements. + // ************************************************************* - // Generate the engine type elements. - TiXmlComment* pComment = new TiXmlComment( "Type Elements" ); - pSchemaElement->LinkEndChild( pComment ); - for ( AbstractClassRep* pType = pRootType; pType != NULL; pType = pType->getNextClass() ) - { - // Add type. - TiXmlElement* pTypeElement = new TiXmlElement( "xs:element" ); - pTypeElement->SetAttribute( "name", pType->getClassName() ); - dSprintf( buffer, sizeof(buffer), "%s_Type", pType->getClassName() ); - pTypeElement->SetAttribute( "type", buffer ); - pSchemaElement->LinkEndChild( pTypeElement ); - } + // Generate the engine type elements. + TiXmlComment* pComment = new TiXmlComment("Type Elements"); + pSchemaElement->LinkEndChild(pComment); + for (AbstractClassRep* pType = pRootType; pType != NULL; pType = pType->getNextClass()) + { + // Add type. + TiXmlElement* pTypeElement = new TiXmlElement("xs:element"); + pTypeElement->SetAttribute("name", pType->getClassName()); + dSprintf(buffer, sizeof(buffer), "%s_Type", pType->getClassName()); + pTypeElement->SetAttribute("type", buffer); + pSchemaElement->LinkEndChild(pTypeElement); + } - // ************************************************************* - // Generate the engine complex types. - // ************************************************************* - for ( AbstractClassRep* pType = pRootType; pType != NULL; pType = pType->getNextClass() ) - { - // Add complex type comment. - dSprintf( buffer, sizeof(buffer), " %s Type ", pType->getClassName() ); - TiXmlComment* pComment = new TiXmlComment( buffer ); - pSchemaElement->LinkEndChild( pComment ); + // ************************************************************* + // Generate the engine complex types. + // ************************************************************* + for (AbstractClassRep* pType = pRootType; pType != NULL; pType = pType->getNextClass()) + { + // Add complex type comment. + dSprintf(buffer, sizeof(buffer), " %s Type ", pType->getClassName()); + TiXmlComment* pComment = new TiXmlComment(buffer); + pSchemaElement->LinkEndChild(pComment); - // Add complex type. - TiXmlElement* pComplexTypeElement = new TiXmlElement( "xs:complexType" ); - dSprintf( buffer, sizeof(buffer), "%s_Type", pType->getClassName() ); - pComplexTypeElement->SetAttribute( "name", buffer ); - pSchemaElement->LinkEndChild( pComplexTypeElement ); + // Add complex type. + TiXmlElement* pComplexTypeElement = new TiXmlElement("xs:complexType"); + dSprintf(buffer, sizeof(buffer), "%s_Type", pType->getClassName()); + pComplexTypeElement->SetAttribute("name", buffer); + pSchemaElement->LinkEndChild(pComplexTypeElement); - // Add sequence. - TiXmlElement* pSequenceElement = new TiXmlElement( "xs:sequence" ); - pComplexTypeElement->LinkEndChild( pSequenceElement ); + // Add sequence. + TiXmlElement* pSequenceElement = new TiXmlElement("xs:sequence"); + pComplexTypeElement->LinkEndChild(pSequenceElement); - // Fetch container child class. - AbstractClassRep* pContainerChildClass = pType->getContainerChildClass( true ); + // Fetch container child class. + AbstractClassRep* pContainerChildClass = pType->getContainerChildClass(true); - // Is the type allowed children? - if ( pContainerChildClass != NULL ) - { + // Is the type allowed children? + if (pContainerChildClass != NULL) + { // Yes, so add choice element. - TiXmlElement* pChoiceElement = new TiXmlElement( "xs:choice" ); - pChoiceElement->SetAttribute( "minOccurs", 0 ); - pChoiceElement->SetAttribute( "maxOccurs", "unbounded" ); - pSequenceElement->LinkEndChild( pChoiceElement ); + TiXmlElement* pChoiceElement = new TiXmlElement("xs:choice"); + pChoiceElement->SetAttribute("minOccurs", 0); + pChoiceElement->SetAttribute("maxOccurs", "unbounded"); + pSequenceElement->LinkEndChild(pChoiceElement); // Find child group. - HashTable::Iterator childGroupItr = childGroups.find( pContainerChildClass ); + HashTable::Iterator childGroupItr = childGroups.find(pContainerChildClass); // Does the group exist? - if ( childGroupItr == childGroups.end() ) + if (childGroupItr == childGroups.end()) { - // No, so format group name. - dSprintf( buffer, sizeof(buffer), "%s_ChildrenTypes", pContainerChildClass->getClassName() ); + // No, so format group name. + dSprintf(buffer, sizeof(buffer), "%s_ChildrenTypes", pContainerChildClass->getClassName()); - // Insert into child group hash. - childGroupItr = childGroups.insertUnique( pContainerChildClass, StringTable->insert( buffer ) ); + // Insert into child group hash. + childGroupItr = childGroups.insertUnique(pContainerChildClass, StringTable->insert(buffer)); - // Add the group. - TiXmlElement* pChildrenGroupElement = new TiXmlElement( "xs:group" ); - pChildrenGroupElement->SetAttribute( "name", buffer ); - pSchemaElement->LinkEndChild( pChildrenGroupElement ); + // Add the group. + TiXmlElement* pChildrenGroupElement = new TiXmlElement("xs:group"); + pChildrenGroupElement->SetAttribute("name", buffer); + pSchemaElement->LinkEndChild(pChildrenGroupElement); - // Add choice element. - TiXmlElement* pChildreGroupChoiceElement = new TiXmlElement( "xs:choice" ); - pChildrenGroupElement->LinkEndChild( pChildreGroupChoiceElement ); + // Add choice element. + TiXmlElement* pChildreGroupChoiceElement = new TiXmlElement("xs:choice"); + pChildrenGroupElement->LinkEndChild(pChildreGroupChoiceElement); - // Add choice members. - for ( AbstractClassRep* pChoiceType = pRootType; pChoiceType != NULL; pChoiceType = pChoiceType->getNextClass() ) - { - // Skip if not derived from the container child class. - if ( !pChoiceType->isClass( pContainerChildClass ) ) - continue; + // Add choice members. + for (AbstractClassRep* pChoiceType = pRootType; pChoiceType != NULL; pChoiceType = pChoiceType->getNextClass()) + { + // Skip if not derived from the container child class. + if (!pChoiceType->isClass(pContainerChildClass)) + continue; - // Add choice member. - TiXmlElement* pChildrenMemberElement = new TiXmlElement( "xs:element" ); - pChildrenMemberElement->SetAttribute( "name", pChoiceType->getClassName() ); - dSprintf( buffer, sizeof(buffer), "%s_Type", pChoiceType->getClassName() ); - pChildrenMemberElement->SetAttribute( "type", buffer ); - pChildreGroupChoiceElement->LinkEndChild( pChildrenMemberElement ); - } + // Add choice member. + TiXmlElement* pChildrenMemberElement = new TiXmlElement("xs:element"); + pChildrenMemberElement->SetAttribute("name", pChoiceType->getClassName()); + dSprintf(buffer, sizeof(buffer), "%s_Type", pChoiceType->getClassName()); + pChildrenMemberElement->SetAttribute("type", buffer); + pChildreGroupChoiceElement->LinkEndChild(pChildrenMemberElement); + } } // Reference the child group. - TiXmlElement* pChoiceGroupReferenceElement = new TiXmlElement( "xs:group" ); - pChoiceGroupReferenceElement->SetAttribute( "ref", childGroupItr->value ); - pChoiceGroupReferenceElement->SetAttribute( "minOccurs", 0 ); - pChoiceElement->LinkEndChild( pChoiceGroupReferenceElement ); - } + TiXmlElement* pChoiceGroupReferenceElement = new TiXmlElement("xs:group"); + pChoiceGroupReferenceElement->SetAttribute("ref", childGroupItr->value); + pChoiceGroupReferenceElement->SetAttribute("minOccurs", 0); + pChoiceElement->LinkEndChild(pChoiceGroupReferenceElement); + } - // Generate the custom Taml schema. - for ( AbstractClassRep* pCustomSchemaType = pType; pCustomSchemaType != NULL; pCustomSchemaType = pCustomSchemaType->getParentClass() ) - { + // Generate the custom Taml schema. + for (AbstractClassRep* pCustomSchemaType = pType; pCustomSchemaType != NULL; pCustomSchemaType = pCustomSchemaType->getParentClass()) + { // Fetch the types custom TAML schema function. AbstractClassRep::WriteCustomTamlSchema customSchemaFn = pCustomSchemaType->getCustomTamlSchema(); // Skip if no function avilable. - if ( customSchemaFn == NULL ) - continue; + if (customSchemaFn == NULL) + continue; // Call schema generation function. - customSchemaFn( pType, pSequenceElement ); - } + customSchemaFn(pType, pSequenceElement); + } - // Generate field attribute group. - TiXmlElement* pFieldAttributeGroupElement = new TiXmlElement( "xs:attributeGroup" ); - dSprintf( buffer, sizeof(buffer), "%s_Fields", pType->getClassName() ); - pFieldAttributeGroupElement->SetAttribute( "name", buffer ); - pSchemaElement->LinkEndChild( pFieldAttributeGroupElement ); + // Generate field attribute group. + TiXmlElement* pFieldAttributeGroupElement = new TiXmlElement("xs:attributeGroup"); + dSprintf(buffer, sizeof(buffer), "%s_Fields", pType->getClassName()); + pFieldAttributeGroupElement->SetAttribute("name", buffer); + pSchemaElement->LinkEndChild(pFieldAttributeGroupElement); - // Fetch field list. - const AbstractClassRep::FieldList& fields = pType->mFieldList; + // Fetch field list. + const AbstractClassRep::FieldList& fields = pType->mFieldList; - // Fetcj field count. - const S32 fieldCount = fields.size(); + // Fetcj field count. + const S32 fieldCount = fields.size(); - // Iterate static fields (in reverse as most types are organized from the root-fields up). - for( S32 index = fieldCount-1; index > 0; --index ) - { + // Iterate static fields (in reverse as most types are organized from the root-fields up). + for (S32 index = fieldCount - 1; index > 0; --index) + { // Fetch field. const AbstractClassRep::Field& field = fields[index]; // Skip if not a data field. - if( field.type == AbstractClassRep::DeprecatedFieldType || - field.type == AbstractClassRep::StartGroupFieldType || - field.type == AbstractClassRep::EndGroupFieldType ) - continue; + if (field.type == AbstractClassRep::DeprecatedFieldType || + field.type == AbstractClassRep::StartGroupFieldType || + field.type == AbstractClassRep::EndGroupFieldType) + continue; // Skip if the field root is not this type. - if ( pType->findFieldRoot( field.pFieldname ) != pType ) - continue; + if (pType->findFieldRoot(field.pFieldname) != pType) + continue; // Add attribute element. - TiXmlElement* pAttributeElement = new TiXmlElement( "xs:attribute" ); - pAttributeElement->SetAttribute( "name", field.pFieldname ); + TiXmlElement* pAttributeElement = new TiXmlElement("xs:attribute"); + pAttributeElement->SetAttribute("name", field.pFieldname); // Handle the console type appropriately. const S32 fieldType = (S32)field.type; @@ -1381,168 +1383,168 @@ bool Taml::generateTamlSchema() // Is the field an enumeration? if ( fieldType == TypeEnum ) { - // Yes, so add attribute type. - TiXmlElement* pAttributeSimpleTypeElement = new TiXmlElement( "xs:simpleType" ); - pAttributeElement->LinkEndChild( pAttributeSimpleTypeElement ); + // Yes, so add attribute type. + TiXmlElement* pAttributeSimpleTypeElement = new TiXmlElement( "xs:simpleType" ); + pAttributeElement->LinkEndChild( pAttributeSimpleTypeElement ); - // Add restriction element. - TiXmlElement* pAttributeRestrictionElement = new TiXmlElement( "xs:restriction" ); - pAttributeRestrictionElement->SetAttribute( "base", "xs:string" ); - pAttributeSimpleTypeElement->LinkEndChild( pAttributeRestrictionElement ); + // Add restriction element. + TiXmlElement* pAttributeRestrictionElement = new TiXmlElement( "xs:restriction" ); + pAttributeRestrictionElement->SetAttribute( "base", "xs:string" ); + pAttributeSimpleTypeElement->LinkEndChild( pAttributeRestrictionElement ); - // Yes, so fetch enumeration count. - const S32 enumCount = field.table->size; + // Yes, so fetch enumeration count. + const S32 enumCount = field.table->size; - // Iterate enumeration. - for( S32 index = 0; index < enumCount; ++index ) - { - // Add enumeration element. - TiXmlElement* pAttributeEnumerationElement = new TiXmlElement( "xs:enumeration" ); - pAttributeEnumerationElement->SetAttribute( "value", field.table->table[index].label ); - pAttributeRestrictionElement->LinkEndChild( pAttributeEnumerationElement ); - } + // Iterate enumeration. + for( S32 index = 0; index < enumCount; ++index ) + { + // Add enumeration element. + TiXmlElement* pAttributeEnumerationElement = new TiXmlElement( "xs:enumeration" ); + pAttributeEnumerationElement->SetAttribute( "value", field.table->table[index].label ); + pAttributeRestrictionElement->LinkEndChild( pAttributeEnumerationElement ); + } } else {*/ - // No, so assume it's a string type initially. - const char* pFieldTypeDescription = "xs:string"; + // No, so assume it's a string type initially. + const char* pFieldTypeDescription = "xs:string"; - // Handle known types. - if( fieldType == TypeF32 ) - { - pFieldTypeDescription = "xs:float"; - } - else if( fieldType == TypeS8 || fieldType == TypeS32 ) - { - pFieldTypeDescription = "xs:int"; - } - else if( fieldType == TypeBool || fieldType == TypeFlag ) - { - pFieldTypeDescription = "xs:boolean"; - } - else if( fieldType == TypePoint2F ) - { - pFieldTypeDescription = "Point2F_ConsoleType"; - } - else if( fieldType == TypePoint2I ) - { - pFieldTypeDescription = "Point2I_ConsoleType"; - } - else if( fieldType == TypeRectI ) - { - pFieldTypeDescription = "RectI_ConsoleType"; - } - else if( fieldType == TypeRectF ) - { - pFieldTypeDescription = "RectF_ConsoleType"; - } - else if( fieldType == TypeColorF ) - { - pFieldTypeDescription = "ColorF_ConsoleType"; - } - else if( fieldType == TypeColorI ) - { - pFieldTypeDescription = "ColorI_ConsoleType"; - } - else if (fieldType == TypeAssetId/* || - fieldType == TypeImageAssetPtr || - fieldType == TypeAnimationAssetPtr || - fieldType == TypeAudioAssetPtr*/) - { - pFieldTypeDescription = "AssetId_ConsoleType"; - } + // Handle known types. + if (fieldType == TypeF32) + { + pFieldTypeDescription = "xs:float"; + } + else if (fieldType == TypeS8 || fieldType == TypeS32) + { + pFieldTypeDescription = "xs:int"; + } + else if (fieldType == TypeBool || fieldType == TypeFlag) + { + pFieldTypeDescription = "xs:boolean"; + } + else if (fieldType == TypePoint2F) + { + pFieldTypeDescription = "Point2F_ConsoleType"; + } + else if (fieldType == TypePoint2I) + { + pFieldTypeDescription = "Point2I_ConsoleType"; + } + else if (fieldType == TypeRectI) + { + pFieldTypeDescription = "RectI_ConsoleType"; + } + else if (fieldType == TypeRectF) + { + pFieldTypeDescription = "RectF_ConsoleType"; + } + else if (fieldType == TypeColorF) + { + pFieldTypeDescription = "ColorF_ConsoleType"; + } + else if (fieldType == TypeColorI) + { + pFieldTypeDescription = "ColorI_ConsoleType"; + } + else if (fieldType == TypeAssetId/* || + fieldType == TypeImageAssetPtr || + fieldType == TypeAnimationAssetPtr || + fieldType == TypeAudioAssetPtr*/) + { + pFieldTypeDescription = "AssetId_ConsoleType"; + } - // Set attribute type. - pAttributeElement->SetAttribute( "type", pFieldTypeDescription ); + // Set attribute type. + pAttributeElement->SetAttribute("type", pFieldTypeDescription); //} - pAttributeElement->SetAttribute( "use", "optional" ); - pFieldAttributeGroupElement->LinkEndChild( pAttributeElement ); - } + pAttributeElement->SetAttribute("use", "optional"); + pFieldAttributeGroupElement->LinkEndChild(pAttributeElement); + } - // Is this the SimObject Type? - if ( pType == pSimObjectType ) - { + // Is this the SimObject Type? + if (pType == pSimObjectType) + { // Yes, so add reserved Taml field attributes here... // Add Taml "Name" attribute element. - TiXmlElement* pNameAttributeElement = new TiXmlElement( "xs:attribute" ); - pNameAttributeElement->SetAttribute( "name", tamlNamedObjectName ); - pNameAttributeElement->SetAttribute( "type", "xs:normalizedString" ); - pFieldAttributeGroupElement->LinkEndChild( pNameAttributeElement ); + TiXmlElement* pNameAttributeElement = new TiXmlElement("xs:attribute"); + pNameAttributeElement->SetAttribute("name", tamlNamedObjectName); + pNameAttributeElement->SetAttribute("type", "xs:normalizedString"); + pFieldAttributeGroupElement->LinkEndChild(pNameAttributeElement); // Add Taml "TamlId" attribute element. - TiXmlElement* pTamlIdAttributeElement = new TiXmlElement( "xs:attribute" ); - pTamlIdAttributeElement->SetAttribute( "name", tamlRefIdName ); - pTamlIdAttributeElement->SetAttribute( "type", "xs:nonNegativeInteger" ); - pFieldAttributeGroupElement->LinkEndChild( pTamlIdAttributeElement ); + TiXmlElement* pTamlIdAttributeElement = new TiXmlElement("xs:attribute"); + pTamlIdAttributeElement->SetAttribute("name", tamlRefIdName); + pTamlIdAttributeElement->SetAttribute("type", "xs:nonNegativeInteger"); + pFieldAttributeGroupElement->LinkEndChild(pTamlIdAttributeElement); // Add Taml "TamlRefId" attribute element. - TiXmlElement* pTamlRefIdAttributeElement = new TiXmlElement( "xs:attribute" ); - pTamlRefIdAttributeElement->SetAttribute( "name", tamlRefToIdName ); - pTamlRefIdAttributeElement->SetAttribute( "type", "xs:nonNegativeInteger" ); - pFieldAttributeGroupElement->LinkEndChild( pTamlRefIdAttributeElement ); - } + TiXmlElement* pTamlRefIdAttributeElement = new TiXmlElement("xs:attribute"); + pTamlRefIdAttributeElement->SetAttribute("name", tamlRefToIdName); + pTamlRefIdAttributeElement->SetAttribute("type", "xs:nonNegativeInteger"); + pFieldAttributeGroupElement->LinkEndChild(pTamlRefIdAttributeElement); + } - // Add attribute group types. - for ( AbstractClassRep* pAttributeGroupsType = pType; pAttributeGroupsType != NULL; pAttributeGroupsType = pAttributeGroupsType->getParentClass() ) - { - TiXmlElement* pFieldAttributeGroupRefElement = new TiXmlElement( "xs:attributeGroup" ); - dSprintf( buffer, sizeof(buffer), "%s_Fields", pAttributeGroupsType->getClassName() ); - pFieldAttributeGroupRefElement->SetAttribute( "ref", buffer ); - pComplexTypeElement->LinkEndChild( pFieldAttributeGroupRefElement ); - } + // Add attribute group types. + for (AbstractClassRep* pAttributeGroupsType = pType; pAttributeGroupsType != NULL; pAttributeGroupsType = pAttributeGroupsType->getParentClass()) + { + TiXmlElement* pFieldAttributeGroupRefElement = new TiXmlElement("xs:attributeGroup"); + dSprintf(buffer, sizeof(buffer), "%s_Fields", pAttributeGroupsType->getClassName()); + pFieldAttributeGroupRefElement->SetAttribute("ref", buffer); + pComplexTypeElement->LinkEndChild(pFieldAttributeGroupRefElement); + } - // Add "any" attribute element (dynamic fields). - TiXmlElement* pAnyAttributeElement = new TiXmlElement( "xs:anyAttribute" ); - pAnyAttributeElement->SetAttribute( "processContents", "skip" ); - pComplexTypeElement->LinkEndChild( pAnyAttributeElement ); - } + // Add "any" attribute element (dynamic fields). + TiXmlElement* pAnyAttributeElement = new TiXmlElement("xs:anyAttribute"); + pAnyAttributeElement->SetAttribute("processContents", "skip"); + pComplexTypeElement->LinkEndChild(pAnyAttributeElement); + } - // Write the schema document. - schemaDocument.SaveFile( filePathBuffer ); + // Write the schema document. + schemaDocument.SaveFile(filePathBuffer); - // Close file. - stream.close(); + // Close file. + stream.close(); - return true; -} + return true; + } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -void Taml::WriteUnrestrictedCustomTamlSchema( const char* pCustomNodeName, const AbstractClassRep* pClassRep, TiXmlElement* pParentElement ) -{ - // Sanity! - AssertFatal( pCustomNodeName != NULL, "Taml::WriteDefaultCustomTamlSchema() - Node name cannot be NULL." ); - AssertFatal( pClassRep != NULL, "Taml::WriteDefaultCustomTamlSchema() - ClassRep cannot be NULL." ); - AssertFatal( pParentElement != NULL, "Taml::WriteDefaultCustomTamlSchema() - Parent Element cannot be NULL." ); + void Taml::WriteUnrestrictedCustomTamlSchema(const char* pCustomNodeName, const AbstractClassRep* pClassRep, TiXmlElement* pParentElement) + { + // Sanity! + AssertFatal(pCustomNodeName != NULL, "Taml::WriteDefaultCustomTamlSchema() - Node name cannot be NULL."); + AssertFatal(pClassRep != NULL, "Taml::WriteDefaultCustomTamlSchema() - ClassRep cannot be NULL."); + AssertFatal(pParentElement != NULL, "Taml::WriteDefaultCustomTamlSchema() - Parent Element cannot be NULL."); - char buffer[1024]; + char buffer[1024]; - // Add custom type element. - TiXmlElement* pCustomElement = new TiXmlElement( "xs:element" ); - dSprintf( buffer, sizeof(buffer), "%s.%s", pClassRep->getClassName(), pCustomNodeName ); - pCustomElement->SetAttribute( "name", buffer ); - pCustomElement->SetAttribute( "minOccurs", 0 ); - pCustomElement->SetAttribute( "maxOccurs", 1 ); - pParentElement->LinkEndChild( pCustomElement ); + // Add custom type element. + TiXmlElement* pCustomElement = new TiXmlElement("xs:element"); + dSprintf(buffer, sizeof(buffer), "%s.%s", pClassRep->getClassName(), pCustomNodeName); + pCustomElement->SetAttribute("name", buffer); + pCustomElement->SetAttribute("minOccurs", 0); + pCustomElement->SetAttribute("maxOccurs", 1); + pParentElement->LinkEndChild(pCustomElement); - // Add complex type element. - TiXmlElement* pComplexTypeElement = new TiXmlElement( "xs:complexType" ); - pCustomElement->LinkEndChild( pComplexTypeElement ); + // Add complex type element. + TiXmlElement* pComplexTypeElement = new TiXmlElement("xs:complexType"); + pCustomElement->LinkEndChild(pComplexTypeElement); - // Add choice element. - TiXmlElement* pChoiceElement = new TiXmlElement( "xs:choice" ); - pChoiceElement->SetAttribute( "minOccurs", 0 ); - pChoiceElement->SetAttribute( "maxOccurs", "unbounded" ); - pComplexTypeElement->LinkEndChild( pChoiceElement ); + // Add choice element. + TiXmlElement* pChoiceElement = new TiXmlElement("xs:choice"); + pChoiceElement->SetAttribute("minOccurs", 0); + pChoiceElement->SetAttribute("maxOccurs", "unbounded"); + pComplexTypeElement->LinkEndChild(pChoiceElement); - // Add sequence element. - TiXmlElement* pSequenceElement = new TiXmlElement( "xs:sequence" ); - pChoiceElement->LinkEndChild( pSequenceElement ); + // Add sequence element. + TiXmlElement* pSequenceElement = new TiXmlElement("xs:sequence"); + pChoiceElement->LinkEndChild(pSequenceElement); - // Add "any" element. - TiXmlElement* pAnyElement = new TiXmlElement( "xs:any" ); - pAnyElement->SetAttribute( "processContents", "skip" ); - pSequenceElement->LinkEndChild( pAnyElement ); -} + // Add "any" element. + TiXmlElement* pAnyElement = new TiXmlElement("xs:any"); + pAnyElement->SetAttribute("processContents", "skip"); + pSequenceElement->LinkEndChild(pAnyElement); + } \ No newline at end of file