Mapping the LISP argument variable of a function of a function C - C

I am developing my own LISP interpreter. It will not support the definition of functions such as LISP, instead all functions are displayed in function C. When it sees such an expression,

(substr 'input '1 '1) 

he knows to call the internal function substr and return the result.

Now I plan to implement a message function that supports basic formatting and writes the output to stdout . Sort of,

 (message "Hello, %s" name) 

%s will be replaced by the value in the name variable.

The current plan is to directly pass the format and arguments to functions like printf . This way I can support all formats supported by printf . But the problem is with a variable number of arguments. One way to do this would be something like:

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

This works, but I wonder if there is a better way to achieve this?

+4
source share
3 answers

I doubt there is a way to do this. The reason is that the number of parameters of your lisp function is known only at runtime, but the number of arguments to the C function must be known at compile time.

This includes va_lists if you don't want to hack them in any specific way for the platform.

The best thing you can really do is write a function in C that is able to cycle through the arguments one at a time and do something with them. The only way I can see this is not only to save a function pointer for each of your internal functions, but also to save a “calling convention”, which will give information on whether the parameters need it in the usual way or if it ends using the equivalent of va_list.

Functions such as printf will have a wrapper, printf_wrapper, say, and you will save a pointer to this wrapper. This shell takes a format string as a regular parameter, followed by a list or an array of other parameters (roughly similar to va_list).

You can specify that printf_wrapper ends with a parameter that expects a list, specifying calling conventions for the printf_wrapper function as "va_list_type", which means that it accepts the usual fixed parameters and that all other parameters should be collected and put to it as a list.

Of course, writing a printf_wrapper function that can split and parse a format string into multiple format strings is a bit of work. Here's an example of where I did just that to add custom specifiers for special formats:

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

+2
source

Let your C function accept parameters somewhat like argc/argv . That is, take a parameter that determines the number of parameters, and then a pointer to a list of pointers for each parameter.

0
source

A little better than the if-else chain would be a switch.

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

Source: https://habr.com/ru/post/1333756/


All Articles