Major grammar/lexer/compiler fixes

This commit is contained in:
smallmodel 2023-08-13 03:33:50 +02:00
parent d2b3f6c12b
commit 5e83e03e33
No known key found for this signature in database
GPG key ID: A96F163ED4891440
11 changed files with 1385 additions and 1105 deletions

View file

@ -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 )

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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 {

View file

@ -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)
{

View file

@ -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;
}

View file

@ -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);