Пример #1
0
/*
    Tests expressions and their evaluation
*/
void test_expressions()
{
    expression_t* ex1 = malloc(sizeof(expression_t));
    expression_t* ex2 = malloc(sizeof(expression_t));
    expression_t* ex3 = malloc(sizeof(expression_t));
    expression_t* ex4 = malloc(sizeof(expression_t));

    ex1->next = ex2;
    ex2->next = ex3;
    ex3->next = ex4;


    /* trying successful evaluation first */

    ex1->type = EXP_NUMBER | '+';
    ex1->data.number = 14;

    ex2->type = EXP_NUMBER | '-';
    ex2->data.number = 4;

    ex3->type = EXP_NUMBER | '/';
    ex3->data.number = 2;

    ex4->type = EXP_NUMBER | '*';
    ex4->data.number = 3;

    ulong result;

    assert(!expression_evaluate(&ex1, &result));
    assert(result == 15);
    assert(ex1 == 0);

    /* trying unsuccessful evaluation */
    ex1 = malloc(sizeof(expression_t));
    ex2 = malloc(sizeof(expression_t));
    ex3 = malloc(sizeof(expression_t));
    ex4 = malloc(sizeof(expression_t));

    ex1->next = ex2;
    ex2->next = ex3;
    ex3->next = ex4;

    ex1->type = EXP_NUMBER | '+';
    ex1->data.number = 14;

    ex2->type = EXP_NUMBER | '-';
    ex2->data.number = 4;

    ex3->type = EXP_NUMBER | '/';
    ex3->data.number = 2;

    ex4->type = EXP_LABEL;
    ex4->data.label = "impossible to find label";

    assert(expression_evaluate(&ex1, &result));
    assert(result == 5);
    assert(ex1 == ex4);

    fprintf(stdout, "%s:\tpassed\n", __FUNCTION__);
}
Пример #2
0
void update(objectmachine_t *obj, player_t **team, int team_size, brick_list_t *brick_list, item_list_t *item_list, object_list_t *object_list)
{
    objectdecorator_t *dec = (objectdecorator_t*)obj;
    objectmachine_t *decorated_machine = dec->decorated_machine;
    objectdecorator_setscale_t *me = (objectdecorator_setscale_t*)obj;
    object_t *object = obj->get_object_instance(obj);

    float scale_x = max(0.0f, expression_evaluate(me->scale_x));
    float scale_y = max(0.0f, expression_evaluate(me->scale_y));
    object->actor->scale = v2d_new(scale_x, scale_y);

    decorated_machine->update(decorated_machine, team, team_size, brick_list, item_list, object_list);
}
Пример #3
0
void update(objectmachine_t *obj, player_t **team, int team_size, brick_list_t *brick_list, item_list_t *item_list, object_list_t *object_list)
{
    objectdecorator_t *dec = (objectdecorator_t*)obj;
    objectmachine_t *decorated_machine = dec->decorated_machine;
    objectdecorator_setplayerposition_t *me = (objectdecorator_setplayerposition_t*)obj;
    object_t *object = obj->get_object_instance(obj);
    player_t *player = enemy_get_observed_player(object);
    v2d_t offset = v2d_new(expression_evaluate(me->offset_x), expression_evaluate(me->offset_y));

    player->actor->position = v2d_add(object->actor->position, offset);
    player->disable_wall = PLAYER_WALL_NONE;

    decorated_machine->update(decorated_machine, team, team_size, brick_list, item_list, object_list);
}
Пример #4
0
/* private strategies */
void createchild_strategy(objectdecorator_children_t *me, player_t **team, int team_size, brick_list_t *brick_list, item_list_t *item_list, object_list_t *object_list)
{
    objectmachine_t *obj = (objectmachine_t*)me;
    object_t *object = obj->get_object_instance(obj);
    object_t *child;
    v2d_t offset;

    offset.x = expression_evaluate(me->offset_x);
    offset.y = expression_evaluate(me->offset_y);
    child = level_create_enemy(me->object_name, v2d_add(object->actor->position, offset));
    if(child != NULL) {
        enemy_add_child(object, me->child_name, child);
        enemy_update(child, team, team_size, brick_list, item_list, object_list); /* important to exchange data between objects */
        nanocalcext_set_target_object(object, brick_list, item_list, object_list); /* restore nanocalc's target object */
    }
}
Пример #5
0
void update(objectmachine_t *obj, player_t **team, int team_size, brick_list_t *brick_list, item_list_t *item_list, object_list_t *object_list)
{
    objectdecorator_t *dec = (objectdecorator_t*)obj;
    objectdecorator_enemy_t *me = (objectdecorator_enemy_t*)obj;
    objectmachine_t *decorated_machine = dec->decorated_machine;
    object_t *object = obj->get_object_instance(obj);
    int i, score;

    score = (int)expression_evaluate(me->score);

    /* player x object collision */
    for(i=0; i<team_size; i++) {
        player_t *player = team[i];
        if(actor_pixelperfect_collision(object->actor, player->actor)) {
            if(player_is_attacking(player) || player->invincible) {
                /* I've been defeated */
                player_bounce(player, object->actor);
                level_add_to_score(score);
                level_create_item(IT_EXPLOSION, v2d_add(object->actor->position, v2d_new(0,-15)));
                level_create_animal(object->actor->position);
                sound_play( soundfactory_get("destroy") );
                object->state = ES_DEAD;
            }
            else {
                /* The player has been hit by me */
                player_hit(player, object->actor);
            }
        }
    }

    decorated_machine->update(decorated_machine, team, team_size, brick_list, item_list, object_list);
}
Пример #6
0
// returns the result of the arithmetic expression_t (expanding subexpressions)
static double 
op_arithmetic(expression_t *expr)
{
    double num1 = 0;
    expression_operand_t *op1;
    double res = -1;
    int offset = 0;
    char op = expr->operation->op;
    expression_operand_t **operands = expr->operands;

    // iterate over the NULL-terminated array of operands
    while(operands[offset] != NULL) {
        op1 = operands[offset];
        switch(op1->type) {
            case EXPR_OPTYPE_CALLBACK:
                num1 = op1->callback.cb(op1->callback.user);
                expression_callback_change_value(op1, num1);
                //op1->callback.lastCall = time(NULL);
            break;
            case EXPR_OPTYPE_EXPRESSION:
                // evaluate sub expression_t (recursion happens here)
                num1 = expression_evaluate(op1->expr);
                if(num1 < 0) 
                        return -1;
                break;
            case EXPR_OPTYPE_INTEGER:
                num1 = (double)op1->inum;
                break;
            case EXPR_OPTYPE_FLOAT:
                num1 = (double)op1->fnum;
                break;
            case EXPR_OPTYPE_STRING:
                if(sscanf(op1->string, "%lf", &num1) != 1) {
                    fprintf(stderr, "op_arithmetic() : accepts only numeric values (no strings)\n");
                    return -1;
                }
                break;
            default:
                fprintf(stderr, "op_boolean() : Uknown operand type: 0x%02x\n", op1->type);
                return -1;
        }

        if(offset == 0) { 
            if (expr->operation->minOperands == 1 && expr->operation->maxOperands == 1)
                res = _do_arithmetic(op, num1, 0);
            else
                res = num1;
        } else {
            res = _do_arithmetic(op, (double)res, num1);
        }

        offset++;
    }
    
    return res;
}
Пример #7
0
void update(objectmachine_t *obj, player_t **team, int team_size, brick_list_t *brick_list, item_list_t *item_list, object_list_t *object_list)
{
    objectdecorator_t *dec = (objectdecorator_t*)obj;
    objectmachine_t *decorated_machine = dec->decorated_machine;
    objectdecorator_addlives_t *me = (objectdecorator_addlives_t*)obj;

    player_set_lives( player_get_lives() + (int)expression_evaluate(me->lives) );

    decorated_machine->update(decorated_machine, team, team_size, brick_list, item_list, object_list);
}
Пример #8
0
void update(objectmachine_t *obj, player_t **team, int team_size, brick_list_t *brick_list, item_list_t *item_list, object_list_t *object_list)
{
    objectdecorator_t *dec = (objectdecorator_t*)obj;
    objectmachine_t *decorated_machine = dec->decorated_machine;
    objectdecorator_textout_t *me = (objectdecorator_textout_t*)obj;
    object_t *object = obj->get_object_instance(obj);
    symboltable_t *st = objectvm_get_symbol_table(object->vm);
    char *processed_text;
    int start, length;
    float wpx;
    v2d_t pos;

    /* 문자열의 범위를 계산한다 ( clip()할 필요가 없다 ) */
    start = (int)expression_evaluate(me->index_of_first_char);
    length = (int)expression_evaluate(me->length);

    /* 글꼴 구성 */
    font_use_substring(me->fnt, start, length);
    font_set_width(me->fnt, (int)expression_evaluate(me->max_width));

    /* 글꼴 텍스트 */
    processed_text = nanocalc_interpolate_string(me->text, st);
    font_set_text(me->fnt, "%s", processed_text);
    free(processed_text);

    /* symbol table tricks */
    symboltable_set(st, "$_STRLEN", tagged_strlen(font_get_text(me->fnt))); /* $_STRLEN의 텍스트 길이를 저장한다. */

    /* 글꼴 위치 */
    pos = v2d_new(expression_evaluate(me->xpos), expression_evaluate(me->ypos));
    wpx = font_get_textsize(me->fnt).x;
    switch(me->style) {
    case TEXTOUT_LEFT: break;
    case TEXTOUT_CENTRE: pos.x -= wpx/2; break;
    case TEXTOUT_RIGHT: pos.x -= wpx; break;
    }
    font_set_position(me->fnt, v2d_add(object->actor->position, pos));

    /* done! */
    decorated_machine->update(decorated_machine, team, team_size, brick_list, item_list, object_list);
}
Пример #9
0
void get_rectangle_coordinates(objectdecorator_lockcamera_t *me, int *x1, int *y1, int *x2, int *y2)
{
    int mi, ma;

    *x1 = (int)expression_evaluate(me->x1);
    *x2 = (int)expression_evaluate(me->x2);
    *y1 = (int)expression_evaluate(me->y1);
    *y2 = (int)expression_evaluate(me->y2);

    if(*x1 == *x2) (*x2)++;
    if(*y1 == *y2) (*y2)++;

    mi = min(*x1, *x2);
    ma = max(*x1, *x2);
    *x1 = mi;
    *x2 = ma;

    mi = min(*y1, *y2);
    ma = max(*y1, *y2);
    *y1 = mi;
    *y2 = ma;
}
Пример #10
0
void expression_simplify(EXPRESSION expression)
{
	if(expression[0].type == END || expression[1].type == END) return;

	int i = 0, j, n;
	int type;
	double value;

	// fudge to make a non-allocated 2x1 matrix act like an allocated one
	double work[2], *p_work[2];
	p_work[0] = &work[0];
	p_work[1] = &work[1];

	// loop until a pass is completed with no simplifications
	do
	{
		// start at the begining haveing done no simplifications
		i = n = 0;

		while(1)
		{
			// find the next value-value-operator pattern
			while(!(expression[i].type == VALUE && expression[i+1].type == VALUE && IS_OPERATOR(expression[i+2].type)) && expression[i+2].type != END) i ++;

			// reached the end
			if(expression[i+2].type == END) break;

			// evaluate the sub-expression
			type = expression[i+3].type;
			expression[i+3].type = END;
			expression_evaluate(1, &value, &expression[i], NULL, p_work);
			expression[i+3].type = type;

			// replace the sub-expression with the value
			expression[i].value = value;
			j = i + 3;
			while(expression[j-1].type != END) { expression[j-2] = expression[j]; j ++; }

			// increment the number of simplifications
			n ++;
		}

	} while(n);
}
Пример #11
0
static int
check_division(expression_t *expr)
{
    double test = 1;
    expression_operand_t *op1 = expr->operands[1];

    if(!check_arithmetic(expr))
        return 0;

    if(!op1)
        return 0;

    switch(op1->type) {
        case EXPR_OPTYPE_STRING:
            if(sscanf(op1->string, "%lf", &test) != 1) {
                fprintf(stderr, "op_arithmetic() : accepts only numeric values (no strings)\n");
                return 0;
            }
            break;
        case EXPR_OPTYPE_INTEGER:
            test = (double)op1->inum;
            break;
        case EXPR_OPTYPE_FLOAT:
            test = op1->fnum;
            break;
        case EXPR_OPTYPE_CALLBACK:
            test = op1->callback.cb(op1->callback.user); 
            expression_callback_change_value(op1, test);
            //op1->callback.lastCall = time(NULL);
            break;
        case EXPR_OPTYPE_EXPRESSION:
            // evaluate sub expression_t (recursion happens here)
            test = expression_evaluate(op1->expr);
            if(test == -1) // abort if we have an invalid subexpression as divisor
                return 0;
            break;
    }
    if(test == 0) // division is not valid if the divisor is 0
        return 0;
    return 1;
}
Пример #12
0
static double
op_change(expression_t *expr)
{
    double period = 1.0;
    struct timeval now;

    gettimeofday(&now, NULL);

    expression_operand_t *op1 = expr->operands[0];

    if(expr->numOperands == 2) {
        expression_operand_t *op2 = expr->operands[1];
        switch(op2->type) {
            case EXPR_OPTYPE_INTEGER:
                    period = (double)op2->inum;
                    break;
            case EXPR_OPTYPE_FLOAT:
                    period = op2->fnum;
                    break;
            case EXPR_OPTYPE_STRING:
                    if(sscanf(op2->string, "%lf", &period) != 1)  {
                            fprintf(stderr, "'%s' string doesn't represent an integer", op2->string);
                            return 0; 
                    }
                    break;
            case EXPR_OPTYPE_CALLBACK:
                    period = op2->callback.cb(op2->callback.user);
                    break;
            case EXPR_OPTYPE_EXPRESSION:
                    period = expression_evaluate(op2->expr);
                    break;
            default:
                    return 0;
        }
    }

    double diff = (now.tv_sec - op1->callback.lastChange.tv_sec) + ((now.tv_usec - op1->callback.lastChange.tv_usec) / 1e6);
    return (double)(diff <= period);
}
Пример #13
0
static CMDERR internal_parse_command(const char *original_command, int execute)
{
	char command[MAX_COMMAND_LENGTH], parens[MAX_COMMAND_LENGTH];
	char *params[MAX_COMMAND_PARAMS];
	CMDERR result = CMDERR_NONE;
	char *command_start;
	char *p, c = 0;

	/* make a copy of the command */
	strcpy(command, original_command);

	/* loop over all semicolon-separated stuff */
	for (p = command; *p != 0; )
	{
		int paramcount = 0, foundend = FALSE, instring = FALSE, isexpr = FALSE, parendex = 0;

		/* find a semicolon or the end */
		for (params[paramcount++] = p; !foundend; p++)
		{
			c = *p;
			if (instring)
			{
				if (c == '"' && p[-1] != '\\')
					instring = FALSE;
			}
			else
			{
				switch (c)
				{
					case '"':	instring = TRUE; break;
					case '(':
					case '[':
					case '{':	parens[parendex++] = c; break;
					case ')':	if (parendex == 0 || parens[--parendex] != '(') return MAKE_CMDERR_UNBALANCED_PARENS(p - command); break;
					case ']':	if (parendex == 0 || parens[--parendex] != '[') return MAKE_CMDERR_UNBALANCED_PARENS(p - command); break;
					case '}':	if (parendex == 0 || parens[--parendex] != '{') return MAKE_CMDERR_UNBALANCED_PARENS(p - command); break;
					case ',':	if (parendex == 0) params[paramcount++] = p; break;
					case ';': 	if (parendex == 0) foundend = TRUE; break;
					case '-':	if (parendex == 0 && paramcount == 1 && p[1] == '-') isexpr = TRUE; *p = c; break;
					case '+':	if (parendex == 0 && paramcount == 1 && p[1] == '+') isexpr = TRUE; *p = c; break;
					case '=':	if (parendex == 0 && paramcount == 1) isexpr = TRUE; *p = c; break;
					case 0:		foundend = TRUE; break;
					default:	*p = tolower(c); break;
				}
			}
		}

		/* check for unbalanced parentheses or quotes */
		if (instring)
			return MAKE_CMDERR_UNBALANCED_QUOTES(p - command);
		if (parendex != 0)
			return MAKE_CMDERR_UNBALANCED_PARENS(p - command);

		/* NULL-terminate if we ended in a semicolon */
		p--;
		if (c == ';') *p++ = 0;

		/* process the command */
		command_start = params[0];

		/* allow for "do" commands */
		if (tolower(command_start[0] == 'd') && tolower(command_start[1] == 'o') && isspace(command_start[2]))
		{
			isexpr = TRUE;
			command_start += 3;
		}

		/* if it smells like an assignment expression, treat it as such */
		if (isexpr && paramcount == 1)
		{
			UINT64 expresult;
			EXPRERR exprerr = expression_evaluate(command_start, debug_get_cpu_info(cpu_getactivecpu())->symtable, &expresult);
			if (exprerr != EXPRERR_NONE)
				return MAKE_CMDERR_EXPRESSION_ERROR(EXPRERR_ERROR_OFFSET(exprerr));
		}
		else
		{
			result = internal_execute_command(execute, paramcount, &params[0]);
			if (result != CMDERR_NONE)
				return MAKE_CMDERR(CMDERR_ERROR_CLASS(result), command_start - command);
		}
	}
	return CMDERR_NONE;
}
Пример #14
0
void set_yspeed(player_t *player, expression_t *speed)
{
    player->actor->speed.y = expression_evaluate(speed);
}
Пример #15
0
// returns -1 on error 0 if FALSE 1 if TRUE
static double 
op_boolean(expression_t *expr)
{
    double num1 = 0;
    char str1[EXPR_STRING_OPERAND_MAX_SIZE];
    char str_prev[EXPR_STRING_OPERAND_MAX_SIZE];
    expression_operand_t *op1;
    double res = 0;
    int offset = 0;
    int is_integer = 0;
    char op = expr->operation->op;
    expression_operand_t **operands = expr->operands;

    // iterate over the NULL-terminated array of operands
    while(operands[offset] != NULL) {
        op1 = operands[offset];
        switch(op1->type) {
            case EXPR_OPTYPE_CALLBACK:
                num1 = op1->callback.cb(op1->callback.user);
                expression_callback_change_value(op1, num1);
                //op1->callback.lastCall = time(NULL);
                sprintf(str1, "%lf", num1);
                break;
            case EXPR_OPTYPE_EXPRESSION:
                // evaluate sub expression_t (recursion happens here)
                num1 = expression_evaluate(op1->expr);
                sprintf(str1, "%lf", num1);
                break;
            case EXPR_OPTYPE_INTEGER:
                num1 = (double)op1->inum;
                sprintf(str1, "%lf", num1);
                break;
            case EXPR_OPTYPE_FLOAT:
                num1 = op1->fnum;
                sprintf(str1, "%lf", num1);
                break;
            case EXPR_OPTYPE_STRING:
                snprintf(str1, sizeof(str1), "%s", op1->string);
                if(sscanf(str1, "%lf", &num1) != 1) 
                    num1 = str1[0]?1:0;
                else
                    is_integer = 1;
                break;
            default:
                fprintf(stderr, "op_boolean() : Uknown operand type: 0x%02x\n", op1->type);
                return 0;
        }

        if(op == EXPR_OP_TEST) 
            return (num1?1:0);
        else if(op == EXPR_OP_NOT)
            return (num1?0:1);

        if(offset == 0) {
            res = num1;
            strcpy(str_prev, str1);                // save the string counterpart of the 'res' variable
        } else {
            if(op1->type == EXPR_OPTYPE_STRING && !is_integer) {
                res = (double)_do_str_boolean(op, str_prev, str1);        
                sprintf(str_prev, "%f", res);
            } else {
                res = _do_number_boolean(op, res, num1);
                sprintf(str_prev, "%f", res);
            }
        }

        offset++;
    }
    
    return res;
}