Ejemplo n.º 1
0
int construct_tree(NODE* root, char *input_string, int index)
{
	if(input_string == NULL)
	{
		return NULL;
	}
	if(input_string[index-1]=='\0' || input_string[index-1]=='$')
	{
		root->left_child = NULL;
		root->right_child = NULL;
		return index;
	}
	int result;
	result = create_number(input_string,index);
	if(result!=NULL)
	{
		NODE *temp = (NODE*)malloc(sizeof(NODE));
		temp->data = result;
		root->left_child = temp;
	}
	else if(result==NULL)
	{
		root->left_child = NULL;
	}
	if(root->left_child!=NULL)
	{
		index = next_element_in_string(input_string,index);
		index = construct_tree(root->left_child,input_string,index);
	}
	index = next_element_in_string(input_string,index);
	result = create_number(input_string,index);
	if(result!=NULL)
	{
		NODE *temp = (NODE*)malloc(sizeof(NODE));
		temp->data = result;
		root->right_child = temp;
	}
	else if(result==NULL)
	{
		root->right_child = NULL;
	}
	if(root->right_child!=NULL)
	{
		index = next_element_in_string(input_string,index);
		index = construct_tree(root->right_child,input_string,index);
		return index;
	}
	else if(root->right_child==NULL)
	{
		return index;
	}
}
Ejemplo n.º 2
0
void test_array_to_tree_convertor()
{
	char input[4][36] = {"1,2,3,4","1,2","1,2,3","1,2,3,4,5,6,7,8,9,10,11,12,13,14,15"};
	char output[4][52] = {
					  "3,2,1,$,-,4,$",
					  "2,1,$",
					  "2,1,$,3,$",
					  "8,4,2,1,$,3,$,6,5,$,7,$,12,10,9,$,11,$,14,13,$,15,$"
					 };
	int iter_loop, index;
	for(iter_loop=0;iter_loop<4;iter_loop++)
	{
		printf("%d-->",iter_loop+1);
		NODE *root1 = string_to_tree_converter(input[iter_loop]);
		NODE *root2 = (NODE*)malloc(sizeof(NODE));

		index = next_element_in_string(output[iter_loop],0);
		root2->data = create_number(output[iter_loop],index);
		index = next_element_in_string(output[iter_loop],index);
		construct_tree(root2,output[iter_loop],index);

		(tree_comparator(root1,root2) == 1)?(printf("ACCEPTED\n")):(printf("REJECTED\n"));
		delete_tree(root1);
		delete_tree(root2);
	}
}
Ejemplo n.º 3
0
int parse_factor(CALC_ELEMENT ** e)
{
	PARSE_SYMBOL s = get_symbol();
	switch (s) {
	case PARSE_NUMBER:
		*e = create_number(get_current_number());
		accept(s);
		return 0;
		break;
	case PARSE_X:
		*e = create_x();
		accept(s);
		return 0;
		break;
	case PARSE_LOG:
		return parse_log(e);
		break;
	case PARSE_LPAREN:
		return parse_paren_expr(e);
		break;
	default:
		parser_error("\'number\', \'x\', \'log\' or \'(\'");
		return -1;
	}
}
Ejemplo n.º 4
0
/*	Create IP address(mask) from a number - num
*	This function creates a string as IP address from an integer value - for instance /25.
*	It checks if the number is big enough to contain a multiple of 8, if it is the one part of IP address is 255
*	If its not, it creates a nubmer that has the specified number of 1's at the begginig.
*/
void create_mask(int num, char *mask){
	int parts[4] = {0, 0, 0, 0};
	int i = 0;

	while(i < 4){
		if(num <= 0){
			parts[i] = 0;
		}
		else if(num % 8 == 0){
			parts[i] = 255;
		}
		else{
			if(num / 8 >= 1){
				parts[i] = 255;
			}
			else{
				parts[i] = create_number(num%8);
			}
		}
		num = num - 8;
		i++;
	}

	//std::cout << parts[0] << "." << parts[1] << "." << parts[2] << "." << parts[3] << std::endl;

	
	snprintf(mask, 15, "%d.%d.%d.%d", parts[0], parts[1], parts[2], parts[3]);
}
Ejemplo n.º 5
0
void MAXIMUM_NODE_IN_TREE()
{
	char input[5][52] = {   
					  "1,$",
					  "2,4,1,$,-,3,$",
					  "1,2,$,-",
					  "1,3,$,2,$",
					  "14,1,4,2,$,6,$,10,8,$,12,$,13,3,15,$,5,$,9,7,$,11,$"
					 };
	int expected_output[6] = {1,4,2,3,15};
	int iter_loop, index;
	for(iter_loop=0;iter_loop<5;iter_loop++)
	{
		NODE *root = (NODE*)malloc(sizeof(NODE));
		index = next_element_in_string(input[iter_loop],0);
		root->data = create_number(input[iter_loop],index);
		index = next_element_in_string(input[iter_loop],index);
		construct_tree(root,input[iter_loop],index);
		
		int previous_value = root->data;
		Inorder(root,&previous_value);
		(expected_output[iter_loop]==previous_value)?printf("ACCEPTED\n"):printf("REJECTED\n");
		delete_tree(root);
	}
}
Ejemplo n.º 6
0
void test_calc_bad(void)
{
	CALC_ELEMENT *t1, *t2;
	/* division by zero, simple */
	t1 = create_number(9.0);
	t2 = create_number(0.0);
	t1 = create_bin_op('/', t1, t2);
	CU_ASSERT_NOT_EQUAL(calculate(&t1), 0);
	CU_ASSERT_EQUAL(t1->status & STATUS_CALC_DIV_BY_ZERO,
			STATUS_CALC_DIV_BY_ZERO);
	free_calc_element(t1);
	/* division by zero, complex */
	t1 = create_bin_op('/', create_number(4.0),
			   create_bin_op('-', create_number(2.0),
					 create_number(2.0)));
	CU_ASSERT_NOT_EQUAL(calculate(&t1), 0);
	CU_ASSERT_EQUAL(t1->status & STATUS_CALC_DIV_BY_ZERO,
			STATUS_CALC_DIV_BY_ZERO);
	free_calc_element(t1);
	/* log zero */
	t1 = create_log(create_number(0.0));
	CU_ASSERT_NOT_EQUAL(calculate(&t1), 0);
	CU_ASSERT_EQUAL(t1->status & STATUS_CALC_DOMAIN, STATUS_CALC_DOMAIN);
	free_calc_element(t1);
	/* log less than zero */
	t1 = create_log(create_number(-3.0));
	CU_ASSERT_NOT_EQUAL(calculate(&t1), 0);
	CU_ASSERT_EQUAL(t1->status & STATUS_CALC_DOMAIN, STATUS_CALC_DOMAIN);
	free_calc_element(t1);
	/* log zero, complex */
	t1 = create_log(create_bin_op
			('*', create_number(0.0), create_number(28.0)));
	CU_ASSERT_NOT_EQUAL(calculate(&t1), 0);
	CU_ASSERT_EQUAL(t1->status & STATUS_CALC_DOMAIN, STATUS_CALC_DOMAIN);
	free_calc_element(t1);
	/* x in the expression, simple */
	t1 = create_x();
	CU_ASSERT_NOT_EQUAL(calculate(&t1), 0);
	CU_ASSERT_EQUAL(t1->status & STATUS_X_PRESENT, STATUS_X_PRESENT);
	free_calc_element(t1);
	/* x in the expression, complex */
	t1 = create_bin_op('-', create_x(), create_number(17));
	CU_ASSERT_NOT_EQUAL(calculate(&t1), 0);
	CU_ASSERT_EQUAL(t1->status & STATUS_X_PRESENT, STATUS_X_PRESENT);
	free_calc_element(t1);
}
Ejemplo n.º 7
0
void test_number_cf(void)
{
	CALC_ELEMENT *t1 = create_number(15.0);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_NUM);
	CU_ASSERT_EQUAL(t1->status, 0);
	CU_ASSERT_EQUAL(t1->value, 15.0);
	CU_ASSERT_PTR_NULL(t1->left);
	CU_ASSERT_PTR_NULL(t1->right);
	free_calc_element(t1);
}
Ejemplo n.º 8
0
Archivo: number.c Proyecto: r6144/wine
static HRESULT NumberConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
        VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
    VARIANT num;
    HRESULT hres;

    TRACE("\n");

    switch(flags) {
    case INVOKE_FUNC:
        if(!arg_cnt(dp)) {
            if(retv) {
                V_VT(retv) = VT_I4;
                V_I4(retv) = 0;
            }
            return S_OK;
        }

        hres = to_number(ctx, get_arg(dp, 0), ei, &num);
        if(FAILED(hres))
            return hres;

        if(retv)
            *retv = num;
        break;

    case DISPATCH_CONSTRUCT: {
        jsdisp_t *obj;

        if(arg_cnt(dp)) {
            hres = to_number(ctx, get_arg(dp, 0), ei, &num);
            if(FAILED(hres))
                return hres;
        }else {
            V_VT(&num) = VT_I4;
            V_I4(&num) = 0;
        }

        hres = create_number(ctx, &num, &obj);
        if(FAILED(hres))
            return hres;

        var_set_jsdisp(retv, obj);
        break;
    }
    default:
        FIXME("unimplemented flags %x\n", flags);
        return E_NOTIMPL;
    }

    return S_OK;
}
Ejemplo n.º 9
0
//0 arg -> return number 0 to 1 (float)
//1 arg -> return number 0 to n (int)
//2 arg -> return number a to b (int)
static DexRef builtin_rand(DexRef* args, size_t n) {
	const char* NAME = "rand";

	if (n > 2) {
		arg_amnt_err(NAME, n, 0, 2);
		return NONE;
	}
	if (n == 0) {
		return create_number(twist_state.genrand_res53());
	} else if (n == 1) {
		int max;
		if (!dex_econv(&max, args[0], NAME)) {
			return NONE;
		} else {
			if (max <= 0)
				arg_type_err(NAME,"int (greater than 0)");
			size_t st = twist_state.genrand_int32();
			return create_number(st % max);
		}
	} else {
		int min, max;
		if (!dex_econv(&min, args[0], NAME) || !dex_econv(&max, args[1], NAME)) {
			return NONE;
		} else {
			if (min > max) {
				int t = min;
				min = max;
				max = t;
			} else if (min == max) {
				return create_number(min);
			}
			size_t st = twist_state.genrand_int32();
			return create_number(min + int(st % (max - min)));
		}
	}
	return NONE;
}
Ejemplo n.º 10
0
static HRESULT NumberConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
                                  jsval_t *r)
{
    double n;
    HRESULT hres;

    TRACE("\n");

    switch(flags) {
    case INVOKE_FUNC:
        if(!argc) {
            if(r)
                *r = jsval_number(0);
            return S_OK;
        }

        hres = to_number(ctx, argv[0], &n);
        if(FAILED(hres))
            return hres;

        if(r)
            *r = jsval_number(n);
        break;

    case DISPATCH_CONSTRUCT: {
        jsdisp_t *obj;

        if(argc) {
            hres = to_number(ctx, argv[0], &n);
            if(FAILED(hres))
                return hres;
        } else {
            n = 0;
        }

        hres = create_number(ctx, n, &obj);
        if(FAILED(hres))
            return hres;

        *r = jsval_obj(obj);
        break;
    }
    default:
        FIXME("unimplemented flags %x\n", flags);
        return E_NOTIMPL;
    }

    return S_OK;
}
Ejemplo n.º 11
0
void test_convert_string_to_tree()
{
	char input[9][104] = {"([8,8],[4,8],[2,4],[1,2],[3,2],[6,4],[5,6],[7,6],[12,8],[10,12],[9,10],[11,10],[14,12],[13,14],[15,14])",
					     "([8,8],[4,8],[2,4],[6,4],[5,6],[7,6],[12,8],[10,12],[9,10],[11,10],[14,12],[13,14],[15,14])",
					     "([8,8],[4,8],[2,4],[1,2],[3,2],[6,4],[5,6],[7,6],[12,8],[10,12],[9,10],[11,10])",
					     "([5,5],[4,5],[2,4],[1,4],[3,5],[6,3],[7,3])",
					     "([5,5],[4,5],[3,5],[6,3],[7,3])",
					     "([5,5],[4,5],[2,4],[1,4],[3,5])",
					     "([1,1],[2,1],[3,1])",
					     "([5,5])",
					     "([1,1],[2,1])"
					    };
	char output[9][86] = {"8,4,2,1,$,3,$,6,5,$,7,$,12,10,9,$,11,$,14,13,$,15,$",
								  "8,4,2,$,6,5,$,7,$,12,10,9,$,11,$,14,13,$,15,$",
								  "8,4,2,1,$,3,$,6,5,$,7,$,12,10,9,$,11,$,-",
								  "5,4,2,$,1,$,3,6,$,7,$",
								  "5,4,$,3,6,$,7,$",
								  "5,4,2,$,1,$,3,$",
								  "1,2,$,3,$",
								  "5,$",
								  "1,2,$,-"
								};
	int iter_loop,index;
	for(iter_loop=0;iter_loop<9;iter_loop++)
	{
		printf("%d-->",iter_loop+1);
		if(input[iter_loop]==NULL || output[iter_loop]==NULL)
		{
			printf("INVALID INPUT");
			continue;
		}

		NODE *root1;
		root1 = driver_for_convert_string_to_tree(input[iter_loop]);
		NODE *root2 = (NODE*)malloc(sizeof(NODE));

		index = next_element_in_string(output[iter_loop],0);
		root2->data = create_number(output[iter_loop],index);
		index = next_element_in_string(output[iter_loop],index);
		construct_tree(root2,output[iter_loop],index);
		(tree_comparator(root1,root2)==1)?printf("ACCEPTED\n"):printf("REJECTED\n");
		delete_tree(root1);
		delete_tree(root2);
	}

}
Ejemplo n.º 12
0
GuiObject *add_number(GuiWindow * win, int type, int x, int y, int seg_length, char *mask)
{
	GuiObject *number;
	int i;

	check_window(win, "add_number");

	number = (GuiObject *) malloc(sizeof(GuiObject));
	if (number == NULL)
		error("Cannot allocate memory for number.");

	number->win = win;
	number->x = number->x_min = x;
	number->y = number->y_min = y;
	number->objclass = NUMBER;
	number->active = TRUE;
	number->pressed = FALSE;
	number->hide = FALSE;
	number->type = type;
	number->fg_col = NUMBER_FORE;
	number->bg_col1 = BLACK;

	number->width = 0;
	for (i = 0;i < strlen(mask);i++)
		if (mask[i] == ' ')
			number->width += 13;
		else
			number->width += bigfont_width[mask[i] - ' '];
	number->height = bigfont_height;

	number->x_max = x + number->width - 1;
	number->y_max = y + number->height - 1;
	number->align = ALIGN_LEFT;
	sprintf(number->label, "%s", mask);
	number->info[0] = '\0';	/* make string length zero */

	number->data[0] = (char *) malloc(number->width * number->height);
	if (number->data[0] == NULL)
		error("Cannot allocate memory for number.");
	number->data[1] = NULL;	/* don't use second data-block */

	create_number(number);
	add_object(number);

	return number;
}
Ejemplo n.º 13
0
void test_traversal()
{
	char input[10][53] = {"8,-4,2,1,$,3,$,6,5,$,7,$,12,10,9,$,11,$,14,13,$,15,$",
								  "8,4,2,$,6,5,$,7,$,12,10,9,$,11,$,14,13,$,15,$",
								  "8,4,2,1,$,3,$,6,5,$,7,$,12,10,9,$,11,$,-",
								  "5,4,2,$,1,$,3,6,$,7,$",
								  "5,4,$,3,6,$,7,$",
								  "5,4,2,$,1,$,3,$",
								  "1,2,$,3,$",
								  "5,$",
								  "1,2,$,-",
								  '\0'
								};

	int output[10][16] ={
						{8,-4,2,1,3,6,5,7,12,10,9,11,14,13,15},
						{8,4,2,6,5,7,12,10,9,11,14,13,15},
						{8,4,2,1,3,6,5,7,12,10,9,11},
						{5,4,2,1,3,6,7},
						{5,4,3,6,7},
						{5,4,2,1,3},
						{1,2,3},
						{5},
						{1,2},
						NULL
						}; 
	int iter_loop;
	for(iter_loop=0;iter_loop<10;iter_loop++)
	{
		int index;
		NODE *root = (NODE*)malloc(sizeof(NODE));

		index = next_element_in_string(input[iter_loop],0);
		root->data = create_number(input[iter_loop],index);
		index = next_element_in_string(input[iter_loop],index);
		construct_tree(root,input[iter_loop],index);

		int *traversal_array;
		traversal_array = driver_of_traverse_arrays(root);
		(compare_arrays(traversal_array,output[iter_loop]) == 1)?printf("ACCEPTED\n"):printf("REJECTED\n");
		free(traversal_array);
		delete_tree(root);
	}
}
Ejemplo n.º 14
0
void test_tree_construction()
{
	char inorder[5][36] = { "8,4,9,2,10,5,11,1,12,6,13,3,14,7,15",
							"1,2,3,4",
							"1,2,3",
							"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15",
							"1,2"
							};

	char preorder[5][36] = { "1,2,4,8,9,5,10,11,3,6,12,13,7,14,15",
							 "2,1,3,4",
							 "2,1,3",
							 "8,4,2,1,3,6,5,7,12,10,9,11,14,13,15",
							 "1,2"
						   };

	char expected_tree[5][52] = {"1,2,4,8,$,9,$,5,10,$,11,$,3,6,12,$,13,$,7,14,$,15,$",
		   						 "2,1,$,3,-,4,$",
								 "2,1,$,3,$",
								 "8,4,2,1,$,3,$,6,5,$,7,$,12,10,9,$,11,$,14,13,$,15,$",
								 "1,-,2,$"
								};
	int iter_loop;
	for(iter_loop=0;iter_loop<5;iter_loop++)
	{
		printf("%d-->",iter_loop+1);
		int preorder_index = 0;
		int *inorder_array = string_to_array(inorder[iter_loop]);
		int *preorder_array = string_to_array(preorder[iter_loop]);
		NODE *head  = construct_tree_from_inorder_preorder(inorder_array,preorder_array,0,array_length(inorder_array)-1,&preorder_index);
		NODE *root = (NODE*)malloc(sizeof(NODE));
		int index;
		index = next_element_in_string(expected_tree[iter_loop],0);
		root->data = create_number(expected_tree[iter_loop],index);
		index = next_element_in_string(expected_tree[iter_loop],index);
		construct_tree(root,expected_tree[iter_loop],index);
		(1==tree_comparator(head,root))?printf("ACCEPTED\n"):printf("REJECTED\n");
		delete_tree(head);
		free(inorder_array);
		free(preorder_array);
	}
}
Ejemplo n.º 15
0
/* ECMA-262 3rd Edition    9.9 */
HRESULT to_object(exec_ctx_t *ctx, VARIANT *v, IDispatch **disp)
{
    DispatchEx *dispex;
    HRESULT hres;

    switch(V_VT(v)) {
    case VT_BSTR:
        hres = create_string(ctx->parser->script, V_BSTR(v), SysStringLen(V_BSTR(v)), &dispex);
        if(FAILED(hres))
            return hres;

        *disp = (IDispatch*)_IDispatchEx_(dispex);
        break;
    case VT_I4:
    case VT_R8:
        hres = create_number(ctx->parser->script, v, &dispex);
        if(FAILED(hres))
            return hres;

        *disp = (IDispatch*)_IDispatchEx_(dispex);
        break;
    case VT_DISPATCH:
        IDispatch_AddRef(V_DISPATCH(v));
        *disp = V_DISPATCH(v);
        break;
    case VT_BOOL:
        hres = create_bool(ctx->parser->script, V_BOOL(v), &dispex);
        if(FAILED(hres))
            return hres;

        *disp = (IDispatch*)_IDispatchEx_(dispex);
        break;
    default:
        FIXME("unsupported vt %d\n", V_VT(v));
        return E_NOTIMPL;
    }

    return S_OK;
}
Ejemplo n.º 16
0
void test_log_cf(void)
{
	CALC_ELEMENT *t1 = create_number(1.0);
	t1 = create_log(t1);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_LOG);
	CU_ASSERT_EQUAL(t1->status, 0);
	CU_ASSERT_EQUAL(t1->value, 1.0);
	CU_ASSERT_PTR_NOT_NULL(t1->left);
	CU_ASSERT_PTR_NULL(t1->right);
	free_calc_element(t1);

	t1 = create_x();
	t1 = create_log(t1);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_LOG);
	CU_ASSERT_EQUAL(t1->status, STATUS_X_PRESENT | STATUS_X_IN_LOG);
	CU_ASSERT_EQUAL(t1->value, 1.0);
	CU_ASSERT_PTR_NOT_NULL(t1->left);
	CU_ASSERT_PTR_NULL(t1->right);
	free_calc_element(t1);
}
Ejemplo n.º 17
0
void test_bad_axb(void)
{
	CALC_ELEMENT *t1, *t2, *t3;
	double a, b;
	/* log */
	t2 = create_number(6.0);
	t1 = create_log(t2);
	CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), -1);
	free_calc_element(t1);
	/* bin op different from + */
	t2 = create_number(-9.0);
	t3 = create_x();
	t1 = create_bin_op('*', t2, t3);
	CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), -1);
	free_calc_element(t1);
	/* two numbers */
	t2 = create_number(2.0);
	t3 = create_number(4.2);
	t1 = create_bin_op('+', t2, t3);
	CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), -1);
	free_calc_element(t1);
	/* two xs */
	t2 = create_x();
	t3 = create_x();
	t1 = create_bin_op('*', t2, t3);
	CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), -1);
	free_calc_element(t1);
	/* something wonky, like 4 * 3 + 2 */
	t2 = create_number(4);
	t3 = create_number(3);
	t2 = create_bin_op('*', t2, t3);
	t3 = create_number(2);
	t1 = create_bin_op('+', t2, t3);
	CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), -1);
	free_calc_element(t1);
}
Ejemplo n.º 18
0
/* ECMA-262 3rd Edition    9.9 */
HRESULT to_object(script_ctx_t *ctx, jsval_t val, IDispatch **disp)
{
    jsdisp_t *dispex;
    HRESULT hres;

    switch(jsval_type(val)) {
    case JSV_STRING:
        hres = create_string(ctx, get_string(val), &dispex);
        if(FAILED(hres))
            return hres;

        *disp = to_disp(dispex);
        break;
    case JSV_NUMBER:
        hres = create_number(ctx, get_number(val), &dispex);
        if(FAILED(hres))
            return hres;

        *disp = to_disp(dispex);
        break;
    case JSV_OBJECT:
        if(get_object(val)) {
            *disp = get_object(val);
            IDispatch_AddRef(*disp);
        }else {
            jsdisp_t *obj;

            hres = create_object(ctx, NULL, &obj);
            if(FAILED(hres))
                return hres;

            *disp = to_disp(obj);
        }
        break;
    case JSV_BOOL:
        hres = create_bool(ctx, get_bool(val), &dispex);
        if(FAILED(hres))
            return hres;

        *disp = to_disp(dispex);
        break;
    case JSV_UNDEFINED:
    case JSV_NULL:
        WARN("object expected\n");
        return throw_type_error(ctx, JS_E_OBJECT_EXPECTED, NULL);
    case JSV_VARIANT:
        switch(V_VT(get_variant(val))) {
        case VT_ARRAY|VT_VARIANT:
            hres = create_vbarray(ctx, V_ARRAY(get_variant(val)), &dispex);
            if(FAILED(hres))
                return hres;

            *disp = to_disp(dispex);
            break;

        default:
            FIXME("Unsupported %s\n", debugstr_variant(get_variant(val)));
            return E_NOTIMPL;
        }
        break;
    }

    return S_OK;
}
Ejemplo n.º 19
0
void test_canon_calc_good(void)
{
	CALC_ELEMENT *t1, *t2;
	/* single number */
	t1 = create_number(12.0);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_NUM);
	CU_ASSERT_EQUAL(t1->status, 0);
	CU_ASSERT_EQUAL(t1->value, 12.0);
	CU_ASSERT_PTR_NULL(t1->left);
	CU_ASSERT_PTR_NULL(t1->right);
	free_calc_element(t1);

	/* addition */
	t1 = create_number(2.0);
	t2 = create_number(-3.5);
	t1 = create_bin_op('+', t1, t2);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_NUM);
	CU_ASSERT_EQUAL(t1->status, 0);
	CU_ASSERT_EQUAL(t1->value, -1.5);
	CU_ASSERT_PTR_NULL(t1->left);
	CU_ASSERT_PTR_NULL(t1->right);
	free_calc_element(t1);

	/* substraction */
	t1 = create_number(-3.0);
	t2 = create_number(-4.25);
	t1 = create_bin_op('-', t1, t2);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_NUM);
	CU_ASSERT_EQUAL(t1->status, 0);
	CU_ASSERT_EQUAL(t1->value, 1.25);
	CU_ASSERT_PTR_NULL(t1->left);
	CU_ASSERT_PTR_NULL(t1->right);
	free_calc_element(t1);

	/* multiplication */
	t1 = create_number(4);
	t2 = create_number(1.25);
	t1 = create_bin_op('*', t1, t2);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_NUM);
	CU_ASSERT_EQUAL(t1->status, 0);
	CU_ASSERT_EQUAL(t1->value, 5.0);
	CU_ASSERT_PTR_NULL(t1->left);
	CU_ASSERT_PTR_NULL(t1->right);
	free_calc_element(t1);

	/* division */
	t1 = create_number(8.0);
	t2 = create_number(16.0);
	t1 = create_bin_op('/', t1, t2);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_NUM);
	CU_ASSERT_EQUAL(t1->status, 0);
	CU_ASSERT_EQUAL(t1->value, 0.5);
	CU_ASSERT_PTR_NULL(t1->left);
	CU_ASSERT_PTR_NULL(t1->right);
	free_calc_element(t1);

	/* natural logarithm */
	t1 = create_number(1.0);
	t1 = create_log(t1);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_NUM);
	CU_ASSERT_EQUAL(t1->status, 0);
	CU_ASSERT_EQUAL(t1->value, 0.0);
	CU_ASSERT_PTR_NULL(t1->left);
	CU_ASSERT_PTR_NULL(t1->right);
	free_calc_element(t1);

	t1 = create_number(M_E);
	t1 = create_log(t1);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_NUM);
	CU_ASSERT_EQUAL(t1->status, 0);
	CU_ASSERT_EQUAL(t1->value, 1.0);
	CU_ASSERT_PTR_NULL(t1->left);
	CU_ASSERT_PTR_NULL(t1->right);
	free_calc_element(t1);

	/* a slightly more complex example (3 + (4 - 1)) * 5 */
	t1 = create_number(4);
	t2 = create_number(1);
	t2 = create_bin_op('-', t1, t2);
	t1 = create_number(3);
	t1 = create_bin_op('+', t1, t2);
	t2 = create_number(5);
	t1 = create_bin_op('*', t1, t2);
	CU_ASSERT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_PTR_NOT_NULL(t1);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_NUM);
	CU_ASSERT_EQUAL(t1->status, 0);
	CU_ASSERT_EQUAL(t1->value, 30.0);
	CU_ASSERT_PTR_NULL(t1->left);
	CU_ASSERT_PTR_NULL(t1->right);
	free_calc_element(t1);
}
NODE* string_to_linked_list(char *input_array)
{
	if(input_array == NULL)
	{
		return NULL;
	}
	int data;
	int iter_loop=0, iter_loop2=0;
	NODE *head=NULL, *temp=NULL;
	while(input_array[iter_loop]!='\0')
	{
	while(input_array[iter_loop2]!=',' && input_array[iter_loop2]!='\0')
	{
		iter_loop2++;
	}
	data  = create_number(input_array, iter_loop, iter_loop2-1);
	if(data == NULL)
	{
		if(input_array[iter_loop2]!='\0')
		{
			iter_loop2++;
		}
		else if(input_array[iter_loop2]=='\0')
		{
			return NULL;
		}
		iter_loop = iter_loop2;
		continue;
	}
	head = create_node(data);
	temp = head;
	temp->next = NULL;
	if(input_array[iter_loop2]!='\0')
	{
		iter_loop2++;
	}
	iter_loop = iter_loop2;
	break;
	}
	while(input_array[iter_loop]!='\0')
	{
		while(input_array[iter_loop2]!=',' && input_array[iter_loop2]!='\0')
		{
			iter_loop2++;
		}
		data = create_number(input_array, iter_loop, iter_loop2-1);
		if(data == NULL)
		{
			if(input_array[iter_loop2]!='\0')
			{
				iter_loop2++;
			}
		else if(input_array[iter_loop2]=='\0')
		{
			return NULL;
		}
			iter_loop = iter_loop2;
			continue;
		}
		NODE *new_node = create_node(data);
		temp->next  = new_node;
		temp = new_node;
		temp->next = NULL;
		if(input_array[iter_loop2]=='\0')
		{
			break;
		}
		else if(input_array[iter_loop2]!='\0')
		{
			iter_loop = ++iter_loop2;
		}
	}
	return head;
}
Ejemplo n.º 21
0
void test_canon_x(void)
{
	CALC_ELEMENT *t1;
	double a, b;
	/* addition x + a * x */
	t1 = create_bin_op('+', create_x(),
			   create_bin_op('*', create_number(2.5), create_x()));
	CU_ASSERT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_X);
	CU_ASSERT_EQUAL(t1->status, STATUS_X_PRESENT);
	CU_ASSERT_EQUAL(t1->value, 3.5);
	free_calc_element(t1);

	/* addition a * x + b */
	t1 = create_bin_op('+',
			   create_bin_op('*', create_number(1.25), create_x()),
			   create_number(14));
	CU_ASSERT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP);
	CU_ASSERT_EQUAL(t1->status, STATUS_X_PRESENT);
	CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), 0);
	CU_ASSERT_EQUAL(a, 1.25);
	CU_ASSERT_EQUAL(b, 14);
	free_calc_element(t1);

	/* addition a * x + b + c */
	t1 = create_bin_op('+',
			   create_bin_op('+',
					 create_bin_op('*', create_number(0.75),
						       create_x()),
					 create_number(6)),
			   create_number(-3.5));
	CU_ASSERT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP);
	CU_ASSERT_EQUAL(t1->status, STATUS_X_PRESENT);
	CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), 0);
	CU_ASSERT_EQUAL(a, 0.75);
	CU_ASSERT_EQUAL(b, 2.5);
	free_calc_element(t1);

	/* addition (a1 * x + b1) + (a2 * x + b2) */
	t1 = create_bin_op('+', create_ax_b(9.0, -1.25), create_ax_b(2.0, 6.5));
	CU_ASSERT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP);
	CU_ASSERT_EQUAL(t1->status, STATUS_X_PRESENT);
	CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), 0);
	CU_ASSERT_EQUAL(a, 11.0);
	CU_ASSERT_EQUAL(b, 5.25);
	free_calc_element(t1);

	/* multiplication a * x */
	t1 = create_bin_op('*', create_x(), create_number(-9.0));
	CU_ASSERT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_X);
	CU_ASSERT_EQUAL(t1->status, STATUS_X_PRESENT);
	CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), 0);
	CU_ASSERT_EQUAL(a, -9.0);
	CU_ASSERT_EQUAL(b, 0);
	free_calc_element(t1);

	/* multiplication x * a */
	t1 = create_bin_op('*', create_number(7.5), create_x());
	CU_ASSERT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_X);
	CU_ASSERT_EQUAL(t1->status, STATUS_X_PRESENT);
	CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), 0);
	CU_ASSERT_EQUAL(a, 7.5);
	CU_ASSERT_EQUAL(b, 0);
	free_calc_element(t1);

	/* multiplication c * (a * x + b) */
	t1 = create_bin_op('*', create_number(19), create_ax_b(4, -0.5));
	CU_ASSERT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP);
	CU_ASSERT_EQUAL(t1->status, STATUS_X_PRESENT);
	CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), 0);
	CU_ASSERT_EQUAL(a, 76);
	CU_ASSERT_EQUAL(b, -9.5);
	free_calc_element(t1);

	/* multiplication (a * x + b) * c */
	t1 = create_bin_op('*', create_ax_b(-6, 4.5), create_number(0.5));
	CU_ASSERT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP);
	CU_ASSERT_EQUAL(t1->status, STATUS_X_PRESENT);
	CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), 0);
	CU_ASSERT_EQUAL(a, -3.0);
	CU_ASSERT_EQUAL(b, 2.25);
	free_calc_element(t1);

	/* multiplication x * x */
	t1 = create_bin_op('*', create_x(), create_x());
	CU_ASSERT_NOT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP);
	CU_ASSERT_EQUAL(t1->status, STATUS_X_NON_LINEAR | STATUS_X_PRESENT);
	free_calc_element(t1);

	/* multiplication x * (a * x + b) */
	t1 = create_bin_op('*', create_x(), create_x());
	CU_ASSERT_NOT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP);
	CU_ASSERT_EQUAL(t1->status, STATUS_X_NON_LINEAR | STATUS_X_PRESENT);
	free_calc_element(t1);

	/* multiplication (2*x - (2*x - 3)) * (3x - 4) - false square, actually linear */
	t1 = create_bin_op('*', create_bin_op('-', create_ax_b(2.0, 0.0),
					      create_ax_b(2, -3)),
			   create_ax_b(3.0, -4.0));
	CU_ASSERT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP);
	CU_ASSERT_EQUAL(get_ax_b(t1, &a, &b), 0);
	CU_ASSERT_EQUAL(a, 9.0);
	CU_ASSERT_EQUAL(b, -12.0);
	free_calc_element(t1);

	/* division x / a */
	t1 = create_bin_op('/', create_x(), create_number(2.0));
	CU_ASSERT_NOT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_BIN_OP);
	CU_ASSERT_EQUAL(t1->status, STATUS_X_IN_DIV | STATUS_X_PRESENT);
	free_calc_element(t1);

	/* log (ax + b) */
	t1 = create_log(create_ax_b(9.0, -3.0));
	CU_ASSERT_NOT_EQUAL(canonical_form(&t1), 0);
	CU_ASSERT_EQUAL(t1->calc_t, CALC_LOG);
	CU_ASSERT_EQUAL(t1->status, STATUS_X_IN_LOG | STATUS_X_PRESENT);
	free_calc_element(t1);
}
Ejemplo n.º 22
0
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.*/

