Esempio n. 1
0
void mesh_render(mesh_s *mesh)
{
    for(int i = 0 ; i < array_length(mesh->attributes); i++)
    {
        mesh_attribute_s *attribute = array_get_ptr(mesh->attributes) + i;
        GLint location = glGetAttribLocation(mesh->program, attribute->name);
        if(location >= 0)
        {
            glBindBuffer(GL_ARRAY_BUFFER, attribute->buffer);
            glVertexAttribPointer(
                location, attribute->components, GL_FLOAT, GL_FALSE,
                sizeof(GLfloat) * attribute->components, (void *)0);
            glEnableVertexAttribArray(location);
        }
    }

    glUseProgram(mesh->program);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->elements.buffer);
    glDrawElements(
        GL_TRIANGLES, mesh->elements.count, GL_UNSIGNED_INT, (void *)0);
    glUseProgram(0);

    for(int i = 0 ; i < array_length(mesh->attributes); i++)
    {
        mesh_attribute_s *attribute = array_get_ptr(mesh->attributes) + i;
        GLint location = glGetAttribLocation(mesh->program, attribute->name);
        if(location >= 0)
        {
            glDisableVertexAttribArray(location);
        }
    }

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
Esempio n. 2
0
static void handle_tick(game_context_s *context, void *data, const nothing_s *n)
{
    input_handler_s *input_handler = data;

    // process the callback-based events
    target_context = context;
    glfwPollEvents();
    target_context = NULL;

    // process joysticks
    for(int i = 0; i < MAX_JOYSTICKS; i++)
    {
        if(glfwGetJoystickParam(i, GLFW_PRESENT) == GL_TRUE)
        {
            joystick_event_s *joystick = &input_handler->joysticks[i];

            int axis_count = glfwGetJoystickParam(i, GLFW_AXES);
            array_set_length(joystick->axes, axis_count);
            glfwGetJoystickPos(i, array_get_ptr(joystick->axes), axis_count);

            int button_count = glfwGetJoystickParam(i, GLFW_BUTTONS);
            array_set_length(joystick->buttons, button_count);
            glfwGetJoystickButtons(i, array_get_ptr(joystick->buttons),
                button_count);

            broadcast_input_handler_joystick_event(context, *joystick);
        }
    }
}
Esempio n. 3
0
File: interp.c Progetto: sbstp/zeta
/**
Evaluate a function call
*/
value_t eval_call(
    clos_t* callee,
    array_t* arg_exprs,
    clos_t* caller,
    value_t* caller_locals
)
{
    ast_fun_t* fptr = callee->fun;
    assert (fptr != NULL);

    if (arg_exprs->len != fptr->param_decls->len)
    {
        printf("argument count mismatch\n");
        exit(-1);
    }

    // Allocate space for the local variables
    value_t* callee_locals = alloca(
        sizeof(value_t) * fptr->local_decls->len
    );

    // Allocate mutable cells for the escaping variables
    for (size_t i = 0; i < fptr->esc_locals->len; ++i)
    {
        ast_decl_t* decl = array_get(fptr->esc_locals, i).word.decl;
        assert (decl->esc);
        assert (decl->idx < fptr->local_decls->len);
        callee_locals[decl->idx] = value_from_obj((heapptr_t)cell_alloc());
    }

    // Evaluate the argument values
    for (size_t i = 0; i < arg_exprs->len; ++i)
    {
        //printf("evaluating arg %ld\n", i);

        heapptr_t param_decl = array_get_ptr(fptr->param_decls, i);

        // Evaluate the parameter value
        value_t arg_val = eval_expr(
            array_get_ptr(arg_exprs, i),
            caller,
            caller_locals
        );

        // Assign the value to the parameter
        eval_assign(
            param_decl,
            arg_val,
            callee,
            callee_locals
        );
    }

    // Evaluate the unit function body in the local frame
    return eval_expr(fptr->body_expr, callee, callee_locals);
}
Esempio n. 4
0
void mesh_set_attribute(
    mesh_s *mesh,
    const char *name,
    GLint components,
    GLsizei size,
    GLfloat *attribute_data)
{
    mesh_attribute_s *target_attribute = NULL;
    for(int i = 0; i < array_length(mesh->attributes); i++)
    {
        if(strcmp(array_get(mesh->attributes, i).name, name) == 0)
        {
            target_attribute = array_get_ptr(mesh->attributes) + i;
        }
    }
    if(target_attribute == NULL)
    {
        mesh_attribute_s new_attribute = {NULL, 0};
        array_add(mesh->attributes, new_attribute);
        target_attribute = array_get_ptr(mesh->attributes)
                         + array_length(mesh->attributes) - 1;
    }

    if(target_attribute->name == NULL)
    {
        char *name_buf = malloc(strlen(name) + 1);
        strcpy(name_buf, name);
        target_attribute->name = name_buf;
    }

    if(target_attribute->buffer != 0)
        glDeleteBuffers(1, &target_attribute->buffer);

    target_attribute->buffer = graphics_make_buffer(
        GL_ARRAY_BUFFER, size, attribute_data, GL_STATIC_DRAW);

    target_attribute->components = components;
}
Esempio n. 5
0
void mesh_release(mesh_s *mesh)
{
    if(mesh->elements.buffer != 0)
        glDeleteBuffers(1, &mesh->elements.buffer);

    for(int i = 0; i < array_length(mesh->attributes); i++)
    {
        mesh_attribute_s *attribute = array_get_ptr(mesh->attributes) + i;
        free((char *)attribute->name);
        glDeleteBuffers(1, &attribute->buffer);
    }
    array_release(mesh->attributes);

    free(mesh);
}
Esempio n. 6
0
File: interp.c Progetto: sbstp/zeta
/**
Resolve variables in a given function
*/
void var_res_pass(ast_fun_t* fun, ast_fun_t* parent)
{
    fun->parent = parent;

    // Add the function parameters to the local scope
    for (size_t i = 0; i < fun->param_decls->len; ++i)
    {
        find_decls(
            array_get_ptr(fun->param_decls, i),
            fun
        );
        assert (array_get(fun->param_decls, i).word.decl->fun == fun);
    }

    // Find declarations in the function body
    find_decls(fun->body_expr, fun);

    // Resolve variable references
    var_res(fun->body_expr, fun);
}
Esempio n. 7
0
File: interp.c Progetto: sbstp/zeta
/**
Evaluate a host function call
*/
value_t eval_host_call(
    hostfn_t* callee,
    array_t* arg_exprs,
    clos_t* caller,
    value_t* caller_locals
)
{
    value_t* arg_vals = alloca(sizeof(value_t) * arg_exprs->len);

    if (arg_exprs->len != callee->num_params)
    {
        printf(
            "argument count mismatch in call to %s, got %d, expected %d\n",
            string_cstr(callee->name),
            arg_exprs->len,
            callee->num_params
        );
        exit(-1);
    }

    // Evaluate the argument values
    for (size_t i = 0; i < arg_exprs->len; ++i)
    {
        //printf("evaluating arg %ld\n", i);

        // Evaluate the parameter value
        arg_vals[i] = eval_expr(
            array_get_ptr(arg_exprs, i),
            caller,
            caller_locals
        );
    }

    // Type test signature
    if (callee->sig_str == vm_get_cstr("bool(tag)"))
    {
        bool (*fptr)(tag_t) = callee->fptr;
        return fptr(arg_vals[0].tag)? VAL_TRUE:VAL_FALSE;
    }

    if (callee->sig_str == vm_get_cstr("void(int)"))
    {
        void (*fptr)(int) = callee->fptr;
        fptr(arg_vals[0].word.int32);
        return VAL_TRUE;
    }

    if (callee->sig_str == vm_get_cstr("void(int64)"))
    {
        void (*fptr)(int64_t) = callee->fptr;
        fptr(arg_vals[0].word.int64);
        return VAL_TRUE;
    }

    if (callee->sig_str == vm_get_cstr("void(string)"))
    {
        void (*fptr)(string_t*) = callee->fptr;
        fptr(arg_vals[0].word.string);
        return VAL_TRUE;
    }

    if (callee->sig_str == vm_get_cstr("string()"))
    {
        string_t* (*fptr)() = callee->fptr;
        string_t* str = fptr();
        return value_from_heapptr((heapptr_t)str, TAG_STRING);
    }

    if (callee->sig_str == vm_get_cstr("string(string)"))
    {
        string_t* (*fptr)(string_t*) = callee->fptr;
        string_t* str = fptr(arg_vals[0].word.string);
        return value_from_heapptr((heapptr_t)str, TAG_STRING);
    }

    printf("unsupported host function signature\n");
    exit(-1);
}
Esempio n. 8
0
File: interp.c Progetto: sbstp/zeta
void var_res(heapptr_t expr, ast_fun_t* fun)
{
    // Get the shape of the AST node
    shapeidx_t shape = get_shape(expr);

    // Constants and strings, do nothing
    if (shape == SHAPE_AST_CONST ||
        shape == SHAPE_STRING)
    {
        return;
    }

    // Array literal expression
    if (shape == SHAPE_ARRAY)
    {
        array_t* array_expr = (array_t*)expr;
        for (size_t i = 0; i < array_expr->len; ++i)
            var_res(array_get(array_expr, i).word.heapptr, fun);

        return;
    }

    // Object literal expression
    if (shape == SHAPE_AST_OBJ)
    {
        ast_obj_t* obj_expr = (ast_obj_t*)expr;

        if (obj_expr->proto_expr)
            var_res(obj_expr->proto_expr, fun);

        for (size_t i = 0; i < obj_expr->val_exprs->len; ++i)
            var_res(array_get(obj_expr->val_exprs, i).word.heapptr, fun);

        return;
    }

    // Variable declaration, do nothing
    if (shape == SHAPE_AST_DECL)
    {
        return;
    }

    // Variable reference
    if (shape == SHAPE_AST_REF)
    {
        ast_ref_t* ref = (ast_ref_t*)expr;

        // Find the declaration for this reference
        ast_decl_t* decl = find_decl(ref, fun);

        if (decl == NULL)
        {
            printf("unresolved reference to \"%s\"\n", string_cstr(ref->name));
            exit(-1);
        }

        // Store the declaration on the reference
        assert (decl->fun != NULL);
        ref->decl = decl;

        // If the variable is from this scope
        if (decl->fun == fun)
        {
            // Store the index of this local
            assert (decl->idx < fun->local_decls->len);
            ref->idx = decl->idx;
        }
        else
        {
            // Mark the variable as escaping
            decl->esc = true;

            // Thread the escaping variable through nested functions
            thread_esc_var(ref, fun, fun);

            // Find the mutable cell index for the variable
            ref->idx = array_indexof_ptr(fun->free_vars, (heapptr_t)ref->decl);
            assert (ref->idx < fun->free_vars->len);
        }

        return;
    }

    // Sequence/block expression
    if (shape == SHAPE_AST_SEQ)
    {
        ast_seq_t* seqexpr = (ast_seq_t*)expr;
        array_t* expr_list = seqexpr->expr_list;

        for (size_t i = 0; i < expr_list->len; ++i)
            var_res(array_get_ptr(expr_list, i), fun);

        return;
    }

    // Binary operator (e.g. a + b)
    if (shape == SHAPE_AST_BINOP)
    {
        ast_binop_t* binop = (ast_binop_t*)expr;

        var_res(binop->left_expr, fun);
        var_res(binop->right_expr, fun);
        return;
    }

    // Unary operator (e.g. -a)
    if (shape == SHAPE_AST_UNOP)
    {
        ast_unop_t* unop = (ast_unop_t*)expr;
        var_res(unop->expr, fun);
        return;
    }

    // If expression
    if (shape == SHAPE_AST_IF)
    {
        ast_if_t* ifexpr = (ast_if_t*)expr;
        var_res(ifexpr->test_expr, fun);
        var_res(ifexpr->then_expr, fun);
        var_res(ifexpr->else_expr, fun);
        return;
    }

    // Function/closure expression
    if (shape == SHAPE_AST_FUN)
    {
        ast_fun_t* child_fun = (ast_fun_t*)expr;

        // Resolve variable references in the nested child function
        var_res_pass(child_fun, fun);

        return;
    }

    // Function call
    if (shape == SHAPE_AST_CALL)
    {
        ast_call_t* callexpr = (ast_call_t*)expr;
        array_t* arg_exprs = callexpr->arg_exprs;

        var_res(callexpr->fun_expr, fun);

        for (size_t i = 0; i < arg_exprs->len; ++i)
            var_res(array_get_ptr(arg_exprs, i), fun);

        return;
    }

    // Unsupported AST node type
    assert (false);
}
Esempio n. 9
0
File: interp.c Progetto: sbstp/zeta
/**
Find all declarations within an AST subtree
*/
void find_decls(heapptr_t expr, ast_fun_t* fun)
{
    assert (expr != NULL);

    // Get the shape of the AST node
    shapeidx_t shape = get_shape(expr);

    // Constants and strings, do nothing
    if (shape == SHAPE_AST_CONST ||
        shape == SHAPE_STRING)
    {
        return;
    }

    // Array literal expression
    if (shape == SHAPE_ARRAY)
    {
        array_t* array_expr = (array_t*)expr;
        for (size_t i = 0; i < array_expr->len; ++i)
            find_decls(array_get(array_expr, i).word.heapptr, fun);

        return;
    }

    // Object literal expression
    if (shape == SHAPE_AST_OBJ)
    {
        ast_obj_t* obj_expr = (ast_obj_t*)expr;

        if (obj_expr->proto_expr)
            find_decls(obj_expr->proto_expr, fun);

        for (size_t i = 0; i < obj_expr->val_exprs->len; ++i)
            find_decls(array_get(obj_expr->val_exprs, i).word.heapptr, fun);

        return;
    }

    // Variable or constant declaration (let/var)
    if (shape == SHAPE_AST_DECL)
    {
        ast_decl_t* decl = (ast_decl_t*)expr;

        // Mark the declaration as belonging to this function
        assert (fun != NULL);
        decl->fun = fun;

        // If this variable is already declared, do nothing
        for (size_t i = 0; i < fun->local_decls->len; ++i)
        {
            ast_decl_t* local = array_get(fun->local_decls, i).word.decl;
            if (local->name == decl->name)
                return;
        }

        decl->idx = fun->local_decls->len;
        array_set_obj(fun->local_decls, decl->idx, (heapptr_t)decl);

        return;
    }

    // Variable reference
    if (shape == SHAPE_AST_REF)
    {
        return;
    }

    // Sequence/block expression
    if (shape == SHAPE_AST_SEQ)
    {
        ast_seq_t* seqexpr = (ast_seq_t*)expr;
        array_t* expr_list = seqexpr->expr_list;

        for (size_t i = 0; i < expr_list->len; ++i)
            find_decls(array_get(expr_list, i).word.heapptr, fun);

        return;
    }

    // Binary operator (e.g. a + b)
    if (shape == SHAPE_AST_BINOP)
    {
        ast_binop_t* binop = (ast_binop_t*)expr;
        find_decls(binop->left_expr, fun);
        find_decls(binop->right_expr, fun);
        return;
    }

    // Unary operator (e.g. -1)
    if (shape == SHAPE_AST_UNOP)
    {
        ast_unop_t* unop = (ast_unop_t*)expr;
        find_decls(unop->expr, fun);
        return;
    }

    // If expression
    if (shape == SHAPE_AST_IF)
    {
        ast_if_t* ifexpr = (ast_if_t*)expr;
        find_decls(ifexpr->test_expr, fun);
        find_decls(ifexpr->then_expr, fun);
        find_decls(ifexpr->else_expr, fun);
        return;
    }

    // Function/closure expression
    if (shape == SHAPE_AST_FUN)
    {
        // Do nothing. Variables declared in the nested
        // function are not of this scope
        return;
    }

    // Function call
    if (shape == SHAPE_AST_CALL)
    {
        ast_call_t* callexpr = (ast_call_t*)expr;
        array_t* arg_exprs = callexpr->arg_exprs;

        find_decls(callexpr->fun_expr, fun);

        for (size_t i = 0; i < arg_exprs->len; ++i)
            find_decls(array_get_ptr(arg_exprs, i), fun);

        return;
    }

    // Unsupported AST node type
    assert (false);
}