Language Folk Wisdom

Andy Wingo, a JavaScript and Guile Scheme blogger writes this insightful comment

There is very little in the way of correct, current, and universal folk wisdom as to how to implement a programming language. Compiler hackers are priests of their languages, yes, but their temples are in reality more or less isolated cults, in which the values of one’s Gods may be unknown or abhorrent to those of others. Witness the attention paid to loop optimizations in some languages, compared to garbage collection in others, or closures in still others.

The personal case he encounters and writes up here is interesting as well — I’d recommend it to language designers and implementers.

Schools of Thought – Compilers

It occurs to me that there are roughly two schools of compiler and language design, typified by the books The Structure and Interpretation of Computer programs (aka SICP) by Ableson and Sussman, and Compilers: Principles, Techniques, and Tools by Aho et al.

They’re also known as the Wizard Book and Dragon Book, respectively, named for their cover illustrations. The choices appear even more fitting in juxtaposition.

A little stack machine

Threw this together to show an example of computed goto. Computed goto is a handy tool for building little interpreters.

#include 

#define NEXT goto **ip++
int main()
{
  int fact = 6, fact_b0 = 16;
  void* program[] = { 
    &&push, (void*)5, &&call, (void*)fact, &&printi, &&end,
    &&beq0, (void*)fact_b0, &&dup, &&push, (void*)1, &&sub, &&call, (void*)fact, &&mult, &&ret, 
    &&pop, &&push, (void*)1, &&ret  };
  void** ip = program;
  void* stack[16] = {0}; void** sp = stack-1;
  void* cstack[16] = {0}; void** cp = cstack-1;
  NEXT;
call:
  *++cp = ip+1; ip = program + (int)*ip;
  NEXT;
ret:
  ip = *cp--;
  NEXT;
beq0:
  ip = *sp ? ip+1 : program + (int)*ip;
  NEXT;
push:
  *++sp = *ip++;
  NEXT;
pop:
  --sp;
  NEXT;
dup:
  sp[1] = sp[0]; sp++;
  NEXT;
mult:
  sp[-1] = (void*)((int)sp[-1] * (int)sp[0]); sp--;
  NEXT;
sub:
  sp[-1] = (void*)((int)sp[-1] - (int)sp[0]); sp--;
  NEXT;
printi:
  printf("%i\n", (int)*sp--);
  NEXT;
end:
  return 0;
}

On codepad

Schrodinger’s Yacc

There was a small controversy last year about parser combinators, a convenient way of rapidly developing parsers in a functional style. Yacc is presumably chosen as the archetypal non-combinator parser generator, requiring separate external parser compiler, known for being a pain to use.

Like Schrodinger’s cat, Yacc seems to be indeterminately alive or dead (though the last article conclusively opened the box for me).