2.74        TRAC

Elaboratore di testi

TRAC (Text Reckoning And Compiling) è opera di Calvin. N. Mooers e  L. Paul Deutsch. La storia di TRAC è piuttosto estesa, ed origina quattro distinte versioni: TRAC-64, TRAC-84, TRAC-2001 e Tint. TRAC nasce come programma per trattare testi, a questo scopo, prima di sviluppare TRAC, Mooers aveva preso in considerazione LISP, IPL-V e COMIT.

TRAC lavora come un filtro su di un testo in cui sono presenti delle macro, queste sono riconosciute dalla presenza di un metacarattere di terminazione, usualmente “” (apostrofo). TRAC invia in output quanto riceve in input, e le eventuali macro presenti sono sostituite con il risultato dell’esecuzione della macro stessa.

2.74.1             TRAC-64

Lo sviluppo di TRAC inizia nel 1959; nel 1964, di qui il postfisso del nome, è disponibile la prima implementazione per opera di Deutsch su PDP-10. I comandi del linguaggio o macro, sono una trentina, ed hanno la forma #(mc,arg1,arg2,...) dove mc è il nome della macro seguito da eventuali argomenti. I tipi di dato sono stringhe di caratteri che semanticamente possono essere dati alfanumerici, programmi o numeri interi. Le variabili sono memorizzate in strutture dette form, contenenti la stringa di dati, il nome assegnatogli ed un puntatore per percorrere la stringa stessa. Il repertorio di macro comprende macro per l’input da tastiera e l’output su video, per operazioni aritmetiche su numeri interi, per gestire dati, per creare macro utente e richiamarle con parametri, macro di tipo logico e di confronto fra stringhe e numeri ed infine di diagnostica. Le macro utente sono, di fatto, delle funzioni. Le macro aritmetiche operano su stringhe in cui nella parte di destra è presente un numero, eventualmente segnato; se la macro ha la forma #(op,alfa1num1,alfa2num2), con alfa1 e alfa2 alfanumerici, num2 e num2 numeri, il risultato sarà: alfa1num3 dove num3 = num1 op num2. L’ampiezza dei numeri dipendeva dalle caratteristiche della macchina, in genere 216, tuttavia con macchine in cui l’aritmetica era implementata non con valori binari, ma con digit, poteva essere virtualmente illimitata. Una limitazione del linguaggio è la mancanza di macro per la reiterazione, cosa che può essere eseguita con la ricorsione:

C:\cygwin\home>perl trac

#(ds,ris,1)

#(ds,fatt,

   (#(gr,#(cl,count),1,

         (#(ds,ris,#(ml,#(cl,count),#(cl,ris)))

          #(ds,count,#(su,#(cl,count),1))

          #(cl,fatt)))

))'

#(ds,count,#(rs))

#(cl,fatt)

#(ps,

#(cl,ris))'

8'

40320

#(ex)'

C:\cygwin\home>

 

Form ris contiene 1

fatt contiene script

confronto di fine ciclo

calcolo fattoriale

decremento contatore

richiamo ricorsivo di fatt

 

Form count: valore da input

Richiamo di fatt

Visualizzazione risultato

Valore immesso

Fattoriale

Uscita da TRAC

L’input ed output su file è possibile solo per le form.

Il “The Retrocomputing Museum” ha reso disponibile un interprete di TRAC-64, scritto in Perl (con limitate estensioni e la possibilità di usare nomi di macro più espressivi).

2.74.2             TRAC-84

TRAC-84 o TR2 è una versione di TRAC del tutto diversa da TRAC-64, in comune i due linguaggi hanno il meccanismo di funzionamento:

·         le macro sono oltre ottanta.

·         I nomi delle macro sono stati razionalizzati, nel senso che il primo carattere individua la famiglia di macro; inoltre il comando è ulteriormente qualificabile tramite un suffisso.

·         Le macro aritmetiche esigono operandi numerici.

·         E’ possibile inserire commenti (solo nel corpo delle macro utente).

·         E’ stata introdotta una macro di iterazione.

·         Sono presenti macro per il trattamento di files.

·         Si possono creare famiglie di variabili con struttura ad albero, di fatto un embrione di oggetto.

Identificatore

Famiglia

a

Aritmetiche 

b

Manipolazione di bit

f

Manipolazione di files

i

Input e comunicazione con la porta seriale

o

Output

m

Gestione della memoria: variabili, macro utente,…

n

Comunicazione in rete

p

Iterazione, richiamo programmi e servizi OS

t

Operazioni su stringhe di testo

x

Diagnostica, data e ora

l

Collegamento a librerie esterne

r

Richiamo di variabile o di procedura

s

Memorizza variabile o script (form)

e

Confronto fra stringhe

g

Uscita da TRAC

Tabella 3

Le macro hanno la forma :(mcs,arg1,arg2,...), dove mc è il nome della macro, seguito da zero o più argomenti ed s è un eventuale suffisso che specifica ulteriormente il comportamento della macro. Nella Tabella 4 sono elencati i suffissi, quali macro li prevedono ed il loro significato.

Suffisso

Si applica  a

Azione

i

r,i

Interpreta la stringa prodotta

d

Macro che generano output

Elimina la stringa prodotta

0,1,...

o,i,n,f

Indica un canale di input/output

Tabella 4

:(ri,decnum.aq,123,11)'11.18

:(ri,decnum.sqrt,7000)'83.66

:(ri,decnum.pigreco)'3.141592

:(s,decnum.dec,3)'

:(ri,decnum.aq,1,3)'.333

:(mt)'

<base node>

=rem

=sqrt0

