将变量参数LISP函数映射到C函数 - C.

时间:2010-12-30 04:20:02

标签: c lisp interpreter

我正在开发一个自定义LISP解释器。它不支持像LISP中那样定义函数,而是将所有函数映射到C函数。当它看到像<,p>这样的表达式时

(substr 'input '1 '1)

它知道调用内部substr函数并返回结果。

现在我计划实现一个支持基本格式化的message函数,并将输出写入stdout。像,

(message "Hello, %s" name)

%s将替换为变量name中的值。

目前的计划是直接将格式和参数传递给printf等函数。这样,我就可以支持printf支持的所有格式。但问题来自可变数量的参数。一种方法是,

if(argcount == 1)
   /* call printf with one arg */
else if(argcount == 2)
   /* call printf with two arg */
....

这有效,但我想知道有没有更好的方法来实现这一目标?

3 个答案:

答案 0 :(得分:2)

我怀疑有办法做到这一点。原因是lisp函数的参数数量仅在运行时已知,但在编译时必须知道C函数的参数数量。

这包括va_lists,除非你想以某种特定于平台的方式攻击它们。

你真正做的最好的事情就是在C中编写一个函数,它能够一次循环一个参数并对它们做一些事情。我能看到的唯一方法是不仅为每个内部函数存储一个函数指针,而且还存储一个“调用约定”,它将提供有关它是以普通方式获取参数还是以其完成的信息。相当于一个va_list。

像printf这样的函数会有一个包装器,printf_wrapper,比如说,你可以存储一个包装器的函数指针。此包装器将接受格式字符串作为普通参数,后跟其他参数的列表或数组(大致类似于va_list)。

您可能指示printf_wrapper与通过指定调用约定为printf_wrapper函数为“va_list_type”期望列表的参数完成的,这意味着它需要通常的固定参数,并且所有其余的参数必须被捆绑起来并供给把它当作一个清单。

当然,编写一个printf_wrapper函数可以将格式字符串拆分并解析为多个格式字符串,这有点工作。这是一个我正好做到这一点的例子,以便我可以添加自己的自定义格式说明符:

https://github.com/wbhart/bsdnt/blob/v0.26/helper.c

答案 1 :(得分:0)

让你的C函数采用类似argc/argv的参数。也就是说,取一个参数指定参数的数量,然后指向每个参数的指针列表。

答案 2 :(得分:0)

稍微好于 if-else 链是一个开关。

switch(argcount){
    case 1: printf(arg[0]); break;
    case 2: printf(arg[0],arg[1]); break;
    //etc.
}