| Programma di esempio STATC.PRT | 
; STATC
;
; Programma per Proteus
;
; (C) 1998-2003 Simone Zanella Productions
;
; Statistiche su un programma C.
;
; Riporta:
; - il numero totale di linee;
; - il numero totale e la percentuale di righe non bianche;
; - il numero totale e la percentuale di linee con direttive.
;
; Nota: i token "/*" e "*/" non possono apparire dentro stringhe.
; Parametri impliciti: output su console
;!proteus -o
; Inizializza le variabili
FUNCTION ONSTART()
  IF STREQ(ARGV(3), "..")
    CONSOLELN "Sintassi: " ARGV(1) " " ARGV(2) " nomefile.c"
    CONSOLELN ""
    CONSOLELN "Scopo: riporta delle statistiche sul file C indicato"
    ABORT 0
  FI
  ; Flag: la linea è dentro un commento?
  _InRem = 0
  ; Numero complessivo di linee
  _TNL = 0
  ; Numero di direttive
  _TPPD = 0
  ; Numero di linee non bianche (escluse le direttive)
  _TML = 0
RETURN
; Incrementa sempre il contatore di riga
INC(@TNL)
IF EQ(InRem, 0)
  ; La linea inizia fuori commento
  ; Trova l'inizio del commento
  Pos = STRSTR(L, "/*")
  ; Duplica la linea
  PL = STRDUP(L)
  ; C'è un commento?
  IF NEQ(Pos, 0)
    PL3 = ""
    REPEAT
      ; Pos è dove la parte fuori commento termina
      DEC(@Pos)
      ; PL2 è la parte fuori commento
      PL2 = LEFT(PL, Pos)
      ; Accoda PL2 a PL3
      IF ISNOTEMPTY(PL2)
        PL3 = PL3 PL2
      FI
      ; Pos2 è dove termina il commento (se sulla stessa riga)
      Pos2 = STRSTR(PL, "*/")
      ; Siamo dentro un commento; imposta il flag
      InRem = 1
      ; Il commento termina sulla riga?
      IF NEQ(Pos2, 0)
        ; Azzera il flag
        InRem = 0
        ; Pos2 è l'inizio della parte fuori commento
        ADD(@Pos2, 2)
        ; C'è qualcosa da appendere?
        IF NEQ(Pos2, 0)
          PL = SUBSTR(PL, Pos2, STRLEN(PL))
        ELSE
          BREAK
        FI
      ELSE
        BREAK
      FI
      Pos = STRSTR(PL, "/*")
    UNTIL EQ(Pos, 0)
  ELSE
    PL3 = STRDUP(L)
  FI
ELSE
  ; Siamo dentro un commento
  ; Trova la fine del commento
  Pos = STRSTR(L, "*/")
  ; Crea una copia della linea
  PL = STRDUP(L)
  ; Trovata la fine del commento
  IF NEQ(Pos, 0)
    PL3 = ""
    REPEAT
      ; Pos è l'inizio della parte fuori commento
      ADD(@Pos, 2)
      ; PL è la parte fuori commento
      PL = SUBSTR(PL, Pos, STRLEN(PL))
      ; Trova in PL l'inizio del prossimo commento
      Pos2 = STRSTR(PL, "/*")
      ; Fuori commento
      InRem = 0
      ; C'è un nuovo commento nel resto della riga?
      IF NEQ(Pos2, 0)
        ; Pos2 è dove termina la parte fuori commento
        DEC(@Pos2)
        ; PL2 è la parte fuori commento
        PL2 = LEFT(PL, Pos2)
        ; Accoda PL2 a PL3
        IF ISNOTEMPTY(PL2)
          PL3 = PL3 PL2
        FI
        ; Trova il prossimo fine commento
        Pos = STRSTR(PL, "*/")
        ; Trovato: aggiorna PL
        IF NEQ(Pos, 0)
          DEC(@Pos)
          PL = SUBSTR(PL, Pos, STRLEN(PL))
        ELSE
          ; Siamo di nuovo dentro un commento
          InRem = 1
        FI
      ELSE
        ; Il resto della linea è fuori commento
        IF ISNOTEMPTY(PL)
          PL3 = PL3 PL
        FI
      FI
      Pos = STRSTR(PL, "*/")
    UNTIL EQ(Pos, 0)
  ELSE
    ; La linea è dentro un commento - ignora (il resto del
    ; programma è saltato)
    IF EOF
      CONSOLELN "Commento non terminato, linea " N
      ABORT 1
    ELSE
      IGNORE
    FI
  FI
FI
; Elimina gli spazi
PL3 = ALLTRIM(PL3, " ")
IF ISNOTEMPTY(PL3)
  ; Controlla se è una direttiva
  IF STREQ(LEFT(PL3, 1), "#")
    INC(@TPPD)
  ELSE
    ; Salta le linee di commento C++ style
    IF NOT(STREQ(LEFT(PL3, 2), "//"))
      INC(@TML)
    FI
  FI
FI
FUNCTION ONEND()
  PRINTLN "File: " _F
  PRINTLN "Numero totale di linee: " _TNL
  T = ADD(_TML, _TPPD)
  PN = MUL(FDIV(T, _TNL), 100)
  PRINTLN "Numero di linee non-bianche: " T \
          " (" PFORMAT("02.02f", PN) "%)"
  PN = MUL(FDIV(_TPPD, _TNL), 100)
  PRINTLN "Numero di direttive: " _TPPD \
          " (" PFORMAT("02.02f", PN) "%)"
RETURN