gpt4 book ai didi

c++ - 在 C++ 中将 ECL 符号名称作为字符串获取

转载 作者:搜寻专家 更新时间:2023-10-31 00:29:15 24 4
gpt4 key购买 nike

我正在努力将可嵌入的 Common Lisp 嵌入到一个库中,并且我一直在编写实用函数来将 ECL 的 cl_object 转换为各种 C/C++ 类型 - 例如将表示字符串的 cl_object 转换为 std::string。

我的问题是 - 为什么我无法在 ECL 中检索到包含符号名称的字符串?

我在使以下函数 ecl_symbol_to_string 工作时遇到问题,它应该采用 ECL 符号并返回一个 std::string 及其名称:

string ecl_symbol_to_string(cl_object sym) {
return ecl_string_to_string(sym->symbol.name);
}

string ecl_string_to_string(cl_object echar) {
string res("");
int j = echar->string.dim; //get dimension
ecl_character* selv = echar->string.self; //get pointer

//do simple pointer addition
for(int i=0;i<j;i++){
res += (*(selv+i));
}
return res;
};

请注意 ecl_string_to_string 适用于 lisp 字符串。

一个简单的单元测试说明了失败:

TEST_CASE( "ecl_symbol_to_string returns a string for symbol",
"[ecl_string_to_string]" ) {

LispRuntime *rt = new LispRuntime("()");
std::string eval_script;
cl_object eval_result;
std::string subject_result;

eval_script = "'mysymbol";
eval_result = rt->evaluate(eval_script);
REQUIRE( ECL_SYMBOLP(eval_result) );
subject_result = ecl_symbol_to_string(eval_result);
REQUIRE ( ECL_STRINGP(cl_symbol_name(eval_result)) );
std::cout << subject_result.c_str() << std::endl;
REQUIRE( subject_result.compare("mysymbol") == 0 );

delete rt;

}

此测试用例打印出 MM 以调用 cout。我也试过比较失败的“MYSYMBOL”和通过的“M”。

LispRuntime::eval_script 简单地转换和计算形式:

cl_object LispRuntime::evaluate(std::string &code) {
cl_object form = c_string_to_object(code.c_str());
cl_object result = cl_eval(form);

return result;
}

我在本地编译了 ECL 版本 16.1.3,启用了 C++ 选项,调试符号和所有其他设置默认。非常感谢任何帮助。

最佳答案

我认为这是 unicode/非 unicode 混淆:ECL 在 object.h 中定义了两种字符串类型.一个是 ecl_base_string,其中成员 self 最终类型定义为 unsigned char*,另一个是 ecl_string,其中成员 self 通常(我认为取决于编译时参数)类型定义为 int*。您正在以 ecl_string 的形式访问它。

如果您跟踪 ecl_make_symbol 的工作原理,您会发现它最终会调用返回基本字符串的函数 make_constant_base_string。因此,您的 ecl_string_to_string 通过错误的类型访问它。

我怀疑最简单的解决方案是在 ecl_string_to_string 中构建类型检查/转换:

string ecl_string_to_string(cl_object echar) {
switch (ecl_t_of(echar)) {
#ifdef ECL_UNICODE
case t_string:
if (!ecl_fits_in_base_string(echar)) {
echar = cl_copy_seq(echar);
} else {
echar = si_copy_to_simple_base_string(echar);
}
break;
#endif
case t_base_string:
// OK
break;
default:
// PRINT SOME ERROR
return string(); // or raise an exception
}

string res("");
int j = echar->base_string.dim; //get dimension
ecl_base_char* selv = echar->base_string.self; //get pointer

//do simple pointer addition
for(int i=0;i<j;i++){
res += (*(selv+i));
}
return res;
};

我添加的额外代码大量复制自 ECL 函数 cl_make_symbol .我决定转换为 ecl_base_string 而不是 ecl_string 因为 C++ 字符串无论如何都不接受 unicode 字符。如果你有充分的理由,你也可以反过来做。

关于c++ - 在 C++ 中将 ECL 符号名称作为字符串获取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41915795/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com