CWEB

If you are in the software industry and do not use CWEB but your competitors do, your competitors will soon overtake you — and you'll miss out on a lot of fun besides.
— D.E. Knuth

CWEB é um sistema de programação letrada criado por Donald Knuth e Silvio Levy.  (Knuth criou WEB e Levy adaptou o sistema à linguagem C.)  O sistema combina programação em C com documentação tipografada em TEX.  O sistema está descrito no livro The CWEB System of Structured Documentation. A introdução do livro diz:

A estrutura de qualquer programa pode ser entendida como uma teia (= web)  feita de muitas partes interligadas. [Knuth começou a usar a palavra web neste sentido muito antes do nascimento da rede WWW.]  Para documentar um tal programa, o programador deve explicar cada parte da teia e explicar como cada parte se relaciona com as partes vizinhas. As ferramentas tipográficas fornecidas pelo TEX nos permitem explicar a estrutura local de cada parte tornando-a visível, enquanto uma linguagem de programação como C torna possível especificar os algoritmos de maneira formal e precisa. A combinação dessas duas ferramentas permite desenvolver um estilo de programação que maximiza nossa habilidade de perceber a estrutura de uma peça complexa de software; ao mesmo tempo, os programas documentados podem ser mecanicamente transformados em software casado com sua documentação.

Do ponto de vista lógico, um programa CWEB é uma espécie de jogo de armar:  ele consiste em

  1. blocos de código em linguagem C,
  2. instruções sobre a maneira de encaixar esses blocos para construir um programa C,
  3. comentários e documentação.

A título de exemplo, veja o programa  wc  escrito por Levy e Knuth.  (Esse exemplo faz parte da distribuição do CWEB.)

Não é difícil entender um programa CWEB sem quaisquer explicações adicionais. Mas se tiver dúvidas, consulte a nota Como ler programas CWEB. (Trata-se de uma tradução livre do capítulo How to read CWEB programs do livro The Stanford GraphBase: A Platform for Combinatorial Computing.)  Um dos detalhes da nota é a correspondência entre símbolos que aparecem nos documentos CWEB e os correspondentes símbolos em código C:

CWEB C significado
<=
>=
!=
==
- subtração
->
&& e lógico
|| ou lógico
¬ ! não lógico
& & e bit-a-bit
| ou inclusivo bit-a-bit
^ ou exclusivo bit-a-bit
~ não bit-a-bit

Exemplos

Um primeiro exemplo de programa CWEB é o programa  wc  já mencionado acima. Se retirarmos toda a documentação e comentários, ele se reduz ao arquivo  wc.c.

Outro exemplo, bem mais simples e didático, é o programa  isort  (que coloca em ordem crescente uma seqüência de números). Se eliminarmos toda a documentação, o programa se reduz ao arquivo isort.c.

Finalmente, uma grande quantidade de programas CWEB interessantes e muito bem escritos pode ser encontrada no Stanford GraphBase de Knuth.

Como processar um programa CWEB

O código-fonte de todo programa CWEB fica em um arquivo com sufixo .w .  Por exemplo, o código-fonte do program  wc  mencionado acima fica no arquivo wc.w.  Esse arquivo precisa ser transformado em dois outros:

Para fazer esses transformações, use a seguinte receita, válida em qualquer instalação Linux.

Transformação do arquivo  wc.w  em programa C.   Use o programa  ctangle  (to tangle = entrelaçar, embaraçar):
    ctangle wc.w

Isso extrai de  wc.w  um arquivo  wc.c  (e possivelmente outros arquivos, como  wc.h,  por exemplo).  O arquivo  wc.c  pode ser submetido a um compilador C para produzir um programa executável. Eu uso o gcc:

    gcc wc.c -o wc

(Se, ao contrário do wc, o seu programa usa alguma biblioteca de funções ou header files não usuais, você deve acrescentar argumentos apropriados, do tipo -L, -l ou -I, à linha de comando que chama o compilador.  Além disso, eu sempre uso as opções -Wall, -ansi e -pedantic, para que o compilador me avise sobre as eventuais bobagens no código.)

Exercício: Use um editor de texto para simular o efeito de  ctangle  sobre  wc.w.

Transformação do arquivo  wc.w  em documento CWEB.   Primeiro, submeta  wc.w  ao programa  cweave  (to weave = tecer):
    cweave wc.w

Isso produzirá um arquivo  wc.tex,  que você não precisa ler nem entender, felizmente. Em seguida, diga

    tex wc.tex

para obter o arquivo  wc.dvi

Para exibir o arquivo na tela do monitor diga  xdvi wc.dvi  e para imprimi-lo diga  printdvi -Pxxx wc.dvi,  onde  xxx  é o nome da impressora.  Se o seu computador não tem software para exibir ou imprimir arquivos .dvi, faça

    dvips wc.dvi -o wc.ps

para obter um arquivo  wc.ps.  Se achar conveniente, transforme .ps em  wc.pdf:

    ps2pdf wc.ps wc.pdf

Para exibir esses arquivos diga  gv wc.ps  ou  gv wc.pdf  ou  acroread wc.pdf.

Não é difícil escrever um script que execute todo o processo descrito acima. Também não é difícil usar o  make  para administrar o processo.

Um usuário normal do CWEB jamais examina os arquivos .c  e .tex:   ele escreve o arquivo .w, lê o documento gerado por cweave, corrige o arquivo .w, testa o programa executável, e assim por diante.

Como escrever um programa CWEB?

Para escrever um programa CWEB, basta imitar o exemplo  wc.w já mencionado acima.   Para escrever CWEB em português (com letras acentuadas, títulos em português, etc.) copie o arquivo de macros  cwebmac-br.tex  para o seu diretório e escreva 

    \input cwebmac-br.tex

no início de seu arquivo  .w.  Fiz isso para escrever o programa isort mencionado acima. Veja todos os arquivos intermediários desse exemplo.


Variante LaTeX do CWEB

O formatador tipográfico usado pelo CWEB é TEX.  Há uma evolução do CWEB, criada por Joachim Schrod (veja The cweb class), que aceita macros LATEX para a formatação tipográfica.  Assim, um programa CWEB pode ser escrito quase como se fosse um documento LATEX.   Veja os arquivos do programa wc reescritos por Schrod:   wcltx.wwcltx.ps  e  wcltx.pdf.

A variante LATEX do CWEB é processada pelos programas ctangle e cweave exatamente como indicado na receita acima;  mas é preciso ativar a opção  +e  do cweave e usar latex no lugar de tex para extrair o arquivo  .dvi  do  .tex.  Em suma, diga

    cweave +e meuprograma.w
    latex meuprograma.tex

para obter  meuprograma.dvi.

Para escrever um programa CWEB LATEX em português, não use os arquivos  cwebmac-br.tex  e  cwebmac-ch.tex  mencionados acima em conexão com o CWEB TEX.  Em vez disso, especifique a opção brazil de \documentclass no início do seu arquivo  meuprograma.w.  A título de exemplo, adaptei o programa isort à versão LATEX do CWEB.