]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
[script] Add support for logical AND and OR
authorCharlie Brej <cbrej@cs.man.ac.uk>
Thu, 18 Jun 2009 16:27:32 +0000 (17:27 +0100)
committerCharlie Brej <cbrej@cs.man.ac.uk>
Thu, 18 Jun 2009 16:27:32 +0000 (17:27 +0100)
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.

src/plugins/splash/script/script-execute.c
src/plugins/splash/script/script-parse.c
src/plugins/splash/script/script.h

index c65d97be7a67caf2bd694764502152309b6e6d2e..9f8524ed1663c271b8777538833136dabe41e124 100644 (file)
@@ -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);
index f542ed5bab782b3af8aa4e95bd0882a3da4c721b..be45fc933ea60510e010eb47aff8fb55e27cf986 100644 (file)
 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);
index 487f6a266c440a4928b55c992f00b5fe7fc6a229..562ca9a08ac0a781da0c2f97c02ccb090f059fa6 100644 (file)
@@ -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,