510 lines
14 KiB
Plaintext
510 lines
14 KiB
Plaintext
|
#include "fcb_inc_prot"
|
||
|
|
||
|
//==========================================/
|
||
|
int get_char_valid_num(string s)
|
||
|
//==========================================/
|
||
|
{
|
||
|
string valid = "0123456789";
|
||
|
|
||
|
return FindSubString(valid, s) + 1;
|
||
|
}
|
||
|
|
||
|
//==========================================/
|
||
|
int get_char_valid_letter(string s)
|
||
|
//==========================================/
|
||
|
{
|
||
|
string valid = "abcdefghijklmnopqrstuvwxyz_";
|
||
|
|
||
|
return FindSubString(valid, s) + 1;
|
||
|
}
|
||
|
|
||
|
//==========================================/
|
||
|
int get_char_valid_name(string s)
|
||
|
//==========================================/
|
||
|
{
|
||
|
string valid = "abcdefghijklmnopqrstuvwxyz_0123456789";
|
||
|
|
||
|
return FindSubString(valid, s) + 1;
|
||
|
}
|
||
|
|
||
|
//==========================================/
|
||
|
int get_is_number(string num)
|
||
|
//==========================================/
|
||
|
{
|
||
|
return (num == IntToString(StringToInt(num)));
|
||
|
}
|
||
|
|
||
|
//==========================================/
|
||
|
void store_arg(string function_arg, int exe_index)
|
||
|
//==========================================/
|
||
|
{
|
||
|
int args_index = GetLocalInt(FCB_HOST, CMD_ARGS_INDEX_ + IntToHexString(exe_index)) + 1;
|
||
|
SetLocalInt(FCB_HOST, CMD_ARGS_INDEX_ + IntToHexString(exe_index), args_index);
|
||
|
|
||
|
SetLocalString(FCB_HOST, CMD_ARGS_ + IntToHexString(exe_index | args_index), function_arg);
|
||
|
}
|
||
|
|
||
|
//==========================================/
|
||
|
string retrieve_arg(int args_index)
|
||
|
//==========================================/
|
||
|
{
|
||
|
int exe_index = GetLocalInt(FCB_HOST, CMD_EXE_REF_INDEX);
|
||
|
|
||
|
int args_index_max = GetLocalInt(FCB_HOST, CMD_ARGS_INDEX_ + IntToHexString(exe_index));
|
||
|
if(args_index_max >= args_index)
|
||
|
{
|
||
|
return GetLocalString(FCB_HOST, CMD_ARGS_ + IntToHexString(exe_index | args_index));
|
||
|
}
|
||
|
|
||
|
return CMD_ERROR_STRING;
|
||
|
}
|
||
|
|
||
|
//==========================================/
|
||
|
void set_function_result(string result)
|
||
|
//==========================================/
|
||
|
{
|
||
|
int exe_index = GetLocalInt(FCB_HOST, CMD_EXE_REF_INDEX);
|
||
|
|
||
|
SetLocalString(FCB_HOST, CMD_FUNCTION_RESULT_ + IntToHexString(exe_index), result);
|
||
|
}
|
||
|
|
||
|
//==========================================/
|
||
|
string get_function_result(int exe_index)
|
||
|
//==========================================/
|
||
|
{
|
||
|
return GetLocalString(FCB_HOST, CMD_FUNCTION_RESULT_ + IntToHexString(exe_index));
|
||
|
}
|
||
|
|
||
|
//==========================================/
|
||
|
void set_function_result_valid()
|
||
|
//==========================================/
|
||
|
{
|
||
|
int exe_index = GetLocalInt(FCB_HOST, CMD_EXE_REF_INDEX);
|
||
|
|
||
|
SetLocalInt(FCB_HOST, CMD_FUNCTION_RESP_VALID_ + IntToHexString(exe_index), CMD_VALID_BIT);
|
||
|
}
|
||
|
|
||
|
//==========================================/
|
||
|
int get_function_result_valid(int exe_index)
|
||
|
//==========================================/
|
||
|
{
|
||
|
int valid = CMD_VALID_BIT & GetLocalInt(FCB_HOST, CMD_FUNCTION_RESP_VALID_ + IntToHexString(exe_index));
|
||
|
DeleteLocalInt(FCB_HOST, CMD_FUNCTION_RESP_VALID_ + IntToHexString(exe_index));
|
||
|
|
||
|
return valid;
|
||
|
}
|
||
|
|
||
|
//==========================================/
|
||
|
string parse_init(string input)
|
||
|
//==========================================/
|
||
|
{
|
||
|
object user = GetLocalObject(FCB_HOST, USER);
|
||
|
|
||
|
int parse_state = INPUT_PARSE_STATE_INIT;
|
||
|
|
||
|
int cmd_str_len = GetStringLength(input);
|
||
|
int cmd_str_pos = 0;
|
||
|
|
||
|
//kill end spaces
|
||
|
string s = GetSubString(input, cmd_str_len-1, 1);
|
||
|
while(cmd_str_len >= 0 && s == CMD_TXT_SPACE)
|
||
|
{
|
||
|
cmd_str_len--;
|
||
|
s = GetSubString(input, cmd_str_len-1, 1);
|
||
|
}
|
||
|
|
||
|
s = GetSubString(input, cmd_str_pos, 1);
|
||
|
while(cmd_str_pos <= cmd_str_len)
|
||
|
{
|
||
|
switch(parse_state)
|
||
|
{
|
||
|
//--------------------------------------/
|
||
|
case INPUT_PARSE_STATE_INIT:
|
||
|
{
|
||
|
if(s == CMD_TXT_CMDSTART)
|
||
|
{
|
||
|
parse_state = INPUT_PARSE_STATE_CMD;
|
||
|
}
|
||
|
|
||
|
else if(s != CMD_TXT_SPACE)
|
||
|
{
|
||
|
return input;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------/
|
||
|
case INPUT_PARSE_STATE_CMD:
|
||
|
{
|
||
|
DeleteLocalInt(FCB_HOST, CMD_EXE_INDEX);
|
||
|
string parsed_cmd = parse_var(GetStringRight(input, cmd_str_len - cmd_str_pos), user);
|
||
|
|
||
|
SendMessageToPC(user, parsed_cmd);
|
||
|
return parsed_cmd;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
cmd_str_pos++;
|
||
|
s = GetSubString(input, cmd_str_pos, 1);
|
||
|
}
|
||
|
|
||
|
return input;
|
||
|
}
|
||
|
|
||
|
//==========================================/
|
||
|
string parse_var(string cmd, object user)
|
||
|
//==========================================/
|
||
|
{
|
||
|
string CMD_TXT_QUOTE = GetLocalString(FCB_HOST, CMD_QUOTE);
|
||
|
|
||
|
string arg = "";
|
||
|
|
||
|
int bracket_cnt = 0;
|
||
|
|
||
|
int parse_state = VAR_PARSE_STATE_INIT;
|
||
|
|
||
|
int cmd_str_len = GetStringLength(cmd);
|
||
|
int cmd_str_pos = 0;
|
||
|
|
||
|
//kill end spaces
|
||
|
string s = GetSubString(cmd, cmd_str_len-1, 1);
|
||
|
while(cmd_str_len >= 0 && s == CMD_TXT_SPACE)
|
||
|
{
|
||
|
cmd_str_len--;
|
||
|
s = GetSubString(cmd, cmd_str_len-1, 1);
|
||
|
}
|
||
|
|
||
|
//begin
|
||
|
//begin
|
||
|
s = GetSubString(cmd, cmd_str_pos, 1);
|
||
|
while(cmd_str_pos <= cmd_str_len)
|
||
|
{
|
||
|
//--------------------------------------/
|
||
|
if(s == CMD_TXT_BRACKET_START)
|
||
|
{
|
||
|
bracket_cnt++;
|
||
|
}
|
||
|
else if(s == CMD_TXT_BRACKET_END)
|
||
|
{
|
||
|
bracket_cnt--;
|
||
|
}
|
||
|
if(bracket_cnt < 0)
|
||
|
{
|
||
|
parse_state = VAR_PARSE_STATE_ERROR;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------/
|
||
|
switch(parse_state)
|
||
|
{
|
||
|
//--------------------------------------/
|
||
|
case VAR_PARSE_STATE_INIT:
|
||
|
{
|
||
|
if(s == CMD_TXT_QUOTE)
|
||
|
{
|
||
|
parse_state = VAR_PARSE_STATE_STRING;
|
||
|
}
|
||
|
|
||
|
else if(get_char_valid_letter(s))
|
||
|
{
|
||
|
arg += s;
|
||
|
|
||
|
parse_state = VAR_PARSE_STATE_FUNCTION;
|
||
|
}
|
||
|
|
||
|
else if(get_char_valid_num(s))
|
||
|
{
|
||
|
arg += s;
|
||
|
|
||
|
if(cmd_str_pos == cmd_str_len-1)
|
||
|
{
|
||
|
return arg;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
parse_state = VAR_PARSE_STATE_NUM;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else if(s != CMD_TXT_SPACE)
|
||
|
{
|
||
|
parse_state = VAR_PARSE_STATE_ERROR;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------/
|
||
|
case VAR_PARSE_STATE_STRING:
|
||
|
{
|
||
|
if(s == CMD_TXT_QUOTE)
|
||
|
{
|
||
|
if(cmd_str_pos == cmd_str_len-1)
|
||
|
{
|
||
|
return arg;
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
parse_state = VAR_PARSE_STATE_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
arg += s;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------/
|
||
|
case VAR_PARSE_STATE_FUNCTION:
|
||
|
{
|
||
|
if(s == CMD_TXT_BRACKET_START)
|
||
|
{
|
||
|
return parse_function_arg(arg, GetStringRight(cmd, cmd_str_len - cmd_str_pos-1), user);
|
||
|
}
|
||
|
|
||
|
else if(get_char_valid_name(s))
|
||
|
{
|
||
|
arg += s;
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
parse_state = VAR_PARSE_STATE_ERROR;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------/
|
||
|
case VAR_PARSE_STATE_NUM:
|
||
|
{
|
||
|
if(get_char_valid_num(s))
|
||
|
{
|
||
|
arg += s;
|
||
|
|
||
|
if(cmd_str_pos == cmd_str_len-1)
|
||
|
{
|
||
|
return arg;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
parse_state = VAR_PARSE_STATE_ERROR;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------/
|
||
|
case VAR_PARSE_STATE_ERROR:
|
||
|
{
|
||
|
SendMessageToPC(user, "var: " + CMD_ERROR_MSG);
|
||
|
return CMD_ERROR_STRING;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
cmd_str_pos++;
|
||
|
s = GetSubString(cmd, cmd_str_pos, 1);
|
||
|
}
|
||
|
|
||
|
////
|
||
|
SendMessageToPC(user, "var: " + CMD_ERROR_MSG);
|
||
|
return CMD_ERROR_STRING;
|
||
|
}
|
||
|
|
||
|
//==========================================/
|
||
|
string parse_function_arg(string function_name, string cmd, object user)
|
||
|
//==========================================/
|
||
|
{
|
||
|
string CMD_TXT_QUOTE = GetLocalString(FCB_HOST, CMD_QUOTE);
|
||
|
//function_name( a, b, c, d, ...)
|
||
|
//**************X <- begin here
|
||
|
|
||
|
int exe_index = GetLocalInt(FCB_HOST, CMD_EXE_INDEX) + INCR_F10;
|
||
|
SetLocalInt(FCB_HOST, CMD_EXE_INDEX, exe_index);
|
||
|
|
||
|
string function_arg = "";
|
||
|
|
||
|
int bracket_cnt = 1;
|
||
|
int quote_state = 0;
|
||
|
|
||
|
int parse_state = CMD_PARSE_STATE_INIT;
|
||
|
|
||
|
int cmd_str_len = GetStringLength(cmd);
|
||
|
int cmd_str_pos = 0;
|
||
|
|
||
|
//kill end spaces
|
||
|
string s = GetSubString(cmd, cmd_str_len-1, 1);
|
||
|
while(cmd_str_len >= 0 && s == CMD_TXT_SPACE)
|
||
|
{
|
||
|
cmd_str_len--;
|
||
|
s = GetSubString(cmd, cmd_str_len-1, 1);
|
||
|
}
|
||
|
|
||
|
//begin
|
||
|
s = GetSubString(cmd, cmd_str_pos, 1);
|
||
|
while(cmd_str_pos <= cmd_str_len)
|
||
|
{
|
||
|
//--------------------------------------/
|
||
|
if(s == CMD_TXT_BRACKET_START)
|
||
|
{
|
||
|
bracket_cnt++;
|
||
|
}
|
||
|
else if(s == CMD_TXT_BRACKET_END)
|
||
|
{
|
||
|
bracket_cnt--;
|
||
|
}
|
||
|
if(bracket_cnt < 0)
|
||
|
{
|
||
|
parse_state = CMD_PARSE_STATE_ERROR;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------/
|
||
|
if(s == CMD_TXT_QUOTE)
|
||
|
{
|
||
|
quote_state = !quote_state;
|
||
|
}
|
||
|
|
||
|
/////
|
||
|
//SpeakString("state: " + IntToString(parse_state));
|
||
|
//SpeakString("arg: " + function_arg);
|
||
|
|
||
|
//--------------------------------------/
|
||
|
switch(parse_state)
|
||
|
{
|
||
|
//--------------------------------------/
|
||
|
case CMD_PARSE_STATE_INIT:
|
||
|
{
|
||
|
if(s == CMD_TXT_BRACKET_END)
|
||
|
{
|
||
|
if(cmd_str_pos == cmd_str_len-1)
|
||
|
{
|
||
|
parse_state = CMD_PARSE_STATE_END;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
parse_state = CMD_PARSE_STATE_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else if(s != CMD_TXT_SPACE)
|
||
|
{
|
||
|
function_arg += s;
|
||
|
|
||
|
parse_state = CMD_PARSE_STATE_ARG;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------/
|
||
|
case CMD_PARSE_STATE_ARG:
|
||
|
{
|
||
|
if(s == CMD_TXT_COMMA && bracket_cnt == 1 && !quote_state)
|
||
|
{
|
||
|
if(function_arg != CMD_TXT_BLANK)
|
||
|
{
|
||
|
string arg = parse_var(function_arg, user);
|
||
|
|
||
|
if(arg != CMD_ERROR_STRING)
|
||
|
{
|
||
|
store_arg(arg, exe_index);
|
||
|
function_arg = CMD_TXT_BLANK;
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
parse_state = CMD_PARSE_STATE_ERROR;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
parse_state = CMD_PARSE_STATE_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else if(s == CMD_TXT_BRACKET_END && bracket_cnt == 0 && !quote_state)
|
||
|
{
|
||
|
if(function_arg != CMD_TXT_BLANK)
|
||
|
{
|
||
|
string arg = parse_var(function_arg, user);
|
||
|
|
||
|
if(arg != CMD_ERROR_STRING)
|
||
|
{
|
||
|
store_arg(arg, exe_index);
|
||
|
|
||
|
if(cmd_str_pos == cmd_str_len-1)
|
||
|
{
|
||
|
parse_state = CMD_PARSE_STATE_END;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
parse_state = CMD_PARSE_STATE_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
parse_state = CMD_PARSE_STATE_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
parse_state = CMD_PARSE_STATE_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
function_arg += s;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------/
|
||
|
case CMD_PARSE_STATE_END:
|
||
|
{
|
||
|
SetLocalInt(FCB_HOST, CMD_EXE_REF_INDEX, exe_index);
|
||
|
ExecuteScript(CMD_SCRIPT_PREFIX + function_name, FCB_HOST);
|
||
|
|
||
|
DeleteLocalInt(FCB_HOST, CMD_EXE_REF_INDEX);
|
||
|
DeleteLocalInt(FCB_HOST, CMD_ARGS_INDEX_ + IntToHexString(exe_index));
|
||
|
|
||
|
if(get_function_result_valid(exe_index))
|
||
|
{
|
||
|
return get_function_result(exe_index);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------/
|
||
|
case CMD_PARSE_STATE_ERROR:
|
||
|
{
|
||
|
SendMessageToPC(user, "function: " + CMD_ERROR_MSG);
|
||
|
|
||
|
DeleteLocalInt(FCB_HOST, CMD_ARGS_INDEX_ + IntToHexString(exe_index));
|
||
|
return CMD_ERROR_STRING;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
cmd_str_pos++;
|
||
|
s = GetSubString(cmd, cmd_str_pos, 1);
|
||
|
}
|
||
|
|
||
|
////
|
||
|
SendMessageToPC(user, "function: " + CMD_ERROR_MSG);
|
||
|
|
||
|
DeleteLocalInt(FCB_HOST, CMD_ARGS_INDEX_ + IntToHexString(exe_index));
|
||
|
return CMD_ERROR_STRING;
|
||
|
}
|