+decnum

        lav

        op

        dec

        buf1

        dummy

        buf3

        buf2

        buf4

        =sqrt0

        =pigreco

        =aq

        =sqrt

=decgen

Nell’esempio che segue è stato costruito un abbozzo di “oggetto” decnum. per aritmetica su numeri interi, con risultato decimale. L’oggetto contiene decnum.dec un campo con il numero di decimali richiesto, decnum.aq una macro per la divisione, decnum.sqrt una macro per il calcolo della radice quadrata e decnum.pigreco che fornisce il valore di pigreco con sei decimali.

Figura 36

Nella Figura 36 ci sono degli esempi di richiamo delle macro e la struttura di decnum. ottenuta tramite la macro mt. Lo script di Figura 37 è una macro utilizzata dalla macro decnum.sqrt per iterare nella ricerca del risultato, nellaFigura 38 è riportato lo script con la macro per generare la struttura dell’oggetto.

:(mm,sqrt0,(

    <* media fra massimo e minimo *>

    :(s,decnum.lav,:(aq,:(aa,:(r,decnum.buf1),:(r,decnum.buf2)),2))

    :(s,decnum.buf3,:(am,:(r,decnum.lav),:(r,decnum.lav)))

    <* calcolo nuovi limiti *>

    :(s,decnum.dummy,

      :(ag,:(r,decnum.buf3),:(r,decnum.op),

         (:(s,decnum.buf1,:(r,decnum.lav))),(),

         (:(s,decnum.buf2,:(r,decnum.lav))))

      )

    :(ri,decnum.dummy) <* esegue istruzione *>

    <* calcolo intervallo *>

    :(s,decnum.buf3,:(as,:(r,decnum.buf1),:(r,decnum.buf2)))

    <* verifico se è il caso di proseguire *>

    :(s,decnum.dummy,

      :(ag,:(r,decnum.buf4),:(r,decnum.buf3),

        (:(s,decnum.buf4,:(r,decnum.buf3))),

        (:(px)),

        (:(px))))

    :(ri,decnum.dummy) <* esegue istruzione *>

 ))

<* salvo lo script nel file sqrt0.mff *>

:(mp,sqrt0,sqrt0.mff)

:(g)'

Figura 37

:(mm,rem,(<* TRAC Version of 11 Feb 1992 *>))

:(mm,decgen,(  <* macro per generare la struttura decnum *>

  :(s,decnum.)

  :(s,decnum.sqrt0) <* macro usata da sqrt *>

  :(s,decnum.dec,2) <* numero decimali *>

  :(s,decnum.op)    <* operando        *>

  :(s,decnum.lav)   <* area di lavoro  *>

  :(s,decnum.buf1)  <* area di lavoro  *>

  :(s,decnum.buf2)  <* area di lavoro  *>

  :(s,decnum.buf3)  <* area di lavoro  *>

  :(s,decnum.buf4)  <* area di lavoro  *>

 ))

:(ri,decgen)

:(mm,decnum.sqrt,(

    :(s,decnum.op,<1>:(pc,0,:(am,2,:(r,decnum.dec))))  <* aggiungo decimali *>

    <* intervallo fra cui cade la radice *>

    :(s,decnum.buf1,:(pc,3,:(aa,:(aq,:(tl,decnum.op),2),1)))  <* 33...3 *>

    :(s,decnum.buf2,1:(pc,0,:(aq,:(as,:(tl,decnum.op),1),2))) <* valore minimo radice 10...0 *>

    :(s,decnum.buf4,:(as,:(r,decnum.buf1),:(r,decnum.buf2)))  <* controllo differenza *>

    <* area controllo convergenza *>

    :(pc,(:(ri,decnum.sqrt0)),-1)                            <* esegue ciclo iterazioni *>

    <* calcolo posizione decimali *>

    :(tps,decnum.lav,:(as,:(tl,decnum.lav),:(r,decnum.dec)))

    :(o,:(tpb,decnum.lav).:(tpe,decnum.lav))

 ))

:(mm,decnum.aq,(

  :(s,decnum.op,<1p>:(pc,0,:(r,decnum.dec)))   <* aggiungo decimali *>

  :(s,decnum.lav,:(aq,:(r,decnum.op),<2p>))

  <* calcolo posizione decimali *>

  :(tps,decnum.lav,:(as,:(tl,decnum.lav),:(r,decnum.dec)))

  :(o,:(tpb,decnum.lav).:(tpe,decnum.lav))

))

:(mm,decnum.pigreco,(:(s,decnum.buf1,:(r,decnum.dec))

                     :(s,decnum.dec,6)

                     :(ri,decnum.aq,355,113)

                     :(s,decnum.dec,:(r.decnum.buf1))))

:(mm,rem,(<* mf,... legge form memorizzata *>))

:(mf,,sqrt0.mff)

:(mm,rem,(<* inserisco in struttura decnum. sqrt0 *>))

:(mm,decnum.sqrt0,:(r,sqrt0))

Figura 38

1.1.3             TRAC T2001

TRAC T2001 è implementato in Java.

1.1.4             Tint

Tint è l’evoluzione di TRAC con supporto di TRAC T2001, ambiente grafico interattivo, programmazione ad oggetti, supporto TCP, espressioni regolari. Gestita ancora solamente l’aritmetica intera.

<* Tint version 0.17 *>

Def:Proc:fatt(%n)

[*]

#(=,%n,1,1,(#(*,%n,#(fatt,#(-,%n,1)))))

[*]

 

Def:Eval:

[*]

#(#(tint.console).put,fattoriale di 10: #(fatt,10))

[*]

C:\Tintware\release>tintc fatt.tnt

fattoriale di 10: 3628800