Npt documentation.
Reference: ANSI Common Lisp npt
Next: 2. Hold Variable
npt was developed with the intention of embedding it in the C language.
The purpose of this chapter is to show how npt can be developed as a module and to run a simple example.
Caution.
The functions for npt modules are still under development and are subject to change.
The amalgamation source is always needed in development. (Learn more about npt amalgamation, 4. Amalgamation)
Especially the header file lisp.h
is required.
First, here’s how to make an amalgamation from the npt source.
$ cd github/npt
$ cd develop/amalgamation/
$ npt --script amalgamation-single.lisp
The amalgamation-single.lisp
works with all Common Lisp programs.
If you don’t have the npt
command, do one of the following instead.
$ sbcl --script amalgamation-single.lisp
$ ccl -l amalgamation-single.lisp
$ clisp amalgamation-single.lisp
The file to be created is as follows
lisp.c
lisp.h
shell.c
The amalgamation page also explains how to use amalgamation-header.lisp
, but you can use either.
The same lisp.h
is generated.
Three main methods of development exist.
lisp.a
file.Regardless of the method, the header file lisp.h
is needed for development, so please run the creation of amalgamation.
The first one, using amalgamation-single.lisp
, is to use the source file lisp.c
.
Although this is the easiest way to use amalgamation, it has the disadvantage that it is very slow for the C language debugger because the lisp.c
file is too big.
If you are concerned about file size, you can use amalgamation-header.lisp
.
Although the number of files will increase slightly, the size of each file can be reduced, making this method easier to use.
The second one, using the npt source as-is, as the name suggests, is to copy a set of src/*.c
files.
This can be done by compiling all the files except for main.c
in npt.
The downside is that when npt is upgraded, the npt source needs to be updated.
It’s fine if the number of npt files only increases, but it can decrease, which makes it more complicated to manage.
The third lisp.a
file is a collection of npt object files, *.o
, for development purposes.
This method is useful and will be used to explain it.
The following are simple steps to compile these three methods.
The example sentence to be executed this time is as follows
int main_lisp(void *ignore)
{
(NULL, "Hello~%", NULL);
lisp_format8_return 0;
}
This statement, when expressed in Common Lisp, is the same as the following
format t "Hello~%") (
To actually compile the code, you have to include not only this, but also the code to initialize npt.
Here’s the complete code, save it as main.c
.
/* main.c */
#include <stdio.h>
#include "lisp.h"
int main_lisp(void *ignore)
{
(NULL, "Hello~%", NULL);
lisp_format8_return 0;
}
static int main_argv(struct lispargv *args)
{
/* mode */
if (args->mode_help)
return lisp_main_help(stdout);
if (args->mode_version)
return lisp_main_version(args, stdout);
if (args->mode_degrade)
return lisp_main_degrade(args);
/* execute */
->call = main_lisp;
args(args);
lisp_argv_init(args);
lisp_argv_run
return lisp_code? 1: lisp_result;
}
int main(int argc, char *argv[], char *env[])
{
int result;
struct lispargv *args;
/* initialize */
();
lisp_init= lispargv_main(argc, argv, env);
args if (args == NULL) {
(stderr, "argv error\n");
fprintfreturn 1;
}
/* main_argv */
->mode_core = 0;
args->mode_degrade = 0;
args->mode_standalone = 1;
args->nocore = 1;
args->noinit = 1;
args->debugger = 1;
args->debuggerp = 0;
args->quit = 1;
args= main_argv(args);
result
/* free */
(args);
lispargv_free();
lisp_free
return result;
}
First of all, let me explain how to use only amalgamation-single.lisp
.
Put the following file in the same directory as main.c
that you created.
lisp.c
lisp.h
No need for shell.c
.
Next, you need to compile the program.
The compilation method varies depending on the environment, so please refer to this page, 2. Compilation.
The example shows how to run it on FreeBSD.
$ cc lisp.c main.c -lm
$ ./a.out
Hello
$
Next, we will explain how to use amalgamation-header.lisp
.
The compiling method is almost the same as single, but since there is not only one source file, it should be specified in bulk like lisp_file_*.c
.
$ cc lisp_file_*.c main.c -lm
$ ./a.out
Hello
$
Create a working directory.
$ mkdir $HOME/libnpt1
Copy main.c
and lisp.h
.
$ cp -i main.c lisp.h $HOME/libnpt1/
Next, copy the npt source from github.
First, go to the npt directory.
$ cd github/npt
Copy the source.
$ cp -i src/*.[ch] $HOME/libnpt1/
overwrite .../main.c? (y/n [n]) n ;; Do not overwrite by entering n.
not overwritten
$
Compilation.
$ cd $HOME/libnpt1
$ cc *.c -lm
$ ./a.out
Hello
$
lisp.a
fileCreate a working directory.
$ mkdir $HOME/libnpt2
Copy main.c
and lisp.h
.
$ cp -i main.c lisp.h $HOME/libnpt2/
Create a lisp.a
file on github npt.
First, move it.
$ cd github/npt
Compile and generate an object file.
You can run the script freebsd_debug.sh
to generate the object file, but you should remember the compile option.
In this case, we are going to do a manual compilation.
$ cc -c src/*.c
Create a lisp.a
file.
$ ar -rc lisp.a *.o
$ ar -d lisp.a main.o
The generated lisp.a
is now copied.
$ cp -i lisp.a $HOME/libnpt2/
Compile.
$ cd $HOME/libnpt2/
$ cc main.c lisp.a -lm
$ ./a.out
Hello
$
In this example sentence, it was simple because we just executed the format
. However, the development can be very complex and confusing because you need to express the equivalent of a Common Lisp statement in C.
The next chapter explains in more detail how to create them.