Top-level V3 procedures are now C-callable:
ADR(Proc) yields a function pointer usable through a C
typedef / void *;short real, CBool, C strings and C-layout record pointers work
in callback signatures.Example:
PROCEDURE add (a, b : INTEGER) : INTEGER;
BEGIN
RETURN a + b
END add;
PROCEDURE call_add (fn : ADDRESS; a, b : INTEGER) : INTEGER;
EXTERNAL "m2_c_call_add";
...
call_add(ADR(add), 20, 22)
The C side is:
int m2_c_call_add(void *fn, int a, int b)
{
int (*f)(int, int) = (int (*)(int, int))fn;
return f(a, b);
}
Covered by compiler/tests/t_callback.mod.
Nested procedures still take a hidden parent-frame link and are not C-callable. Keep callbacks at module level, or use a small C/Modula-2 trampoline with a context record.
A GtkClosures-style design now works without a C wrapper for the
V3 procedure itself:
PROCEDURE Tramp2 (instance, ctx : ADDRESS);
The C side registers Tramp2 as the signal callback and passes the
ctx pointer as user data. Keep allocation, destroy handling and
user_data ownership in a context object, as in the existing
GtkClosures design.