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

将变量参数LISP函数映射到C函数-C,c,lisp,interpreter,C,Lisp,Interpreter,我正在开发一个自定义的LISP解释器。它不支持在LISP中定义函数,而是将所有函数映射到C函数。当它看到这样的表情时 (substr 'input '1 '1) 它知道调用内部substr函数并返回结果 现在我计划实现一个消息函数,该函数支持基本格式,并将输出写入stdout。大概 (message "Hello, %s" name) if(argcount == 1) /* call printf with one arg */ else if(argcount == 2) /

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

(substr 'input '1 '1)
它知道调用内部
substr
函数并返回结果

现在我计划实现一个
消息
函数,该函数支持基本格式,并将输出写入
stdout
。大概

(message "Hello, %s" name)
if(argcount == 1)
   /* call printf with one arg */
else if(argcount == 2)
   /* call printf with two arg */
....
%s
将替换为变量
name
中的值

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

(message "Hello, %s" name)
if(argcount == 1)
   /* call printf with one arg */
else if(argcount == 2)
   /* call printf with two arg */
....

这是可行的,但我想知道有没有更好的方法来实现这一点

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

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

这包括va_列表,除非您想以某种特定于平台的方式攻击它们

你能做的最好的事情就是用C写一个函数,这个函数能够一次循环一个参数,并用它们做一些事情。我能看到的唯一方法是,不仅为每个内部函数存储一个函数指针,而且还存储一个“调用约定”,该约定将提供有关它是否以普通方式接受参数或是否以等价于va_列表的方式结束的信息

像printf这样的函数将有一个包装器,比如printf_包装器,并且您将存储一个指向包装器的函数指针。这个包装器将接受格式字符串作为普通参数,后面是其他参数的列表或数组(大致类似于va_列表)

您可以通过将printf_wrapper函数的调用约定指定为“va_list_type”来指示printf_wrapper以一个期望列表的参数结束,这意味着它采用通常的固定参数,并且所有剩余的参数都必须打包并作为列表提供给它

当然,编写printf_包装函数将一个格式字符串拆分并解析为多个格式字符串需要一点工作。下面是一个例子,我正是这样做的,以便添加自己的自定义格式说明符:

比if-else链稍微好一点,它是一个开关

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

我明白这一点。但问题是我必须在内部使用
printf
或类似的现有函数。你认为我可以从参数中创建它吗?@Appu是的,但这将涉及了解您平台的va_列表的实现细节。但它是一种数据结构,与其他任何结构一样,可以动态生成。@Conrad..我不认为手动创建
va_列表
是一个好主意,我也不想以独立于平台的方式来实现它。很好,或者自己实现
printf
。你更喜欢那个主意吗?