]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
[script] Add inheritance to the language
authorCharlie Brej <cbrej@cs.man.ac.uk>
Wed, 9 Sep 2009 19:57:19 +0000 (20:57 +0100)
committerCharlie Brej <cbrej@cs.man.ac.uk>
Wed, 9 Sep 2009 20:17:08 +0000 (21:17 +0100)
The inheritance works primarily on objects and functions.
Object example:
 A.v1 = 1;
 A.v2 = 2;
 B.v2 = 7;
 B.v3 = 3;
 C = A | B;

C is now equal to A with B as a base (C.v1 = 1, C.v2 = 2, C.v3 = 3).
A and B remain unchanged.

Function example:
 fib = fun (a) if (a < 2) 1; else fail;
     | fun (a) if (fibcache[a]) fibcache[a] ; else fail;
     | fun (a) fib (a - 1) + fib (a - 2); ;

Fail means a function is aborted and a more base function is attempted.

14 files changed:
src/plugins/splash/script/script-execute.c
src/plugins/splash/script/script-execute.h
src/plugins/splash/script/script-lib-image.c
src/plugins/splash/script/script-lib-image.script
src/plugins/splash/script/script-lib-math.c
src/plugins/splash/script/script-lib-math.script
src/plugins/splash/script/script-lib-plymouth.c
src/plugins/splash/script/script-lib-plymouth.script
src/plugins/splash/script/script-lib-sprite.c
src/plugins/splash/script/script-lib-sprite.script
src/plugins/splash/script/script-object.c
src/plugins/splash/script/script-object.h
src/plugins/splash/script/script-parse.c
src/plugins/splash/script/script.h

index 0a0edad999ad0fc24b5c9424df480b420c5b3d8c..0ab15cf49af43903ee8512ee2679a911dbc9b959 100644 (file)
@@ -227,11 +227,49 @@ static script_obj_t *script_evaluate_unary (script_state_t *state,
   script_obj_unref (obj);
   return new_obj;
 }
