Once you get past the formatting and cryptic variable names it's actually a pretty straightforward program, have a look at one of the older threads if you are interested in understanding it:
EDIT: In fact, you can see for yourself using https://gist.github.com/piotrklibert/4d32c8cc6fcf20643a257a2... (thanks, klibertp!)
$ ./j
warning: this program uses gets(), which is unsafe.
5 + 10
Segmentation fault: 11
$ ./j
warning: this program uses gets(), which is unsafe.
5 + 10 20 30
j(70679,0x7fffa46de3c0) malloc: *** error for object 0x7f7fc74001b8: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
From http://code.jsoftware.com/wiki/Studio/TasteofJPart1, `5 + 10` should be a valid J program, but it crashes. Is there any input that doesn't crash it? I *ma(n){ R (I*) malloc(n*4); }
to: I *ma(n){ R (I*) malloc(n*8); }
Note that it's a very tiny interpreter for a very tiny simple language - it does not have any error handling (it still WILL segfault if you enter "incorrect" programs, where "correct" is whatever doesn't crash the interpreter :)), the letters a-z are the only available variable names etc., this is why it is so short. Once you get over the APLish way of writing the C code, and once you deduce what the operators are intended to do, it's a pretty straightforward C program.Here is a sample session:
a=1,2,3
3
1 2 3
b=4,5,6
3
4 5 6
a+b
3
5 7 9
This piece of the gist is the "symbol table" for respectively binary and unary operators, you can use it to get started understanding the language: C vt[] = "+{~<#,";
A(*vd[])() = { 0, plus, from, find, 0, rsh, cat},
(*vm[])() = { 0, id, size, iota, box, sha, 0};plus a+b: addition
Example: 1+2 -> 3
from a{b: selects the a-th element from b Example: 3{4,5,6,7,8 -> 7
find a~b: Not implemented? Or maybe this exploits some old-style C behavior?rsh a#b: repeat a items of b
Example: 3#9 -> [9,9,9]
Example: 7#2,3 -> [2,3,2,3,2,3,2]
cat a,b: concatenate item a onto the list b Example: 1,2,3 -> [1,2,3]
id +a: identity Example: +7 -> 7
size {a: get the size (in the first dimension) of a Example: {7,8,9 -> 3
Example: a=4,5
b=a#7
{b -> 4
iota ~a: enumerates all integers from 0 to a-1 Example: ~3 -> 0,1,2
Example: ~2,3 -> [0,1,2,3,4,5]
box <a: Put a into an indirection box Example: <1 -> <1
sha #a: get the shape (size in all dimensions) of a Example: #7,8,9 -> 3
Example: a=4,5
b=a#7
#b -> 4,5
I don't remember or haven't figured out how to dereference a boxed value, or what this can be used for.The struct A has members:
t: The "type": 0=integer, 1=boxed reference
r: The "rank": size of array d
d: The "dimensions": Multiply to get the size of array p
p: The actual data. Can be integers or pointers to boxed data (cast to a 32-bit integer!)Thank you for detailing all of this.
Thanks for the helpful example program.
EDIT: Sort of. `5+10` crashes, as does `a=5 \n b=10`. But single digit numbers work, so this is pretty cool.