Known bugs in the GNU SETL binary distribution, as of 1 Oct 2008: - I don't know if this is a real bug or just a misguided feature: when you point the 'setl' command at a file containing multiple programs, and there's a syntax error in the 47th, on line 3586, the reported line number is like 13 (relative to the beginning of the 47th pgm). This won't bother you unless you actually put multiple programs in one file, which should probably be deprecated...in fact, I'm not sure I even document how to do it any more. - PI should probably be built in, so you don't have to put "CONST pi = 4 * ATAN 1" or whatever at the top of so many programs. - It is odd that there is no WRITES or PRINTS to complement READS, but not a show-stopper given STR and the semantics of '+' (implicit conversion to string whenever at least one operand is a string). - EXIT may be followed by loop header tokens as in CIMS SETL, not an expression as in SETL2. - In a few places, integers are not unbounded, but are limited to the range of a C "long int". I would be very interested to know if any of these cases seem unreasonable to anybody - they tend to be things like subscripts and replication factors, where memory constraints impose a practical limit anyway, but also include the F, N, and L in F..L and F,N..L expressions, where ease of implementation and the weak demands of efficiency happen to pull in the same direction. (You can easily work around this silly restriction, of course, simply by iterating in a more moderate range and then mapping upward using the regular integer arithmetic.) - The LALR(1) parser in 'setltran' tends not to give very helpful error diagnostics. - Error reporting by 'setlrun' tends to point to the rightmost part of the larger expression (if any) in which the error occurs. - Floating-point operations can produce numbers that print or are converted by STR to "nan", "inf", or "-inf", but "nan" and "inf" are treated as strings on input (by virtue of their having the form of identifiers), and "-inf" is treated as an error. This applies to READ, READA, READS, GETB, VAL, and UNSTR. - There is no direct way to get an effect like sprintf's "g" format combined with precision control; FIXED is like "f", FLOATING is like "e", and STR is like "g" but without the means to control the number of significant digits. - You can write atoms (created by NEWAT or copied) and convert them to strings, but you can't read them nor create them via UNSTR or READS. This is actually a deliberate design decision, but may be surprising. - FSIZE is not compatible with SETL2, and should probably be extended to allow a stream designator (fd). - There is no LSTAT, though for a symbolic link f, you can get that information as #READLINK f. - Patterns that match long strings can fail to match. For example, s1 := 'abc'; print(s1('a.*c')); s2 := 'a'+9999*'b'+'c'; print(s2('a.*c')); prints abc on a line and then prints * (which stands for OM), rather than the appropriate 10001-character string. - In os_connect() in src/run/os.c, the response to an EINTR return from connect() is to retry the connect(), which is suboptimal if not downright wrong. The POSIX standard says that the connection attempt will continue asynchronously in that circumstance, and that select() can then be used to wait for the connection to complete or abort. I'm not aware of any observed SETL program misbehaviour arising from this deficient handling of connect(), but an illustrative demo would be most welcome, and could perhaps be constructed by hitting a program with signals at high frequency during a network OPEN call. - Forms like [-,x] are allowed in "lhs" positions but not in WR-only actual arg positions (e.g., READ([-,x])), due to limitations in the current LALR(1) parser. The workaround is to use a variable name such as 'dummy' in place of the hyphen (e.g., READ([dummy,x])). - %s in FDATE format specs (standing for the 3-digit representation of milliseconds within the second) conflicts with a (nonstandard) GNU extension to strftime() meaning number of seconds since the beginning of 1970. - The macro processor treats "#" as a very special character (unary # is an argument stringifier, and binary ## is a concatenator). Thus you are denied access to the cardinality operator and to radix denotations within macro definitions. For those who are sufficiently hard-core, it is still possible to get a # to show up in the code emitted by a macro by means of a truly horrible workaround, illustrated by #define f(op,arg) op##arg ... f(#,x) -- emits #x ! - Under Cygwin, the compound.setl test fails in a weird way. For now, I'm just forcing the test to succeed (see the comments therein) so that it doesn't crash a make distcheck. Here is compound.setl: fd := open('/bin/ls "'+getenv 'srcdir'+'"/*.setl','pipe-in'); s := {}; --- The following WHILE condition shouldn't be guarded with the --- silly-looking SELECT; it's just there to make this test pass --- on Cygwin pending diagnosis of the underlying problem (it --- fails on a make distcheck, when the above ls command's output --- is more than 1024 bytes). --while (name := getline fd) /= om loop <--- how we *should* look while select([{fd}])(1) = {fd} and (name := getline fd) /= om loop t := split(filter('wc < '+name)); p := {}; p.lines := val t(1); p.words := val t(2); p.chars := val t(3); s(name) := p; end loop; print(+/[p.lines : p = s (name)]); - With some effort, you can nest a tuple deeply enough to cause C stack overflow in the garbage collector, e.g.: t := []; loop t := [t]; end loop; Note that the time taken by this program is quadratic in the number of loop iterations, in the current implementation. The interpreter will, however, segfault after perhaps half an hour or so, given a stack size limit of 8MB. You can of course change this on most POSIXy systems. For example, in the Bash shell, to make it 64MB, the prior command "ulimit -s 65536" should do the trick. As of this writing, I know of no way other than by creating such a pathologically nested structure to get 'setlrun' to crash without issuing its own diagnostic. When run under control of the 'setl' command, the symptom of a segfault (SIGSEGV) is the message: setl: setlrun killed by signal 11 - The 'setl' command, when it sees a child process such as 'setlrun' get terminated by a signal, tries to report what signal that was. But in the case of SIGINT and SIGTERM, which are normally sent by job control shells to the process group for keyboard-generated interrupts such as CTRL-C and commands like "kill %1" respectively, this is not only not very helpful but also nondeterministic, because the order in which process-group-directed signals get delivered is not defined. So depending on whether 'setl' or 'setlrun' gets hit first, you may or may not see the message. The one-line program select(om); is an infinite sleep suitable for demonstrating this.