Subject: Re: Making an engineering case for Lisp
From: rpw3@rigden.engr.sgi.com (Rob Warnock)
Date: 1999/11/18
Newsgroups: comp.lang.lisp
Message-ID: <80vvaf$1lfqj@fido.engr.sgi.com>
Tim Bradshaw  <tfb@tfeb.org> wrote:
+---------------
| * Rob Warnock wrote:
| > Or even "typeless" languages such as BLISS!  
| 
| This is pretty off-topic, but do you know if there's any family
| relation between BLISS and BCPL?
+---------------

I don't think so, not in the sense of the well-documented evolution
from BCPL -> B -> C, say. But I strongly suspect the authors of BLISS
*knew* of BCPL, and were at least somewhat influenced by it (and also
a bunch of other things)...

B.t.w., if you want to read more, the BLISS-11 Programmers Manual is
online at <URL:http://www.dbit.com/pub/alpha/bliss11/bliss.txt>, and
in fact, that same directory contains the entire source of the BLISS-11
compiler (written in BLISS-64, though the original BLISS-11 was written
in BLISS-10).

One really nice idea I got from the BLISS compilers that I continue
to use in Scheme & CL is the notion of parsing infix languages using
a mixture of top-down recursive descent for the control structures
and simple operator precedence for the arithmetic expressions. The
"trick" is to define the control structure keywords (IF, CASE, etc.)
to be left-associative "operators" of *very* high precedence. Then things
like "a + b * if this then x + y * z else other fi - 32" are very easily
parsed into (- (+ a (* b (if this (+ x (* y z)) other))) 32)".

[The other part of that "trick" is that "stoppers" or terminators such
as "FI", "ESAC", comma, semicolon, right-parens & -brackets, etc., are
defined as "operators" of very *low* precedence, so that they "stop"
any recursively-embedded expressions and return control to the top-down
parser.]

I don't think it's any more powerful than "pure" recursive descent
in terms of the languages it parses, but it makes it a *lot* easier
to encode the grammar of the infix arithmetic sub-expressions than
the "pure" recursive descent style...  (IMHO)

If you want to look at the original BLISS version of this, the routines
"lexan.bli" (routine "RUND", or Read Until Next Delimeter) and "syntax.bli"
(routine "EXPRESSION") have most of the guts. [Or if somebody wuld rather
see a piece of Scheme that does a similar (though a lot simpler) thing, I
could dig that out of some old code I have and post that...]

Obligatory (vaguely) Lisp-related note: The macro "XCTSYNTAX" in routine
EXPRESSION can be thought of as a kind of generic function dispatch that
vectors off to the parsing routine for the specific operator (in BLISS
compiler terms, "delimiter") currently in the "DEL" slot of the current
"lexical window". That is, all you have to do to add a new operator to
the compiler is add a defmethod to XCTSYNTAX with an EQL specializer
on the new operator type. (O.k., o.k., so there are about a dozen *other*
"generic functions" you have to add specialized methods to too, e.g.,
the one that builds a graph-table lexeme from the results of parsing
the operator & its arguments from the user code. Details...)


-Rob

p.s. Pardon me if this was a bit long, but most of my early learning
about compiling came from reading the BLISS-10 & BLISS-11 compilers'
source codes and Wulf et al's "The Design of an Optimizing Compiler" --
a classic, IMHO!!

-----
Rob Warnock, 8L-846		rpw3@sgi.com
Applied Networking		http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673
1600 Amphitheatre Pkwy.		FAX: 650-933-0511
Mountain View, CA  94043	PP-ASEL-IA