From: Charlie Brej Date: Mon, 22 Jun 2009 15:48:46 +0000 (+0100) Subject: [script] Add support for unary operations (!/+/-/++/--) X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e48fa36ef6f43fd7095d1592f36c5a22002e858f;p=thirdparty%2Fplymouth.git [script] Add support for unary operations (!/+/-/++/--) Allows execution of unary operations: Pre/postfix inc/decrement, logical negation and unary plus/minus. The writebacks of increment/decrements happen during the execution of the expression, unlike C where they are executed after the line if executed. This is the case simply because it is simpler to execute this way. --- diff --git a/src/plugins/splash/script/script-execute.c b/src/plugins/splash/script/script-execute.c index 9f8524ed..46c0c198 100644 --- a/src/plugins/splash/script/script-execute.c +++ b/src/plugins/splash/script/script-execute.c @@ -9,12 +9,12 @@ #include #include #include +#include #include "script.h" #include "script-execute.h" #include "script-object.h" - static script_obj* script_evaluate (script_state* state, script_exp* exp); static script_obj* script_evaluate_plus (script_state* state, script_exp* exp) @@ -392,7 +392,6 @@ static script_obj* script_evaluate_assign (script_state* state, script_exp* exp) 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_deref (&script_obj_b); - script_obj_reset (script_obj_a); script_obj_assign (script_obj_a, script_obj_b); script_obj_unref(script_obj_b); @@ -515,6 +514,10 @@ static script_obj* script_evaluate_cmp (script_state* state, script_exp* exp) } break; } + case SCRIPT_OBJ_TYPE_REF: + { + assert(0); + } } if(valset){ if (val < 0) {lt = 1; ne = 1;} @@ -565,6 +568,62 @@ static script_obj* script_evaluate_logic (script_state* state, script_exp* exp) return obj; } +static script_obj* script_evaluate_unary (script_state* state, script_exp* exp) +{ + script_obj* obj = script_evaluate (state, exp->data.sub); + script_obj* new_obj; + script_obj_deref (&obj); + if (exp->type == SCRIPT_EXP_TYPE_NOT){ + int reply = !script_obj_as_bool(obj); + script_obj_unref (obj); + return script_obj_new_int (reply); + } + if (exp->type == SCRIPT_EXP_TYPE_POS){ // FIXME what should happen on non number operands? + return obj; // Does nothing, maybe just remove at parse stage + } + if (exp->type == SCRIPT_EXP_TYPE_NEG){ + if (obj->type == SCRIPT_OBJ_TYPE_INT){ + new_obj = script_obj_new_int (-obj->data.integer); + } + else if (obj->type == SCRIPT_OBJ_TYPE_FLOAT){ + new_obj = script_obj_new_float (-obj->data.floatpoint); + } + else new_obj = script_obj_new_null (); + script_obj_unref (obj); + return new_obj; + } + + + int change_pre = 0; + int change_post; + + if (exp->type == SCRIPT_EXP_TYPE_PRE_INC || SCRIPT_EXP_TYPE_POST_INC) + change_post = 1; + else + change_post = -1; + + if (exp->type == SCRIPT_EXP_TYPE_PRE_INC) + change_pre = 1; + else if (exp->type == SCRIPT_EXP_TYPE_PRE_DEC) + change_pre = -1; + + if (obj->type == SCRIPT_OBJ_TYPE_INT){ + new_obj = script_obj_new_int (obj->data.integer + change_pre); + obj->data.integer += change_post; + } + else if (obj->type == SCRIPT_OBJ_TYPE_FLOAT){ + new_obj = script_obj_new_float (obj->data.floatpoint + change_pre); + obj->data.floatpoint += change_post; + } + else { + new_obj = script_obj_new_null (); // If performeing something like a=hash++; a and hash become NULL + script_obj_reset (obj); + } + + script_obj_unref (obj); + return new_obj; +} + static script_obj* script_evaluate_func (script_state* state, script_exp* exp) { script_state localstate; @@ -664,6 +723,16 @@ static script_obj* script_evaluate (script_state* state, script_exp* exp) { return script_evaluate_logic (state, exp); } + case SCRIPT_EXP_TYPE_NOT: + case SCRIPT_EXP_TYPE_POS: + case SCRIPT_EXP_TYPE_NEG: + case SCRIPT_EXP_TYPE_PRE_INC: + case SCRIPT_EXP_TYPE_PRE_DEC: + case SCRIPT_EXP_TYPE_POST_INC: + case SCRIPT_EXP_TYPE_POST_DEC: + { + return script_evaluate_unary (state, exp); + } case SCRIPT_EXP_TYPE_TERM_INT: { return script_obj_new_int (exp->data.integer); diff --git a/src/plugins/splash/script/script-parse.c b/src/plugins/splash/script/script-parse.c index be45fc93..2c8824da 100644 --- a/src/plugins/splash/script/script-parse.c +++ b/src/plugins/splash/script/script-parse.c @@ -21,14 +21,16 @@ /* done todo -int var (exp) tm = ! ++ -- -f() f[] f.a pi = +int var (exp) tm = +f() f[] f.a pi = +pre: ! ++ -- + - pr = +post: ++ -- po = * / % md = + - pm = < <= > >= gt = == != eq = -&& an -|| or +&& an = +|| or = = as = += -= *= %= */ @@ -166,11 +168,88 @@ static script_exp* script_parse_exp_pi (ply_scan_t* scan) } +static script_exp* script_parse_exp_pr (ply_scan_t* scan) +{ + script_exp_type type; + ply_scan_token_t* curtoken = ply_scan_get_current_token(scan); + ply_scan_token_t* peektoken = ply_scan_peek_next_token(scan); + + if (curtoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL){ + if (curtoken->data.symbol == '+'){ + if (peektoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL && peektoken->data.symbol == '+'){ + ply_scan_get_next_token(scan); + ply_scan_get_next_token(scan); + type = SCRIPT_EXP_TYPE_PRE_INC; + } + else { + ply_scan_get_next_token(scan); + type = SCRIPT_EXP_TYPE_POS; + } + } + else if (curtoken->data.symbol == '-'){ + if (peektoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL && peektoken->data.symbol == '-'){ + ply_scan_get_next_token(scan); + ply_scan_get_next_token(scan); + type = SCRIPT_EXP_TYPE_PRE_DEC; + } + else { + ply_scan_get_next_token(scan); + type = SCRIPT_EXP_TYPE_NEG; + } + } + else if (curtoken->data.symbol == '!'){ + ply_scan_get_next_token(scan); + type = SCRIPT_EXP_TYPE_NOT; + } + else { + return script_parse_exp_pi (scan); + } + script_exp* exp = malloc(sizeof(script_exp)); + exp->type = type; + exp->data.sub = script_parse_exp_pr (scan); + return exp; + } + return script_parse_exp_pi (scan); +} + + + +static script_exp* script_parse_exp_po (ply_scan_t* scan) +{ + script_exp* exp = script_parse_exp_pr (scan); + + while (true){ + ply_scan_token_t* curtoken = ply_scan_get_current_token(scan); + ply_scan_token_t* peektoken = ply_scan_peek_next_token(scan); + if (curtoken->type != PLY_SCAN_TOKEN_TYPE_SYMBOL) break; + if (peektoken->type != PLY_SCAN_TOKEN_TYPE_SYMBOL) break; + if (curtoken->data.symbol == '+' && peektoken->data.symbol == '+') { + ply_scan_get_next_token(scan); + ply_scan_get_next_token(scan); + script_exp* new_exp = malloc(sizeof(script_exp)); + new_exp->type = SCRIPT_EXP_TYPE_POST_INC; + new_exp->data.sub = exp; + exp = new_exp; + } + else if (curtoken->data.symbol == '-' && peektoken->data.symbol == '-') { + ply_scan_get_next_token(scan); + ply_scan_get_next_token(scan); + script_exp* new_exp = malloc(sizeof(script_exp)); + new_exp->type = SCRIPT_EXP_TYPE_POST_DEC; + new_exp->data.sub = exp; + exp = new_exp; + } + else break; + } + + return exp; +} + static script_exp* script_parse_exp_md (ply_scan_t* scan) { - script_exp* sub_a = script_parse_exp_pi (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); while (curtoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL && @@ -183,7 +262,7 @@ static script_exp* script_parse_exp_md (ply_scan_t* scan) else exp->type = SCRIPT_EXP_TYPE_MOD; exp->data.dual.sub_a = sub_a; ply_scan_get_next_token(scan); - exp->data.dual.sub_b = script_parse_exp_pi (scan); + exp->data.dual.sub_b = script_parse_exp_po (scan); assert(exp->data.dual.sub_b); //FIXME syntax error sub_a = exp; curtoken = ply_scan_get_current_token(scan); @@ -576,6 +655,15 @@ static void script_parse_exp_free (script_exp* exp) script_parse_exp_free (exp->data.dual.sub_a); script_parse_exp_free (exp->data.dual.sub_b); break; + case SCRIPT_EXP_TYPE_NOT: + case SCRIPT_EXP_TYPE_POS: + case SCRIPT_EXP_TYPE_NEG: + case SCRIPT_EXP_TYPE_PRE_INC: + case SCRIPT_EXP_TYPE_PRE_DEC: + case SCRIPT_EXP_TYPE_POST_INC: + case SCRIPT_EXP_TYPE_POST_DEC: + script_parse_exp_free (exp->data.sub); + break; case SCRIPT_EXP_TYPE_TERM_INT: case SCRIPT_EXP_TYPE_TERM_FLOAT: case SCRIPT_EXP_TYPE_TERM_NULL: diff --git a/src/plugins/splash/script/script.h b/src/plugins/splash/script/script.h index 562ca9a0..c26d6453 100644 --- a/src/plugins/splash/script/script.h +++ b/src/plugins/splash/script/script.h @@ -120,6 +120,13 @@ typedef enum SCRIPT_EXP_TYPE_NE, SCRIPT_EXP_TYPE_AND, SCRIPT_EXP_TYPE_OR, + SCRIPT_EXP_TYPE_NOT, + SCRIPT_EXP_TYPE_POS, + SCRIPT_EXP_TYPE_NEG, + SCRIPT_EXP_TYPE_PRE_INC, + SCRIPT_EXP_TYPE_PRE_DEC, + SCRIPT_EXP_TYPE_POST_INC, + SCRIPT_EXP_TYPE_POST_DEC, SCRIPT_EXP_TYPE_HASH, SCRIPT_EXP_TYPE_FUNCTION, SCRIPT_EXP_TYPE_ASSIGN, diff --git a/themes/script/script.script b/themes/script/script.script index 3db6e150..60ca573d 100644 --- a/themes/script/script.script +++ b/themes/script/script.script @@ -16,13 +16,13 @@ fun update_logo_sprite (sprite){ image_height = ImageGetHeight(sprite.image); if (sprite.x < 0) - sprite.xd = global.random % 5 + 1; + sprite.xd = +(global.random % 5 + 1)/0.5; if (sprite.y < 0) - sprite.yd = global.random % 5 + 1; + sprite.yd = +(global.random % 5 + 1)/0.5; if ((sprite.x + image_width) > 800) - sprite.xd = 0 - (global.random % 5 + 1); + sprite.xd = -((global.random % 5 + 1)/0.5); if ((sprite.y + image_height) > 600) - sprite.yd = 0 - (global.random % 5 + 1); + sprite.yd = -((global.random % 5 + 1)/0.5); global.random = (1 + global.random * 7) % 101; @@ -35,9 +35,9 @@ fun update_logo_sprite (sprite){ fun refresh (){ index = 0; - while (index<30){ + while (!(index>=30)){ update_logo_sprite (sprites[index]); - index = index + 1; + index++; } return; }