about GCL declarations

3 views
Skip to first unread message

Qian Yun

unread,
Nov 18, 2023, 7:42:27 AM11/18/23
to fricas-devel
I'm pretty sure GCL's 'defentry' will automatically generate
declarations.

1. When I generate extra "clines" before "defentry", I can get error:

error: static declaration of ‘writeablep’ follows non-static declaration

(I was intentionally using "clines" to generate "static" declarations
here.)

2. From GCL source code gcl/cmpnew/gcl_cmptop.lsp:

=====
(defmacro defentry (n args c &optional (lt t)
&aux (tsyms (load-time-value
(mapl (lambda (x) (setf (car x)
(gensym "DEFENTRY")))
(make-list
call-arguments-limit)))))
(let* ((cp (consp c))
(st (and cp (eq (car c) 'static)))
(c (if st (cdr c) c))
(m (if cp (cadr c) c))
(m (if (symbolp m) (string-downcase m) m))
(rt (intern (symbol-name (if cp (car c) lt)) 'keyword))
(tps (mapcar (lambda (x) (intern (string (if (consp x) (car x)
x)) 'keyword)) args))
(decl (reduce (lambda (y x) (strcat y (if (> (length y) 0) ","
"") x)) args :initial-value ""))
(decl (concatenate 'string (string-downcase rt) " " m "(" decl
");"))
(decl (if st "" decl))
(syms (mapcar (lambda (x) (declare (ignore x)) (pop tsyms))
args)))
`(defun ,n ,syms
(declare (optimize (safety 2)))
,@(mapcar (lambda (x y) `(check-type ,x ,(get y 'lisp-type))) syms
tps)
(lit ,(if (eq rt :void) :object rt)
"({" ,decl
,@(when (eq rt :void) `("("))
,m "("
,@(mapcon (lambda (x y z) `((,(car z) ,(car y))
,(if (cdr x) (if (consp (car x))
"+" ",") ""))) args syms tps)
")"
,@(when (eq rt :void) `(",Cnil)"))
";})"))))
=====

I can't confirm it in interpreter by macroexpand because "defentry"
doesn't work in interpreter.

But I'm 99% sure that GCL did generate declarations by itself.

- Qian

Waldek Hebisch

unread,
Nov 18, 2023, 7:54:37 AM11/18/23
to fricas...@googlegroups.com
On Sat, Nov 18, 2023 at 08:42:23PM +0800, Qian Yun wrote:
> I'm pretty sure GCL's 'defentry' will automatically generate
> declarations.

AFAIK there is an option to save generated C file. Looking there
would give definite answer.

--
Waldek Hebisch

Qian Yun

unread,
Nov 18, 2023, 8:06:38 AM11/18/23
to fricas...@googlegroups.com
Using GCL documentation example:

==== foo.lisp
(defentry joe (string int) (char "our_c_fun"))
====

Compile by:
gcl -eval '(compile-file "foo.lisp" :h-file t)'

Result of foo.h:

====
static void L1();
char our_c_fun(char *,int);
static void * VVi[1]={
#define Cdata VV[0]
(void *)(L1)
};
#define VV (VVi)
====

(However, the documentation suggests in the past, extra "clines" is
needed?)

- Qian

Waldek Hebisch

unread,
Nov 18, 2023, 9:24:17 AM11/18/23
to fricas...@googlegroups.com
On Sat, Nov 18, 2023 at 09:06:30PM +0800, Qian Yun wrote:
> Using GCL documentation example:
>
> ==== foo.lisp
> (defentry joe (string int) (char "our_c_fun"))
> ====
>
> Compile by:
> gcl -eval '(compile-file "foo.lisp" :h-file t)'
>
> Result of foo.h:
>
> ====
> static void L1();
> char our_c_fun(char *,int);
> static void * VVi[1]={
> #define Cdata VV[0]
> (void *)(L1)
> };
> #define VV (VVi)
> ====

So GCL emits declarations, good.

>
> (However, the documentation suggests in the past, extra "clines" is
> needed?)

Yes, in 2008 we had to add extern declarations. However, now we
do not support any version earlier than gcl-2.13 and IIUC in
almost any aspect gcl-2.13 and gcl-2.14 are identical (and there
are no reason to prefer 2.13), so we may depend on current
behaviour.

--
Waldek Hebisch

Qian Yun

unread,
Nov 18, 2023, 8:11:19 PM11/18/23
to fricas...@googlegroups.com
Yes, and I also want to do a GCL cleanup. So I will see if the various
#+GCL is still useful for gcl-2.14+, and submit them together with this
"clines" cleanup.

- Qian
Reply all
Reply to author
Forward
0 new messages