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
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 |
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.
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.
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.
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.
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.
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.w, wcltx.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.