|
@@ -5,8 +5,9 @@ questions do not have to be re-derived later. It covers `TBITSIZE`,
|
|
|
address arithmetic, set ordering, complex types, pragmas, UTF-8 string
|
|
address arithmetic, set ordering, complex types, pragmas, UTF-8 string
|
|
|
libraries, collections, the TopSpeed B-tree Toolkit, communications,
|
|
libraries, collections, the TopSpeed B-tree Toolkit, communications,
|
|
|
pyserial, ModBase, network-library design, terminal escape libraries,
|
|
pyserial, ModBase, network-library design, terminal escape libraries,
|
|
|
-PIM versus ISO coroutines, external assembly, and the dynamic-set
|
|
|
|
|
-design. It is not a commitment to implement everything.
|
|
|
|
|
|
|
+C FFI and GTK4/SQLite/SDL bindings, PIM versus ISO coroutines, external
|
|
|
|
|
+assembly, and the dynamic-set design. It is not a commitment to
|
|
|
|
|
+implement everything.
|
|
|
|
|
|
|
|
**State at the time of writing:** suite 310/310, one-shot fixpoint OK
|
|
**State at the time of writing:** suite 310/310, one-shot fixpoint OK
|
|
|
(3,845,439 bytes), per-object fixpoint OK (11 objects), corpus
|
|
(3,845,439 bytes), per-object fixpoint OK (11 objects), corpus
|
|
@@ -1817,7 +1818,318 @@ No compiler changes are required.
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
-## 14. Suggested order of future work
|
|
|
|
|
|
|
+## 14. C FFI foundation and GTK4/SQLite/SDL bindings
|
|
|
|
|
+
|
|
|
|
|
+The planned GTK4, SQLite and SDL bindings are not just three wrapper
|
|
|
|
|
+libraries. They need a C ABI/FFI layer, a binding generator and
|
|
|
|
|
+`pkg-config`-aware build/link integration.
|
|
|
|
|
+
|
|
|
|
|
+### 14.1 Current FFI state
|
|
|
|
|
+
|
|
|
|
|
+V3 already has:
|
|
|
|
|
+
|
|
|
|
|
+- `DEFINITION/IMPLEMENTATION MODULE FOR "C"`;
|
|
|
|
|
+- `EXPORT UNQUALIFIED`;
|
|
|
|
|
+- `EXTERNAL` procedures;
|
|
|
|
|
+- a special `FROM libc IMPORT ...` path with known prototypes and
|
|
|
|
|
+ permissive varargs for unknown names;
|
|
|
|
|
+- raw `ADDRESS`, `POINTER TO` and pointer-sized procedure values;
|
|
|
|
|
+- C varargs support for the special `libc` intrinsic path.
|
|
|
|
|
+
|
|
|
|
|
+What is missing for large C APIs:
|
|
|
|
|
+
|
|
|
|
|
+- explicit C link-name mapping;
|
|
|
|
|
+- C-compatible record/union layout;
|
|
|
|
|
+- a true 4-byte `float`;
|
|
|
|
|
+- correct `size_t`/`ssize_t` widths;
|
|
|
|
|
+- C `bool` vs V3 `BOOLEAN`;
|
|
|
|
|
+- C arrays versus V3 descriptors;
|
|
|
|
|
+- general foreign varargs;
|
|
|
|
|
+- callback/trampoline support;
|
|
|
|
|
+- a binding generator;
|
|
|
|
|
+- multi-library build/link integration.
|
|
|
|
|
+
|
|
|
|
|
+### 14.2 Underscores are already allowed
|
|
|
|
|
+
|
|
|
|
|
+The scanner already accepts underscores:
|
|
|
|
|
+
|
|
|
|
|
+```text
|
|
|
|
|
+ident = ( letter | "_" ) { letter | digit | "_" } .
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+This was added for `__FILE__` / `__LINE__` compatibility (commit
|
|
|
|
|
+`a33fc7c`). Names such as these already parse:
|
|
|
|
|
+
|
|
|
|
|
+```modula2
|
|
|
|
|
+gtk_application_new
|
|
|
|
|
+SDL_CreateWindow
|
|
|
|
|
+sqlite3_open_v2
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+The docs in `docs/features.md` and `docs/language-report.md` still say
|
|
|
|
|
+“no underscores” and should be updated.
|
|
|
|
|
+
|
|
|
|
|
+This reduces binding friction:
|
|
|
|
|
+
|
|
|
|
|
+- direct C function names;
|
|
|
|
|
+- C constants such as `GTK_ALIGN_FILL`;
|
|
|
|
|
+- C struct fields such as `SDL_Event.type`;
|
|
|
|
|
+- fewer renamed identifiers in generated bindings.
|
|
|
|
|
+
|
|
|
|
|
+It does **not** solve:
|
|
|
|
|
+
|
|
|
|
|
+- C struct layout and alignment;
|
|
|
|
|
+- C unions and bitfields;
|
|
|
|
|
+- C arrays vs V3 descriptors;
|
|
|
|
|
+- `char *` and string ownership;
|
|
|
|
|
+- true 4-byte `float`;
|
|
|
|
|
+- `size_t`/`ssize_t` width;
|
|
|
|
|
+- C `bool`;
|
|
|
|
|
+- callbacks and closures;
|
|
|
|
|
+- varargs;
|
|
|
|
|
+- C macros/inline functions;
|
|
|
|
|
+- build/link integration.
|
|
|
|
|
+
|
|
|
|
|
+Policy recommendation:
|
|
|
|
|
+
|
|
|
|
|
+- keep `_` as a documented V3 extension;
|
|
|
|
|
+- gate it behind strict PIM/ISO mode if strict compatibility matters;
|
|
|
|
|
+- update the feature matrix and language report;
|
|
|
|
|
+- still provide explicit `EXTERNAL "c_name"` for long/decorated names
|
|
|
|
|
+ and C wrappers.
|
|
|
|
|
+
|
|
|
|
|
+`SymTab.Name` is 64 bytes, so names longer than 63 characters can
|
|
|
|
|
+truncate; link names need an independent, larger mechanism.
|
|
|
|
|
+
|
|
|
|
|
+### 14.3 C ABI/type gaps
|
|
|
|
|
+
|
|
|
|
|
+The binding layer needs a C ABI profile:
|
|
|
|
|
+
|
|
|
|
|
+```modula2
|
|
|
|
|
+TYPE
|
|
|
|
|
+ CInt = INTEGER; (* C int *)
|
|
|
|
|
+ CUInt = CARDINAL; (* C unsigned int *)
|
|
|
|
|
+ CLong = LONGINT; (* C long on LP64 *)
|
|
|
|
|
+ CULong = LONGCARD;
|
|
|
|
|
+ CSize = LONGCARD; (* size_t, 64-bit on amd64 *)
|
|
|
|
|
+ CSSize = LONGINT; (* ssize_t *)
|
|
|
|
|
+ CFloat = SHORTREAL; (* needs a true 4-byte float *)
|
|
|
|
|
+ CDouble = REAL;
|
|
|
|
|
+ CBool = INTEGER; (* C int / gboolean / SDL_bool *)
|
|
|
|
|
+ CEnum = INTEGER; (* C enum, 32-bit *)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Required changes:
|
|
|
|
|
+
|
|
|
|
|
+- true `SHORTREAL`/`REAL32` 4-byte float;
|
|
|
|
|
+- correct `CSIZE_T`/`CSSIZE_T` widths on amd64;
|
|
|
|
|
+- C `bool` (1 byte) separate from `BOOLEAN` (4 bytes);
|
|
|
|
|
+- C enums represented as integer aliases, not Modula-2 enums;
|
|
|
|
|
+- C `long`/`unsigned long` target-dependent aliases;
|
|
|
|
|
+- C string and buffer ownership helpers;
|
|
|
|
|
+- C `void *` as `ADDRESS`;
|
|
|
|
|
+- C function pointers as compatible procedure values.
|
|
|
|
|
+
|
|
|
|
|
+### 14.4 Structs, unions and arrays
|
|
|
|
|
+
|
|
|
|
|
+V3 records are tightly packed, with no alignment/padding. One-
|
|
|
|
|
+dimensional array fields use V3 descriptors; C arrays are inline.
|
|
|
|
|
+Variant records are not C unions.
|
|
|
|
|
+
|
|
|
|
|
+Two strategies:
|
|
|
|
|
+
|
|
|
|
|
+1. **C accessor/wrapper strategy (recommended first)**
|
|
|
|
|
+ - C shims allocate and manipulate C structs.
|
|
|
|
|
+ - V3 sees opaque `ADDRESS` handles and gets/sets fields through C
|
|
|
|
|
+ functions.
|
|
|
|
|
+ - Avoids compiler layout work.
|
|
|
|
|
+ - Works for SDL `SDL_Event`, `SDL_AudioSpec`, SQLite structs, GTK
|
|
|
|
|
+ `GdkRGBA`/`GValue`.
|
|
|
|
|
+
|
|
|
|
|
+2. **C-compatible record layout (long term)**
|
|
|
|
|
+ - Add `ALIGN`, `PACKED`, `UNION`, inline arrays and bitfields.
|
|
|
|
|
+ - Allows direct struct declarations.
|
|
|
|
|
+ - Much larger and requires ABI layout tests.
|
|
|
|
|
+
|
|
|
|
|
+For the first bindings, use wrappers. Do not start by making every V3
|
|
|
|
|
+record C-compatible.
|
|
|
|
|
+
|
|
|
|
|
+### 14.5 C FFI support library
|
|
|
|
|
+
|
|
|
|
|
+Add a small C support module, for example `lib/c/C`:
|
|
|
|
|
+
|
|
|
|
|
+- C scalar aliases;
|
|
|
|
|
+- `char *` <-> `ARRAY OF CHAR` conversion;
|
|
|
|
|
+- raw buffer with explicit length;
|
|
|
|
|
+- allocation/free matching the C allocator;
|
|
|
|
|
+- errno/`GetLastError` mapping;
|
|
|
|
|
+- optional callback/trampoline helpers;
|
|
|
|
|
+- opaque C-struct accessor conventions.
|
|
|
|
|
+
|
|
|
|
|
+The exact API can evolve, but ownership must be explicit:
|
|
|
|
|
+
|
|
|
|
|
+- borrowed string;
|
|
|
|
|
+- owned string;
|
|
|
|
|
+- C-allocated string that must be freed with `free`/`g_free`;
|
|
|
|
|
+- pointer valid only for the duration of a call.
|
|
|
|
|
+
|
|
|
|
|
+### 14.6 Binding generator
|
|
|
|
|
+
|
|
|
|
|
+Recommended source by target:
|
|
|
|
|
+
|
|
|
|
|
+| Target | Best source | Strategy |
|
|
|
|
|
+| --- | --- | --- |
|
|
|
|
|
+| GTK4 | GObject Introspection `.gir` files | Generate types, enums, functions, signals, ownership |
|
|
|
|
|
+| GLib/GObject/GIO | `.gir` files | Base bindings |
|
|
|
|
|
+| SQLite | `sqlite3.h` | Small hand-written thin binding |
|
|
|
|
|
+| SDL3 | `SDL3/SDL.h` | Header parsing plus hand-written struct/callback wrappers |
|
|
|
|
|
+
|
|
|
|
|
+The generator should emit:
|
|
|
|
|
+
|
|
|
|
|
+- `.def` declarations with safe Modula-2 names;
|
|
|
|
|
+- `EXTERNAL "c_name"` link names;
|
|
|
|
|
+- C shims for structs/unions, callbacks, varargs, `GError**`, `GValue`
|
|
|
|
|
+ and string ownership;
|
|
|
|
|
+- tests for each generated subsystem.
|
|
|
|
|
+
|
|
|
|
|
+For GTK4, use the installed `.gir` files as the source of truth rather
|
|
|
|
|
+than raw headers. They include type names, transfer/ownership rules,
|
|
|
|
|
+nullable annotations, signals and properties.
|
|
|
|
|
+
|
|
|
|
|
+Do not attempt full GTK4 generation first. Start with application,
|
|
|
|
|
+window, widget basics, buttons, labels, boxes, lists, files and signals.
|
|
|
|
|
+
|
|
|
|
|
+### 14.7 Build and link integration
|
|
|
|
|
+
|
|
|
|
|
+`M2make` currently supports one extra C file and links `-lm` only. It
|
|
|
|
|
+needs:
|
|
|
|
|
+
|
|
|
|
|
+```text
|
|
|
|
|
+--cflag ...
|
|
|
|
|
+--ldflag ...
|
|
|
|
|
+--include ...
|
|
|
|
|
+--c-source ...
|
|
|
|
|
+--library ...
|
|
|
|
|
+--pkg-config gtk4
|
|
|
|
|
+--pkg-config sqlite3
|
|
|
|
|
+--pkg-config sdl3
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Requirements:
|
|
|
|
|
+
|
|
|
|
|
+- multiple C shim files;
|
|
|
|
|
+- multiple include directories;
|
|
|
|
|
+- library order;
|
|
|
|
|
+- `-pthread` where needed;
|
|
|
|
|
+- `pkg-config --cflags --libs`;
|
|
|
|
|
+- rpath handling;
|
|
|
|
|
+- C shim/library flags in the ABI stamp.
|
|
|
|
|
+
|
|
|
|
|
+GTK4 needs `glib-2.0`, `gobject-2.0`, `gio-2.0`, `gtk4` and usually
|
|
|
|
|
+`-pthread`. SQLite and SDL3 are much simpler.
|
|
|
|
|
+
|
|
|
|
|
+### 14.8 Callbacks and event loops
|
|
|
|
|
+
|
|
|
|
|
+C callbacks need special handling:
|
|
|
|
|
+
|
|
|
|
|
+- callbacks must be top-level, not nested procedures;
|
|
|
|
|
+- no static-link closure can cross into C;
|
|
|
|
|
+- Modula-2 exceptions must not escape a C callback;
|
|
|
|
|
+- user data should be passed as `ADDRESS` and decoded by a dispatcher;
|
|
|
|
|
+- GTK signals, SDL audio/timer callbacks and SQLite callbacks need
|
|
|
|
|
+ trampolines or a global callback registry.
|
|
|
|
|
+
|
|
|
|
|
+GTK4 also brings in GLib/GObject:
|
|
|
|
|
+
|
|
|
|
|
+- reference counting (`g_object_ref`/`g_object_unref`);
|
|
|
|
|
+- floating references;
|
|
|
|
|
+- signals (`g_signal_connect_data`);
|
|
|
|
|
+- `GError**` out-parameters;
|
|
|
|
|
+- `GValue` and properties;
|
|
|
|
|
+- `GMainLoop`/`GtkApplication` integration.
|
|
|
|
|
+
|
|
|
|
|
+A V3 GTK binding must define its main-loop and ownership policy
|
|
|
|
|
+explicitly.
|
|
|
|
|
+
|
|
|
|
|
+### 14.9 Target strategy
|
|
|
|
|
+
|
|
|
|
|
+**SQLite first**
|
|
|
|
|
+
|
|
|
|
|
+SQLite is the best first binding:
|
|
|
|
|
+
|
|
|
|
|
+- opaque `sqlite3` and `sqlite3_stmt`;
|
|
|
|
|
+- C strings;
|
|
|
|
|
+- `sqlite3_int64`;
|
|
|
|
|
+- bind/column operations;
|
|
|
|
|
+- callbacks;
|
|
|
|
|
+- in-memory databases for tests.
|
|
|
|
|
+
|
|
|
|
|
+A safe wrapper should hide statement finalization, `sqlite3_free`,
|
|
|
|
|
+`SQLITE_TRANSIENT` ownership, error strings and column lifetimes.
|
|
|
|
|
+SQLite is an excellent FFI conformance test for ints, int64, doubles,
|
|
|
|
|
+blobs, strings, pointers, callbacks and error codes.
|
|
|
|
|
+
|
|
|
|
|
+**SDL3 second**
|
|
|
|
|
+
|
|
|
|
|
+SDL3 needs:
|
|
|
|
|
+
|
|
|
|
|
+- opaque window/renderer/texture pointers;
|
|
|
|
|
+- `SDL_Event`, `SDL_Keysym`, `SDL_Rect`, `SDL_Color`, `SDL_AudioSpec`;
|
|
|
|
|
+- `SDL_bool`, `Uint32`, `Sint32`, `Uint64`;
|
|
|
|
|
+- true `float` or conversion wrappers;
|
|
|
|
|
+- audio/timer callbacks;
|
|
|
|
|
+- `SDL_Log` varargs;
|
|
|
|
|
+- event loop.
|
|
|
|
|
+
|
|
|
|
|
+Use C helpers to translate `SDL_Event` and `SDL_AudioSpec` to small V3
|
|
|
|
|
+records. Prefer SDL3 unless SDL2 compatibility is required. Test with
|
|
|
|
|
+`SDL_VIDEODRIVER=dummy` and `SDL_AUDIODRIVER=dummy`.
|
|
|
|
|
+
|
|
|
|
|
+**GTK4 last**
|
|
|
|
|
+
|
|
|
|
|
+GTK4 is the largest:
|
|
|
|
|
+
|
|
|
|
|
+- GLib base types and strings;
|
|
|
|
|
+- GObject refcount and signals;
|
|
|
|
|
+- `GError`;
|
|
|
|
|
+- `GValue` and properties;
|
|
|
|
|
+- `GList`/`GSList`;
|
|
|
|
|
+- `GMainLoop`/`GtkApplication`;
|
|
|
|
|
+- many opaque types;
|
|
|
|
|
+- ownership/transfer annotations.
|
|
|
|
|
+
|
|
|
|
|
+GTK4 should come after the C FFI foundation, callbacks, build/link
|
|
|
|
|
+integration and GIR generator. A first binding should be a curated
|
|
|
|
|
+subset, not the full API.
|
|
|
|
|
+
|
|
|
|
|
+### 14.10 Recommended order
|
|
|
|
|
+
|
|
|
|
|
+1. C FFI foundation:
|
|
|
|
|
+ - underscore policy/docs;
|
|
|
|
|
+ - `EXTERNAL "c_name"` / `FFIDENT`;
|
|
|
|
|
+ - true 4-byte float;
|
|
|
|
|
+ - correct `size_t`/`ssize_t`;
|
|
|
|
|
+ - C string/buffer/error helpers;
|
|
|
|
|
+ - C struct accessor strategy.
|
|
|
|
|
+2. `pkg-config`-aware build integration and ABI stamping.
|
|
|
|
|
+3. FFI conformance tests.
|
|
|
|
|
+4. SQLite binding plus safe wrapper.
|
|
|
|
|
+5. SDL3 binding plus event/audio helpers.
|
|
|
|
|
+6. GIR-based generator for GLib/GObject.
|
|
|
|
|
+7. GTK4 binding subset and headless tests.
|
|
|
|
|
+
|
|
|
|
|
+Bindings should live outside the core library:
|
|
|
|
|
+
|
|
|
|
|
+```text
|
|
|
|
|
+lib/c/ C FFI helpers
|
|
|
|
|
+bindings/sqlite3/ SQLite binding and wrapper
|
|
|
|
|
+bindings/sdl3/ SDL3 binding and wrapper
|
|
|
|
|
+bindings/gtk4/ GLib/GObject/GTK4 bindings
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 15. Suggested order of future work
|
|
|
|
|
|
|
|
1. `TBITSIZE` (small, standard-facing).
|
|
1. `TBITSIZE` (small, standard-facing).
|
|
|
2. `ADDADR`/`SUBADR`/`DIFADR` (small, ISO SYSTEM).
|
|
2. `ADDADR`/`SUBADR`/`DIFADR` (small, ISO SYSTEM).
|
|
@@ -1832,14 +2144,17 @@ No compiler changes are required.
|
|
|
`BTreeMap`; persistent `BTreeFile` last.
|
|
`BTreeMap`; persistent `BTreeFile` last.
|
|
|
8. Terminal emitters: `TermOut`, `VT100`, `VT52`, `Ansi`, optional
|
|
8. Terminal emitters: `TermOut`, `VT100`, `VT52`, `Ansi`, optional
|
|
|
`Regis`; `Tty` and headless tests.
|
|
`Regis`; `Tty` and headless tests.
|
|
|
-9. Communications: `Serial`/`Transport` first; protocols and terminal
|
|
|
|
|
- emulation optional.
|
|
|
|
|
-10. Network: `Net`/`Transport`, TCP/UDP, `Poll`, then optional TLS/HTTP.
|
|
|
|
|
-11. Database: SQLite binding or typed B-tree table layer; dBase III
|
|
|
|
|
|
|
+9. C FFI foundation and bindings: underscore policy, link names,
|
|
|
|
|
+ float32, size_t, C strings/buffers, struct/callback wrappers,
|
|
|
|
|
+ pkg-config; SQLite, then SDL3, then GTK4.
|
|
|
|
|
+10. Communications: `Serial`/`Transport` first; protocols and terminal
|
|
|
|
|
+ emulation optional.
|
|
|
|
|
+11. Network: `Net`/`Transport`, TCP/UDP, `Poll`, then optional TLS/HTTP.
|
|
|
|
|
+12. Database: SQLite binding or typed B-tree table layer; dBase III
|
|
|
only if required.
|
|
only if required.
|
|
|
-12. ISO `COROUTINES` subset, then interrupt/protection layer.
|
|
|
|
|
-13. Dynamic `SET CONST` and deep composite copies.
|
|
|
|
|
-14. Parser error recovery and diagnostics.
|
|
|
|
|
|
|
+13. ISO `COROUTINES` subset, then interrupt/protection layer.
|
|
|
|
|
+14. Dynamic `SET CONST` and deep composite copies.
|
|
|
|
|
+15. Parser error recovery and diagnostics.
|
|
|
|
|
|
|
|
External assembly needs no compiler work; document it as the supported
|
|
External assembly needs no compiler work; document it as the supported
|
|
|
low-level escape hatch.
|
|
low-level escape hatch.
|