mirror of
https://gitlab.freedesktop.org/plymouth/plymouth.git
synced 2026-05-08 11:19:17 +02:00
[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.
This commit is contained in:
parent
02e878a728
commit
cf8c99c38f
3 changed files with 83 additions and 7 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue