From: Charlie Brej Date: Thu, 18 Jun 2009 16:27:32 +0000 (+0100) Subject: [script] Add support for logical AND and OR X-Git-Tag: 0.7.0~154 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cf8c99c38fec4ccbdbe5977cb80f49da2045850b;p=thirdparty%2Fplymouth.git [script] Add support for logical AND and OR Allows the use of "&&" and "||". These are evaluated lazily and return the evaluated sub-value which completed the operation rather than a bool. It allows things like: reply = cache_lookup(index) || slow_lookup(index); If cache_lookup returns a false value (NULL, or 0) then slow_lookup is executed and its result is placed in reply. Otherwise the result from cache_lookup is used. --- diff --git a/src/plugins/splash/script/script-execute.c b/src/plugins/splash/script/script-execute.c index c65d97be..9f8524ed 100644 --- a/src/plugins/splash/script/script-execute.c +++ b/src/plugins/splash/script/script-execute.c @@ -553,6 +553,18 @@ static script_obj* script_evaluate_cmp (script_state* state, script_exp* exp) return script_obj_new_int (reply); } +static script_obj* script_evaluate_logic (script_state* state, script_exp* exp) +{ + script_obj* obj = script_evaluate (state, exp->data.dual.sub_a); + if (exp->type == SCRIPT_EXP_TYPE_AND && !script_obj_as_bool(obj)) + return obj; + else if (exp->type == SCRIPT_EXP_TYPE_OR &&script_obj_as_bool(obj)) + return obj; + script_obj_unref (obj); + obj = script_evaluate (state, exp->data.dual.sub_b); + return obj; +} + static script_obj* script_evaluate_func (script_state* state, script_exp* exp) { script_state localstate; @@ -647,6 +659,11 @@ static script_obj* script_evaluate (script_state* state, script_exp* exp) { return script_evaluate_cmp (state, exp); } + case SCRIPT_EXP_TYPE_AND: + case SCRIPT_EXP_TYPE_OR: + { + return script_evaluate_logic (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 f542ed5b..be45fc93 100644 --- a/src/plugins/splash/script/script-parse.c +++ b/src/plugins/splash/script/script-parse.c @@ -24,9 +24,11 @@ int var (exp) tm = ! ++ -- f() f[] f.a pi = * / % md = -+ - pm = && || ++ - pm = < <= > >= gt = == != eq = +&& an +|| or = as = += -= *= %= */ @@ -250,9 +252,9 @@ static script_exp* script_parse_exp_eq (ply_scan_t* scan) { script_exp* sub_a = script_parse_exp_gt (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 (1){ + 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; @@ -269,22 +271,75 @@ static script_exp* script_parse_exp_eq (ply_scan_t* scan) exp->data.dual.sub_b = script_parse_exp_gt (scan); assert(exp->data.dual.sub_b); //FIXME syntax error sub_a = exp; - curtoken = ply_scan_get_current_token(scan); - peektoken = ply_scan_peek_next_token(scan); } return sub_a; } + +static script_exp* script_parse_exp_an (ply_scan_t* scan) +{ + script_exp* sub_a = script_parse_exp_eq (scan); + if (!sub_a) return NULL; + while (1){ + 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 != '&') break; + if (peektoken->data.symbol != '&') break; + ply_scan_get_next_token(scan); + ply_scan_get_next_token(scan); + + script_exp* exp = malloc(sizeof(script_exp)); + exp->type = SCRIPT_EXP_TYPE_AND; + exp->data.dual.sub_a = sub_a; + exp->data.dual.sub_b = script_parse_exp_eq (scan); + assert(exp->data.dual.sub_b); //FIXME syntax error + sub_a = exp; + } + + return sub_a; +} + + +static script_exp* script_parse_exp_or (ply_scan_t* scan) +{ + script_exp* sub_a = script_parse_exp_an (scan); + if (!sub_a) return NULL; + while (1){ + 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 (peektoken->data.symbol != '|') break; + if (curtoken->data.symbol != '|') break; + ply_scan_get_next_token(scan); + ply_scan_get_next_token(scan); + + script_exp* exp = malloc(sizeof(script_exp)); + exp->type = SCRIPT_EXP_TYPE_OR; + exp->data.dual.sub_a = sub_a; + exp->data.dual.sub_b = script_parse_exp_an (scan); + assert(exp->data.dual.sub_b); //FIXME syntax error + sub_a = exp; + } + + return sub_a; +} + + static script_exp* script_parse_exp_as (ply_scan_t* scan) { - script_exp* lhs = script_parse_exp_eq (scan); + script_exp* lhs = script_parse_exp_or (scan); if (!lhs) return NULL; ply_scan_token_t* curtoken = ply_scan_get_current_token(scan); if (curtoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL && curtoken->data.symbol == '=' ){ ply_scan_get_next_token(scan); - script_exp* rhs = script_parse_exp_eq(scan); + script_exp* rhs = script_parse_exp_or(scan); assert(rhs); //FIXME syntax error script_exp* exp = malloc(sizeof(script_exp)); exp->type = SCRIPT_EXP_TYPE_ASSIGN; @@ -514,6 +569,8 @@ static void script_parse_exp_free (script_exp* exp) case SCRIPT_EXP_TYPE_GE: case SCRIPT_EXP_TYPE_LT: case SCRIPT_EXP_TYPE_LE: + case SCRIPT_EXP_TYPE_AND: + case SCRIPT_EXP_TYPE_OR: case SCRIPT_EXP_TYPE_ASSIGN: case SCRIPT_EXP_TYPE_HASH: script_parse_exp_free (exp->data.dual.sub_a); diff --git a/src/plugins/splash/script/script.h b/src/plugins/splash/script/script.h index 487f6a26..562ca9a0 100644 --- a/src/plugins/splash/script/script.h +++ b/src/plugins/splash/script/script.h @@ -118,6 +118,8 @@ typedef enum SCRIPT_EXP_TYPE_LE, SCRIPT_EXP_TYPE_EQ, SCRIPT_EXP_TYPE_NE, + SCRIPT_EXP_TYPE_AND, + SCRIPT_EXP_TYPE_OR, SCRIPT_EXP_TYPE_HASH, SCRIPT_EXP_TYPE_FUNCTION, SCRIPT_EXP_TYPE_ASSIGN,