#include "../types/funcs/dexbuiltin.h"
#include "math.h"
#include "../types/dexnum.h"
#include "../types/dexstr.h"
#include "objdefutil.h"
#include "../libs/rand/mtwist.h"
#include "../objdef/dex_conv.h"

static DexRef DSTR_MATHCPP = create_string("math.cpp");

DexRef DNUM_PI = create_number(PI), DNUM_E = create_number(E);

DexRef DNUM_NEG_ONE = create_number(-1), DNUM_ONE = create_number(1), DNUM_ZERO = create_number(0);

//0 arg -> return number 0 to 1 (float)
//1 arg -> return number 0 to n (int)
//2 arg -> return number a to b (int)
static DexRef builtin_rand(DexRef* args, size_t n) {
	const char* NAME = "rand";

	if (n > 2) {
		arg_amnt_err(NAME, n, 0, 2);
		return NONE;
	}
	if (n == 0) {
		return create_number(twist_state.genrand_res53());
Ejemplo n.º 23
0
void test_binop_cf(void)
{
	/* + */
	CALC_ELEMENT *e1 = create_number(3.0), *e2 = create_number(-4.0);
	CALC_ELEMENT *expr = create_bin_op('+', e1, e2);
	CU_ASSERT_PTR_NOT_NULL(expr);
	CU_ASSERT_EQUAL(expr->calc_t, CALC_BIN_OP);
	CU_ASSERT_EQUAL(expr->bin_op, '+');
	CU_ASSERT_EQUAL(expr->status, 0);
	CU_ASSERT_EQUAL(expr->value, 1.0);
	CU_ASSERT_PTR_NOT_NULL(expr->left);
	CU_ASSERT_PTR_NOT_NULL(expr->right);
	free_calc_element(expr);

	/* - */
	e1 = create_number(-7.0);
	e2 = create_number(9.0);
	expr = create_bin_op('-', e1, e2);
	CU_ASSERT_PTR_NOT_NULL(expr);
	CU_ASSERT_EQUAL(expr->calc_t, CALC_BIN_OP);
	CU_ASSERT_EQUAL(expr->bin_op, '+');
	CU_ASSERT_EQUAL(expr->status, 0);
	CU_ASSERT_EQUAL(expr->value, 1.0);
	CU_ASSERT_PTR_NOT_NULL(expr->left);
	CU_ASSERT_PTR_NOT_NULL(expr->right);
	CU_ASSERT_EQUAL(expr->right->value, -9.0);
	free_calc_element(expr);

	/* * */
	e1 = create_number(3.0);
	e2 = create_number(11.5);
	expr = create_bin_op('*', e1, e2);
	CU_ASSERT_PTR_NOT_NULL(expr);
	CU_ASSERT_EQUAL(expr->calc_t, CALC_BIN_OP);
	CU_ASSERT_EQUAL(expr->bin_op, '*');
	CU_ASSERT_EQUAL(expr->status, 0);
	CU_ASSERT_EQUAL(expr->value, 1.0);
	CU_ASSERT_PTR_NOT_NULL(expr->left);
	CU_ASSERT_PTR_NOT_NULL(expr->right);
	free_calc_element(expr);

	/* /, only numbers */
	e1 = create_number(-7.0);
	e2 = create_number(5.0);
	expr = create_bin_op('/', e1, e2);
	CU_ASSERT_PTR_NOT_NULL(expr);
	CU_ASSERT_EQUAL(expr->calc_t, CALC_BIN_OP);
	CU_ASSERT_EQUAL(expr->bin_op, '/');
	CU_ASSERT_EQUAL(expr->status, 0);
	CU_ASSERT_EQUAL(expr->value, 1.0);
	CU_ASSERT_PTR_NOT_NULL(expr->left);
	CU_ASSERT_PTR_NOT_NULL(expr->right);
	free_calc_element(expr);

	/* /, with an x */
	e1 = create_x();
	e2 = create_number(2.0);
	expr = create_bin_op('/', e1, e2);
	CU_ASSERT_PTR_NOT_NULL(expr);
	CU_ASSERT_EQUAL(expr->calc_t, CALC_BIN_OP);
	CU_ASSERT_EQUAL(expr->bin_op, '/');
	CU_ASSERT_EQUAL(expr->status, STATUS_X_PRESENT | STATUS_X_IN_DIV);
	CU_ASSERT_EQUAL(expr->value, 1.0);
	CU_ASSERT_PTR_NOT_NULL(expr->left);
	CU_ASSERT_PTR_NOT_NULL(expr->right);
	free_calc_element(expr);
}
Ejemplo n.º 24
0
Link interpret(Link codeblock_link ,  Link This, Link Arg){
    
    CallEnv env = callenv_new_root( codeblock_link, This, Arg);
    LinkStack stack = env->stack;
    
    
    Link b          = NULL;
    Link link       = NULL;
    Link parent     = NULL;
    Link child_key  = NULL;
    
    Link pusher     = NULL; // Anything in this variable gets pushed onto the stack
    Link trapped    = NULL; // This is the last critical caught by the trap operator
    
    int    delta = 0; // jump delta

    /* Main interpreter loop */
    while(1){

        switch( *(env->current++) ){

            case INTRO:
                env->current+=4;
                break;

            case ALLOC_MODULE:
                delta = read_offset(env);
                env->module->global_vars = linkarray_new(delta);
                break;
            
            case ALLOC_LOCAL:
                delta = read_offset(env);
                env->local = linkarray_new(delta);
                break;
                                
            case NO_OP:
                break;
            
            case RETURN: // if there is something on the env->stack stack pop it off and return it, if not return null link
                if (   stack_length(stack) - env->stack_offset ){
                    pusher = stack_pop(stack);
                }else{
                    pusher = object_create(Global->null_type);
                }
                goto done;

            case RAISE: // if there is something on the stack stack pop it off and return it, if not return null link
            
                if (  stack_length(stack) - env->stack_offset ){
                    pusher = create_critical(stack_pop(stack));
                }else{
                    pusher = create_critical(object_create(Global->null_type));
                }
                goto done;

            case PUSH_LEX:
                delta = read_offset(env);
                //fprintf(stderr , "push lex [%i]    %p\n", delta,env->function->value.codeblock->lexicals);
                pusher = link_dup(env->function->value.codeblock->lexicals->vars[delta]);
                break;
                
            case STORE_LEX:
                delta = read_offset(env);
                //fprintf(stderr , "storing lex [%i]    %p\n", delta,env->function->value.codeblock->lexicals);
                b = env->function->value.codeblock->lexicals->vars[delta];
            
                if (b){
                    if  ( (b->type == Global->function_type) && 
                          (b->value.codeblock->lexicals == env->function->value.codeblock->lexicals)
                        )  b->value.codeblock->lexical_cycles--;
                    link_free(b);
                }
                
                b = link_dup(stack_peek(stack));
                if  ( (b->type == Global->function_type) && 
                      (b->value.codeblock->lexicals == env->function->value.codeblock->lexicals)
                    )  b->value.codeblock->lexical_cycles++;
                
                env->function->value.codeblock->lexicals->vars[delta] = b;
                
                break;
            
            case DEF:
                if (env->Def) link_free(env->Def);
                env->Def = stack_pop(env->stack);
                pusher = link_dup(env->Def);
                break;
            
            case PUSH_DEF:
                if ( ! env->Def){
                    pusher = exception("NoDefObject",NULL, NULL);
                }
                pusher = link_dup(env->Def);
                break;
                
                
                
            case ALLOC_LEXICAL:
                delta = read_offset(env);
                lexicals_alloc( env->function, delta);
                //env->lexical_root = 1;
                break;
                
            case STORE_ARG:
                delta = read_offset(env);
                
                if (env->Arg->value.array->length  > delta){
                    retry_store_arg:
                    env->Arg->value.array->links[delta] =  link_dup( stack_peek(stack) );
                }else{
                    array_push(env->Arg, NULL);
                    goto retry_store_arg;
                } 
                break;
                
            case PUSH_ARG:
                delta = read_offset(env);
                if (env->Arg->value.array->length  > delta){
                    pusher = link_dup(  env->Arg->value.array->links[delta]);
                }else{
                    pusher = exception("ArgsIndexOutOfBounds", NULL, NULL);
                }
            
                break;
                
            case STORE_GVAR:
                delta = read_offset(env);
                if (env->module->global_vars->links[delta]){
                    link_free(env->module->global_vars->links[delta]);
                }
                env->module->global_vars->links[delta] = link_dup( stack_peek(stack) );
                break;

            case STORE_VAR:
                delta = read_offset(env);

                if (env->local->links[delta]){
                    link_free(env->local->links[delta]);
                }
            
                env->local->links[delta] = link_dup( stack_peek(stack) );
                break;

            case STORE_CHILD:
                link        = stack_pop(stack); // value
                child_key   = stack_pop(stack); // key to find the child
                parent      = stack_pop(stack); // parent to look in
                pusher = object_addChild(parent, link, child_key);
                goto STORE_COMMON;

            case STORE_ATTR:
                link           = stack_pop(stack); // value
                child_key      = stack_pop(stack); // key to find the child
                parent         = stack_pop(stack); // parent to look in
                pusher = addAttr(parent, link,child_key);
                goto STORE_COMMON;
                
            STORE_COMMON:
                if (! pusher){
                    pusher = exception("AssignError", NULL, NULL);
                    link_free(link);
                }
            
                link_free(child_key);
                link_free(parent);
                break;

            case LT:
                delta = compare(env);
                pusher = create_numberi( (delta < 0)  ? 1 : 0 );
                break;

            case GT:
                delta = compare(env);
                pusher = create_numberi( (delta > 0)  ? 1 : 0 );
                break;

            case EQ:
                delta = compare(env);
                pusher = create_numberi( (delta == 0)  ? 1 : 0 );
                break;

            case NE:
                delta = compare(env);
                pusher = create_numberi( (delta == 0)  ? 0 : 1 );
                break;

            case LE:
                delta = compare(env);
                pusher = create_numberi( (delta <= 0)  ? 1 : 0 );
                break;

            case GE:
                delta = compare(env);
                pusher = create_numberi( (delta >= 0)  ? 1 : 0 );
                break;
        
            case CMP:
                delta = compare(env);
                pusher = create_numberi( delta );
                break;
            
            case OR:
            case AND:
                break;

            case SUB:
                b = stack_pop(env->stack);
                link = stack_pop(env->stack);
            
                if ( (link->type == Global->number_type) && (link->type == b->type)){
                    pusher = create_number(link->value.number - b->value.number);
                    link_free(link);
                    link_free(b);
                    break;
                }            
            
                pusher = object_op_minus(link,b);
                link_free(link);
                link_free(b);
            
                break;
            
            case ADD:
                b = stack_pop(env->stack);
                link = stack_pop(env->stack);
            
                if ( (link->type == Global->number_type) && (link->type == b->type)){
                    pusher = create_number(link->value.number + b->value.number);
                    link_free(link);
                    link_free(b);
                    break;
                }            
            
                pusher = object_op_plus(link,b);
                link_free(link);
                link_free(b);
                
                break;
                        
            case DIV:
                binary_op(env , object_op_divide);
                break;
            
            case MULT:
                binary_op(env , object_op_multiply);
                break;
            
            case MOD:
                binary_op(env , object_op_modulus);
                break;
            
            case POW:
                binary_op(env , object_op_power);
                break;
            
            case NEG:
                unary_op(env, object_op_neg);
                break;
            
            case NOT:
                link = stack_pop(stack);
                pusher = create_numberi(  (object_is_true(link))  ?  0 : 1 );
                link_free(link);
                break;

            case TEST:
            case ELSE:
                break;

            case DO:
                delta = read_offset(env);
                link  = codeblock_literal2( env->function->value.codeblock->parent, delta  );
                if (env->function->value.codeblock->lexicals) {
                    lexicals_attach( env->function->value.codeblock->lexicals, link);
                }
                env = callenv_new_doblock(env,link);
                break;
            
            case PUSH_ARRAY:
                delta = read_offset(env);
                pusher =  array_new_subarray( stack , delta);
                break;
                
            case CALL:
                link   = stack_pop(stack);     // the arguments in an array
                b      = stack_pop(stack);     // the function that gets called
                parent = link_dup(env->This);  // caller
                goto CALL_COMMON;

            
            case CALL_ATTR:            
                link       = stack_pop(stack);    // arguments
                child_key  = stack_pop(stack);    // name of the function
                parent     = stack_pop(stack);    // caller
                b = getAttr(parent,child_key); // the function that gets called           
                link_free(child_key); // no longer need the attributes key
            
                if (! b) {
                    pusher = exception("AttrNotFound", NULL, NULL);
                    break;
                }
                goto CALL_COMMON;
                
            case CALL_CHILD:
                link       = stack_pop(stack);     // ARG
                child_key  = stack_pop(stack);
                parent     = stack_pop(stack);     // THIS
                b = object_getChild(parent,child_key);
                link_free(child_key);
                goto CALL_COMMON;

            CALL_COMMON:
                /* function type so we can call it inline */
                if (b->type == Global->function_type){
                    env = callenv_new_function(env, b, parent, link); // ce , func,this, arg

                /* Not a CodeBlock so we have to use its virtual call function */
                }else{
                    pusher = object_call(b,  parent, link);// function, caller, args
                    link_free(link);
                    if (parent) link_free(parent);
                    link_free(b);
                    if (! pusher) pusher = object_create(Global->null_type);
                }
                break;

            case DEL_CHILD:
                child_key      = stack_pop(stack); // key to find the child
                parent         = stack_pop(stack); // parent to look in

                /* delete child from container */
                pusher = object_delChild(parent,child_key);
                if (! pusher) pusher = exception("ChildNotFound", object_getString(child_key), NULL);
                        
                link_free(child_key);
                link_free(parent);
                break;                
                
            case DEL_ATTR:
                child_key      = stack_pop(stack); // key to find the child
                parent         = stack_pop(stack); // parent to look in

                /* delete attr from container */
                pusher = delAttr(parent,child_key);
                if (! pusher) pusher = exception("AttrNotFound", object_getString(child_key), NULL);

                link_free(child_key);
                link_free(parent);
                break;                
                
            case GET_CHILD:
                child_key      = stack_pop(stack); // key to find the child
                parent         = stack_pop(stack); // parent to look in

                pusher = object_getChild(parent, child_key);            
                if (! pusher) pusher = exception("ChildNotFound", object_getString(child_key), NULL);

                link_free(parent);
                link_free(child_key);
                break;

            case GET_ATTR:
                child_key      = stack_pop(stack); // key to find the child
                parent         = stack_pop(stack); // parent to look in

                pusher = getAttr(parent, child_key);
                if (! pusher) pusher = exception("AttrNotFound", object_getString(child_key), NULL);

                link_free(parent);
                link_free(child_key);
                break;

            case TRAP:
                break;

            case CLEAR:
                for ( delta = stack_length( stack ) ; delta > env->stack_offset ; delta--){
                    link_free( stack_pop(stack) );    
                }    
                break;
            
            case STOP:
                break;

            done:
            case END:
                for ( delta = stack_length( stack ) ; delta > env->stack_offset ; delta--){
                    link_free( stack_pop(stack) );    
                }    
                addBacktrace(pusher, env->function, env->linenum);
                env = callenv_free(env);

                if (! env) goto end;
                
                if (! pusher) pusher = object_create(Global->null_type);
                break;

            /* JUMPS */
            case JIT:  /* Jump if true */
                delta = read_offset(env);
                link = stack_peek(stack);
                if ( link->type->is_true(link) )  env->current = env->start+delta;
                break;

            case JIF:  /* Jump if false */
                delta = read_offset(env);
                link = stack_peek(stack);
                if ( ! link->type->is_true(link) )  env->current = env->start+delta;
                break;
                

            case JIF_POP:  /* Pop value then jump if value is false,  */
                delta = read_offset(env);
                link = stack_pop(stack);
                if ( ! link->type->is_true(link) )  env->current = env->start+delta;
                link_free(link);
                break;
                
            case JUMP:  /* Absolute jump */
                delta = read_offset(env);
                env->current = env->start + delta;
                break;

            case JINC: /* Jump If Not Critical */
                delta = read_offset(env);
                env->current = env->start+delta;
                break;
                
              jinc_critical:
                delta = read_offset(env);
            
                if (trapped) link_free(trapped);
                trapped = pusher->value.link;
                pusher->value.link = NULL;
                link_free(pusher);
                pusher = NULL;
                break;

            case PUSH_NULL:
                pusher = create_null();
                break;

            case PUSH_NUM:
                pusher = create_number( *((number_t *)env->current) );
                env->current+= sizeof(number_t);
                break;
            
            case PUSH_STR:
                delta = read_offset(env);
                pusher = create_string_literal( env->start + delta  );
                break;

            case PUSH_GVAR:
                delta = read_offset(env);
                pusher = link_dup(env->module->global_vars->links[delta]);
            
                if (! pusher){
                    pusher = exception("GlobalVariableUsedBeforeSet",NULL,NULL);
                }
                break;
            
            case PUSH_VAR:
                delta = read_offset(env);
             
                pusher = link_dup(env->local->links[delta]);
                
                if (! pusher){
                    pusher = exception("VariableUsedBeforeSet",NULL,NULL);;
                }
                break;
            
            case PUSH_BLOCK:
                delta = read_offset(env);
                pusher  = codeblock_literal2( env->function->value.codeblock->parent, delta  );
                if (env->function->value.codeblock->lexicals) {
                    lexicals_attach( env->function->value.codeblock->lexicals, pusher);
                }
                break;

            case PUSH_SYS:
                pusher = link_dup(Global->SYS_MODULE);
                break;
            
            case PUSH_MODULE:
                pusher = link_dup( env->function->value.codeblock->parent);
                break;
            
            case TYPEOF:
                link = stack_pop(stack);
                pusher = link_dup( link->type->type_link);
                link_free(link);
                break;
            
            case PUSH_THIS:
                pusher = link_dup(env->This);
                break;

            case PUSH_SELF:
                pusher = link_dup(env->Self);
                break;
            
            case PUSH_ARGS:
                pusher = link_dup(env->Arg);
                break;

            case PUSH_TRAPPED:
                pusher = trapped ? link_dup(trapped) : object_create(Global->null_type);
                break;
            
            case POP:
                link_free( stack_pop(stack) );
                break;

            case LINE:
                env->linenum = read_offset(env);
                break;

            default:
                fprintf(stderr," UNRECOGNIZED OPCODE ERROR %i\n", *(env->current));
                fprintf(stderr,"     near line %i\n", (int)(env->linenum));
                exit(1);
                break;
        }
                
        if (pusher) {
            
            if ( is_critical( pusher ) ){
                if ( *(env->current) == JINC)  goto jinc_critical;
                goto done;
            }
            
            stack_push(stack , pusher);
            pusher = NULL;
        }
        
    }

    end:

    if (trapped) link_free(trapped);
    return pusher;
}
Ejemplo n.º 25
0
void update_number(GuiObject * obj)
{
	check_object(obj, "obj", "update_number");

	create_number(obj);
}