Beispiel #1
0
int test2()
{
    const char str[] = "y=26*2/2+x*30/(20*1)";
    mapper_expr e = mapper_expr_new_from_string(str, 0, 0, 1);
    printf("\nParsing %s\n", str);
    if (!e) { printf("Test FAILED.\n"); return 1; }
#ifdef DEBUG
    printexpr("Parser returned: ", e);
#endif
    printf("\n");

    int inp, outp;
    inp = 3;
    mapper_expr_evaluate(e, &inp, &outp);

    printf("Evaluate with x=%d: %d (expected: %d)\n",
           inp, outp,
           26*2/2+inp*30/(20*1));

    inp = 321;
    mapper_expr_evaluate(e, &inp, &outp);

    printf("Evaluate with x=%d: %d (expected: %d)\n",
           inp, outp,
           26*2/2+inp*30/(20*1));

    mapper_expr_free(e);

    return 0;
}
Beispiel #2
0
int main()
{
    const char str[] = "y=26*2/2+log10(pi)+2.*pow(2,1*(3+7*.1)*1.1+x{0}[0])*3*4+cos(2.)";
    //const char str[] = "y=x?1:2";
    int input_history_size, output_history_size;
    mapper_expr e = mapper_expr_new_from_string(str, 'f', 'f', 1, 1,
                                                &input_history_size,
                                                &output_history_size);
    printf("Parsing %s\n", str);
    if (!e) { printf("Test FAILED.\n"); return 1; }
#ifdef DEBUG
    printexpr("Parser returned: ", e);
#endif
    printf("\n");

    float inp = 3.0, outp;

    // create signal_history structures
    mapper_signal_history_t inh, outh;
    inh.type = 'f';
    inh.size = 1;
    inh.length = 1;
    inh.value = &inp;
    inh.timetag = calloc(1, sizeof(mapper_timetag_t));
    inh.position = 0;

    outh.type = 'f';
    outh.size = 1;
    outh.length = 1;
    outh.value = &outp;
    outh.timetag = calloc(1, sizeof(mapper_timetag_t));
    outh.position = -1;

    int iterations = 1000000;
    int results = 0;
    double then = get_current_time();
    printf("Calculate expression %i times... ", iterations);
    while (iterations--) {
        results += mapper_expr_evaluate(e, &inh, &outh);
    }
    double now = get_current_time();
    printf("%f seconds.\n", now-then);

    if (results) {
        printf("Evaluate with x=%f: %f (expected: %f)\n",
               inp, outp,
               26*2/2+log10f(M_PI)+2.f*powf(2,1*(3+7*.1f)*1.1f+inp)*3*4+cosf(2.0f));
    }
    else
        printf("NO results.\n");

    mapper_expr_free(e);
    free(inh.timetag);
    free(outh.timetag);

    return 0;
}
Beispiel #3
0
void mapper_connection_set_mode_expression(mapper_connection c,
                                           const char *expr)
{
    int input_history_size, output_history_size;
    if (replace_expression_string(c, expr, &input_history_size,
                                  &output_history_size))
        return;

    c->props.mode = MO_EXPRESSION;
    reallocate_connection_histories(c, input_history_size,
                                    output_history_size);
    /* Special case: if we are the receiver and the new expression
     * evaluates to a constant we can update immediately. */
    /* TODO: should call handler for all instances updated
     * through this connection. */
    mapper_signal sig = c->parent->signal;
    if (!sig->props.is_output && mapper_expr_constant_output(c->expr)
        && !c->props.send_as_instance) {
        int index = 0;
        mapper_timetag_t now;
        mapper_clock_now(&sig->device->admin->clock, &now);
        if (!sig->id_maps[0].instance)
            index = msig_get_instance_with_local_id(sig, 0, 1, &now);
        if (index < 0)
            return;
        mapper_signal_instance si = sig->id_maps[index].instance;

        // evaluate expression
        mapper_signal_history_t h;
        h.type = sig->props.type;
        h.value = si->value;
        h.position = -1;
        h.length = sig->props.length;
        h.size = 1;
        char typestring[h.length];
        mapper_expr_evaluate(c->expr, 0, &c->expr_vars[si->index],
                             &h, typestring);

        // call handler if it exists
        if (sig->handler)
            sig->handler(sig, &sig->props, 0, si->value, 1, &now);
    }
}
Beispiel #4
0
int test1()
{
    const char str[] = "y=26*2/2+log10(pi)+2.*pow(2,1*(3+7*.1)*1.1+x{-6*2+12})*3*4+cos(2.)";
    mapper_expr e = mapper_expr_new_from_string(str, 1, 1, 1);
    printf("Parsing %s\n", str);
    if (!e) { printf("Test FAILED.\n"); return 1; }
#ifdef DEBUG
    printexpr("Parser returned: ", e);
#endif
    printf("\n");

    float inp, outp;
    inp = 3.0;
    mapper_expr_evaluate(e, &inp, &outp);

    printf("Evaluate with x=%f: %f (expected: %f)\n",
           inp, outp,
           26*2/2+log10f(M_PI)+2.f*powf(2,1*(3+7*.1f)*1.1f+inp)*3*4+cosf(2.0f));

    mapper_expr_free(e);

    return 0;
}
Beispiel #5
0
int mapper_connection_perform(mapper_connection connection,
                              mapper_signal_history_t *from,
                              mapper_signal_history_t **expr_vars,
                              mapper_signal_history_t *to,
                              char *typestring)
{
    int changed = 0, i;
    int vector_length = from->length < to->length ? from->length : to->length;

    if (connection->props.muted)
        return 0;

    /* If the destination type is unknown, we can't do anything
     * intelligent here -- even bypass mode might screw up if we
     * assume the types work out. */
    if (connection->props.dest_type != 'f'
        && connection->props.dest_type != 'i'
        && connection->props.dest_type != 'd')
    {
        return 0;
    }

    if (!connection->props.mode || connection->props.mode == MO_BYPASS)
    {
        /* Increment index position of output data structure. */
        to->position = (to->position + 1) % to->size;
        if (connection->props.src_type == connection->props.dest_type) {
            memcpy(msig_history_value_pointer(*to),
                   msig_history_value_pointer(*from),
                   mapper_type_size(to->type) * vector_length);
            memset(msig_history_value_pointer(*to) +
                   mapper_type_size(to->type) * vector_length, 0,
                   (to->length - vector_length) * mapper_type_size(to->type));
        }
        else if (connection->props.src_type == 'f') {
            float *vfrom = msig_history_value_pointer(*from);
            if (connection->props.dest_type == 'i') {
                int *vto = msig_history_value_pointer(*to);
                for (i = 0; i < vector_length; i++) {
                    vto[i] = (int)vfrom[i];
                }
                for (; i < to->length; i++) {
                    vto[i] = 0;
                }
            }
            else if (connection->props.dest_type == 'd') {
                double *vto = msig_history_value_pointer(*to);
                for (i = 0; i < vector_length; i++) {
                    vto[i] = (double)vfrom[i];
                }
                for (; i < to->length; i++) {
                    vto[i] = 0;
                }
            }
        }
        else if (connection->props.src_type == 'i') {
            int *vfrom = msig_history_value_pointer(*from);
            if (connection->props.dest_type == 'f') {
                float *vto = msig_history_value_pointer(*to);
                for (i = 0; i < vector_length; i++) {
                    vto[i] = (float)vfrom[i];
                }
                for (; i < to->length; i++) {
                    vto[i] = 0;
                }
            }
            else if (connection->props.dest_type == 'd') {
                double *vto = msig_history_value_pointer(*to);
                for (i = 0; i < vector_length; i++) {
                    vto[i] = (double)vfrom[i];
                }
                for (; i < to->length; i++) {
                    vto[i] = 0;
                }
            }
        }
        else if (connection->props.src_type == 'd') {
            double *vfrom = msig_history_value_pointer(*from);
            if (connection->props.dest_type == 'i') {
                int *vto = msig_history_value_pointer(*to);
                for (i = 0; i < vector_length; i++) {
                    vto[i] = (int)vfrom[i];
                }
                for (; i < to->length; i++) {
                    vto[i] = 0;
                }
            }
            else if (connection->props.dest_type == 'f') {
                float *vto = msig_history_value_pointer(*to);
                for (i = 0; i < vector_length; i++) {
                    vto[i] = (float)vfrom[i];
                }
                for (; i < to->length; i++) {
                    vto[i] = 0;
                }
            }
        }
        for (i = 0; i < vector_length; i++) {
            typestring[i] = to->type;
        }
        return 1;
    }
    else if (connection->props.mode == MO_EXPRESSION
             || connection->props.mode == MO_LINEAR)
    {
        die_unless(connection->expr!=0, "Missing expression.\n");
        return (mapper_expr_evaluate(connection->expr, from, expr_vars,
                                     to, typestring));
    }
    else if (connection->props.mode == MO_CALIBRATE)
    {
        /* Increment index position of output data structure. */
        to->position = (to->position + 1) % to->size;

        if (!connection->props.src_min) {
            connection->props.src_min =
                malloc(connection->props.src_length *
                       mapper_type_size(connection->props.src_type));
        }
        if (!connection->props.src_max) {
            connection->props.src_max =
                malloc(connection->props.src_length *
                       mapper_type_size(connection->props.src_type));
        }

        /* If calibration mode has just taken effect, first data
         * sample sets source min and max */
        if (connection->props.src_type == 'f') {
            float *v = msig_history_value_pointer(*from);
            float *src_min = (float*)connection->props.src_min;
            float *src_max = (float*)connection->props.src_max;
            if (!connection->calibrating) {
                for (i = 0; i < from->length; i++) {
                    src_min[i] = v[i];
                    src_max[i] = v[i];
                }
                connection->calibrating = 1;
                changed = 1;
            }
            else {
                for (i = 0; i < from->length; i++) {
                    if (v[i] < src_min[i]) {
                        src_min[i] = v[i];
                        changed = 1;
                    }
                    if (v[i] > src_max[i]) {
                        src_max[i] = v[i];
                        changed = 1;
                    }
                }
            }
        }
        else if (connection->props.src_type == 'i') {
            int *v = msig_history_value_pointer(*from);
            int *src_min = (int*)connection->props.src_min;
            int *src_max = (int*)connection->props.src_max;
            if (!connection->calibrating) {
                for (i = 0; i < from->length; i++) {
                    src_min[i] = v[i];
                    src_max[i] = v[i];
                }
                connection->calibrating = 1;
                changed = 1;
            }
            else {
                for (i = 0; i < from->length; i++) {
                    if (v[i] < src_min[i]) {
                        src_min[i] = v[i];
                        changed = 1;
                    }
                    if (v[i] > src_max[i]) {
                        src_max[i] = v[i];
                        changed = 1;
                    }
                }
            }
        }
        else if (connection->props.src_type == 'd') {
            double *v = msig_history_value_pointer(*from);
            double *src_min = (double*)connection->props.src_min;
            double *src_max = (double*)connection->props.src_max;
            if (!connection->calibrating) {
                for (i = 0; i < from->length; i++) {
                    src_min[i] = v[i];
                    src_max[i] = v[i];
                }
                connection->calibrating = 1;
                changed = 1;
            }
            else {
                for (i = 0; i < from->length; i++) {
                    if (v[i] < src_min[i]) {
                        src_min[i] = v[i];
                        changed = 1;
                    }
                    if (v[i] > src_max[i]) {
                        src_max[i] = v[i];
                        changed = 1;
                    }
                }
            }
        }

        if (changed) {
            mapper_connection_set_mode_linear(connection);

            /* Stay in calibrate mode. */
            connection->props.mode = MO_CALIBRATE;
        }

        if (connection->expr)
            return (mapper_expr_evaluate(connection->expr, from, expr_vars,
                                         to, typestring));
        else
            return 0;
    }
    return 1;
}
Beispiel #6
0
int mapper_connection_perform(mapper_connection connection,
                              mapper_signal sig,
                              mapper_signal_value_t *from_value,
                              mapper_signal_value_t *to_value)
{
    int changed = 0;
    float f = 0;
    
    if (connection->props.muted)
        return 0;

    /* If the destination type is unknown, we can't do anything
     * intelligent here -- even bypass mode might screw up if we
     * assume the types work out. */
    if (connection->props.dest_type != 'f'
        && connection->props.dest_type != 'i')
    {
        return 0;
    }

    if (!connection->props.mode || connection->props.mode == MO_BYPASS)
    {
        if (connection->props.src_type == connection->props.dest_type)
            *to_value = *from_value;
        else if (connection->props.src_type == 'f'
                 && connection->props.dest_type == 'i')
            to_value->i32 = (int)from_value->f;
        else if (connection->props.src_type == 'i'
                 && connection->props.dest_type == 'f')
            to_value->f = (float)from_value->i32;
    }
    else if (connection->props.mode == MO_EXPRESSION
             || connection->props.mode == MO_LINEAR)
    {
        die_unless(connection->expr!=0, "Missing expression.\n");
        *to_value = mapper_expr_evaluate(connection->expr, from_value);
    }

    else if (connection->props.mode == MO_CALIBRATE)
    {
        if (connection->props.src_type == 'f')
            f = from_value->f;
        else if (connection->props.src_type == 'i')
            f = (float)from_value->i32;

        /* If calibration mode has just taken effect, first data
         * sample sets source min and max */
        if (!connection->calibrating) {
            connection->props.range.src_min = f;
            connection->props.range.src_max = f;
            connection->props.range.known |=
                CONNECTION_RANGE_SRC_MIN | CONNECTION_RANGE_SRC_MAX;
            connection->calibrating = 1;
            changed = 1;
        } else {
            if (f < connection->props.range.src_min) {
                connection->props.range.src_min = f;
                connection->props.range.known |= CONNECTION_RANGE_SRC_MIN;
                changed = 1;
            }
            if (f > connection->props.range.src_max) {
                connection->props.range.src_max = f;
                connection->props.range.known |= CONNECTION_RANGE_SRC_MAX;
                changed = 1;
            }
        }

        if (changed) {
            mapper_connection_set_linear_range(connection, sig,
                                               &connection->props.range);

            /* Stay in calibrate mode. */
            connection->props.mode = MO_CALIBRATE;
        }

        if (connection->expr)
            *to_value = mapper_expr_evaluate(connection->expr, from_value);
    }

    return 1;
}
Beispiel #7
0
int parse_and_eval(int expectation)
{
    // clear output arrays
    int i;
    for (i = 0; i < DEST_ARRAY_LEN; i++) {
        dest_int[i] = 0;
        dest_float[i] = 0.0f;
        dest_double[i] = 0.0;
    }

    eprintf("***************** Expression %d *****************\n",
            expression_count++);
    eprintf("Parsing string '%s'\n", str);
    e = mapper_expr_new_from_string(str, num_sources, src_types, src_lengths,
                                    outh.type, outh.length);
    if (!e) {
        eprintf("Parser FAILED.\n");
        goto fail;
    }
    for (i = 0; i < num_sources; i++) {
        inh[i].size = mapper_expr_input_history_size(e, i);
    }
    outh.size = mapper_expr_output_history_size(e);

    if (mapper_expr_num_variables(e) > MAX_VARS) {
        eprintf("Maximum variables exceeded.\n");
        goto fail;
    }

    // reallocate variable value histories
    for (i = 0; i < e->num_variables; i++) {
        eprintf("user_var[%d]: %p\n", i, &user_vars[i]);
        mhist_realloc(&user_vars[i], e->variables[i].history_size,
                      sizeof(double), 0);
    }
    user_vars_p = user_vars;

#ifdef DEBUG
    if (verbose) {
        char str[128];
        snprintf(str, 128, "Parser returned %d tokens:", e->length);
        printexpr(str, e);
    }
#endif

    token_count += e->length;

    eprintf("Try evaluation once... ");
    if (!mapper_expr_evaluate(e, inh_p, &user_vars_p, &outh, &tt_in, typestring)) {
        eprintf("FAILED.\n");
        goto fail;
    }
    eprintf("OK\n");

    then = current_time();
    eprintf("Calculate expression %i times... ", iterations);
    i = iterations-1;
    while (i--) {
        mapper_expr_evaluate(e, inh_p, &user_vars_p, &outh, &tt_in, typestring);
    }
    now = current_time();
    eprintf("%g seconds.\n", now-then);
    total_elapsed_time += now-then;

    if (verbose) {
        printf("Got:      ");
        print_value(typestring, outh.length, outh.value, outh.position);
        printf(" \n");
    }
    else
        printf(".");

    mapper_expr_free(e);

    return expectation != EXPECT_SUCCESS;

fail:
    return expectation != EXPECT_FAILURE;
}
Beispiel #8
0
static void collapse_expr_to_left(exprnode* plhs, exprnode rhs,
                                  int constant_folding)
{
    // track whether any variable references
    int refvar = 0;
    int is_float = 0;

    // find trailing operator on right hand side
    exprnode rhs_last = rhs;
    if (rhs->tok.type == TOK_VAR)
        refvar = 1;
    while (rhs_last->next) {
        if (rhs_last->tok.type == TOK_VAR)
            refvar = 1;
        rhs_last = rhs_last->next;
    }

    // find pointer to insertion place:
    // - could be a function that needs args,
    // - otherwise assume it's before the trailing operator
    exprnode *plhs_last = plhs;
    if ((*plhs_last)->tok.type == TOK_VAR)
        refvar = 1;
    while ((*plhs_last)->next) {
        if ((*plhs_last)->tok.type == TOK_VAR)
            refvar = 1;
        plhs_last = &(*plhs_last)->next;
    }

    // insert float coersion if sides disagree on type
    token_t coerce;
    coerce.type = TOK_TOFLOAT;
    is_float = (*plhs_last)->is_float || rhs_last->is_float;
    if ((*plhs_last)->is_float && !rhs_last->is_float) {
        rhs_last = rhs_last->next = exprnode_new(&coerce, 1);
    } else if (!(*plhs_last)->is_float && rhs_last->is_float) {
        exprnode e = exprnode_new(&coerce, 1);
        e->next = (*plhs_last);
        (*plhs_last) = e;
        plhs_last = &e->next;
        e->next->is_float = 1;
    }

    // insert the list before the trailing op of left hand side
    rhs_last->next = (*plhs_last);
    (*plhs_last) = rhs;

    // if there were no variable references, then expression is
    // constant, so evaluate it immediately
    if (constant_folding && !refvar) {
        struct _mapper_expr e;
        e.node = *plhs;
        mapper_signal_value_t v = mapper_expr_evaluate(&e, 0);

        exprnode_free((*plhs)->next);
        (*plhs)->next = 0;
        (*plhs)->is_float = is_float;

        if (is_float) {
            (*plhs)->tok.type = TOK_FLOAT;
            (*plhs)->tok.f = v.f;
        }
        else {
            (*plhs)->tok.type = TOK_INT;
            (*plhs)->tok.i = v.i32;
        }
    }
}