#include "ply-list.h"
#include <stdio.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <fcntl.h>
#include <assert.h>
#include <stdbool.h>
#include "script-object.h"
static script_obj* script_evaluate (script_state* state, script_exp* exp);
+static script_return script_execute_function_with_parlist (script_state* state, script_function* function, ply_list_t* parameter_data);
static script_obj* script_evaluate_plus (script_state* state, script_exp* exp)
{
static script_obj* script_evaluate_func (script_state* state, script_exp* exp)
{
- script_state localstate;
script_obj* func = script_evaluate (state, exp->data.function.name);
script_obj* obj = NULL;
script_obj_deref (&func);
if (func->type != SCRIPT_OBJ_TYPE_FUNCTION)
return script_obj_new_null ();
- localstate = *state;
- localstate.local = script_obj_new_hash();
+ ply_list_t* parameter_expressions = exp->data.function.parameters;
+ ply_list_t* parameter_data = ply_list_new();
- ply_list_t* parameter_names = func->data.function->parameters;
- ply_list_t* parameter_data = exp->data.function.parameters;
-
- ply_list_node_t *node_name = ply_list_get_first_node (parameter_names);
- ply_list_node_t *node_data = ply_list_get_first_node (parameter_data);
- while (node_name && node_data){
- script_exp* data_exp = ply_list_node_get_data (node_data);
- char* name = ply_list_node_get_data (node_name);
+ ply_list_node_t *node_expression = ply_list_get_first_node (parameter_expressions);
+ while (node_expression){
+ script_exp* data_exp = ply_list_node_get_data (node_expression);
script_obj* data_obj = script_evaluate (state, data_exp);
-
- script_vareable* vareable = malloc(sizeof(script_vareable));
- vareable->name = strdup(name);
- vareable->object = data_obj;
-
- ply_hashtable_insert (localstate.local->data.hash, vareable->name, vareable);
-
-
- node_name = ply_list_get_next_node (parameter_names, node_name);
- node_data = ply_list_get_next_node (parameter_data, node_data);
+ ply_list_append_data (parameter_data, data_obj);
+ node_expression = ply_list_get_next_node (parameter_expressions, node_expression);
}
- script_return reply;
- switch (func->data.function->type){
- case SCRIPT_FUNCTION_TYPE_SCRIPT:
- {
- script_op* op = func->data.function->data.script;
- reply = script_execute (&localstate, op);
- break;
- }
- case SCRIPT_FUNCTION_TYPE_NATIVE:
- {
- reply = func->data.function->data.native (&localstate, func->data.function->user_data);
- break;
- }
- }
-
-
-
- script_obj_unref (localstate.local);
- script_obj_unref (func);
+ script_return reply = script_execute_function_with_parlist (state, func->data.function, parameter_data);
if (reply.type == SCRIPT_RETURN_TYPE_RETURN)
obj = reply.object;
- if (!obj){
- obj = script_obj_new_null ();
+ else
+ obj = script_obj_new_null();
+
+ ply_list_node_t *node_data = ply_list_get_first_node (parameter_data);
+ while (node_data){
+ script_obj* data_obj = ply_list_node_get_data (node_data);
+ script_obj_unref (data_obj);
+ node_data = ply_list_get_next_node (parameter_data, node_data);
}
+ ply_list_free(parameter_data);
+
+ script_obj_unref (func);
+
return obj;
}
return reply;
}
+ // parameter_data list should be freed by caller
+static script_return script_execute_function_with_parlist (script_state* state, script_function* function, ply_list_t* parameter_data)
+{
+ script_state* sub_state = script_state_init_sub(state);
+
+ ply_list_t* parameter_names = function->parameters;
+
+ ply_list_node_t *node_name = ply_list_get_first_node (parameter_names);
+ ply_list_node_t *node_data = ply_list_get_first_node (parameter_data);
+ while (node_name && node_data){
+ script_obj* data_obj = ply_list_node_get_data (node_data);
+ char* name = ply_list_node_get_data (node_name);
+
+ script_obj_hash_add_element (sub_state->local, data_obj, name);
+
+ node_name = ply_list_get_next_node (parameter_names, node_name);
+ node_data = ply_list_get_next_node (parameter_data, node_data);
+ }
+
+ script_return reply;
+ switch (function->type){
+ case SCRIPT_FUNCTION_TYPE_SCRIPT:
+ {
+ script_op* op = function->data.script;
+ reply = script_execute (sub_state, op);
+ break;
+ }
+ case SCRIPT_FUNCTION_TYPE_NATIVE:
+ {
+ reply = function->data.native (sub_state, function->user_data);
+ break;
+ }
+ }
+
+ script_state_destroy(sub_state);
+ return reply;
+}
+
+
+script_return script_execute_function (script_state* state, script_function* function, script_obj* first_arg, ...)
+{
+ script_return reply;
+ va_list args;
+ script_obj* arg;
+ ply_list_t *parameter_data = ply_list_new();
+
+ arg = first_arg;
+ va_start (args, first_arg);
+ while (arg){
+ ply_list_append_data (parameter_data, arg);
+ arg = va_arg (args, script_obj*);
+ }
+ va_end (args);
+
+ reply = script_execute_function_with_parlist (state, function, parameter_data);
+ ply_list_free(parameter_data);
+
+ return reply;
+}
+
script_return script_execute (script_state* state, script_op* op)
{
#define _GNU_SOURCE
#include "ply-utils.h"
#include "script.h"
+#include "script-parse.h"
#include "script-execute.h"
#include "script-object.h"
#include "script-lib-plymouth.h"
static script_return plymouth_set_refresh (script_state* state, void* user_data)
{
- script_lib_plymouth_data_t* data = user_data;
+ script_obj** script_func = user_data;
script_obj* obj = script_obj_hash_get_element (state->local, "function");
script_obj_deref(&obj);
+ if (*script_func)
+ script_obj_unref(*script_func);
+
if (obj->type == SCRIPT_OBJ_TYPE_FUNCTION){
- data->script_refresh_func = obj;
+ *script_func = obj;
+ }
+ else {
+ *script_func = NULL;
+ script_obj_unref(obj);
}
+
return (script_return){SCRIPT_RETURN_TYPE_RETURN, script_obj_new_null ()};
}
data->script_refresh_func = NULL;
- script_add_native_function (state->global, "PlymouthSetRefreshFunction", plymouth_set_refresh, data, "function", NULL);
+ script_add_native_function (state->global, "PlymouthSetRefreshFunction", plymouth_set_refresh, &data->script_refresh_func, "function", NULL);
data->script_main_op = script_parse_string (script_lib_plymouth_string);
script_return ret = script_execute(state, data->script_main_op);
if (ret.object) script_obj_unref(ret.object); // Throw anything sent back away
script_obj_unref(data->script_refresh_func);
free(data);
}
+
+
+
+
+void script_lib_plymouth_on_refresh(script_state* state, script_lib_plymouth_data_t* data)
+{
+ script_obj* refresh_func_obj = data->script_refresh_func;
+ if (refresh_func_obj && refresh_func_obj->type == SCRIPT_OBJ_TYPE_FUNCTION){
+ script_return ret = script_execute_function (state, data->script_refresh_func->data.function, NULL);
+ if (ret.object) script_obj_unref(ret.object); // Throw anything sent back away
+ }
+}
+