[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.
This commit is contained in:
Charlie Brej 2009-09-09 20:57:19 +01:00
parent 771cf20a49
commit e564655e13
14 changed files with 624 additions and 452 deletions

View 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);
}
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_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 ();
}
}
}
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 ();

View file

@ -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 */

View 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;
}

View 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 ();
}

View 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);

View 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;

View 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);
}

View 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;

View 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;

View 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);
}

View 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;
}
bool script_obj_as_bool (script_obj_t *obj)
{
return script_obj_as_custom(obj, script_obj_direct_as_bool, NULL);
}
char *script_obj_as_string (script_obj_t *obj) /* reply is strdupped and may be NULL */
{
obj = script_obj_deref_direct (obj);
char *reply;
switch (obj->type)
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;
}

View 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 );

View 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);

View 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})