Ejemplo n.º 1
0
_STATIC_
void disable_node(MathTree* tree, int level, int n)
{
    Node* node = tree->nodes[level][n];

    // Fill all of the result slots with this value
    fill_results(node, node->results.i.upper);

    // Figure out where we should swap this node to.
    int back = --tree->active[level];
    Node* swap = tree->nodes[level][back];

    // And execute the swap.
    tree->nodes[level][n--]  = swap;
    tree->nodes[level][back] = node;

    // Finally, increase the count of disabled nodes
    ustack_increment(&tree->disabled[level]);
}
Ejemplo n.º 2
0
Node* binary_n(Node* lhs, Node* rhs, float (*f)(float, float), Opcode op)
{
    Node* n = malloc(sizeof(Node));

    _Bool constant = (lhs->flags & NODE_CONSTANT) &&
                     (rhs->flags & NODE_CONSTANT);

    *n = (Node) {
        .opcode     = constant ? OP_CONST : op,
        .rank       = constant ? 0 : 1 + (lhs->rank > rhs->rank ?
                                          lhs->rank : rhs->rank),
        .flags      = constant ? NODE_CONSTANT : 0,
        .lhs        = constant ? NULL : lhs,
        .rhs        = constant ? NULL : rhs,
        .clone_address = NULL,
    };

    if (constant) {
        fill_results(n, (*f)(lhs->results.f, rhs->results.f));
    }

    return n;
}

Node* add_n(Node* lhs, Node* rhs) { return binary_n(lhs, rhs, add_f, OP_ADD); }
Node* sub_n(Node* lhs, Node* rhs) { return binary_n(lhs, rhs, sub_f, OP_SUB); }
Node* mul_n(Node* lhs, Node* rhs) { return binary_n(lhs, rhs, mul_f, OP_MUL); }
Node* div_n(Node* lhs, Node* rhs) { return binary_n(lhs, rhs, div_f, OP_DIV); }

Node* min_n(Node* lhs, Node* rhs) { return binary_n(lhs, rhs, min_f, OP_MIN); }
Node* max_n(Node* lhs, Node* rhs) { return binary_n(lhs, rhs, max_f, OP_MAX); }
Node* pow_n(Node* lhs, Node* rhs) { return binary_n(lhs, rhs, pow_f, OP_POW); }


////////////////////////////////////////////////////////////////////////////////

Node* unary_n(Node* arg, float (*f)(float), Opcode op)
{
    Node* n = malloc(sizeof(Node));

    _Bool constant = arg->flags & NODE_CONSTANT;

    *n = (Node) {
        .opcode     = constant ? OP_CONST : op,
        .rank       = constant ? 0 : 1 + arg->rank,
        .flags      = constant ? NODE_CONSTANT : 0,
        .lhs        = constant ? NULL : arg,
        .rhs        = NULL,
        .clone_address = NULL,
    };

    if (constant) {
        fill_results(n, (*f)(arg->results.f));
    }
    return n;
}

Node* abs_n(Node* child) { return unary_n(child, abs_f, OP_ABS); }
Node* square_n(Node* child) { return unary_n(child, square_f, OP_SQUARE); }
Node* sqrt_n(Node* child) { return unary_n(child, sqrt_f, OP_SQRT); }
Node* sin_n(Node* child) { return unary_n(child, sin_f, OP_SIN); }
Node* cos_n(Node* child) { return unary_n(child, cos_f, OP_COS); }
Node* tan_n(Node* child) { return unary_n(child, tan_f, OP_TAN); }
Node* asin_n(Node* child) { return unary_n(child, asin_f, OP_ASIN); }
Node* acos_n(Node* child) { return unary_n(child, acos_f, OP_ACOS); }
Node* atan_n(Node* child) { return unary_n(child, atan_f, OP_ATAN); }
Node* neg_n(Node* child) { return unary_n(child, neg_f, OP_NEG); }

////////////////////////////////////////////////////////////////////////////////

Node* nonary_n(Opcode op)
{
    Node* n = malloc(sizeof(Node));

    *n = (Node) {
        .opcode     = op,
        .rank       = 0,
        .flags      = 0,
        .lhs        = NULL,
        .rhs        = NULL,
        .clone_address = NULL,
    };

    return n;
}

Node* constant_n(float value)
{
    Node* n = nonary_n(OP_CONST);
    n->flags = NODE_CONSTANT;
    fill_results(n, value);
    return n;
}