越界索引从chibi方案中创建的向量返回正确的值



我已经将chibi scheme嵌入到我的C++应用程序中,并试图在scheme中创建一个大小为3的浮点向量,然后将该向量的各个值返回到我的C++程序中,然而,当我尝试这样做时,只有在使用超出向量大小的索引时,我才能得到正确的结果。正如你在下面看到的,我验证了向量的大小。

测试.scm

(define (test-vec in-a in-b)
(let ((vec (vector (* 3.1 in-a) (* 4.1 in-b) 5.0)))
(display "From Scheme: ")
(display vec)
(display "n")
vec))

test.cpp

#include <iostream>
#include <chibi/eval.h>
int is_defined(sexp ctx, const char *sym)
{
sexp_gc_var1(ret);
sexp_gc_preserve1(ctx, ret);
ret = sexp_eval_string(ctx, sym, -1, NULL);
int defined = sexp_procedurep(ret);
sexp_gc_release1(ctx);
return defined;
}
int main()
{
float returnA, returnB, returnC, returnD, returnE, returnF;
sexp_scheme_init();
sexp ctx = sexp_make_eval_context(NULL, NULL, NULL, 0, 0);
sexp_load_standard_env(ctx, NULL, SEXP_SEVEN);
sexp_load_standard_ports(ctx, NULL, stdin, stdout, stderr, 1);
// Load the scheme file and create temp variables to pass the values to chibi
sexp_gc_var6(inAVal, inASym, inBVal, inBSym, returnedVector, filePath);
sexp_gc_preserve6(ctx, inAVal, inASym, inBVal, inBSym, returnedVector, filePath);
filePath = sexp_c_string(ctx, "test.scm", -1);
sexp_load(ctx, filePath, NULL);
// Ensure our procedure is defined
if(is_defined(ctx, "test-vec"))
std::cout << "test-vec is defined" << std::endl;
// Create the values and create the symbols
inAVal = sexp_make_flonum(ctx, 1.0);
inASym = sexp_intern(ctx, "a", -1);
inBVal = sexp_make_flonum(ctx, 2.0);
inBSym = sexp_intern(ctx, "b", -1);
// Bind the values to the symbols and pass them to chibi
sexp_env_define(ctx, sexp_context_env(ctx), inASym, inAVal);
sexp_env_define(ctx, sexp_context_env(ctx), inBSym, inBVal);
// Evaluate the expression and store the result
returnedVector = sexp_eval_string(ctx, "(test-vec a b)", -1, NULL);
std::cout << "Vector size: " << sexp_vector_length(returnedVector) << std::endl;
// I would expect this to return the expected results?
returnA = sexp_flonum_value(sexp_vector_ref(returnedVector, 0));
returnB = sexp_flonum_value(sexp_vector_ref(returnedVector, 1));
returnC = sexp_flonum_value(sexp_vector_ref(returnedVector, 2));
std::cout << "Vector[0] = " << returnA << "nVector[1] = " << returnB << "nVector[2] = " << returnC << std::endl << std::endl;
// If I index outside of the range of the vector, it gives me the correct results?
returnD = sexp_flonum_value(sexp_vector_ref(returnedVector, 0));
returnE = sexp_flonum_value(sexp_vector_ref(returnedVector, 3));
returnF = sexp_flonum_value(sexp_vector_ref(returnedVector, 4));
std::cout << "Vector[0] = " << returnD << "nVector[3] = " << returnE << "nVector[4] = " << returnF << std::endl;
sexp_gc_release6(ctx);
}

这给了我输出:

test-vec is defined
From Scheme: #(3.1 8.2 5.0)
Vector size: 3
Vector[0] = 3.1
Vector[1] = 3.1
Vector[2] = 8.2
Vector[0] = 3.1
Vector[3] = 8.2
Vector[4] = 5

为什么超过向量长度的索引会给我正确的值?

解决了这个问题。这是因为sexp_vector_ref(vec, i)评估为

#define sexp_vector_ref(x,i)   (sexp_vector_data(x)[sexp_unbox_fixnum(i)])

CCD_ 2评估为

#define sexp_unbox_fixnum(n)   (((sexp_sint_t)((sexp_uint_t)(n) & ~SEXP_FIXNUM_TAG))/(sexp_sint_t)((sexp_sint_t)1<<SEXP_FIXNUM_BITS))

当我们只传入直整数时

std::cout << "Unboxed fixnums: " << 
sexp_unbox_fixnum(0) << " " << 
sexp_unbox_fixnum(1) << " " << 
sexp_unbox_fixnum(2) << " " << 
sexp_unbox_fixnum(3) << " " << 
sexp_unbox_fixnum(4) << std::endl;

给我们输出Unboxed fixnums: 0 0 1 1 2

然而,如果我们首先将它们转换为chibi期望的正确类型,比如

std::cout << "Fixnum: " <<
sexp_unbox_fixnum(sexp_make_fixnum(0)) << " " <<
sexp_unbox_fixnum(sexp_make_fixnum(1)) << " " <<
sexp_unbox_fixnum(sexp_make_fixnum(2)) << " " <<
sexp_unbox_fixnum(sexp_make_fixnum(3)) << " " <<
sexp_unbox_fixnum(sexp_make_fixnum(4)) << std::endl;

我们得到了正确的输出

Fixnum: 0 1 2 3 4

解决方案:索引时使用正确的类型

相关内容

  • 没有找到相关文章

最新更新