如何让用户创建一个函数? [ 图书馆 ? ]

发布于 2024-10-21 03:56:37 字数 148 浏览 1 评论 0原文

是否有任何免费的库可以让用户轻松构建 C 数学表达式,并且可以像任何其他函数一样使用?我的意思是 c 表达式/函数,它可以像“内联”数学表达式一样快,并且可以在程序中多次使用。 我想我可以用 C 来完成,但是如果它必须是 CUDA dveice 函数,有人可以告诉它是否是真实的吗?

Is there any free library to let a user easily build a C mathematical expression, which can be used like any other function? I mean c expression/function which could be as quick as 'inline' mathematical expression and could be used many times in program.
I think I can be done in C somehow, but does anybody can tell if it could be real if it have to be a CUDA dveice function?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

做个少女永远怀春 2024-10-28 03:56:37

有几种选择。我假设您想要用户可以多次“调用”的东西,如下所示:

void *s = make_func("2 * x + 7");
...
printf("%lf\n", call_func(s, 3.0)); // prints 13
...
printf("%lf\n", call_func(s, 5.0)); // prints 17
...
free_func(s);

一种选择是将其实现为保存函数指针和常量的递归结构。类似的东西:

enum item_type { VAR, CONST, FUNC };

struct var {
  enum item_type;
  int id;
};

struct constant {
  enum item_type;
  double value;
};

struct func {
  enum item_type;
  double (*func)(double, double);
  enum item_type *a, *b;
};

然后 make_func 会将上面的字符串解析为类似的东西:

(struct func *){ FUNC, &plus,
  (struct func *){ FUNC, ×,
    (struct constant *){ CONST, 2 },
    (struct var *){ VAR, 'x' } }
  (struct constant *){ CONST, 7 } }

如果你能理解 - 使用 struct func 中的 enum type_item指向树中的下一个节点(或者更确切地说,该节点的第一个元素,即 enum),而 enum 是我们的代码用来查找的内容找出项目类型是什么。然后,当我们使用 call(void *, ...) 函数时,它会计算有多少个变量 - 这是 call 函数应该有多少个额外参数已传递 - 然后用我们调用它的值替换变量,然后进行计算。

另一种选择(可能会更快且更容易扩展)是使用类似 libjit 为您完成大部分工作。我从未使用过它,但是 JIT 编译器为您提供了一些基本的构建块(例如加法、乘法等“指令”),您可以根据需要将它们串在一起,并将它们编译为实际的汇编代码(因此无需像以前那样通过构造的语法树调用函数指针),这样当您调用它时,它会尽可能快速和动态。

我不知道 libjit 的 API,但它看起来很容易就能完成您似乎需要的操作。 make_funcfree_func 可能与上面的几乎相同(您可能必须更改对 call_func 的调用),并且基本上会根据 JIT 对象如何解析用户字符串来构造、使用和销毁 JIT 对象。实际上与上面相同,但是您不需要自己定义语法树、数据类型等。

希望这有点帮助。

There are a few options. I assume you want something that the user can "call" several times, like this:

void *s = make_func("2 * x + 7");
...
printf("%lf\n", call_func(s, 3.0)); // prints 13
...
printf("%lf\n", call_func(s, 5.0)); // prints 17
...
free_func(s);

One option is to implement this as a recursive structure holding function pointers and constants. Something like:

enum item_type { VAR, CONST, FUNC };

struct var {
  enum item_type;
  int id;
};

struct constant {
  enum item_type;
  double value;
};

struct func {
  enum item_type;
  double (*func)(double, double);
  enum item_type *a, *b;
};

Then make_func would parse the above string into something like:

(struct func *){ FUNC, &plus,
  (struct func *){ FUNC, ×,
    (struct constant *){ CONST, 2 },
    (struct var *){ VAR, 'x' } }
  (struct constant *){ CONST, 7 } }

If you can understand that - the enum type_item in the struct func is used to point to the next node in the tree (or rather, the first element of that node, which is the enum), and the enum is what our code uses to find out what the item type is. Then, when we use the call(void *, ...) function, it counts how many variables there are - this is how many extra arguments the call function should have been passed - then replaces the variables with the values we've called it with, then does the calculations.

The other option (which will probably be considerably faster and easier to extend) is to use something like libjit to do most of that work for you. I've never used it, but a JIT compiler gives you some basic building blocks (like add, multiply, etc. "instructions") that you can string together as you need them, and it compiles them down to actual assembly code (so no going through a constructed syntax tree calling function pointers like we had to before) so that when you call it it's as fast and dynamic as possible.

I don't know libjit's API, but it looks easily capable of doing what you seem to need. The make_func and free_func could all be pretty much the same as they are above (you might have to alter your calls to call_func) and would basically construct, use, and destroy a JIT object based on how it parses the user's string. The same as above, really, but you wouldn't need to define the syntax tree, data types, etc. yourself.

Hope that is somewhat helpful.

月下伊人醉 2024-10-28 03:56:37

libtcc(来自 TCC)可以用作非常小且快速的 JIT;请参阅 libtcc_test.cc 了解示例用法。

libtcc (from TCC) can be used as a very small and fast JIT; see libtcc_test.cc for sample usage.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文