+typedef struct 
+{
+  script_state_t    *state;
+  script_obj_t      *this;
+  ply_list_t        *parameter_data;
+} script_obj_execute_data_t;
+
+static void *script_obj_execute (script_obj_t *obj,
+                                 void         *user_data)
+{
+  script_obj_execute_data_t *execute_data = user_data;
+  if (obj->type == SCRIPT_OBJ_TYPE_FUNCTION){
+      script_function_t *function = obj->data.function;
+      script_return_t reply = script_execute_function_with_parlist (execute_data->state,
+                                                                    function,
+                                                                    execute_data->this,
+                                                                    execute_data->parameter_data);
+      if (reply.type != SCRIPT_RETURN_TYPE_FAIL)
+        return reply.object ? reply.object : script_obj_new_null ();
+    }
+  return NULL;
+}
+
+static script_return_t script_execute_object_with_parlist (script_state_t    *state,
+                                                           script_obj_t      *obj,
+                                                           script_obj_t      *this,
+                                                           ply_list_t        *parameter_data)
+{
+  script_obj_execute_data_t execute_data;
+  execute_data.state = state;
+  execute_data.this = this;
+  execute_data.parameter_data = parameter_data;
+
+  obj = script_obj_as_custom (obj, script_obj_execute, &execute_data);
+
+  if (obj) return script_return_obj(obj);
+  return script_return_fail();
+}
 
 static script_obj_t *script_evaluate_func (script_state_t *state,
                                            script_exp_t   *exp)
 {
-  script_obj_t *this_obj;
+  script_obj_t *this_obj = NULL; ;
   script_obj_t *func_obj;
   script_exp_t *name_exp = exp->data.function_exe.name;
   
@@ -241,27 +279,30 @@ static script_obj_t *script_evaluate_func (script_state_t *state,
       this_obj = script_evaluate (state, name_exp->data.dual.sub_a);
       char *this_key_name = script_obj_as_string (this_key);
       script_obj_unref (this_key);
-      if (script_obj_is_hash(this_obj))
+      func_obj = script_obj_hash_get_element (this_obj, this_key_name);
+      free(this_key_name);
+    }
+  else if (name_exp->type == SCRIPT_EXP_TYPE_TERM_VAR)
+    {
+      char *name = name_exp->data.string;
+      func_obj = script_obj_hash_peek_element (state->local, name);
+      if (!func_obj)
         {
-          func_obj = script_obj_hash_get_element (this_obj, this_key_name);
+          func_obj = script_obj_hash_peek_element (state->this, name);
+          if (func_obj)
+            this_obj = state->this;
+          else
+            {
+              func_obj = script_obj_hash_peek_element (state->global, name);
+              if (!func_obj) func_obj = script_obj_new_null ();
+            }
         }
-      free(this_key_name);
     }
   else
     {
       func_obj = script_evaluate (state, exp->data.function_exe.name);
-      this_obj = NULL; 
     }
   
-  script_function_t *function = script_obj_as_function (func_obj);
-
-  if (!function)
-    {
-      script_execute_error(exp, "Call operated on an object with is not a function");
-      script_obj_unref (func_obj);
-      if (this_obj) script_obj_unref (this_obj);
-      return script_obj_new_null ();
-    }
   ply_list_t *parameter_expressions = exp->data.function_exe.parameters;
   ply_list_t *parameter_data = ply_list_new ();
 
@@ -274,15 +315,9 @@ static script_obj_t *script_evaluate_func (script_state_t *state,
       node_expression = ply_list_get_next_node (parameter_expressions,
                                                 node_expression);
     }
-  script_return_t reply = script_execute_function_with_parlist (state,
-                                                                function,
-                                                                this_obj,
-                                                                parameter_data);
-  script_obj_t *obj;
-  if (reply.type == SCRIPT_RETURN_TYPE_RETURN)
-    obj = reply.object;
-  else
-    obj = script_obj_new_null ();
+
+  script_return_t reply = script_execute_object_with_parlist (state, func_obj, this_obj, parameter_data);
+    
   ply_list_node_t *node_data = ply_list_get_first_node (parameter_data);
   while (node_data)
     {
@@ -295,7 +330,7 @@ static script_obj_t *script_evaluate_func (script_state_t *state,
   script_obj_unref (func_obj);
   if (this_obj) script_obj_unref (this_obj);
 
-  return obj;
+  return reply.object ? reply.object : script_obj_new_null ();
 }
 
 static script_obj_t *script_evaluate (script_state_t *state,
@@ -360,6 +395,11 @@ static script_obj_t *script_evaluate (script_state_t *state,
           return script_evaluate_logic (state, exp);
         }
 
+      case SCRIPT_EXP_TYPE_EXTEND:
+        {
+          return script_evaluate_apply_function (state, exp, script_obj_new_extend);
+        }
+
       case SCRIPT_EXP_TYPE_NOT:
       case SCRIPT_EXP_TYPE_POS:
       case SCRIPT_EXP_TYPE_NEG:
@@ -449,6 +489,13 @@ static script_obj_t *script_evaluate (script_state_t *state,
                                                             script_obj_mod);
         }
 
+      case SCRIPT_EXP_TYPE_ASSIGN_EXTEND:
+        {
+          return script_evaluate_apply_function_and_assign (state,
+                                                            exp,
+                                                            script_obj_new_extend);
+        }
+
       case SCRIPT_EXP_TYPE_HASH:
         {
           return script_evaluate_hash (state, exp);
@@ -477,13 +524,14 @@ static script_return_t script_execute_list (script_state_t *state,
        node = ply_list_get_next_node (op_list, node))
     {
       script_op_t *op = ply_list_node_get_data (node);
+      script_obj_unref (reply.object);
       reply = script_execute (state, op);
       switch (reply.type)
         {
           case SCRIPT_RETURN_TYPE_NORMAL:
             break;
-
           case SCRIPT_RETURN_TYPE_RETURN:
+          case SCRIPT_RETURN_TYPE_FAIL:
           case SCRIPT_RETURN_TYPE_BREAK:
           case SCRIPT_RETURN_TYPE_CONTINUE:
             return reply;
@@ -548,16 +596,17 @@ static script_return_t script_execute_function_with_parlist (script_state_t    *
           break;
         }
     }
-
   script_state_destroy (sub_state);
+  if (reply.type != SCRIPT_RETURN_TYPE_FAIL)
+    reply.type = SCRIPT_RETURN_TYPE_RETURN;
   return reply;
 }
 
-script_return_t script_execute_function (script_state_t    *state,
-                                         script_function_t *function,
-                                         script_obj_t      *this,
-                                         script_obj_t      *first_arg,
-                                         ...)
+script_return_t script_execute_object (script_state_t    *state,
+                                       script_obj_t      *function,
+                                       script_obj_t      *this,
+                                       script_obj_t      *first_arg,
+                                       ...)
 {
   script_return_t reply;
   va_list args;
@@ -573,7 +622,7 @@ script_return_t script_execute_function (script_state_t    *state,
     }
   va_end (args);
 
-  reply = script_execute_function_with_parlist (state, function, this, parameter_data);
+  reply = script_execute_object_with_parlist (state, function, this, parameter_data);
   ply_list_free (parameter_data);
 
   return reply;
@@ -583,21 +632,18 @@ script_return_t script_execute (script_state_t *state,
                                 script_op_t    *op)
 {
   script_return_t reply = script_return_normal ();
-
   if (!op) return reply;
   switch (op->type)
     {
       case SCRIPT_OP_TYPE_EXPRESSION:
         {
-          script_obj_t *obj = script_evaluate (state, op->data.exp);
-          script_obj_unref (obj);  /* there is always a reply from all expressions (even assigns) which we chuck away */
+          reply.object = script_evaluate (state, op->data.exp);
           break;
         }
 
       case SCRIPT_OP_TYPE_OP_BLOCK:
         {
           reply = script_execute_list (state, op->data.list);
-          /* FIXME blocks should normall reply a NULL , but if they replied something else then that was a return */
           break;
         }
 
@@ -621,6 +667,7 @@ script_return_t script_execute (script_state_t *state,
               obj = script_evaluate (state, op->data.cond_op.cond);
               if (script_obj_as_bool (obj))
                 {
+                  script_obj_unref (reply.object);
                   reply = script_execute (state, op->data.cond_op.op1);
                   script_obj_unref (obj);
                   switch (reply.type)
@@ -629,6 +676,7 @@ script_return_t script_execute (script_state_t *state,
                         break;
 
                       case SCRIPT_RETURN_TYPE_RETURN:
+                      case SCRIPT_RETURN_TYPE_FAIL:
                         return reply;
 
                       case SCRIPT_RETURN_TYPE_BREAK:
@@ -637,7 +685,11 @@ script_return_t script_execute (script_state_t *state,
                       case SCRIPT_RETURN_TYPE_CONTINUE:
                         break;
                     }
-                  script_execute (state, op->data.cond_op.op2);
+                  if (op->data.cond_op.op2)
+                    {
+                      script_obj_unref (reply.object);
+                      reply = script_execute (state, op->data.cond_op.op2);
+                    }
                 }
               else
                 {
@@ -657,6 +709,12 @@ script_return_t script_execute (script_state_t *state,
           break;
         }
 
+      case SCRIPT_OP_TYPE_FAIL:
+        {
+          reply = script_return_fail ();
+          break;
+        }
+
       case SCRIPT_OP_TYPE_BREAK:
         {
           reply = script_return_break ();
index 8eb1174cb39d2cd6eadd8ca8a5b001ab4a65c09d..efba3ed8d733d4cf42f6c29acc56ef00d538b5aa 100644 (file)
 
 script_return_t script_execute (script_state_t *state,
                                 script_op_t    *op);
-script_return_t script_execute_function (script_state_t    *state,
-                                         script_function_t *function,
-                                         script_obj_t      *this,
-                                         script_obj_t      *first_arg,
-                                         ...);
+script_return_t script_execute_object (script_state_t    *state,
+                                       script_obj_t      *function,
+                                       script_obj_t      *this,
+                                       script_obj_t      *first_arg,
+                                       ...);
 
 #endif /* SCRIPT_EXECUTE_H */
index 37ad2e9dba1aa552ec959631c2b51e4267ebb5be..0474ae9cf531638e4967ca66597de0763568d4ac 100644 (file)
@@ -85,9 +85,7 @@ static script_return_t image_get_width (script_state_t *state,
                                         void           *user_data)
 {
   script_lib_image_data_t *data = user_data;
-  ply_image_t *image = script_obj_hash_get_native_of_class (state->local,
-                                                            "image",
-                                                            data->class);
+  ply_image_t *image = script_obj_as_native_of_class (state->this, data->class);
   if (image)
     return script_return_obj (script_obj_new_number (ply_image_get_width (image)));
   return script_return_obj_null ();
@@ -97,9 +95,7 @@ static script_return_t image_get_height (script_state_t *state,
                                          void           *user_data)
 {
   script_lib_image_data_t *data = user_data;
-  ply_image_t *image = script_obj_hash_get_native_of_class (state->local,
-                                                            "image",
-                                                            data->class);
+  ply_image_t *image = script_obj_as_native_of_class (state->this, data->class);
   if (image)
     return script_return_obj (script_obj_new_number (ply_image_get_height (image)));
   return script_return_obj_null ();
@@ -109,9 +105,7 @@ static script_return_t image_rotate (script_state_t *state,
                                      void           *user_data)
 {
   script_lib_image_data_t *data = user_data;
-  ply_image_t *image = script_obj_hash_get_native_of_class (state->local,
-                                                            "image",
-                                                            data->class);
+  ply_image_t *image = script_obj_as_native_of_class (state->this, data->class);
   float angle = script_obj_hash_get_number (state->local, "angle");
 
   if (image)
@@ -129,9 +123,7 @@ static script_return_t image_scale (script_state_t *state,
                                     void           *user_data)
 {
   script_lib_image_data_t *data = user_data;
-  ply_image_t *image = script_obj_hash_get_native_of_class (state->local,
-                                                            "image",
-                                                            data->class);
+  ply_image_t *image = script_obj_as_native_of_class (state->this, data->class);
   int width = script_obj_hash_get_number (state->local, "width");
   int height = script_obj_hash_get_number (state->local, "height");
 
@@ -151,44 +143,42 @@ script_lib_image_data_t *script_lib_image_setup (script_state_t *state,
   data->class = script_obj_native_class_new (image_free, "image", data);
   data->image_dir = strdup (image_dir);
 
-  script_add_native_function (state->global,
-                              "ImageNew",
+  script_obj_t *image_hash = script_obj_hash_get_element (state->global, "Image");
+  
+  script_add_native_function (image_hash,
+                              "_New",
                               image_new,
                               data,
                               "filename",
                               NULL);
-  script_add_native_function (state->global,
-                              "ImageRotate",
+  script_add_native_function (image_hash,
+                              "_Rotate",
                               image_rotate,
                               data,
-                              "image",
                               "angle",
                               NULL);
-  script_add_native_function (state->global,
-                              "ImageScale",
+  script_add_native_function (image_hash,
+                              "_Scale",
                               image_scale,
                               data,
-                              "image",
                               "width",
                               "height",
                               NULL);
-  script_add_native_function (state->global,
-                              "ImageGetWidth",
+  script_add_native_function (image_hash,
+                              "GetWidth",
                               image_get_width,
                               data,
-                              "image",
                               NULL);
-  script_add_native_function (state->global,
-                              "ImageGetHeight",
+  script_add_native_function (image_hash,
+                              "GetHeight",
                               image_get_height,
                               data,
-                              "image",
                               NULL);
 
+  script_obj_unref (image_hash);
   data->script_main_op = script_parse_string (script_lib_image_string, "script-lib-image.script");
   script_return_t ret = script_execute (state, data->script_main_op);
   script_obj_unref (ret.object);
-
   return data;
 }
 
index bac9c714d4a7930053aee9aa8a311db2e4c1af3b..a64a3e45ed3860f3a015bb4dc7a7222d3b3e8968 100644 (file)
@@ -1 +1,47 @@
-   
+Image.Adopt = fun( raw_image)
+{
+  if (raw_image) return raw_image | Image;
+  else return NULL;
+};
+
+Image.Rotate = fun (angle)
+{
+  return Image.Adopt (this._Rotate(angle));
+};
+
+Image.Scale = fun (width, height)
+{
+  return Image.Adopt (this._Scale(width, height));
+};
+
+Image |= fun (filename)
+{
+  return Image.Adopt (Image._New(filename));
+};
+
+#------------------------- Compatability Functions -------------------------
+
+fun ImageNew (filename)
+{
+  return Image (filename);
+}
+
+fun ImageScale (image, width, height)
+{
+  return image.Scale (width, height);
+}
+
+fun ImageRotate (image, angle)
+{
+  return image.Rotate (angle);
+}
+
+fun ImageGetWidth (image)
+{
+  return image.GetWidth ();
+}
+
+fun ImageGetHeight (image)
+{
+  return image.GetHeight ();
+}
index ad3b0054b6912fa43cb40bb4c42dfe840b19967c..a78221b82afe3600c1e7843c026562feab5e277a 100644 (file)
@@ -20,7 +20,6 @@
  * Written by: Charlie Brej <cbrej@cs.man.ac.uk>
  */
 #define _GNU_SOURCE
-#include "ply-utils.h"
 #include "script.h"
 #include "script-parse.h"
 #include "script-execute.h"
@@ -65,43 +64,45 @@ script_lib_math_data_t *script_lib_math_setup (script_state_t *state)
 {
   script_lib_math_data_t *data = malloc (sizeof (script_lib_math_data_t));
 
-  script_add_native_function (state->global,
-                              "MathCos",
+  script_obj_t *math_hash = script_obj_hash_get_element (state->global, "Math");
+  script_add_native_function (math_hash,
+                              "Cos",
                               script_lib_math_double_from_double_function,
                               cos,
                               "value",
                               NULL);
-  script_add_native_function (state->global,
-                              "MathSin",
+  script_add_native_function (math_hash,
+                              "Sin",
                               script_lib_math_double_from_double_function,
                               sin,
                               "value",
                               NULL);
-  script_add_native_function (state->global,
-                              "MathTan",
+  script_add_native_function (math_hash,
+                              "Tan",
                               script_lib_math_double_from_double_function,
                               tan,
                               "value",
                               NULL);
-  script_add_native_function (state->global,
-                              "MathATan2",
+  script_add_native_function (math_hash,
+                              "ATan2",
                               script_lib_math_double_from_double_double_function,
                               atan2,
                               "value_a",
                               "value_b",
                               NULL);
-  script_add_native_function (state->global,
-                              "MathSqrt",
+  script_add_native_function (math_hash,
+                              "Sqrt",
                               script_lib_math_double_from_double_function,
                               sqrt,
                               "value",
                               NULL);
-  script_add_native_function (state->global,
-                              "MathInt",
+  script_add_native_function (math_hash,
+                              "Int",
                               script_lib_math_double_from_double_function,
                               double_to_int,
                               "value",
                               NULL);
+  script_obj_unref (math_hash);
 
   data->script_main_op = script_parse_string (script_lib_math_string, "script-lib-math.script");
   script_return_t ret = script_execute (state, data->script_main_op);
index e5c6542438ecf3d26edd85ffd943cb6e9ef3c9f5..daaada1000adb2d074e0ea3032360f86aa82e125 100644 (file)
@@ -1,23 +1,40 @@
-fun MathAbs (value){
-    if (value < 0) return -value;
-    return value;
-    }
+Math.Abs = fun (value)
+{
+  if (value < 0) return -value;
+  return value;
+};
 
-fun MathMin (value_a, value_b){
-    if (value_a < value_b) return value_a;
-    return value_b;
-    }
+Math.Min = fun (value_a, value_b)
+{
+  if (value_a < value_b) return value_a;
+  return value_b;
+};
 
-fun MathMax (value_a, value_b){
-    if (value_a > value_b) return value_a;
-    return value_b;
-    }
+Math.Max = fun (value_a, value_b)
+{
+  if (value_a > value_b) return value_a;
+  return value_b;
+};
 
-fun MathClamp (value, min, max){
-    if (value < min) return min;
-    if (value > max) return max;
-    return value;
-    }
+Math.Clamp = fun (value, min, max)
+{
+  if (value < min) return min;
+  if (value > max) return max;
+  return value;
+};
 
+Math.Pi = 3.14159265358979323846;
 
-MathPi = 3.14159265358979323846;
+#------------------------- Compatability Functions -------------------------
+
+MathAbs = Math.Abs;
+MathMin = Math.Min;
+MathMax = Math.Max;
+MathClamp = Math.Clamp;
+MathPi = Math.Pi;
+MathCos = Math.Cos;
+MathSin = Math.Sin;
+MathTan = Math.Tan;
+MathATan2 = Math.ATan2;
+MathSqrt = Math.Sqrt;
+MathInt = Math.Int;
index 2dfee919d482a5c828805143238baba396b0d701..8a3fe2e84c46f1d3c80e673d3495341513384aaa 100644 (file)
@@ -44,14 +44,7 @@ static script_return_t plymouth_set_function (script_state_t *state,
 
   script_obj_deref (&obj);
   script_obj_unref (*script_func);
-  
-  if (script_obj_is_function (obj))
-    *script_func = obj;
-  else
-    {
-      *script_func = NULL;
-      script_obj_unref (obj);
-    }
+  *script_func = obj;
   return script_return_obj_null ();
 }
 
@@ -97,65 +90,68 @@ script_lib_plymouth_data_t *script_lib_plymouth_setup (script_state_t         *s
   data->script_message_func = script_obj_new_null ();
   data->mode = mode;
   
-  script_add_native_function (state->global,
-                              "PlymouthSetRefreshFunction",
+  script_obj_t *plymouth_hash = script_obj_hash_get_element (state->global, "Plymouth");
+  script_add_native_function (plymouth_hash,
+                              "SetRefreshFunction",
                               plymouth_set_function,
                               &data->script_refresh_func,
                               "function",
                               NULL);
-  script_add_native_function (state->global,
-                              "PlymouthSetBootProgressFunction",
+  script_add_native_function (plymouth_hash,
+                              "SetBootProgressFunction",
                               plymouth_set_function,
                               &data->script_boot_progress_func,
                               "function",
                               NULL);
-  script_add_native_function (state->global,
-                              "PlymouthSetRootMountedFunction",
+  script_add_native_function (plymouth_hash,
+                              "SetRootMountedFunction",
                               plymouth_set_function,
                               &data->script_root_mounted_func,
                               "function",
                               NULL);
-  script_add_native_function (state->global,
-                              "PlymouthSetKeyboardInputFunction",
+  script_add_native_function (plymouth_hash,
+                              "SetKeyboardInputFunction",
                               plymouth_set_function,
                               &data->script_keyboard_input_func,
                               "function",
                               NULL);
-  script_add_native_function (state->global,
-                              "PlymouthSetUpdateStatusFunction",
+  script_add_native_function (plymouth_hash,
+                              "SetUpdateStatusFunction",
                               plymouth_set_function,
                               &data->script_update_status_func,
                               "function",
                               NULL);
-  script_add_native_function (state->global,
-                              "PlymouthSetDisplayNormalFunction",
+  script_add_native_function (plymouth_hash,
+                              "SetDisplayNormalFunction",
                               plymouth_set_function,
                               &data->script_display_normal_func,
                               "function",
                               NULL);
-  script_add_native_function (state->global,
-                              "PlymouthSetDisplayPasswordFunction",
+  script_add_native_function (plymouth_hash,
+                              "SetDisplayPasswordFunction",
                               plymouth_set_function,
                               &data->script_display_password_func,
                               "function",
                               NULL);
-  script_add_native_function (state->global,
-                              "PlymouthSetDisplayQuestionFunction",
+  script_add_native_function (plymouth_hash,
+                              "SetDisplayQuestionFunction",
                               plymouth_set_function,
                               &data->script_display_question_func,
                               "function",
                               NULL);
-  script_add_native_function (state->global,
-                              "PlymouthSetMessageFunction",
+  script_add_native_function (plymouth_hash,
+                              "SetMessageFunction",
                               plymouth_set_function,
                               &data->script_message_func,
                               "function",
                               NULL);
-  script_add_native_function (state->global,
-                              "PlymouthGetMode",
+  script_add_native_function (plymouth_hash,
+                              "GetMode",
                               plymouth_get_mode,
                               data,
                               NULL);
+  script_obj_unref (plymouth_hash);
+
   data->script_main_op = script_parse_string (script_lib_plymouth_string, "script-lib-plymouth.script");
   script_return_t ret = script_execute (state, data->script_main_op);
   script_obj_unref (ret.object);                /* Throw anything sent back away */
@@ -181,15 +177,11 @@ void script_lib_plymouth_destroy (script_lib_plymouth_data_t *data)
 void script_lib_plymouth_on_refresh (script_state_t             *state,
                                      script_lib_plymouth_data_t *data)
 {
-  script_function_t *function = script_obj_as_function (data->script_refresh_func);
-  if (function)
-    {
-      script_return_t ret = script_execute_function (state,
-                                                     function,
-                                                     NULL,
-                                                     NULL);
-      script_obj_unref (ret.object);
-    }
+    script_return_t ret = script_execute_object (state,
+                                                 data->script_refresh_func,
+                                                 NULL,
+                                                 NULL);
+    script_obj_unref (ret.object);
 }
 
 void script_lib_plymouth_on_boot_progress (script_state_t             *state,
@@ -197,85 +189,65 @@ void script_lib_plymouth_on_boot_progress (script_state_t             *state,
                                            double                     duration,
                                            double                     progress)
 {
-  script_function_t *function = script_obj_as_function (data->script_boot_progress_func);
-  if (function)
-    {
-      script_obj_t *duration_obj = script_obj_new_number (duration);
-      script_obj_t *progress_obj = script_obj_new_number (progress);
-      script_return_t ret = script_execute_function (state,
-                                                     function,
-                                                     NULL,
-                                                     duration_obj,
-                                                     progress_obj,
-                                                     NULL);
-      script_obj_unref (ret.object);
-      script_obj_unref (duration_obj);
-      script_obj_unref (progress_obj);
-    }
+  script_obj_t *duration_obj = script_obj_new_number (duration);
+  script_obj_t *progress_obj = script_obj_new_number (progress);
+  script_return_t ret = script_execute_object (state,
+                                               data->script_boot_progress_func,
+                                               NULL,
+                                               duration_obj,
+                                               progress_obj,
+                                               NULL);
+  script_obj_unref (ret.object);
+  script_obj_unref (duration_obj);
+  script_obj_unref (progress_obj);
 }
 
 void script_lib_plymouth_on_root_mounted (script_state_t             *state,
                                           script_lib_plymouth_data_t *data)
 {
-  script_function_t *function = script_obj_as_function (data->script_root_mounted_func);
-  if (function)
-    {
-      script_return_t ret = script_execute_function (state,
-                                                     function,
-                                                     NULL,
-                                                     NULL);
-      script_obj_unref (ret.object);
-    }
+  script_return_t ret = script_execute_object (state,
+                                               data->script_root_mounted_func,
+                                               NULL,
+                                               NULL);
+  script_obj_unref (ret.object);
 }
 
 void script_lib_plymouth_on_keyboard_input (script_state_t             *state,
                                             script_lib_plymouth_data_t *data,
                                             const char                 *keyboard_input)
 {
-  script_function_t *function = script_obj_as_function (data->script_keyboard_input_func);
-  if (function)
-    {
-      script_obj_t *keyboard_input_obj = script_obj_new_string (keyboard_input);
-      script_return_t ret = script_execute_function (state,
-                                                     function,
-                                                     NULL,
-                                                     keyboard_input_obj,
-                                                     NULL);
-      script_obj_unref (keyboard_input_obj);
-      script_obj_unref (ret.object);
-    }
+  script_obj_t *keyboard_input_obj = script_obj_new_string (keyboard_input);
+  script_return_t ret = script_execute_object (state,
+                                                 data->script_keyboard_input_func,
+                                                 NULL,
+                                                 keyboard_input_obj,
+                                                 NULL);
+  script_obj_unref (keyboard_input_obj);
+  script_obj_unref (ret.object);
 }
 
 void script_lib_plymouth_on_update_status (script_state_t             *state,
                                            script_lib_plymouth_data_t *data,
                                            const char                 *new_status)
 {
-  script_function_t *function = script_obj_as_function (data->script_update_status_func);
-  if (function)
-    {
-      script_obj_t *new_status_obj = script_obj_new_string (new_status);
-      script_return_t ret = script_execute_function (state,
-                                                     function,
-                                                     NULL,
-                                                     new_status_obj,
-                                                     NULL);
-      script_obj_unref (new_status_obj);
-      script_obj_unref (ret.object);
-    }
+  script_obj_t *new_status_obj = script_obj_new_string (new_status);
+  script_return_t ret = script_execute_object (state,
+                                               data->script_update_status_func,
+                                               NULL,
+                                               new_status_obj,
+                                               NULL);
+  script_obj_unref (new_status_obj);
+  script_obj_unref (ret.object);
 }
 
 void script_lib_plymouth_on_display_normal (script_state_t             *state,
                                             script_lib_plymouth_data_t *data)
 {
-  script_function_t *function = script_obj_as_function (data->script_display_normal_func);
-  if (function)
-    {
-      script_return_t ret = script_execute_function (state,
-                                                     function,
-                                                     NULL,
-                                                     NULL);
-      script_obj_unref (ret.object);
-    }
+  script_return_t ret = script_execute_object (state,
+                                               data->script_display_normal_func,
+                                               NULL,
+                                               NULL);
+  script_obj_unref (ret.object);
 }
 
 void script_lib_plymouth_on_display_password (script_state_t             *state,
@@ -283,21 +255,17 @@ void script_lib_plymouth_on_display_password (script_state_t             *state,
                                               const char                 *prompt,
                                               int                         bullets)
 {
-  script_function_t *function = script_obj_as_function (data->script_display_password_func);
-  if (function)
-    {
-      script_obj_t *prompt_obj = script_obj_new_string (prompt);
-      script_obj_t *bullets_obj = script_obj_new_number (bullets);
-      script_return_t ret = script_execute_function (state,
-                                                     function,
-                                                     NULL,
-                                                     prompt_obj,
-                                                     bullets_obj,
-                                                     NULL);
-      script_obj_unref (prompt_obj);
-      script_obj_unref (bullets_obj);
-      script_obj_unref (ret.object);
-    }
+  script_obj_t *prompt_obj = script_obj_new_string (prompt);
+  script_obj_t *bullets_obj = script_obj_new_number (bullets);
+  script_return_t ret = script_execute_object (state,
+                                               data->script_display_password_func,
+                                               NULL,
+                                               prompt_obj,
+                                               bullets_obj,
+                                               NULL);
+  script_obj_unref (prompt_obj);
+  script_obj_unref (bullets_obj);
+  script_obj_unref (ret.object);
 }
 
 void script_lib_plymouth_on_display_question (script_state_t             *state,
@@ -305,37 +273,29 @@ void script_lib_plymouth_on_display_question (script_state_t             *state,
                                               const char                 *prompt,
                                               const char                 *entry_text)
 {
-  script_function_t *function = script_obj_as_function (data->script_display_question_func);
-  if (function)
-    {
-      script_obj_t *prompt_obj = script_obj_new_string (prompt);
-      script_obj_t *entry_text_obj = script_obj_new_string (entry_text);
-      script_return_t ret = script_execute_function (state,
-                                                     function,
-                                                     NULL,
-                                                     prompt_obj,
-                                                     entry_text_obj,
-                                                     NULL);
-      script_obj_unref (prompt_obj);
-      script_obj_unref (entry_text_obj);
-      script_obj_unref (ret.object);
-    }
+  script_obj_t *prompt_obj = script_obj_new_string (prompt);
+  script_obj_t *entry_text_obj = script_obj_new_string (entry_text);
+  script_return_t ret = script_execute_object (state,
+                                               data->script_display_question_func,
+                                               NULL,
+                                               prompt_obj,
+                                               entry_text_obj,
+                                               NULL);
+  script_obj_unref (prompt_obj);
+  script_obj_unref (entry_text_obj);
+  script_obj_unref (ret.object);
 }
 
 void script_lib_plymouth_on_message (script_state_t             *state,
                                      script_lib_plymouth_data_t *data,
                                      const char                 *message)
 {
-  script_function_t *function = script_obj_as_function (data->script_message_func);
-  if (function)
-    {
-      script_obj_t *new_message_obj = script_obj_new_string (message);
-      script_return_t ret = script_execute_function (state,
-                                                     function,
-                                                     NULL,
-                                                     new_message_obj,
-                                                     NULL);
-      script_obj_unref (new_message_obj);
-      script_obj_unref (ret.object);
-    }
+  script_obj_t *new_message_obj = script_obj_new_string (message);
+  script_return_t ret = script_execute_object (state,
+                                               data->script_message_func,
+                                               NULL,
+                                               new_message_obj,
+                                               NULL);
+  script_obj_unref (new_message_obj);
+  script_obj_unref (ret.object);
 }
index bac9c714d4a7930053aee9aa8a311db2e4c1af3b..4eb85c8061e0498dd554117761fb6f9683f52cc9 100644 (file)
@@ -1 +1,12 @@
-   
+#------------------------- Compatability Functions -------------------------
+
+PlymouthSetRefreshFunction = Plymouth.SetRefreshFunction;
+PlymouthSetBootProgressFunction = Plymouth.SetBootProgressFunction;
+PlymouthSetRootMountedFunction = Plymouth.SetRootMountedFunction;
+PlymouthSetKeyboardInputFunction = Plymouth.SetKeyboardInputFunction;
+PlymouthSetUpdateStatusFunction = Plymouth.SetUpdateStatusFunction;
+PlymouthSetDisplayNormalFunction = Plymouth.SetDisplayNormalFunction;
+PlymouthSetDisplayPasswordFunction = Plymouth.SetDisplayPasswordFunction;
+PlymouthSetDisplayQuestionFunction = Plymouth.SetDisplayQuestionFunction;
+PlymouthSetMessageFunction = Plymouth.SetMessageFunction;
+PlymouthGetMode = Plymouth.GetMode;
index e8dde377f38922f29a1153bf395cc0f2a461b671..3beded22cfad240ccadd69221282bdc6ed2ff06b 100644 (file)
@@ -73,12 +73,9 @@ static script_return_t sprite_set_image (script_state_t *state,
                                          void           *user_data)
 {
   script_lib_sprite_data_t *data = user_data;
-  sprite_t *sprite = script_obj_hash_get_native_of_class (state->local,
-                                                          "sprite",
-                                                          data->class);
+  sprite_t *sprite = script_obj_as_native_of_class (state->this, data->class);
   script_obj_t *script_obj_image = script_obj_hash_get_element (state->local,
                                                               "image");
-
   script_obj_deref (&script_obj_image);
   ply_image_t *image = script_obj_as_native_of_class_name (script_obj_image,
                                                            "image");
@@ -100,9 +97,7 @@ static script_return_t sprite_set_x (script_state_t *state,
                                      void           *user_data)
 {
   script_lib_sprite_data_t *data = user_data;
-  sprite_t *sprite = script_obj_hash_get_native_of_class (state->local,
-                                                          "sprite",
-                                                          data->class);
+  sprite_t *sprite = script_obj_as_native_of_class (state->this, data->class);
 
   if (sprite)
     sprite->x = script_obj_hash_get_number (state->local, "value");
@@ -113,9 +108,7 @@ static script_return_t sprite_set_y (script_state_t *state,
                                      void           *user_data)
 {
   script_lib_sprite_data_t *data = user_data;
-  sprite_t *sprite = script_obj_hash_get_native_of_class (state->local,
-                                                          "sprite",
-                                                          data->class);
+  sprite_t *sprite = script_obj_as_native_of_class (state->this, data->class);
 
   if (sprite)
     sprite->y = script_obj_hash_get_number (state->local, "value");
@@ -126,9 +119,7 @@ static script_return_t sprite_set_z (script_state_t *state,
                                      void           *user_data)
 {
   script_lib_sprite_data_t *data = user_data;
-  sprite_t *sprite = script_obj_hash_get_native_of_class (state->local,
-                                                          "sprite",
-                                                          data->class);
+  sprite_t *sprite = script_obj_as_native_of_class (state->this, data->class);
 
   if (sprite)
     sprite->z = script_obj_hash_get_number (state->local, "value");
@@ -139,9 +130,7 @@ static script_return_t sprite_set_opacity (script_state_t *state,
                                            void           *user_data)
 {
   script_lib_sprite_data_t *data = user_data;
-  sprite_t *sprite = script_obj_hash_get_native_of_class (state->local,
-                                                          "sprite",
-                                                          data->class);
+  sprite_t *sprite = script_obj_as_native_of_class (state->this, data->class);
 
   if (sprite)
     sprite->opacity = script_obj_hash_get_number (state->local, "value");
@@ -264,72 +253,73 @@ script_lib_sprite_data_t *script_lib_sprite_setup (script_state_t *state,
   data->sprite_list = ply_list_new ();
   data->window = window;
 
-  script_add_native_function (state->global,
-                              "SpriteNew",
+  script_obj_t *sprite_hash = script_obj_hash_get_element (state->global, "Sprite");
+  script_add_native_function (sprite_hash,
+                              "_New",
                               sprite_new,
                               data,
                               NULL);
-  script_add_native_function (state->global,
-                              "SpriteSetImage",
+  script_add_native_function (sprite_hash,
+                              "SetImage",
                               sprite_set_image,
                               data,
-                              "sprite",
                               "image",
                               NULL);
-  script_add_native_function (state->global,
-                              "SpriteSetX",
+  script_add_native_function (sprite_hash,
+                              "SetX",
                               sprite_set_x,
                               data,
-                              "sprite",
                               "value",
                               NULL);
-  script_add_native_function (state->global,
-                              "SpriteSetY",
+  script_add_native_function (sprite_hash,
+                              "SetY",
                               sprite_set_y,
                               data,
-                              "sprite",
                               "value",
                               NULL);
-  script_add_native_function (state->global,
-                              "SpriteSetZ",
+  script_add_native_function (sprite_hash,
+                              "SetZ",
                               sprite_set_z,
                               data,
-                              "sprite",
                               "value",
                               NULL);
-  script_add_native_function (state->global,
-                              "SpriteSetOpacity",
+  script_add_native_function (sprite_hash,
+                              "SetOpacity",
                               sprite_set_opacity,
                               data,
-                              "sprite",
                               "value",
                               NULL);
-  script_add_native_function (state->global,
-                              "SpriteWindowGetWidth",
+  script_obj_unref (sprite_hash);
+
+  
+  script_obj_t *window_hash = script_obj_hash_get_element (state->global, "Window");
+  script_add_native_function (window_hash,
+                              "GetWidth",
                               sprite_window_get_width,
                               data,
                               NULL);
-  script_add_native_function (state->global,
-                              "SpriteWindowGetHeight",
+  script_add_native_function (window_hash,
+                              "GetHeight",
                               sprite_window_get_height,
                               data,
                               NULL);
-  script_add_native_function (state->global,
-                              "SpriteWindowSetBackgroundTopColor",
+  script_add_native_function (window_hash,
+                              "SetBackgroundTopColor",
                               sprite_window_set_background_top_color,
                               data,
                               "red",
                               "green",
                               "blue",
                               NULL);
-  script_add_native_function (state->global,
-                              "SpriteWindowSetBackgroundBottomColor",
+  script_add_native_function (window_hash,
+                              "SetBackgroundBottomColor",
                               sprite_window_set_background_bottom_color,
                               data,
                               "red",
                               "green",
                               "blue",
                               NULL);
+  script_obj_unref (window_hash);
 
   data->script_main_op = script_parse_string (script_lib_sprite_string, "script-lib-sprite.script");
   data->background_color_start = 0x000000;
index 847778abffc63dbd305633aa6ea91dd7d183fda1..b88127f5e563151e084f15072d4487246cff62aa 100644 (file)
@@ -1,5 +1,77 @@
-fun SpriteSetPosition(sprite, x, y, z){
-    SpriteSetX(sprite, x);
-    SpriteSetY(sprite, y);
-    SpriteSetZ(sprite, z);
-    }
+Sprite.SetPosition = fun (x, y, z)
+{
+  this.SetX(x);
+  this.SetY(y);
+  this.SetZ(z);
+};
+
+Sprite |= fun(image)
+{
+  new_sprite = Sprite._New() | Sprite;
+  if (image) new_sprite.SetImage(image);
+  return new_sprite;
+};
+
+#------------------------- Compatability Functions -------------------------
+
+fun SpriteNew ()
+{
+  return Sprite ();
+}
+
+fun SpriteSetImage (sprite, image)
+{
+  return sprite.SetImage (image);
+}
+
+fun SpriteSetX (sprite, value)
+{
+  return sprite.SetX (value);
+}
+
+fun SpriteSetY (sprite, value)
+{
+  return sprite.SetY (value);
+}
+
+fun SpriteSetZ (sprite, value)
+{
+  return sprite.SetZ (value);
+}
+
+fun SpriteSetPosition (sprite, x, y, z)
+{
+  sprite.SetX(x);
+  sprite.SetY(y);
+  sprite.SetZ(z);
+}
+
+fun SpriteSetOpacity (sprite, value)
+{
+  return sprite.SetOpacity (value);
+}
+
+
+fun SpriteWindowGetWidth ()
+{
+  return Window.GetWidth ();
+}
+
+
+fun SpriteWindowGetHeight ()
+{
+  return Window.GetHeight ();
+}
+
+
+fun SpriteWindowSetBackgroundTopColor (red, green, blue)
+{
+  return Window.SetBackgroundTopColor (red, green, blue);
+}
+
+
+fun SpriteWindowGetSetBackgroundBottomColor (red, green, blue)
+{
+  return Window.SetBackgroundBottomColor (red, green, blue);
+}
+
index 1cf52636eeb600d860739af3620e3c9df86a431a..95b96366a20975b66fbcad98bfaeafcb7a0927b8 100644 (file)
@@ -78,6 +78,11 @@ void script_obj_reset (script_obj_t *obj)
         script_obj_unref (obj->data.obj);
         break;
 
+      case SCRIPT_OBJ_TYPE_EXTEND:
+        script_obj_unref (obj->data.dual_obj.obj_a);
+        script_obj_unref (obj->data.dual_obj.obj_b);
+        break;
+
       case SCRIPT_OBJ_TYPE_NUMBER:
         break;
 
@@ -199,6 +204,20 @@ script_obj_t *script_obj_new_ref (script_obj_t *sub_obj)
   return obj;
 }
 
+script_obj_t *script_obj_new_extend (script_obj_t *obj_a, script_obj_t *obj_b)
+{
+  script_obj_t *obj = malloc (sizeof (script_obj_t));
+  obj_a = script_obj_deref_direct (obj_a);
+  obj_b = script_obj_deref_direct (obj_b);
+  script_obj_ref (obj_a);
+  script_obj_ref (obj_b);
+  obj->type = SCRIPT_OBJ_TYPE_EXTEND;
+  obj->data.dual_obj.obj_a = obj_a;
+  obj->data.dual_obj.obj_b = obj_b;
+  obj->refcount = 1;
+  return obj;
+}
+
 script_obj_t *script_obj_new_native (void                      *object_data,
                                      script_obj_native_class_t *class)
 {
@@ -211,194 +230,198 @@ script_obj_t *script_obj_new_native (void                      *object_data,
   return obj;
 }
 
+void *script_obj_as_custom (script_obj_t             *obj,
+                            script_obj_direct_func_t  user_func,
+                            void                     *user_data)
+{
+  obj = script_obj_deref_direct (obj);
+  void *reply = user_func(obj, user_data);
+  if (reply) return reply;
+  if (obj->type == SCRIPT_OBJ_TYPE_EXTEND)
+    {
+      reply = script_obj_as_custom(obj->data.dual_obj.obj_a, user_func, user_data);
+      if (reply) return reply;
+      reply = script_obj_as_custom(obj->data.dual_obj.obj_b, user_func, user_data);
+      if (reply) return reply;
+    }
+  return NULL;
+}
+
+script_obj_t *script_obj_as_obj_type (script_obj_t      *obj,
+                                      script_obj_type_t  type)
+{
+  obj = script_obj_deref_direct (obj);
+  if (obj->type == type) return obj;
+  if (obj->type == SCRIPT_OBJ_TYPE_EXTEND)
+    {
+      script_obj_t *reply;
+      reply = script_obj_as_obj_type(obj->data.dual_obj.obj_a, type);
+      if (reply) return reply;
+      reply = script_obj_as_obj_type(obj->data.dual_obj.obj_b, type);
+      if (reply) return reply;
+    }
+  return NULL;
+}
+
 script_number_t script_obj_as_number (script_obj_t *obj)
 {                                                     /* If in then reply contents, otherwise reply NAN */
-  obj = script_obj_deref_direct (obj);
-  if (obj->type == SCRIPT_OBJ_TYPE_NUMBER)
-    return obj->data.number;
+  obj = script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_NUMBER);
+  if (obj) return obj->data.number;
   return NAN;
 }
 
-bool script_obj_as_bool (script_obj_t *obj)
+static void *script_obj_direct_as_bool (script_obj_t *obj,
+                                        void         *user_data)
 {                                                 /* False objects are NULL, 0, NAN, "" */
-  obj = script_obj_deref_direct (obj);
   switch (obj->type)
     {
       case SCRIPT_OBJ_TYPE_NUMBER:
         {
           int num_type = fpclassify(obj->data.number);
-          if (num_type == FP_ZERO || num_type == FP_NAN) return false;
-          return true;
+          if (num_type == FP_ZERO || num_type == FP_NAN) return NULL;
+          return obj;
         }
-
       case SCRIPT_OBJ_TYPE_NULL:
-        return false;
-
       case SCRIPT_OBJ_TYPE_REF:
+      case SCRIPT_OBJ_TYPE_EXTEND:
+        return NULL;
       case SCRIPT_OBJ_TYPE_HASH:
       case SCRIPT_OBJ_TYPE_FUNCTION:
       case SCRIPT_OBJ_TYPE_NATIVE:
-        return true;
-
+        return obj;
       case SCRIPT_OBJ_TYPE_STRING:
-        if (*obj->data.string) return true;
-        return false;
+        if (*obj->data.string) return obj;
+        return NULL;
     }
-  return false;
+  return NULL;
 }
 
-char *script_obj_as_string (script_obj_t *obj)              /* reply is strdupped and may be NULL */
+bool script_obj_as_bool (script_obj_t *obj)
 {
-  obj = script_obj_deref_direct (obj);
-  char *reply;
+  return script_obj_as_custom(obj, script_obj_direct_as_bool, NULL);
+}
 
-  switch (obj->type)
+char *script_obj_as_string (script_obj_t *obj)              /* reply is strdupped and may be NULL */
+{
+  script_obj_t *string_obj = script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_STRING);
+  if (string_obj) return strdup (string_obj->data.string);
+  string_obj = script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_NUMBER);
+  if (string_obj)
     {
-      case SCRIPT_OBJ_TYPE_NUMBER:
-        asprintf (&reply, "%g", obj->data.number);
+        char *reply;        
+        asprintf (&reply, "%g", string_obj->data.number);
         return reply;
-
-      case SCRIPT_OBJ_TYPE_NULL:
-        return NULL;
-
-      case SCRIPT_OBJ_TYPE_REF:
-      case SCRIPT_OBJ_TYPE_HASH:
-      case SCRIPT_OBJ_TYPE_FUNCTION:
-      case SCRIPT_OBJ_TYPE_NATIVE:
-        return NULL;
-
-      case SCRIPT_OBJ_TYPE_STRING:
-        return strdup (obj->data.string);
     }
-
   return NULL;
 }
 
-script_function_t *script_obj_as_function (script_obj_t *obj)
+static void *script_obj_direct_as_native_of_class (script_obj_t *obj,
+                                                   void         *user_data)
 {
-  obj = script_obj_deref_direct (obj);
-  if (obj->type == SCRIPT_OBJ_TYPE_FUNCTION)
-    return obj->data.function;
-  
+  script_obj_native_class_t *class = user_data;
+  if (obj->type == SCRIPT_OBJ_TYPE_NATIVE && obj->data.native.class == class)
+    return obj->data.native.object_data;
   return NULL;
 }
 
 void *script_obj_as_native_of_class (script_obj_t              *obj,
                                      script_obj_native_class_t *class)
 {
-  obj = script_obj_deref_direct (obj);
-  if (script_obj_is_native_of_class (obj, class))
+  return script_obj_as_custom(obj, script_obj_direct_as_native_of_class, class);
+}
+
+static void *script_obj_direct_as_native_of_class_name (script_obj_t *obj,
+                                                        void         *user_data)
+{
+  const char *class_name = user_data;
+  if (obj->type == SCRIPT_OBJ_TYPE_NATIVE &&
+      !strcmp (obj->data.native.class->name, class_name))
     return obj->data.native.object_data;
   return NULL;
 }
 
 void *script_obj_as_native_of_class_name (script_obj_t *obj,
-                                          const char *class_name)
+                                          const char   *class_name)
 {
-  obj = script_obj_deref_direct (obj);
-  if (script_obj_is_native_of_class_name (obj, class_name))
-    return obj->data.native.object_data;
-  return NULL;
+  return script_obj_as_custom(obj, 
+                              script_obj_direct_as_native_of_class_name,
+                              (void*) class_name);
 }
 
 bool script_obj_is_null (script_obj_t *obj)
 {
-  obj = script_obj_deref_direct (obj);
-  return obj->type == SCRIPT_OBJ_TYPE_NULL;
+  return script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_NULL);
 }
 
 bool script_obj_is_number (script_obj_t *obj)
 {
-  obj = script_obj_deref_direct (obj);
-  return obj->type == SCRIPT_OBJ_TYPE_NUMBER;
+  return script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_NUMBER);
 }
 
 bool script_obj_is_string (script_obj_t *obj)
 {
-  obj = script_obj_deref_direct (obj);
-  return obj->type == SCRIPT_OBJ_TYPE_STRING;
+  return script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_STRING);
 }
 
 bool script_obj_is_hash (script_obj_t *obj)
 {
-  obj = script_obj_deref_direct (obj);
-  return obj->type == SCRIPT_OBJ_TYPE_HASH;
-}
-
-bool script_obj_is_function (script_obj_t *obj)
-{
-  obj = script_obj_deref_direct (obj);
-  return obj->type == SCRIPT_OBJ_TYPE_FUNCTION;
+  return script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_HASH);
 }
 
 bool script_obj_is_native (script_obj_t *obj)
 {
-  obj = script_obj_deref_direct (obj);
-  return obj->type == SCRIPT_OBJ_TYPE_NATIVE;
+  return script_obj_as_obj_type (obj, SCRIPT_OBJ_TYPE_NATIVE);
 }
 
 bool script_obj_is_native_of_class (script_obj_t              *obj,
                                     script_obj_native_class_t *class)
 {
-  obj = script_obj_deref_direct (obj);
-  return obj->type == SCRIPT_OBJ_TYPE_NATIVE && obj->data.native.class == class;
+  return script_obj_as_custom(obj, 
+                              script_obj_direct_as_native_of_class,
+                              class);
 }
 
 bool script_obj_is_native_of_class_name (script_obj_t *obj,
                                          const char   *class_name)
 {
-  obj = script_obj_deref_direct (obj);
-  return obj->type == SCRIPT_OBJ_TYPE_NATIVE && !strcmp (
-           obj->data.native.class->name,
-           class_name);
+  return script_obj_as_custom(obj, 
+                              script_obj_direct_as_native_of_class_name,
+                              (void*)class_name);
 }
 
 void script_obj_assign (script_obj_t *obj_a,
                         script_obj_t *obj_b)
 {
   obj_b = script_obj_deref_direct (obj_b);
-  if (obj_a == obj_b) return;                   /* FIXME triple check this */
+  script_obj_ref (obj_b);
   script_obj_reset (obj_a);
+  obj_a->type = SCRIPT_OBJ_TYPE_REF;
+  obj_a->data.obj = obj_b;
+}
 
-  switch (obj_b->type)
+static void *script_obj_direct_as_hash_element (script_obj_t *obj,
+                                                void         *user_data)
+{
+  const char *name = user_data;
+  if (obj->type == SCRIPT_OBJ_TYPE_HASH)
     {
-      case SCRIPT_OBJ_TYPE_NULL:
-        obj_a->type = SCRIPT_OBJ_TYPE_NULL;
-        break;
-
-      case SCRIPT_OBJ_TYPE_NUMBER:
-        obj_a->type = SCRIPT_OBJ_TYPE_NUMBER;
-        obj_a->data.number = obj_b->data.number;
-        break;
-
-      case SCRIPT_OBJ_TYPE_STRING:
-        obj_a->type = SCRIPT_OBJ_TYPE_STRING;
-        obj_a->data.string = strdup (obj_b->data.string);
-        break;
-
-      case SCRIPT_OBJ_TYPE_REF:
-        break;
-      case SCRIPT_OBJ_TYPE_HASH:
-      case SCRIPT_OBJ_TYPE_FUNCTION:
-      case SCRIPT_OBJ_TYPE_NATIVE:
-        obj_a->type = SCRIPT_OBJ_TYPE_REF;
-        obj_a->data.obj = obj_b;
-        script_obj_ref (obj_b);
-        break;
+      script_variable_t *variable = ply_hashtable_lookup (obj->data.hash, (void *) name);
+      if (!variable) return NULL;
+      return variable->object;
     }
+  return NULL;
 }
 
 script_obj_t *script_obj_hash_peek_element (script_obj_t *hash,
                                             const char   *name)
 {
-  hash = script_obj_deref_direct (hash);
-  if (hash->type != SCRIPT_OBJ_TYPE_HASH) return NULL;
-  script_variable_t *variable = ply_hashtable_lookup (hash->data.hash,
-                                                      (void *) name);
-  if (!variable) return NULL;
-  
-  script_obj_ref (variable->object);
-  return variable->object;
+  script_obj_t *object;
+  if (!name) return script_obj_new_null ();
+  object = script_obj_as_custom(hash,
+                                script_obj_direct_as_hash_element,
+                                (void*) name);
+  if (object) script_obj_ref (object);
+  return object;
 }
 
 script_obj_t *script_obj_hash_get_element (script_obj_t *hash,
@@ -406,13 +429,16 @@ script_obj_t *script_obj_hash_get_element (script_obj_t *hash,
 {
   script_obj_t *obj = script_obj_hash_peek_element (hash, name);
   if (obj) return obj;
-
-  hash = script_obj_deref_direct (hash);
+  script_obj_t *realhash = script_obj_as_obj_type (hash, SCRIPT_OBJ_TYPE_HASH);
+  if (!realhash)
+    {
+      realhash = script_obj_new_hash();   /* If it wasn't a hash then make it into one */
+      script_obj_assign (hash, realhash);
+    }
   script_variable_t *variable = malloc (sizeof (script_variable_t));
   variable->name = strdup (name);
   variable->object = script_obj_new_null ();
-  ply_hashtable_insert (hash->data.hash, variable->name, variable);
-
+  ply_hashtable_insert (realhash->data.hash, variable->name, variable);
   script_obj_ref (variable->object);
   return variable->object;
 }
@@ -447,16 +473,6 @@ char *script_obj_hash_get_string (script_obj_t *hash,
   return reply;
 }
 
-script_function_t *script_obj_hash_get_function (script_obj_t *hash,
-                                                 const char   *name)
-{
-  script_obj_t *obj = script_obj_hash_get_element (hash, name);
-  script_function_t *function = script_obj_as_function (obj);
-
-  script_obj_unref (obj);
-  return function;
-}
-
 void *script_obj_hash_get_native_of_class (script_obj_t              *hash,
                                            const char                *name,
                                            script_obj_native_class_t *class)
@@ -491,6 +507,11 @@ void script_obj_hash_add_element (script_obj_t *hash,
 script_obj_t *script_obj_plus (script_obj_t *script_obj_a,
                                script_obj_t *script_obj_b)
 {
+  if (script_obj_is_number (script_obj_a) && script_obj_is_number (script_obj_b))
+    {
+      script_number_t value = script_obj_as_number (script_obj_a) + script_obj_as_number (script_obj_b);
+      return script_obj_new_number (value);
+    }
   if (script_obj_is_string (script_obj_a) || script_obj_is_string (script_obj_b))
     {
       script_obj_t *obj;
@@ -509,11 +530,6 @@ script_obj_t *script_obj_plus (script_obj_t *script_obj_a,
       free (string_b);
       return obj;
     }
-  if (script_obj_is_number (script_obj_a) && script_obj_is_number (script_obj_b))
-    {
-      script_number_t value = script_obj_as_number (script_obj_a) + script_obj_as_number (script_obj_b);
-      return script_obj_new_number (value);
-    }
   return script_obj_new_null ();
 }
 
@@ -596,13 +612,8 @@ script_obj_cmp_result_t script_obj_cmp (script_obj_t *script_obj_a,
           return SCRIPT_OBJ_CMP_RESULT_EQ;
         }
     }
-  else if ((script_obj_is_hash (script_obj_a) && script_obj_is_function (script_obj_b)) ||
-           (script_obj_is_function (script_obj_a) && script_obj_is_function (script_obj_b)) ||
-           (script_obj_is_native (script_obj_a) && script_obj_is_native (script_obj_b)))
-    {
-      if (script_obj_deref_direct (script_obj_a) == script_obj_deref_direct (script_obj_b))
+  else if (script_obj_deref_direct (script_obj_a) == script_obj_deref_direct (script_obj_b))
         return SCRIPT_OBJ_CMP_RESULT_EQ;
-    }
   return SCRIPT_OBJ_CMP_RESULT_NE;
 }
 
index 27115d2d2bb8a5d246ee89d86c98da8ba477b52d..8d5981b45eb42bd2f13b0739c49d9a696b98201c 100644 (file)
@@ -34,6 +34,10 @@ typedef enum
   SCRIPT_OBJ_CMP_RESULT_NE = 1<<4,
 } script_obj_cmp_result_t;
 
+
+typedef void *(*script_obj_direct_func_t)(script_obj_t *, void *);
+
+
 void script_obj_free (script_obj_t *obj);
 void script_obj_ref (script_obj_t *obj);
 void script_obj_unref (script_obj_t *obj);
@@ -46,13 +50,18 @@ script_obj_t *script_obj_new_null (void);
 script_obj_t *script_obj_new_hash (void);
 script_obj_t *script_obj_new_function (script_function_t *function);
 script_obj_t *script_obj_new_ref (script_obj_t *sub_obj);
+script_obj_t *script_obj_new_extend (script_obj_t *obj_a, script_obj_t *obj_b);
 
 script_obj_t *script_obj_new_native (void                       *object_data,
                                      script_obj_native_class_t  *class );
+void *script_obj_as_custom (script_obj_t             *obj,
+                            script_obj_direct_func_t  user_func,
+                            void                     *user_data);
+script_obj_t *script_obj_as_obj_type (script_obj_t      *obj,
+                                      script_obj_type_t  type);
 script_number_t script_obj_as_number (script_obj_t *obj);
 bool script_obj_as_bool (script_obj_t *obj);
 char *script_obj_as_string (script_obj_t *obj);
-script_function_t *script_obj_as_function (script_obj_t *obj);
 void *script_obj_as_native_of_class (script_obj_t              *obj,
                                      script_obj_native_class_t *class );
 void *script_obj_as_native_of_class_name (script_obj_t *obj,
@@ -61,7 +70,6 @@ bool script_obj_is_null (script_obj_t *obj);
 bool script_obj_is_number (script_obj_t *obj);
 bool script_obj_is_string (script_obj_t *obj);
 bool script_obj_is_hash (script_obj_t *obj);
-bool script_obj_is_function (script_obj_t *obj);
 bool script_obj_is_native (script_obj_t *obj);
 
 bool script_obj_is_native_of_class (script_obj_t * obj,
@@ -80,8 +88,6 @@ bool script_obj_hash_get_bool (script_obj_t *hash,
                                const char   *name);
 char *script_obj_hash_get_string (script_obj_t *hash,
                                   const char   *name);
-script_function_t *script_obj_hash_get_function (script_obj_t *hash,
-                                                 const char   *name);
 void *script_obj_hash_get_native_of_class (script_obj_t *hash,
                                            const char   *name,
                                            script_obj_native_class_t *class );
index b2799776dc8fd73f87d577cb7838083561930d03..8e9a355976c0ec4d06437463a863aef3b2415be2 100644 (file)
@@ -438,28 +438,30 @@ static script_exp_t *script_parse_exp_ltr (script_scan_t *scan, int presedence)
 {
   static const script_parse_operator_table_entry_t operator_table[] =
     {
-      {"||", SCRIPT_EXP_TYPE_OR,         0},    /* FIXME Does const imply static? */
-      {"&&", SCRIPT_EXP_TYPE_AND,        1},
-      {"==", SCRIPT_EXP_TYPE_EQ,         2},
-      {"!=", SCRIPT_EXP_TYPE_NE,         2},
-      {">=", SCRIPT_EXP_TYPE_GE,         3},
-      {"<=", SCRIPT_EXP_TYPE_LE,         3},
+      {"||", SCRIPT_EXP_TYPE_OR,         1},    /* FIXME Does const imply static? */
+      {"&&", SCRIPT_EXP_TYPE_AND,        2},
+      {"==", SCRIPT_EXP_TYPE_EQ,         3},
+      {"!=", SCRIPT_EXP_TYPE_NE,         3},
+      {">=", SCRIPT_EXP_TYPE_GE,         4},
+      {"<=", SCRIPT_EXP_TYPE_LE,         4},
       {"+=", SCRIPT_EXP_TYPE_TERM_NULL, -1},    /* A few things it shouldn't consume */
       {"-=", SCRIPT_EXP_TYPE_TERM_NULL, -1},
       {"*=", SCRIPT_EXP_TYPE_TERM_NULL, -1},
       {"/=", SCRIPT_EXP_TYPE_TERM_NULL, -1},
       {"%=", SCRIPT_EXP_TYPE_TERM_NULL, -1},
-      {">",  SCRIPT_EXP_TYPE_GT,         3},
-      {"<",  SCRIPT_EXP_TYPE_LT,         3},
-      {"+",  SCRIPT_EXP_TYPE_PLUS,       4},
-      {"-",  SCRIPT_EXP_TYPE_MINUS,      4},
-      {"*",  SCRIPT_EXP_TYPE_MUL,        5},
-      {"/",  SCRIPT_EXP_TYPE_DIV,        5},
-      {"%",  SCRIPT_EXP_TYPE_MOD,        5},
+      {"|=", SCRIPT_EXP_TYPE_TERM_NULL, -1},
+      {"|",  SCRIPT_EXP_TYPE_EXTEND,     0},
+      {">",  SCRIPT_EXP_TYPE_GT,         4},
+      {"<",  SCRIPT_EXP_TYPE_LT,         4},
+      {"+",  SCRIPT_EXP_TYPE_PLUS,       5},
+      {"-",  SCRIPT_EXP_TYPE_MINUS,      5},
+      {"*",  SCRIPT_EXP_TYPE_MUL,        6},
+      {"/",  SCRIPT_EXP_TYPE_DIV,        6},
+      {"%",  SCRIPT_EXP_TYPE_MOD,        6},    /* Put this number into the "presedence > ?" line below*/
       {NULL, SCRIPT_EXP_TYPE_TERM_NULL, -1},
     };
     
-  if (presedence > 5) return script_parse_exp_po (scan);
+  if (presedence > 6) return script_parse_exp_po (scan);
   script_exp_t *exp = script_parse_exp_ltr (scan, presedence + 1);
   if (!exp) return NULL;
   
@@ -474,7 +476,7 @@ static script_exp_t *script_parse_exp_ltr (script_scan_t *scan, int presedence)
       if (!exp->data.dual.sub_b)
         {
           script_parse_error (&script_scan_get_current_token (scan)->location,
-                              "An invalid RHS of an expression");
+                              "An invalid RHS of an operation");
           return NULL;
         }
     }
@@ -490,6 +492,7 @@ static script_exp_t *script_parse_exp_as (script_scan_t *scan)
       {"*=", SCRIPT_EXP_TYPE_ASSIGN_MUL,   0}, 
       {"/=", SCRIPT_EXP_TYPE_ASSIGN_DIV,   0}, 
       {"%=", SCRIPT_EXP_TYPE_ASSIGN_MOD,   0}, 
+      {"|=", SCRIPT_EXP_TYPE_ASSIGN_EXTEND,0},
       {"=",  SCRIPT_EXP_TYPE_ASSIGN,       0}, 
       {NULL, SCRIPT_EXP_TYPE_TERM_NULL,   -1}, 
     };
@@ -505,7 +508,7 @@ static script_exp_t *script_parse_exp_as (script_scan_t *scan)
   if (!rhs)
     {
       script_parse_error (&script_scan_get_current_token (scan)->location,
-                          "An invalid RHS of an expression");
+                          "An invalid RHS of an assign");
       return NULL;
     }
   return script_parse_new_exp_dual (entry->exp_type, lhs, rhs, &location);
@@ -695,6 +698,8 @@ static script_op_t *script_parse_return (script_scan_t *scan)
   script_op_type_t type;
   if      (script_scan_token_is_identifier_of_value (curtoken, "return"))
     type = SCRIPT_OP_TYPE_RETURN;
+  else if (script_scan_token_is_identifier_of_value (curtoken, "fail"))
+    type = SCRIPT_OP_TYPE_FAIL;
   else if (script_scan_token_is_identifier_of_value (curtoken, "break"))
     type = SCRIPT_OP_TYPE_BREAK;
   else if (script_scan_token_is_identifier_of_value (curtoken, "continue"))
@@ -790,12 +795,14 @@ static void script_parse_exp_free (script_exp_t *exp)
       case SCRIPT_EXP_TYPE_LE:
       case SCRIPT_EXP_TYPE_AND:
       case SCRIPT_EXP_TYPE_OR:
+      case SCRIPT_EXP_TYPE_EXTEND:
       case SCRIPT_EXP_TYPE_ASSIGN:
       case SCRIPT_EXP_TYPE_ASSIGN_PLUS:
       case SCRIPT_EXP_TYPE_ASSIGN_MINUS:
       case SCRIPT_EXP_TYPE_ASSIGN_MUL:
       case SCRIPT_EXP_TYPE_ASSIGN_DIV:
       case SCRIPT_EXP_TYPE_ASSIGN_MOD:
+      case SCRIPT_EXP_TYPE_ASSIGN_EXTEND:
       case SCRIPT_EXP_TYPE_HASH:
         script_parse_exp_free (exp->data.dual.sub_a);
         script_parse_exp_free (exp->data.dual.sub_b);
@@ -864,38 +871,29 @@ void script_parse_op_free (script_op_t *op)
   switch (op->type)
     {
       case SCRIPT_OP_TYPE_EXPRESSION:
-        {
-          script_parse_exp_free (op->data.exp);
-          break;
-        }
+        script_parse_exp_free (op->data.exp);
+        break;
 
       case SCRIPT_OP_TYPE_OP_BLOCK:
-        {
-          script_parse_op_list_free (op->data.list);
-          break;
-        }
+        script_parse_op_list_free (op->data.list);
+        break;
 
       case SCRIPT_OP_TYPE_IF:
       case SCRIPT_OP_TYPE_WHILE:
       case SCRIPT_OP_TYPE_FOR:
-        {
-          script_parse_exp_free (op->data.cond_op.cond);
-          script_parse_op_free  (op->data.cond_op.op1);
-          script_parse_op_free  (op->data.cond_op.op2);
-          break;
-        }
+        script_parse_exp_free (op->data.cond_op.cond);
+        script_parse_op_free  (op->data.cond_op.op1);
+        script_parse_op_free  (op->data.cond_op.op2);
+        break;
 
       case SCRIPT_OP_TYPE_RETURN:
-        {
-          if (op->data.exp) script_parse_exp_free (op->data.exp);
-          break;
-        }
+        if (op->data.exp) script_parse_exp_free (op->data.exp);
+        break;
 
+      case SCRIPT_OP_TYPE_FAIL:
       case SCRIPT_OP_TYPE_BREAK:
       case SCRIPT_OP_TYPE_CONTINUE:
-        {
-          break;
-        }
+        break;
     }
   script_debug_remove_element (op);
   free (op);
index 1e984f79b996d232910b7235964d9ea32dd38bef..45254bd6ef83b875d61594374c634e25a84b8bf3 100644 (file)
@@ -30,6 +30,7 @@ typedef enum                        /* FIXME add _t to all types */
 {
   SCRIPT_RETURN_TYPE_NORMAL,
   SCRIPT_RETURN_TYPE_RETURN,
+  SCRIPT_RETURN_TYPE_FAIL,
   SCRIPT_RETURN_TYPE_BREAK,
   SCRIPT_RETURN_TYPE_CONTINUE,
 } script_return_type_t;
@@ -92,6 +93,7 @@ typedef enum
 {
   SCRIPT_OBJ_TYPE_NULL,
   SCRIPT_OBJ_TYPE_REF,
+  SCRIPT_OBJ_TYPE_EXTEND,
   SCRIPT_OBJ_TYPE_NUMBER,
   SCRIPT_OBJ_TYPE_STRING,
   SCRIPT_OBJ_TYPE_HASH,
@@ -108,6 +110,11 @@ typedef struct script_obj_t
     script_number_t number;
     char *string;
     struct script_obj_t *obj;
+    struct
+      {
+        struct script_obj_t *obj_a;
+        struct script_obj_t *obj_b;
+      } dual_obj;
     script_function_t *function;
     ply_hashtable_t *hash;
     script_obj_native_t native;
@@ -136,6 +143,7 @@ typedef enum
   SCRIPT_EXP_TYPE_NE,
   SCRIPT_EXP_TYPE_AND,
   SCRIPT_EXP_TYPE_OR,
+  SCRIPT_EXP_TYPE_EXTEND,
   SCRIPT_EXP_TYPE_NOT,
   SCRIPT_EXP_TYPE_POS,
   SCRIPT_EXP_TYPE_NEG,
@@ -152,6 +160,7 @@ typedef enum
   SCRIPT_EXP_TYPE_ASSIGN_MUL,
   SCRIPT_EXP_TYPE_ASSIGN_DIV,
   SCRIPT_EXP_TYPE_ASSIGN_MOD,
+  SCRIPT_EXP_TYPE_ASSIGN_EXTEND,
 } script_exp_type_t;
 
 typedef struct script_exp_t
@@ -184,6 +193,7 @@ typedef enum
   SCRIPT_OP_TYPE_WHILE,
   SCRIPT_OP_TYPE_FOR,
   SCRIPT_OP_TYPE_RETURN,
+  SCRIPT_OP_TYPE_FAIL,
   SCRIPT_OP_TYPE_BREAK,
   SCRIPT_OP_TYPE_CONTINUE,
 } script_op_type_t;
@@ -213,7 +223,9 @@ typedef struct
 
 #define script_return_obj(_return_object) ((script_return_t) {SCRIPT_RETURN_TYPE_RETURN, _return_object})
 #define script_return_obj_null() ((script_return_t) {SCRIPT_RETURN_TYPE_RETURN, script_obj_new_null ()})
+#define script_return_fail() ((script_return_t) {SCRIPT_RETURN_TYPE_FAIL, NULL})
 #define script_return_normal() ((script_return_t) {SCRIPT_RETURN_TYPE_NORMAL, NULL})
+#define script_return_normal_obj(_return_object) ((script_return_t) {SCRIPT_RETURN_TYPE_NORMAL, _return_object})
 #define script_return_break() ((script_return_t) {SCRIPT_RETURN_TYPE_BREAK, NULL})
 #define script_return_continue() ((script_return_t) {SCRIPT_RETURN_TYPE_CONTINUE, NULL})