From: Charlie Brej Date: Wed, 9 Sep 2009 19:57:19 +0000 (+0100) Subject: [script] Add inheritance to the language X-Git-Tag: 0.7.2~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e564655e13b5ac7f0d4acf37db098cc66bc43958;p=thirdparty%2Fplymouth.git [script] Add inheritance to the language 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. --- diff --git a/src/plugins/splash/script/script-execute.c b/src/plugins/splash/script/script-execute.c index 0a0edad9..0ab15cf4 100644 --- a/src/plugins/splash/script/script-execute.c +++ b/src/plugins/splash/script/script-execute.c @@ -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 (); diff --git a/src/plugins/splash/script/script-execute.h b/src/plugins/splash/script/script-execute.h index 8eb1174c..efba3ed8 100644 --- a/src/plugins/splash/script/script-execute.h +++ b/src/plugins/splash/script/script-execute.h @@ -26,10 +26,10 @@ 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 */ diff --git a/src/plugins/splash/script/script-lib-image.c b/src/plugins/splash/script/script-lib-image.c index 37ad2e9d..0474ae9c 100644 --- a/src/plugins/splash/script/script-lib-image.c +++ b/src/plugins/splash/script/script-lib-image.c @@ -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; } diff --git a/src/plugins/splash/script/script-lib-image.script b/src/plugins/splash/script/script-lib-image.script index bac9c714..a64a3e45 100644 --- a/src/plugins/splash/script/script-lib-image.script +++ b/src/plugins/splash/script/script-lib-image.script @@ -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 (); +} diff --git a/src/plugins/splash/script/script-lib-math.c b/src/plugins/splash/script/script-lib-math.c index ad3b0054..a78221b8 100644 --- a/src/plugins/splash/script/script-lib-math.c +++ b/src/plugins/splash/script/script-lib-math.c @@ -20,7 +20,6 @@ * Written by: Charlie Brej */ #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); diff --git a/src/plugins/splash/script/script-lib-math.script b/src/plugins/splash/script/script-lib-math.script index e5c65424..daaada10 100644 --- a/src/plugins/splash/script/script-lib-math.script +++ b/src/plugins/splash/script/script-lib-math.script @@ -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; diff --git a/src/plugins/splash/script/script-lib-plymouth.c b/src/plugins/splash/script/script-lib-plymouth.c index 2dfee919..8a3fe2e8 100644 --- a/src/plugins/splash/script/script-lib-plymouth.c +++ b/src/plugins/splash/script/script-lib-plymouth.c @@ -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); } diff --git a/src/plugins/splash/script/script-lib-plymouth.script b/src/plugins/splash/script/script-lib-plymouth.script index bac9c714..4eb85c80 100644 --- a/src/plugins/splash/script/script-lib-plymouth.script +++ b/src/plugins/splash/script/script-lib-plymouth.script @@ -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; diff --git a/src/plugins/splash/script/script-lib-sprite.c b/src/plugins/splash/script/script-lib-sprite.c index e8dde377..3beded22 100644 --- a/src/plugins/splash/script/script-lib-sprite.c +++ b/src/plugins/splash/script/script-lib-sprite.c @@ -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; diff --git a/src/plugins/splash/script/script-lib-sprite.script b/src/plugins/splash/script/script-lib-sprite.script index 847778ab..b88127f5 100644 --- a/src/plugins/splash/script/script-lib-sprite.script +++ b/src/plugins/splash/script/script-lib-sprite.script @@ -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); +} + diff --git a/src/plugins/splash/script/script-object.c b/src/plugins/splash/script/script-object.c index 1cf52636..95b96366 100644 --- a/src/plugins/splash/script/script-object.c +++ b/src/plugins/splash/script/script-object.c @@ -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; } diff --git a/src/plugins/splash/script/script-object.h b/src/plugins/splash/script/script-object.h index 27115d2d..8d5981b4 100644 --- a/src/plugins/splash/script/script-object.h +++ b/src/plugins/splash/script/script-object.h @@ -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 ); diff --git a/src/plugins/splash/script/script-parse.c b/src/plugins/splash/script/script-parse.c index b2799776..8e9a3559 100644 --- a/src/plugins/splash/script/script-parse.c +++ b/src/plugins/splash/script/script-parse.c @@ -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); diff --git a/src/plugins/splash/script/script.h b/src/plugins/splash/script/script.h index 1e984f79..45254bd6 100644 --- a/src/plugins/splash/script/script.h +++ b/src/plugins/splash/script/script.h @@ -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})