Newsgroups: comp.lang.apl Path: utzoo!utgpu!news-server.csri.toronto.edu!torsqnt!jtsv16!blister!itcyyz!yrloc!hui From: hui@yrloc.ipsa.reuter.COM (Roger Hui) Subject: Re: Interfacing J Message-ID: <1991Apr19.123746.17543@yrloc.ipsa.reuter.COM> Reply-To: hui@yrloc.ipsa.reuter.COM (Roger Hui) Organization: Iverson Software Inc. References: <1991Apr17.202320.13658@math.ufl.edu> Date: Fri, 19 Apr 91 12:37:46 GMT You have Professor L.J. Dickey to thank for the updated J/Sun3. The product described below is currently in beta test. It will be available soon, sooner on some machines than others. I should point out that we have not yet decided whether or not it'd be shareware, or how much it'd cost. -------------------------------------------------------------- LinkJ Roger Hui 1991 3 31 J is a dialect of APL specified by "A Dictionary of J". LinkJ is a set of object modules which together offer the full capability of J while allowing links to other compiled routines and libraries. It is possible to call LinkJ from C and to call C from LinkJ. The interface consists of the following definitions and functions. typedef char C; C jinit(void); typedef long I; A jx(C*s); typedef struct{I t,c,n,r,*s;}*A; A jpr(A x); typedef A (*AF)(); A jma(I t,I n,I r); C jfr(A x); C jerr; A jset(C*name,A x); C jc(I k,AF*f1,AF*f2); "A" is the type of an array. The parts are the type, an internal reference count, the number of elements in the array, the rank, the shape, and the array elements, in a contiguous segment of memory. (Array types are boolean, literal, integer, floating point, complex, and boxed. See file lj.h.) AF typifies a function which accepts one or more array arguments, and returns an array result; i.e. AF is the type of a verb. jinit() initializes J. The result is 1 if the operation is successful, and 0 if not. jx() takes a 0-terminated string argument representing a sentence, and returns the array result of executing the sentence. For example, jinit(); p=jx("a=.i.3 4\0"); q=jx("+/,a\0"); p is a 3 by 4 matrix of the integers from 0 to 11, and q is the atom 66. The space occupied by the array result of jx() is reused the next time jx() is called. Therefore, jinit() and jx() by themselves offer the full capabilities of J. The other functions provide a more convenient and efficient interface. jpr(x) prints array x on the standard output. The result is x itself. jma(t,n,r) allocates memory for an array of type t, having n elements and rank r; you are then responsible for filling in the shape and the elements. jfr() frees an array previously allocated by jma(). Array arguments and results must use space managed by jma() and jfr(). jset(name,x) assigns a value to a global name (as in the copula =:). name is a 0-terminated string; x is an array. The result of jset() is x itself. jx(name) returns the referent of a name. The preceding functions allow calling J from C. Here, we describe how to call C from J. A new case of the !: external conjunction is defined: 10!:k is a verb whose definition is controlled by jc(), a C function you write yourself, as follows: C jc(I k,AF*f1,AF*f2){ switch(k){ /* k: index */ /* f1: pointer to monad (NULL if no monad) */ /* f2: pointer to dyad (NULL if no dyad ) */ /* function result is zero if there is an error, nonzero if no error */ }} 10!:k invokes jc(k,&f1,&f2), wherein (presumably depending on k) you assign to *f1 a pointer to a monadic function and to *f2 a pointer to a dyadic function. The result of 10!:k is a verb like any other; in particular, it may be assigned a name and (orthogonally) may serve as argument to adverbs and conjunction such as prefix and rank; and when it is invoked with arguments the functions you assigned to *f1 and *f2 will be invoked with those arguments. When an error is encountered in an interface function, the result is 0 (if the result type is C) or NULL (if the result type is A), and the global variable jerr contains an error number. Error numbers are defined in file lj.h. File main.c contains an example of using LinkJ. It has a main() function which does, ad infinitum: - get a line of input from the terminal; - execute the line; - print the result (or the error number). (To terminate, enter ")off".) As well, main.c has an example of using jc(), whereby 10!:0 y computes #,y , the number of elements in array y; and x 10!:0 y computes x{.,y , the first x elements of integer array y. C compilation procedures differ from system to system, so the procedure for using LinkJ is necessarily system dependent. On the IBM PC, in the TurboC Integrated Development Environment: a) Put the names of all the LinkJ object modules in the project file. b) Put the names of your own C source files ("main" in the current example) into the project file. c) Select the Make option. Under UNIX, enter: cc main.c linkj/*.o -o test . Acknowledgement. Paul Chapman described the design of 10!:k and jc() to me on December 12, 1990, during his Toronto visit. ---------------------------------------------------------------- Roger Hui Iverson Software Inc., 33 Major Street, Toronto, Ontario M5S 2K9 (416) 925 6096