3 ms·
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 i
by stiff 9y ago
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:
https://news.ycombinator.com/item?id=8533843 https://news.ycombinator.com/item?id=8533843
- sillysaurus3 9y agoUnfortunately, I tried getting it to run and it simply doesn't work. Unless the expected behavior of every input is to crash the interpreter. EDIT: In fact, you can see for yourself using https://gist.github.com/piotrklibert/4d32c8cc6fcf20643a257a26bd17bcde 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 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?
- stiff 9y agoI did run it back in the day, it works, I think it just happens to assume a 32 bit OS. You can fix the gist by changing this: 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};
- sillysaurus3 9y agoIt works! I compiled it with `gcc j.c -m32 -o j` and it runs now. Awesome. 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.
- 1wd 9y agoWhen I last looked at this I found: 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!)
- sillysaurus3 9y agoWow. This is genuinely incredible. The interpreter works, and all of your examples run. Thank you for detailing all of this.