SNOBOL4LOAD(3)

πŸ“¦
version 2.3.1 Β· 3 versions
, in fedora 43, fedora 44, opensuse-leap 16.0

✨ NAME ✨

snobol4load β€” loading extension modules into SNOBOL4. that's it, that's the whole serve πŸ’…


πŸ’– SYNOPSIS πŸ’–

okay bestie, before you do literally anything else, here's the shape of your modulename.c and it is giving template:

modulename.c:
       #ifdef HAVE_CONFIG_H
       #include "config.h"
       #endif

       #include "h.h"
       #include "snotypes.h"
       #include "macros.h"
       #include "load.h"
       #include "equ.h"

       SNOBOL_MODULE(modulename)

       /*
       **=pea
       **=sect NAME
       **modulename \- A SNOBOL4 extension module
       **=sect SYNOPSYS
       **=code
       **-INCLUDE 'modulename.sno'
       **=cut
       */

       /*
        * LOAD("FUNC_NAME(ARG_TYPES,....)RET_TYPE", MODULENAME_DL)
        */
       /*
       **=code
       **        result = B<FUNC_NAME(ARG_TYPES,....)>
       **=ecode
       */
       lret_t
       FUNC_NAME(LA_ALIST) {
        /* function body */
       }

like. copy the vibe, not the typos. 🫢


🌸 SYNOPSIS 🌸 (yes, another one, keep up)

External C functions get loaded into SNOBOL4 through the LOAD() function. <purple>periodt.</purple> πŸŽ€

LOAD() gets handed a prototype, and that prototype is doing three jobs at once (main character energy fr): it names the function, it may describe the minimum number and types of the parameters the function will be passed, and it also covers the return type.

⚠️ important, do not skip: use the typedefs int_t and real_t in your C code for all SNOBOL4 INTEGER and REAL values. if you don't, value truncation may occur and you will be sad. 😭

Your function should return a value using one of these macros β€” and the type you return should be compatible with the type in the prototype you passed to LOAD():

RETINT(i)             /* return INTEGER (int_t) value */
RETREAL(a)            /* return REAL (real_t) value */
RETNULL               /* return null string */
RETSTR_FREE(buf)      /* return C string and free malloc'ed buf */
RETSTR2_FREE(buf,len) /* return counted str and free malloc'ed buf */
RETSTR(buf)           /* return C string from static buffer */
RETSTR2(buf,len)      /* return counted string from static buf */
RETPRED(success)      /* return predicate value (NULL or failure) */
RETFAIL               /* return failure */

πŸ¦‹ getting at your parameters πŸ¦‹

Parameters are accessed positionally via these macros. here's the slay part: when a data type is specified in the LOAD() prototype, values passed to the function get automatically converted to that specified data type. ✨

πŸ’€ BUT. the macros below do NOT perform data type conversion. use the wrong macro to grab a parameter and you get garbage, or worse. and "or worse" is doing a lot of heavy lifting in that sentence, ngl.
int_t i = LA_INT(0);    /* gets value of 1st parameter; returns int_t */
real_t a = LA_REAL(1);  /* gets value of 2nd parameter; returns real_t */
char *s = mgetstring(LA_PTR(2)); /* get string argument as C string
                      * in malloc'ed buffer. MUST be free'ed */
const char *sp = LA_STR_PTR(2); /* get pointer (or NULL) */
int sl = LA_STR_LEN(2); /* returns string length. */
🫢 friendly reminder from your bestie: that mgetstring buffer is malloc'ed and it MUST be free'ed. don't leak, babe.

🌈 polymorphic parameters (iconic behaviour) 🌈

External functions can be written to take polymorphic parameters β€” you do this by leaving the type name blank in the prototype, or by passing arguments in excess of those described in the prototype. so for example:

"FOO(,STRING)INTEGER"

that's a function with two parameters, and the first one is polymorphic. πŸ’…

To figure out the actual parameter data type, you must use the LA_TYPE(n) macro. here's the decoder ring:

  • I β€” arg n is an integer of C type int_t (fetch it with LA_INT(n))
  • R β€” arg n is a real of C type real_t (fetch it with LA_REAL(n))
  • S β€” arg n references a string (fetch it with mgetstring etc).

🧚 build & install 🧚

Loadable code can be compiled and installed using snobol4setup(3), which generates a modulename.sno include file. it's giving ✨convenience✨.


πŸ‘‘ SEE ALSO πŸ‘‘


and that's the whole page, bestie!! πŸŽ€ this was CSNOBOL4B version 2.3.1, dated March 31, 2022, and honestly? she ate. go write your module, hydrate, and remember to free your buffers. mwah πŸ’–πŸŒΈβœ¨

πŸ“¦ where this page comes from