]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
[script] Add support for unary operations (!/+/-/++/--)
authorCharlie Brej <cbrej@cs.man.ac.uk>
Mon, 22 Jun 2009 15:48:46 +0000 (16:48 +0100)
committerCharlie Brej <cbrej@cs.man.ac.uk>
Mon, 22 Jun 2009 15:48:46 +0000 (16:48 +0100)
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.

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

index 9f8524ed1663c271b8777538833136dabe41e124..46c0c198ac5c0cb029cf4fe810718a03d8508cef 100644 (file)
@@ -9,12 +9,12 @@
 #include <stdbool.h>
 #include <string.h>
 #include <stdbool.h>
+#include <math.h>
 
 #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);
index be45fc933ea60510e010eb47aff8fb55e27cf986..2c8824da4e565d767148d5e8ea68d9e142bf49a7 100644 (file)
 
 
 /*                          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:
index 562ca9a08ac0a781da0c2f97c02ccb090f059fa6..c26d645309a6f64f0f8408494d1bf2c29993ab50 100644 (file)
@@ -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,
index 3db6e150f9353c3695273571dd1356d1464b0d9f..60ca573d9a21f073a325146a50f78102a812da55 100644 (file)
@@ -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;
     }