mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 13:47:58 +03:00
Major grammar/lexer/compiler fixes
This commit is contained in:
parent
d2b3f6c12b
commit
5e83e03e33
11 changed files with 1385 additions and 1105 deletions
|
@ -193,7 +193,7 @@ bool StateScript::AddLabel( const_str label, unsigned char *pos, bool private_se
|
|||
{
|
||||
if( label_list.findKeyValue( label ) )
|
||||
{
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
script_label_t &s = label_list.addKeyValue( label );
|
||||
|
@ -209,7 +209,7 @@ bool StateScript::AddLabel( const_str label, unsigned char *pos, bool private_se
|
|||
|
||||
reverse_label_list.AddObject( &s );
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StateScript::AddLabel( str label, unsigned char *pos, bool private_section )
|
||||
|
@ -717,17 +717,21 @@ void GameScript::Load( const void *sourceBuffer, size_t sourceLength )
|
|||
size_t nodeLength;
|
||||
char *m_PreprocessedBuffer;
|
||||
|
||||
m_SourceBuffer = ( char * )glbs.Malloc( sourceLength + 1 );
|
||||
m_SourceBuffer = ( char * )glbs.Malloc( sourceLength + 2 );
|
||||
m_SourceLength = sourceLength;
|
||||
|
||||
m_SourceBuffer[ sourceLength ] = 0;
|
||||
// Original mohaa doesn't reallocate the input string to append a newline
|
||||
// This is a temporary workaround to handle the absolute disaster of newlines
|
||||
// Both the lexer and grammar are extremely abhorrent at handling newlines followed by an EOF
|
||||
m_SourceBuffer[ sourceLength ] = '\n';
|
||||
m_SourceBuffer[ sourceLength + 1] = 0;
|
||||
|
||||
memcpy( m_SourceBuffer, sourceBuffer, sourceLength );
|
||||
|
||||
Compiler.Reset();
|
||||
|
||||
m_PreprocessedBuffer = Compiler.Preprocess( m_SourceBuffer );
|
||||
nodeLength = Compiler.Parse( this, m_PreprocessedBuffer );
|
||||
nodeLength = Compiler.Parse( this, m_PreprocessedBuffer, "script" );
|
||||
Compiler.Preclean( m_PreprocessedBuffer );
|
||||
|
||||
if( !nodeLength )
|
||||
|
|
|
@ -47,7 +47,7 @@ int success_pos;
|
|||
%locations
|
||||
%define api.location.type { parse_pos_t }
|
||||
|
||||
%expect 127
|
||||
%expect 131
|
||||
|
||||
%precedence TOKEN_EOF 0 "end of file"
|
||||
%precedence TOKEN_EOL
|
||||
|
@ -116,9 +116,11 @@ int success_pos;
|
|||
%type <s.val> func_prim_expr
|
||||
%type <s.val> prim_expr
|
||||
%type <s.val> nonident_prim_expr
|
||||
%type <s.val> func_expr
|
||||
%type <s.val> const_array_list
|
||||
%type <s.val> const_array
|
||||
%type <s.val> identifier_prim
|
||||
%type <s.val> identifier
|
||||
|
||||
%start program
|
||||
|
||||
|
@ -222,8 +224,7 @@ expr:
|
|||
func_prim_expr:
|
||||
TOKEN_IDENTIFIER event_parameter_list_need { $$ = node3(ENUM_cmd_event_expr, $1, $2, TOKPOS(@1)); }
|
||||
| nonident_prim_expr TOKEN_IDENTIFIER event_parameter_list { $$ = node4(ENUM_method_event_expr, $1, $2, $3, TOKPOS(@2)); }
|
||||
| TOKEN_NEG func_prim_expr { $$ = node3(ENUM_func1_expr, node1b(OP_UN_MINUS), $2, TOKPOS(@1)); }
|
||||
| TOKEN_COMPLEMENT func_prim_expr { $$ = node3(ENUM_func1_expr, node1b(OP_UN_COMPLEMENT), $2, TOKPOS(@1)); }
|
||||
| func_expr func_prim_expr { $$ = node3(ENUM_func1_expr, $1, $2, TOKPOS(@1)); }
|
||||
| TOKEN_NOT func_prim_expr { $$ = node2(ENUM_bool_not, $2, TOKPOS(@1)); }
|
||||
| TOKEN_IDENTIFIER TOKEN_DOUBLE_COLON const_array_list
|
||||
{
|
||||
|
@ -269,9 +270,18 @@ prim_expr
|
|||
| prim_expr TOKEN_DOUBLE_COLON const_array_list { $$ = node3(ENUM_const_array_expr, $1, $3, TOKPOS(@2)); }
|
||||
;
|
||||
|
||||
identifier_prim:
|
||||
TOKEN_IDENTIFIER { $$ = $1; @$ = @1; }
|
||||
;
|
||||
|
||||
identifier
|
||||
: TOKEN_IDENTIFIER { $$ = $1; @$ = @1; }
|
||||
| TOKEN_STRING { $$ = $1; @$ = @1; }
|
||||
;
|
||||
|
||||
nonident_prim_expr
|
||||
: TOKEN_DOLLAR prim_expr { $$ = node3(ENUM_func1_expr, node1b(OP_UN_TARGETNAME), $2, TOKPOS(@1)); }
|
||||
| nonident_prim_expr TOKEN_PERIOD TOKEN_IDENTIFIER { $$ = node3(ENUM_field, $1, $3, TOKPOS(@3)); }
|
||||
| nonident_prim_expr TOKEN_PERIOD identifier { $$ = node3(ENUM_field, $1, $3, TOKPOS(@3)); }
|
||||
| nonident_prim_expr TOKEN_PERIOD TOKEN_SIZE { $$ = node3(ENUM_func1_expr, node1b(OP_UN_SIZE), $1, TOKPOS(@3)); }
|
||||
| nonident_prim_expr TOKEN_LEFT_SQUARE_BRACKET expr TOKEN_RIGHT_SQUARE_BRACKET { $$ = node3(ENUM_array_expr, $1, $3, TOKPOS(@2)); }
|
||||
| TOKEN_STRING { $$ = node2(ENUM_string, $1, TOKPOS(@1)); }
|
||||
|
@ -280,15 +290,15 @@ nonident_prim_expr
|
|||
| TOKEN_LEFT_BRACKET expr[exp1] expr[exp2] expr[exp3] TOKEN_RIGHT_BRACKET { $$ = node4(ENUM_vector, $exp1, $exp2, $exp3, TOKPOS(@1)); }
|
||||
| TOKEN_LISTENER { $$ = node2(ENUM_listener, $1, TOKPOS(@1)); }
|
||||
| TOKEN_LEFT_BRACKET expr TOKEN_RIGHT_BRACKET { $$ = $2; }
|
||||
| TOKEN_NEG nonident_prim_expr { $$ = node3(ENUM_func1_expr, node1b(OP_UN_MINUS), $2, TOKPOS(@1)); }
|
||||
| TOKEN_COMPLEMENT nonident_prim_expr { $$ = node3(ENUM_func1_expr, node1b(OP_UN_COMPLEMENT), $2, TOKPOS(@1)); }
|
||||
| func_expr nonident_prim_expr { $$ = node3(ENUM_func1_expr, $1, $2, TOKPOS(@1)); }
|
||||
| TOKEN_NOT nonident_prim_expr { $$ = node2(ENUM_bool_not, $2, TOKPOS(@1)); }
|
||||
| TOKEN_NULL { $$ = node1(ENUM_NULL, TOKPOS(@1)); }
|
||||
| TOKEN_NIL { $$ = node1(ENUM_NIL, TOKPOS(@1)); }
|
||||
;
|
||||
|
||||
identifier_prim:
|
||||
TOKEN_IDENTIFIER { $$ = $1; @$ = @1; }
|
||||
func_expr
|
||||
: TOKEN_NEG { $$ = node1b(OP_UN_MINUS); }
|
||||
| TOKEN_COMPLEMENT { $$ = node1b(OP_UN_COMPLEMENT); }
|
||||
;
|
||||
|
||||
makearray_statement_list:
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -203,9 +203,6 @@ void yyfree ( void * );
|
|||
|
||||
/* Begin user sect3 */
|
||||
|
||||
#define yywrap() (/*CONSTCOND*/1)
|
||||
#define YY_SKIP_YYWRAP
|
||||
|
||||
extern int yylineno;
|
||||
|
||||
extern char *yytext;
|
||||
|
@ -216,10 +213,11 @@ extern char *yytext;
|
|||
|
||||
#ifdef YY_HEADER_EXPORT_START_CONDITIONS
|
||||
#define INITIAL 0
|
||||
#define C_COMMENT 1
|
||||
#define C_LINE_COMMENT 2
|
||||
#define VARIABLES 3
|
||||
#define IDENTIFIER 4
|
||||
#define SCRIPT 1
|
||||
#define C_COMMENT 2
|
||||
#define C_LINE_COMMENT 3
|
||||
#define VARIABLES 4
|
||||
#define IDENTIFIER 5
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -465,9 +463,9 @@ extern int yylex (void);
|
|||
#undef yyTABLES_NAME
|
||||
#endif
|
||||
|
||||
#line 360 "E:/Src/openmohaa/code/parser/lex_source.txt"
|
||||
#line 364 "E:/Src/openmohaa/code/parser/lex_source.txt"
|
||||
|
||||
|
||||
#line 471 "E:/Src/openmohaa/code/parser/generated/yyLexer.h"
|
||||
#line 469 "E:/Src/openmohaa/code/parser/generated/yyLexer.h"
|
||||
#undef yyIN_HEADER
|
||||
#endif /* yyHEADER_H */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -96,9 +96,139 @@ static const char* token_names[] =
|
|||
"TOKEN_ENDARRAY",
|
||||
};
|
||||
|
||||
extern yy_state_type yy_last_accepting_state;
|
||||
extern char* yy_last_accepting_cpos;
|
||||
|
||||
enum yytokentype
|
||||
{
|
||||
YYEMPTY = -2,
|
||||
TOKEN_EOF = 0, /* TOKEN_EOF */
|
||||
YYerror = 256, /* error */
|
||||
TOKEN_EOL = 257,
|
||||
TOKEN_IF,
|
||||
TOKEN_ELSE,
|
||||
TOKEN_WHILE,
|
||||
TOKEN_FOR,
|
||||
TOKEN_IDENTIFIER,
|
||||
TOKEN_LEFT_BRACES,
|
||||
TOKEN_RIGHT_BRACES,
|
||||
TOKEN_LEFT_BRACKET,
|
||||
TOKEN_RIGHT_BRACKET,
|
||||
TOKEN_LEFT_SQUARE_BRACKET,
|
||||
TOKEN_RIGHT_SQUARE_BRACKET,
|
||||
TOKEN_EQUALITY,
|
||||
TOKEN_ASSIGNMENT,
|
||||
TOKEN_COLON,
|
||||
TOKEN_DOUBLE_COLON,
|
||||
TOKEN_SEMICOLON,
|
||||
TOKEN_LOGICAL_OR,
|
||||
TOKEN_LOGICAL_AND,
|
||||
TOKEN_BITWISE_OR,
|
||||
TOKEN_BITWISE_EXCL_OR,
|
||||
TOKEN_BITWISE_AND,
|
||||
TOKEN_INEQUALITY,
|
||||
TOKEN_LESS_THAN,
|
||||
TOKEN_GREATER_THAN,
|
||||
TOKEN_LESS_THAN_OR_EQUAL,
|
||||
TOKEN_GREATER_THAN_OR_EQUAL,
|
||||
TOKEN_PLUS,
|
||||
TOKEN_PLUS_EQUALS,
|
||||
TOKEN_MINUS,
|
||||
TOKEN_NEG,
|
||||
TOKEN_POS,
|
||||
TOKEN_MINUS_EQUALS,
|
||||
TOKEN_MULTIPLY,
|
||||
TOKEN_DIVIDE,
|
||||
TOKEN_PERCENTAGE,
|
||||
TOKEN_DOLLAR,
|
||||
TOKEN_NOT,
|
||||
TOKEN_COMPLEMENT,
|
||||
TOKEN_STRING,
|
||||
TOKEN_INTEGER,
|
||||
TOKEN_FLOAT,
|
||||
TOKEN_LISTENER,
|
||||
TOKEN_PERIOD,
|
||||
TOKEN_NULL,
|
||||
TOKEN_NIL,
|
||||
TOKEN_INC,
|
||||
TOKEN_DEC,
|
||||
TOKEN_SCRIPT,
|
||||
TOKEN_TRY,
|
||||
TOKEN_CATCH,
|
||||
TOKEN_SWITCH,
|
||||
TOKEN_CASE,
|
||||
TOKEN_BREAK,
|
||||
TOKEN_CONTINUE,
|
||||
TOKEN_SIZE,
|
||||
TOKEN_END,
|
||||
TOKEN_MAKEARRAY,
|
||||
TOKEN_ENDARRAY,
|
||||
};
|
||||
typedef enum yytokentype yytoken_kind_t;
|
||||
|
||||
extern ScriptDisplayTokenFunc* _scriptDisplayToken;
|
||||
extern int prev_yylex;
|
||||
|
||||
static void DisplayToken()
|
||||
{
|
||||
scriptDisplayToken(token_names[prev_yylex - TOKEN_EOL], yytext);
|
||||
}
|
||||
|
||||
static void TextEscapeValue(char* str, int len)
|
||||
{
|
||||
char *to = parsetree_malloc( len + 1 );
|
||||
|
||||
yylval.s.val.stringValue = to;
|
||||
|
||||
while( len )
|
||||
{
|
||||
if( *str == '\\' )
|
||||
{
|
||||
len--;
|
||||
|
||||
if( !len )
|
||||
break;
|
||||
|
||||
str++;
|
||||
if( *str == 'n' )
|
||||
{
|
||||
*to = '\n';
|
||||
}
|
||||
else if( *str == 't' )
|
||||
{
|
||||
*to = '\t';
|
||||
}
|
||||
else if( *str == '"' )
|
||||
{
|
||||
*to = '\"';
|
||||
}
|
||||
else
|
||||
{
|
||||
*to = *str;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*to = *str;
|
||||
}
|
||||
|
||||
len--;
|
||||
str++;
|
||||
to++;
|
||||
}
|
||||
|
||||
*to = 0;
|
||||
}
|
||||
|
||||
static int UseField()
|
||||
{
|
||||
return prev_yylex == TOKEN_DOLLAR || prev_yylex == TOKEN_PERIOD;
|
||||
}
|
||||
|
||||
static int yylex()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int yy_get_next_buffer()
|
||||
|
@ -107,16 +237,56 @@ static int yy_get_next_buffer()
|
|||
return 0;
|
||||
}
|
||||
|
||||
static yy_state_type yy_get_previous_state()
|
||||
/* yy_get_previous_state - get the state just before the EOB char was reached */
|
||||
|
||||
static yy_state_type yy_get_previous_state(void)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
yy_state_type yy_current_state;
|
||||
char* yy_cp;
|
||||
|
||||
yy_current_state = (yy_start);
|
||||
|
||||
for (yy_cp = yytext + yy_more_len; yy_cp < (yy_c_buf_p); ++yy_cp)
|
||||
{
|
||||
YY_CHAR yy_c = (*yy_cp ? yy_ec[((YY_CHAR)(*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 >= 303)
|
||||
yy_c = yy_meta[yy_c];
|
||||
}
|
||||
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
|
||||
}
|
||||
|
||||
return yy_current_state;
|
||||
}
|
||||
|
||||
static yy_state_type yy_try_NUL_trans(yy_state_type yy_current_state)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
int yy_is_jam;
|
||||
char* yy_cp = (yy_c_buf_p);
|
||||
|
||||
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 >= 303)
|
||||
yy_c = yy_meta[yy_c];
|
||||
}
|
||||
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
|
||||
yy_is_jam = (yy_current_state == 302);
|
||||
|
||||
return yy_is_jam ? 0 : yy_current_state;
|
||||
}
|
||||
|
||||
static void yyunput(int c, char* yy_bp)
|
||||
|
@ -206,23 +376,6 @@ static void yy_flex_free(void* ptr)
|
|||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void TextEscapeValue(char* str, int len)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static int UseField()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int yylex()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
void IntegerValue(char* str)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
|
|
|
@ -43,37 +43,13 @@ void fprintf2( FILE *f, const char *format, ... )
|
|||
|
||||
#define fprintf fprintf2
|
||||
|
||||
const char* start_ptr;
|
||||
const char* in_ptr;
|
||||
extern int prev_yylex;
|
||||
extern int out_pos;
|
||||
extern int success_pos;
|
||||
parseStage_e parseStage;
|
||||
|
||||
/*
|
||||
extern "C" int yywrap(void);
|
||||
|
||||
int yywrap(void) {
|
||||
if (parseStage == PS_TYPE) {
|
||||
parseStage = PS_BODY;
|
||||
out_pos = 0;
|
||||
success_pos = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (parseStage == PS_BODY)
|
||||
{
|
||||
if (YY_START != 0)
|
||||
{
|
||||
parseStage = PS_BODY_END;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Compiler.CompileError(success_pos, "unexpected end of file found in comment");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
extern yyparsedata parsedata;
|
||||
|
||||
void yyllocset(YYLTYPE *loc, uint32_t off)
|
||||
|
@ -167,6 +143,34 @@ static bool UseField( void )
|
|||
|| prev_yylex == TOKEN_DOLLAR;
|
||||
}
|
||||
|
||||
#define YY_INPUT(buf,result,max_size) \
|
||||
{ \
|
||||
char c; \
|
||||
int n; \
|
||||
\
|
||||
c = '*'; \
|
||||
for(n = 0; n < max_size; n++) \
|
||||
{ \
|
||||
c = *in_ptr++; \
|
||||
if (!c || c == '\n') { \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
buf[n] = c; \
|
||||
} \
|
||||
\
|
||||
if (c == '\n') \
|
||||
{ \
|
||||
buf[n++] = c; \
|
||||
} \
|
||||
else if (!c) \
|
||||
{ \
|
||||
in_ptr--; \
|
||||
} \
|
||||
\
|
||||
result = n; \
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
/*%option debug*/
|
||||
|
@ -175,8 +179,8 @@ static bool UseField( void )
|
|||
|
||||
%option never-interactive
|
||||
%option yylineno
|
||||
%option noyywrap
|
||||
|
||||
%x SCRIPT
|
||||
%x C_COMMENT
|
||||
%x C_LINE_COMMENT
|
||||
%x VARIABLES
|
||||
|
@ -226,7 +230,7 @@ varname [a-zA-Z0-9_\"]+
|
|||
"for" { YYLEX( TOKEN_FOR ); }
|
||||
"do" { YYLEX( TOKEN_DO ); }
|
||||
|
||||
"game"? { BEGIN( VARIABLES ); yylval.s.val = node1_( method_game ); YYLEX( TOKEN_LISTENER ); }
|
||||
"game" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_game ); YYLEX( TOKEN_LISTENER ); }
|
||||
"group" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_group ); YYLEX( TOKEN_LISTENER ); }
|
||||
"level" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_level ); YYLEX( TOKEN_LISTENER ); }
|
||||
"local" { BEGIN( VARIABLES ); yylval.s.val = node1_( method_local ); YYLEX( TOKEN_LISTENER ); }
|
||||
|
@ -303,7 +307,7 @@ varname [a-zA-Z0-9_\"]+
|
|||
"makearray"|"makeArray" { YYLEX( TOKEN_MAKEARRAY ); }
|
||||
"endarray"|"endArray" { YYLEX( TOKEN_ENDARRAY ); }
|
||||
|
||||
[\r\n]* { if (prev_yylex != TOKEN_EOL) YYLEX(TOKEN_EOL); }
|
||||
[\r\n]+ { if (prev_yylex != TOKEN_EOL) YYLEX(TOKEN_EOL); }
|
||||
[ \t] { ; }
|
||||
|
||||
[0-9]+ {
|
||||
|
@ -347,7 +351,7 @@ varname [a-zA-Z0-9_\"]+
|
|||
yymore();
|
||||
}
|
||||
|
||||
<<EOF>> { YYLEX(TOKEN_EOF); }
|
||||
<SCRIPT>[a-zA-Z0-9]+ { BEGIN(INITIAL); }
|
||||
|
||||
. { YY_FATAL_ERROR("bad token:\n"); }
|
||||
|
||||
|
@ -358,3 +362,35 @@ varname [a-zA-Z0-9_\"]+
|
|||
%}
|
||||
|
||||
%%
|
||||
|
||||
//
|
||||
// Implements yywrap to always append a newline to the source
|
||||
//
|
||||
int yywrap(void) {
|
||||
if (parseStage == PS_TYPE) {
|
||||
parseStage = PS_BODY;
|
||||
in_ptr = start_ptr;
|
||||
out_pos = 0;
|
||||
success_pos = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (parseStage == PS_BODY)
|
||||
{
|
||||
if (YY_START == C_COMMENT)
|
||||
{
|
||||
Compiler.CompileError(success_pos, "unexpected end of file found in comment");
|
||||
return 1;
|
||||
}
|
||||
|
||||
parseStage = PS_BODY_END;
|
||||
in_ptr = "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void yy_init_script() {
|
||||
BEGIN(SCRIPT);
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ typedef enum {
|
|||
|
||||
typedef union sval_u {
|
||||
int type;
|
||||
const char *stringValue;
|
||||
const char *stringValue;
|
||||
float floatValue;
|
||||
int intValue;
|
||||
char charValue;
|
||||
|
@ -94,9 +94,9 @@ struct stype_t {
|
|||
};
|
||||
|
||||
enum parseStage_e {
|
||||
PS_TYPE,
|
||||
PS_BODY,
|
||||
PS_BODY_END
|
||||
PS_TYPE,
|
||||
PS_BODY,
|
||||
PS_BODY_END
|
||||
};
|
||||
|
||||
void parsetree_freeall();
|
||||
|
@ -125,10 +125,10 @@ sval_u node6(int type, sval_u val1, sval_u val2, sval_u val3, sval_u val4, sval_
|
|||
|
||||
typedef struct parse_pos_s {
|
||||
int sourcePos;
|
||||
int first_line;
|
||||
int first_column;
|
||||
int last_line;
|
||||
int last_column;
|
||||
int first_line;
|
||||
int first_column;
|
||||
int last_line;
|
||||
int last_column;
|
||||
} parse_pos_t;
|
||||
|
||||
struct yyexception {
|
||||
|
|
|
@ -4,8 +4,8 @@ typedef int yy_state_type;
|
|||
|
||||
static int braces_count;
|
||||
static sval_t parseValue;
|
||||
static int prev_yylex;
|
||||
static ScriptDisplayTokenFunc* _scriptDisplayToken;
|
||||
int prev_yylex;
|
||||
ScriptDisplayTokenFunc* _scriptDisplayToken;
|
||||
static unsigned int out_pos;
|
||||
static unsigned int success_pos;
|
||||
static char* in_ptr;
|
||||
|
@ -25,9 +25,9 @@ static char yy_hold_char;
|
|||
static int yy_n_chars;
|
||||
static int yy_did_buffer_switch_on_eof;
|
||||
char* yytext;
|
||||
static yy_state_type yy_last_accepting_state;
|
||||
static char* yy_last_accepting_cpos;
|
||||
static parseStage_e parseStage;
|
||||
yy_state_type yy_last_accepting_state;
|
||||
char* yy_last_accepting_cpos;
|
||||
parseStage_e parseStage;
|
||||
|
||||
void TextValue(const char* str, int len)
|
||||
{
|
||||
|
|
|
@ -234,10 +234,10 @@ bool ScriptCompiler::BuiltinWriteVariable(unsigned int sourcePos, int type, int
|
|||
|
||||
void ScriptCompiler::EmitAssignmentStatement(sval_t lhs, unsigned int sourcePos)
|
||||
{
|
||||
int eventnum;
|
||||
sval_t listener_val;
|
||||
const char *name = lhs.node[2].stringValue;
|
||||
str name2 = name;
|
||||
int eventnum;
|
||||
sval_t listener_val;
|
||||
const char *name = lhs.node[2].stringValue;
|
||||
str name2 = name;
|
||||
name2.tolower();
|
||||
|
||||
if (lhs.node[0].type != ENUM_field) {
|
||||
|
@ -247,8 +247,8 @@ void ScriptCompiler::EmitAssignmentStatement(sval_t lhs, unsigned int sourcePos)
|
|||
EmitOpcode(OP_LOAD_ARRAY_VAR, lhs.node[3].sourcePosValue);
|
||||
} else {
|
||||
CompileError(sourcePos, "bad lvalue: %d (expecting field or array)", lhs.node[0].type);
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int index = Director.AddString(name);
|
||||
|
@ -367,14 +367,13 @@ void ScriptCompiler::EmitCatch(sval_t val, unsigned char *try_begin_code_pos, un
|
|||
|
||||
void ScriptCompiler::EmitConstArray(sval_t lhs, sval_t rhs, unsigned int sourcePos)
|
||||
{
|
||||
uint32_t iCount = 1;
|
||||
uint32_t iCount = 1;
|
||||
|
||||
EmitValue(lhs);
|
||||
EmitValue(lhs);
|
||||
|
||||
for (const sval_t* node = rhs.node[0].node; node; node = node[1].node, iCount++)
|
||||
{
|
||||
EmitValue(*node);
|
||||
}
|
||||
for (const sval_t *node = rhs.node[0].node; node; node = node[1].node, iCount++) {
|
||||
EmitValue(*node);
|
||||
}
|
||||
|
||||
EmitConstArrayOpcode(iCount);
|
||||
}
|
||||
|
@ -661,23 +660,22 @@ void ScriptCompiler::EmitLabel(str name, unsigned int sourcePos)
|
|||
glbs.DPrintf("<%s>:\n", name.c_str());
|
||||
}
|
||||
|
||||
if (stateScript->AddLabel(name, code_pos)) {
|
||||
if (!stateScript->AddLabel(name, code_pos)) {
|
||||
CompileError(sourcePos, "Duplicate label '%s'", name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptCompiler::EmitLabelParameterList(sval_t parameter_list, unsigned int sourcePos)
|
||||
{
|
||||
if (parameter_list.node)
|
||||
{
|
||||
EmitOpcode(OP_MARK_STACK_POS, sourcePos);
|
||||
if (parameter_list.node) {
|
||||
EmitOpcode(OP_MARK_STACK_POS, sourcePos);
|
||||
|
||||
for (const sval_t* param = parameter_list.node->node; param; param = param[1].node) {
|
||||
EmitParameter(*param, sourcePos);
|
||||
};
|
||||
for (const sval_t *param = parameter_list.node->node; param; param = param[1].node) {
|
||||
EmitParameter(*param, sourcePos);
|
||||
};
|
||||
|
||||
EmitOpcode(OP_RESTORE_STACK_POS, sourcePos);
|
||||
}
|
||||
EmitOpcode(OP_RESTORE_STACK_POS, sourcePos);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptCompiler::EmitLabelPrivate(str name, unsigned int sourcePos)
|
||||
|
@ -686,7 +684,7 @@ void ScriptCompiler::EmitLabelPrivate(str name, unsigned int sourcePos)
|
|||
glbs.DPrintf("<%s>:\n", name.c_str());
|
||||
}
|
||||
|
||||
if (stateScript->AddLabel(name, code_pos, true)) {
|
||||
if (!stateScript->AddLabel(name, code_pos, true)) {
|
||||
CompileError(sourcePos, "Duplicate label '%s'", name.c_str());
|
||||
}
|
||||
}
|
||||
|
@ -859,8 +857,8 @@ void ScriptCompiler::EmitParameter(sval_t lhs, unsigned int sourcePos)
|
|||
CompileError(sourcePos, "bad parameter lvalue: %d (expecting field)", lhs.node[0].type);
|
||||
}
|
||||
|
||||
sval_u listener_val = lhs.node[1];
|
||||
const char *name = lhs.node[2].stringValue;
|
||||
sval_u listener_val = lhs.node[1];
|
||||
const char *name = lhs.node[2].stringValue;
|
||||
|
||||
int eventnum = Event::FindSetterEventNum(name);
|
||||
|
||||
|
@ -871,28 +869,27 @@ void ScriptCompiler::EmitParameter(sval_t lhs, unsigned int sourcePos)
|
|||
EmitOpcode(OP_STORE_PARAM, sourcePos);
|
||||
EmitOpcode(OP_LOAD_GAME_VAR + listener_val.node[1].byteValue, sourcePos);
|
||||
|
||||
unsigned int index = Director.AddString(name);
|
||||
unsigned int index = Director.AddString(name);
|
||||
EmitOpcodeValue(index, sizeof(unsigned int));
|
||||
}
|
||||
}
|
||||
|
||||
int ScriptCompiler::EmitParameterList(sval_t event_parameter_list)
|
||||
{
|
||||
sval_t* node;
|
||||
uint32_t iParamCount = 0;
|
||||
sval_t *node;
|
||||
uint32_t iParamCount = 0;
|
||||
|
||||
if (!event_parameter_list.node) {
|
||||
return 0;
|
||||
}
|
||||
if (!event_parameter_list.node) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (node = event_parameter_list.node->node; node; node = node[1].node)
|
||||
{
|
||||
EmitValue(*node);
|
||||
for (node = event_parameter_list.node->node; node; node = node[1].node) {
|
||||
EmitValue(*node);
|
||||
|
||||
iParamCount++;
|
||||
}
|
||||
iParamCount++;
|
||||
}
|
||||
|
||||
return iParamCount;
|
||||
return iParamCount;
|
||||
}
|
||||
|
||||
void ScriptCompiler::EmitRef(sval_t val, unsigned int sourcePos)
|
||||
|
@ -906,8 +903,8 @@ void ScriptCompiler::EmitRef(sval_t val, unsigned int sourcePos)
|
|||
EmitOpcode(OP_STORE_ARRAY_REF, val.node[3].sourcePosValue);
|
||||
} else {
|
||||
CompileError(sourcePos, "bad lvalue: %d (expecting field or array)", val.node[0].type);
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
index = Director.AddString(val.node[2].stringValue);
|
||||
|
@ -1047,91 +1044,85 @@ __emit:
|
|||
}
|
||||
|
||||
case ENUM_cmd_event_statement:
|
||||
{
|
||||
const int eventnum = Event::FindNormalEventNum(val.node[1].stringValue);
|
||||
sval_t parameter_list = val.node[2];
|
||||
const uint32_t iParamCount = EmitParameterList(parameter_list);
|
||||
{
|
||||
const int eventnum = Event::FindNormalEventNum(val.node[1].stringValue);
|
||||
sval_t parameter_list = val.node[2];
|
||||
const uint32_t iParamCount = EmitParameterList(parameter_list);
|
||||
|
||||
if (!eventnum) {
|
||||
CompileError(val.node[3].sourcePosValue, "unknown command: %s", val.node[1].stringValue);
|
||||
}
|
||||
if (!eventnum) {
|
||||
CompileError(val.node[3].sourcePosValue, "unknown command: %s", val.node[1].stringValue);
|
||||
}
|
||||
|
||||
if (iParamCount > 5)
|
||||
{
|
||||
SetOpcodeVarStackOffset(OP_EXEC_CMD_COUNT1, -(int32_t)iParamCount);
|
||||
EmitOpcode(OP_EXEC_CMD_COUNT1, val.node[3].sourcePosValue);
|
||||
if (iParamCount > 5) {
|
||||
SetOpcodeVarStackOffset(OP_EXEC_CMD_COUNT1, -(int32_t)iParamCount);
|
||||
EmitOpcode(OP_EXEC_CMD_COUNT1, val.node[3].sourcePosValue);
|
||||
|
||||
EmitOpcodeValue(iParamCount, sizeof(byte));
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitOpcode(OP_EXEC_CMD0 + iParamCount, val.node[3].sourcePosValue);
|
||||
}
|
||||
EmitOpcodeValue(iParamCount, sizeof(byte));
|
||||
} else {
|
||||
EmitOpcode(OP_EXEC_CMD0 + iParamCount, val.node[3].sourcePosValue);
|
||||
}
|
||||
|
||||
EmitOpcodeValue((op_ev_t)eventnum, sizeof(unsigned int));
|
||||
break;
|
||||
}
|
||||
EmitOpcodeValue((op_ev_t)eventnum, sizeof(unsigned int));
|
||||
break;
|
||||
}
|
||||
|
||||
case ENUM_cmd_event_expr:
|
||||
{
|
||||
const int eventnum = Event::FindReturnEventNum(val.node[1].stringValue);
|
||||
sval_t parameter_list = val.node[2];
|
||||
const uint32_t iParamCount = EmitParameterList(parameter_list);
|
||||
const int eventnum = Event::FindReturnEventNum(val.node[1].stringValue);
|
||||
sval_t parameter_list = val.node[2];
|
||||
const uint32_t iParamCount = EmitParameterList(parameter_list);
|
||||
|
||||
EmitOpcode(OP_STORE_LOCAL, val.node[3].sourcePosValue);
|
||||
EmitOpcode(OP_STORE_LOCAL, val.node[3].sourcePosValue);
|
||||
|
||||
if (!eventnum) {
|
||||
CompileError(val.node[3].sourcePosValue, "unknown command: %s", val.node[1].stringValue);
|
||||
}
|
||||
if (!eventnum) {
|
||||
CompileError(val.node[3].sourcePosValue, "unknown command: %s", val.node[1].stringValue);
|
||||
}
|
||||
|
||||
EmitMethodExpression(iParamCount, eventnum, val.node[3].sourcePosValue);
|
||||
EmitMethodExpression(iParamCount, eventnum, val.node[3].sourcePosValue);
|
||||
|
||||
EmitOpcodeValue((op_ev_t)eventnum, sizeof(unsigned int));
|
||||
break;
|
||||
EmitOpcodeValue((op_ev_t)eventnum, sizeof(unsigned int));
|
||||
break;
|
||||
}
|
||||
|
||||
case ENUM_method_event_statement:
|
||||
{
|
||||
const int eventnum = Event::FindNormalEventNum(val.node[2].stringValue);
|
||||
sval_t parameter_list = val.node[3];
|
||||
const uint32_t iParamCount = EmitParameterList(parameter_list);
|
||||
const int eventnum = Event::FindNormalEventNum(val.node[2].stringValue);
|
||||
sval_t parameter_list = val.node[3];
|
||||
const uint32_t iParamCount = EmitParameterList(parameter_list);
|
||||
|
||||
if (!eventnum) {
|
||||
CompileError(val.node[3].sourcePosValue, "unknown command: %s", val.node[2].stringValue);
|
||||
}
|
||||
if (!eventnum) {
|
||||
CompileError(val.node[4].sourcePosValue, "unknown command: %s", val.node[2].stringValue);
|
||||
}
|
||||
|
||||
EmitValue(val.node[1]);
|
||||
EmitValue(val.node[1]);
|
||||
|
||||
if (iParamCount > 5)
|
||||
{
|
||||
SetOpcodeVarStackOffset(OP_EXEC_CMD_COUNT1, -(int32_t)iParamCount);
|
||||
EmitOpcode(OP_EXEC_CMD_COUNT1, val.node[4].sourcePosValue);
|
||||
if (iParamCount > 5) {
|
||||
SetOpcodeVarStackOffset(OP_EXEC_CMD_COUNT1, -(int32_t)iParamCount);
|
||||
EmitOpcode(OP_EXEC_CMD_COUNT1, val.node[4].sourcePosValue);
|
||||
|
||||
EmitOpcodeValue(iParamCount, sizeof(byte));
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitOpcode(OP_EXEC_CMD_METHOD0 + iParamCount, val.node[4].sourcePosValue);
|
||||
}
|
||||
EmitOpcodeValue(iParamCount, sizeof(byte));
|
||||
} else {
|
||||
EmitOpcode(OP_EXEC_CMD_METHOD0 + iParamCount, val.node[4].sourcePosValue);
|
||||
}
|
||||
|
||||
EmitOpcodeValue(eventnum, sizeof(unsigned int));
|
||||
break;
|
||||
EmitOpcodeValue(eventnum, sizeof(unsigned int));
|
||||
break;
|
||||
}
|
||||
|
||||
case ENUM_method_event_expr:
|
||||
{
|
||||
const int eventnum = Event::FindReturnEventNum(val.node[2].stringValue);
|
||||
sval_t parameter_list = val.node[3];
|
||||
const uint32_t iParamCount = EmitParameterList(parameter_list);
|
||||
{
|
||||
const int eventnum = Event::FindReturnEventNum(val.node[2].stringValue);
|
||||
sval_t parameter_list = val.node[3];
|
||||
const uint32_t iParamCount = EmitParameterList(parameter_list);
|
||||
|
||||
if (!eventnum) {
|
||||
CompileError(val.node[4].sourcePosValue, "unknown command: %s", val.node[2].stringValue);
|
||||
}
|
||||
if (!eventnum) {
|
||||
CompileError(val.node[4].sourcePosValue, "unknown command: %s", val.node[2].stringValue);
|
||||
}
|
||||
|
||||
EmitValue(val.node[1]);
|
||||
EmitMethodExpression(iParamCount, eventnum, val.node[4].sourcePosValue);
|
||||
break;
|
||||
}
|
||||
EmitValue(val.node[1]);
|
||||
EmitMethodExpression(iParamCount, eventnum, val.node[4].sourcePosValue);
|
||||
break;
|
||||
}
|
||||
|
||||
case ENUM_const_array_expr:
|
||||
return EmitConstArray(val.node[1], val.node[2], val.node[3].sourcePosValue);
|
||||
|
@ -1408,11 +1399,15 @@ char *ScriptCompiler::Preprocess(char *sourceBuffer)
|
|||
|
||||
void ScriptCompiler::Preclean(char *processedBuffer) {}
|
||||
|
||||
extern int prev_yylex;
|
||||
extern int out_pos;
|
||||
extern int success_pos;
|
||||
extern int prev_yylex;
|
||||
extern int out_pos;
|
||||
extern int success_pos;
|
||||
extern const char *start_ptr;
|
||||
extern const char *in_ptr;
|
||||
extern parseStage_e parseStage;
|
||||
|
||||
void yy_init_script();
|
||||
|
||||
int yyerror(const char *msg)
|
||||
{
|
||||
//parsedata.pos -= yyleng;
|
||||
|
@ -1424,13 +1419,13 @@ int yyerror(const char *msg)
|
|||
|
||||
glbs.Printf("parse error:\n%s:\n", parsedata.exc.yytoken.c_str());
|
||||
|
||||
parsedata.gameScript->PrintSourcePos(parsedata.pos - yyleng, false);
|
||||
parsedata.gameScript->PrintSourcePos(success_pos, false);
|
||||
parsedata.pos++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t ScriptCompiler::Parse(GameScript *gameScript, char *sourceBuffer)
|
||||
size_t ScriptCompiler::Parse(GameScript *gameScript, char *sourceBuffer, const char *type)
|
||||
{
|
||||
parsedata = yyparsedata();
|
||||
|
||||
|
@ -1438,23 +1433,23 @@ size_t ScriptCompiler::Parse(GameScript *gameScript, char *sourceBuffer)
|
|||
parsedata.gameScript = gameScript;
|
||||
parsedata.braces_count = 0;
|
||||
|
||||
start_ptr = sourceBuffer;
|
||||
prev_yylex = 0;
|
||||
out_pos = 0;
|
||||
out_pos = 0;
|
||||
success_pos = 0;
|
||||
parseStage = PS_TYPE;
|
||||
parseStage = PS_TYPE;
|
||||
in_ptr = type;
|
||||
|
||||
script = gameScript;
|
||||
stateScript = &gameScript->m_State;
|
||||
yy_scan_string(sourceBuffer);
|
||||
|
||||
yy_init_script();
|
||||
parsetree_init();
|
||||
|
||||
try {
|
||||
if (yyparse() != 0 || parsedata.exc.yytoken != "") {
|
||||
// an error occured
|
||||
|
||||
yylex_destroy();
|
||||
|
||||
if (!parsedata.exc.yytext) {
|
||||
if (parsedata.braces_count) {
|
||||
glbs.DPrintf("unmatching {} pair\n");
|
||||
|
@ -1463,9 +1458,11 @@ size_t ScriptCompiler::Parse(GameScript *gameScript, char *sourceBuffer)
|
|||
}
|
||||
}
|
||||
|
||||
yylex_destroy();
|
||||
return 0;
|
||||
}
|
||||
} catch (ScriptException& exc) {
|
||||
yylex_destroy();
|
||||
exc;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
class ScriptVariable;
|
||||
|
||||
typedef void (*ScriptDisplayTokenFunc)(const char* type, const char* name);
|
||||
typedef void (*ScriptDisplayTokenFunc)(const char *type, const char *name);
|
||||
|
||||
enum {
|
||||
method_game,
|
||||
|
@ -161,7 +161,7 @@ public:
|
|||
|
||||
char *Preprocess(char *sourceBuffer);
|
||||
void Preclean(char *processedBuffer);
|
||||
size_t Parse(GameScript *m_GameScript, char *sourceBuffer);
|
||||
size_t Parse(GameScript *m_GameScript, char *sourceBuffer, const char *type);
|
||||
size_t Compile(GameScript *m_GameScript, unsigned char *progBuffer);
|
||||
|
||||
static str GetLine(str content, int line);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue