[script] Add modify assignments (+=, *= ...)

Adds the following modify assignments: +=, -=, *=, /=, %=
This commit is contained in:
Charlie Brej 2009-07-01 16:13:13 +01:00 committed by Ray Strode
parent a99a8a27c9
commit 4a82c35e4a
3 changed files with 89 additions and 6 deletions

View file

@ -29,6 +29,17 @@ static script_obj* script_evaluate_apply_function (script_state* state, script_e
return obj;
}
static script_obj* script_evaluate_apply_function_and_assign (script_state* state, script_exp* exp, script_obj* (*function) (script_obj*, script_obj*))
{
script_obj* script_obj_a = script_evaluate (state, exp->data.dual.sub_a);
script_obj* script_obj_b = script_evaluate (state, exp->data.dual.sub_b);
script_obj* obj = function (script_obj_a, script_obj_b);
script_obj_assign (script_obj_a, obj);
script_obj_unref (script_obj_a);
script_obj_unref (script_obj_b);
return obj;
}
static script_obj* script_evaluate_hash (script_state* state, script_exp* exp)
{
script_obj* hash = script_evaluate (state, exp->data.dual.sub_a);
@ -458,6 +469,26 @@ static script_obj* script_evaluate (script_state* state, script_exp* exp)
{
return script_evaluate_assign (state, exp);
}
case SCRIPT_EXP_TYPE_ASSIGN_PLUS:
{
return script_evaluate_apply_function_and_assign (state, exp, script_obj_plus);
}
case SCRIPT_EXP_TYPE_ASSIGN_MINUS:
{
return script_evaluate_apply_function_and_assign (state, exp, script_obj_minus);
}
case SCRIPT_EXP_TYPE_ASSIGN_MUL:
{
return script_evaluate_apply_function_and_assign (state, exp, script_obj_mul);
}
case SCRIPT_EXP_TYPE_ASSIGN_DIV:
{
return script_evaluate_apply_function_and_assign (state, exp, script_obj_div);
}
case SCRIPT_EXP_TYPE_ASSIGN_MOD:
{
return script_evaluate_apply_function_and_assign (state, exp, script_obj_mod);
}
case SCRIPT_EXP_TYPE_HASH:
{
return script_evaluate_hash (state, exp);

View file

@ -32,7 +32,7 @@ post: ++ -- po =
== != eq =
&& an =
|| or =
= as = += -= *= %=
= as = += -= *= %= /=
*/
@ -277,10 +277,13 @@ static script_exp* script_parse_exp_md (ply_scan_t* scan)
script_exp* sub_a = script_parse_exp_po (scan);
if (!sub_a) return NULL;
ply_scan_token_t* curtoken = ply_scan_get_current_token(scan);
ply_scan_token_t* peektoken = ply_scan_peek_next_token(scan);
while (curtoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL &&
(curtoken->data.symbol == '*' ||
curtoken->data.symbol == '/' ||
curtoken->data.symbol == '%' )){
curtoken->data.symbol == '%' ) &&
!(peektoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL &&
peektoken->data.symbol == '=' )){
script_exp* exp = malloc(sizeof(script_exp));
if (curtoken->data.symbol == '*') exp->type = SCRIPT_EXP_TYPE_MUL;
else if (curtoken->data.symbol == '/') exp->type = SCRIPT_EXP_TYPE_DIV;
@ -290,6 +293,7 @@ static script_exp* script_parse_exp_md (ply_scan_t* scan)
sub_a = exp;
exp->data.dual.sub_b = script_parse_exp_po (scan);
curtoken = ply_scan_get_current_token(scan);
peektoken = ply_scan_peek_next_token(scan);
if (!exp->data.dual.sub_b){
script_parse_error (curtoken, "An invalid RHS of an expression");
return NULL;
@ -304,9 +308,12 @@ static script_exp* script_parse_exp_pm (ply_scan_t* scan)
script_exp* sub_a = script_parse_exp_md (scan);
if (!sub_a) return NULL;
ply_scan_token_t* curtoken = ply_scan_get_current_token(scan);
ply_scan_token_t* peektoken = ply_scan_peek_next_token(scan);
while (curtoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL &&
(curtoken->data.symbol == '+' ||
curtoken->data.symbol == '-' )){
curtoken->data.symbol == '-' ) &&
!(peektoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL &&
peektoken->data.symbol == '=' )){
script_exp* exp = malloc(sizeof(script_exp));
if (curtoken->data.symbol == '+') exp->type = SCRIPT_EXP_TYPE_PLUS;
else exp->type = SCRIPT_EXP_TYPE_MINUS;
@ -315,6 +322,7 @@ static script_exp* script_parse_exp_pm (ply_scan_t* scan)
exp->data.dual.sub_b = script_parse_exp_md (scan);
sub_a = exp;
curtoken = ply_scan_get_current_token(scan);
peektoken = ply_scan_peek_next_token(scan);
if (!exp->data.dual.sub_b){
script_parse_error (curtoken, "An invalid RHS of an expression");
return NULL;
@ -462,16 +470,50 @@ static script_exp* script_parse_exp_as (ply_scan_t* scan)
script_exp* lhs = script_parse_exp_or (scan);
if (!lhs) return NULL;
ply_scan_token_t* curtoken = ply_scan_get_current_token(scan);
ply_scan_token_t* peektoken = ply_scan_peek_next_token(scan);
bool modify_assign;
if (curtoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL && curtoken->data.symbol == '=' ){
modify_assign = !peektoken->whitespace &&
curtoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL &&
peektoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL &&
peektoken->data.symbol == '=';
if (modify_assign || (curtoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL && curtoken->data.symbol == '=')){
script_exp_type type;
if (modify_assign) {
switch (curtoken->data.symbol){
case '+':
type = SCRIPT_EXP_TYPE_ASSIGN_PLUS;
break;
case '-':
type = SCRIPT_EXP_TYPE_ASSIGN_MINUS;
break;
case '*':
type = SCRIPT_EXP_TYPE_ASSIGN_MUL;
break;
case '/':
type = SCRIPT_EXP_TYPE_ASSIGN_DIV;
break;
case '%':
type = SCRIPT_EXP_TYPE_ASSIGN_MOD;
break;
default:
script_parse_error (ply_scan_get_current_token(scan), "An invalid modify assign character");
return NULL;
}
ply_scan_get_next_token(scan);
}
else
type = SCRIPT_EXP_TYPE_ASSIGN;
ply_scan_get_next_token(scan);
script_exp* rhs = script_parse_exp_or(scan);
script_exp* rhs = script_parse_exp_as(scan);
if (!rhs){
script_parse_error (ply_scan_get_current_token(scan), "An invalid RHS of an expression");
return NULL;
}
script_exp* exp = malloc(sizeof(script_exp));
exp->type = SCRIPT_EXP_TYPE_ASSIGN;
exp->type = type;
exp->data.dual.sub_a = lhs;
exp->data.dual.sub_b = rhs;
return exp;
@ -824,6 +866,11 @@ static void script_parse_exp_free (script_exp* exp)
case SCRIPT_EXP_TYPE_AND:
case SCRIPT_EXP_TYPE_OR:
case SCRIPT_EXP_TYPE_ASSIGN:
case SCRIPT_EXP_TYPE_ASSIGN_PLUS:
case SCRIPT_EXP_TYPE_ASSIGN_MINUS:
case SCRIPT_EXP_TYPE_ASSIGN_MUL:
case SCRIPT_EXP_TYPE_ASSIGN_DIV:
case SCRIPT_EXP_TYPE_ASSIGN_MOD:
case SCRIPT_EXP_TYPE_HASH:
script_parse_exp_free (exp->data.dual.sub_a);
script_parse_exp_free (exp->data.dual.sub_b);

View file

@ -130,6 +130,11 @@ typedef enum
SCRIPT_EXP_TYPE_HASH,
SCRIPT_EXP_TYPE_FUNCTION,
SCRIPT_EXP_TYPE_ASSIGN,
SCRIPT_EXP_TYPE_ASSIGN_PLUS,
SCRIPT_EXP_TYPE_ASSIGN_MINUS,
SCRIPT_EXP_TYPE_ASSIGN_MUL,
SCRIPT_EXP_TYPE_ASSIGN_DIV,
SCRIPT_EXP_TYPE_ASSIGN_MOD,
} script_exp_type;