home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / spezial / 20 / dos_txl / source / interp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-19  |  9.5 KB  |  315 lines

  1. /**********************************************************/
  2. /*                       INTERP.C                         */
  3. /*   Hier werden Interpreterbefehle erkannt und dann die  */
  4. /*   notwendigen ausführenden Routinen gestartet.         */
  5. /*                                                        */
  6. /*          (c) 1990 Michael Beising & TOOLBOX            */
  7. /**********************************************************/
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include "interp.h"
  13. #include "neuutil.h"
  14.  
  15. /* Benoetigte Globalvariablen */
  16. extern  PRGZEILE  *FirstLine; /* erste Interpreterzeile   */
  17. extern  PRGZEILE  *ActLine;   /* aktuelle interp. Zeile   */
  18. extern  char      *LinePos;   /* Zeilenpos. der Akt. Zeile*/
  19. extern  int       Steuer;    /* der aufrufenden Routine wird
  20.                        mitgeteilt, um was es sich handelt.*/
  21.                            /* Ergebnisbuffer des Scanners */
  22. extern  char ScanBuffer[ZEILENLAENGE];
  23. extern  VAR  *FirstVar;         /* Zeiger auf die erste Variable */
  24.  
  25. extern  TOKBEF  TokBefDesc[]; /*  NEU     für Befehlsfindung       */
  26.  
  27. /* lokale Funktionen und deren Prototypen dieses Files */
  28.  
  29. static  int     TestBefehl (int *Befehl);
  30.  
  31. void error(int);
  32.  
  33. void
  34. InterAct ()
  35. {
  36. PRGZEILE NewLine;         /* interaktiv eingegebene Zeile */
  37. PRGZEILE *EditZeile;      /* NEU    Editierzeile         */
  38. int      Error;           /* Fehlermeldungen zwischensp.  */
  39. int abbruch[3];           /* NEU    intarray für Abbruchtasten von LESE() */
  40. int i;                    /* NEU    Zähler                 */
  41. int loesch=1;             /* NEU    Switch für ReadBuffer-Löschung   */
  42. register int reg;         /* NEU    für Befehlsfindung               */
  43. int farbe_v,farbe_h;      /* NEU    für Farbsicherung                */
  44. char     ReadBuffer[ZEILENLAENGE];  /* Buffer für eine Eingabezeile*/
  45.  
  46.   abbruch[0]=ESC;        /* NEU     ESC-Abbruch für LESE()   */
  47.   abbruch[1]=F1;         /* NEU      F1-Abbruch für LESE()   */
  48.   abbruch[2]='\0';
  49.   FirstLine = NULL;      /* kein Interpretertext vorhanden */
  50.   ActLine   = NULL;
  51.   FirstVar  = NULL;          /* keine Variablen vorhanden */
  52.   SetFileName ("work.mbl");     /* Defaultfilename setzen */
  53.  
  54.   while (TRUE) {
  55.     ResetError ();     /* Fehlermeldungsflag zurücksetzen */
  56.     *NewLine.Zeile = '\0'; /* Zwischenspeicher rücksetzen */
  57.     setcr(24,0);
  58.     putchar (0x0d);putchar(0x0a);   /* <cr>-<lf> ausgeben */
  59.     putchar ('>');                     /* Prompt ausgeben */
  60.  
  61.  
  62.     /*         NEUE VERSION    */
  63.  
  64.     _lastkey=ESC;
  65.  
  66.     if(loesch)                           /* ReadBuffer Löschen  */
  67.     for(i=0;i<=ZEILENLAENGE-1;i++)
  68.         ReadBuffer[i]=' ';
  69.     else                                 /* ReadBuffer auf orginallänge setzen */
  70.     for(i=strlen(ReadBuffer); i<=(ZEILENLAENGE-1) ;i++)
  71.         ReadBuffer[i]=' ';
  72.  
  73.     ReadBuffer[ZEILENLAENGE-1]='\0';    /* Stringende setzen    */
  74.  
  75.     loesch=1;                           /*  Lösch-Switch Initialisieren  */
  76.  
  77.     while(_lastkey == ESC || _lastkey == F1)  /* While letzte Taste ESC oder F1 */
  78.     {
  79.     putchar ('>');                     /* Prompt ausgeben */
  80.     farbe_v=_set_f_v;
  81.     farbe_h=_set_f_h;
  82.     set_color(7,0);
  83.     /*  ReadBuffer einlesen  auf Zeile 24 Spalte 1  */
  84.     lese(24,3,ReadBuffer,"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",abbruch);
  85.     if (_lastkey==F1)    /*   Hilfe ausgeben  */
  86.         {
  87.         LinePos = ReadBuffer;
  88.         SkipChar ();
  89.         chilfe();
  90.         setcr(24,0);
  91.         }
  92.     set_color(farbe_v,farbe_h);
  93.     }
  94.  
  95.     /*  ReadBuffer auf Eingabelänge kürzen  */
  96.     for(i=strlen(ReadBuffer)-1;ReadBuffer[i] == ' ' && i >= 0;i--)
  97.     ;
  98.     ReadBuffer[++i] = '\0';
  99.  
  100.     /*    ENDE NEU   */
  101.  
  102.  
  103.     /* beginnt die Zeile mit einer Ziffernfolge */
  104.     LinePos = ReadBuffer;
  105.     SkipChar ();
  106.     Scan ();                         /* Zeile untersuchen */
  107.                                                                             /* Überprüfe Zeilenanfang auf Ziffer */
  108.     if (Steuer == ZIFFER)      /* Zeilennummer vorhanden */
  109.       {
  110.       NewLine.LineNumber = atoi (ScanBuffer);
  111.       ActLine =                   /* setze aktuelle,
  112.                                     zu bearbeitende Zeile */
  113.       if (MakeToken () == OK)  /* erzeuge eine Tokenzeile */
  114.     InsIntLine ();   /* Prog.zeile in Prg.text einfügen */
  115.       else
  116. /*                          NEUE VERSION            */
  117.     {
  118.     Scan();
  119.     if(strlen(ScanBuffer)==1 && Steuer == ALPHA)  /* 1 Alphazeichen */
  120.         {
  121.         switch ((int)ScanBuffer[0])
  122.             {
  123.             case 'D':    /*     Zeile löschen  */
  124.             case 'd':
  125.                 /* Wenn Zeilennummer vorhanden , Zeile löschen */
  126.                 if (FindInsPos(ActLine->LineNumber,&EditZeile))
  127.                     {
  128.                     printf ("\n Zeile [%d] ist gelöscht !",NewLine.LineNumber);
  129.                     DelLine (NewLine.LineNumber);
  130.                     }
  131.                 else
  132.                 /* Sonst Fehlermeldung        */
  133.                     printf("\n Zeile [%d] nicht gefunden !",NewLine.LineNumber);
  134.  
  135.                 break;
  136.  
  137.             case 'E':   /*     Zeile editieren  */
  138.             case 'e':
  139.                 /* Wenn Zeilennummer vorhanden , Zeile aufbereiten */
  140.                 if (FindInsPos(ActLine->LineNumber,&EditZeile))
  141.                     /* Kopiere den alten Inhalt in die Eingabe Zeile */
  142.                     {
  143.                     itoa(EditZeile->LineNumber,ReadBuffer,10);
  144.                     strcat(ReadBuffer," ");
  145.                     reg = 0xff & *(EditZeile->Zeile);
  146.                     strncat(ReadBuffer,TokBefDesc[reg-TOKMIN].Befehl,10);
  147.                     strcat(ReadBuffer," ");
  148.                     strcat(ReadBuffer,(EditZeile->Zeile+1));
  149.                     loesch=0;
  150.                     }
  151.                 else
  152.                 /* Sonst Fehlermeldung        */
  153.                     printf("\n Zeile [%d] nicht gefunden !",NewLine.LineNumber);
  154.                 break;
  155.  
  156.             default:
  157.                 /*   Falsches Argument    */
  158.                 loesch=0;
  159.                 printf("\n Zeile [%d] ist fehlerhaft !",
  160.                     NewLine.LineNumber);
  161.             }
  162.         }
  163.     else
  164.         /*   Kein Argument oder ungültiger Befehl      */
  165.         {
  166.         printf("\n Zeile [%d] ist fehlerhaft !",NewLine.LineNumber);
  167.         loesch=0;
  168.         }
  169.     }
  170. /*                    ENDE NEUE VERSION                    */
  171.  
  172.       }
  173.     else                /* ansonsten interpretiere Zeile */
  174.       {
  175.       ActLine = 
  176.       SkipChar ();           /* Mit neuem Zeichen starten */
  177.       LinePos = ReadBuffer;  /* Zeilenzeiger zurücksetzen */
  178.       if (MakeToken () == OK)     /* Tokenzeile erzeugen */
  179.     {
  180.         LinePos = ActLine->Zeile;
  181.         InterpLine ();          /* Zeile ausführen lassen */
  182.     }
  183.       else
  184.     {
  185.     sprintf (ReadBuffer,"Befehl <%s> unbekannt",ScanBuffer);
  186.         serror (ReadBuffer);
  187.     }
  188.       }
  189.   }
  190. }
  191.  
  192.  
  193. /* InterpLine
  194.    Die Zeile, auf welche ActLine zeigt, wird interpretiert
  195. */
  196.  
  197. int
  198. InterpLine ()
  199. {
  200. register int i,error;
  201.  
  202.   i = 0xff & *LinePos;                   /* make unsigned */
  203.   if ((i >= TOKMIN) && (i <= TOKMAX)) {
  204.     LinePos++;              /* aktuellen Befehl überlesen */
  205.     SkipChar ();
  206.                                       /* Befehl ausführen */
  207.     error = TokBefDesc[i-TOKMIN].function ();
  208.   }
  209.   else {
  210.     serror ("<InterpLine> Unbekannter Befehl! ");
  211.     error = FALSE;
  212.   }
  213. return (error);
  214. }
  215.  
  216. /* DoProgram
  217.    arbeitet ein Interpreterprogramm zeilenweise so lange
  218.    ab, bis entweder das Programmtextende erreicht wird, ein
  219.    Fehler auftritt oder die Endeanweisung gefunden wurde.
  220. */
  221. extern  int     IntError;
  222. int     GetNextLine;
  223.  
  224. int
  225. DoProgram ()
  226. {
  227. register int error = TRUE;
  228.  
  229.   while (ActLine && error) {    /* Solange, bis Programmende
  230.                                                  erreicht */
  231.     LinePos = ActLine->Zeile;
  232.     GetNextLine = TRUE;
  233.     error = InterpLine ();    /* Aktuelle Zeile ausführen */
  234.     if (GetNextLine)   /* nächste Programmzeile ausführen */
  235.       ActLine = ActLine->NextZeile;
  236.                          /* Fehler aufgetreten => Abbruch */
  237.       if (IntError) break;
  238.     }
  239.  
  240. return (error);
  241. }
  242.  
  243. /* MakeToken
  244.    Es wird versucht, einen Quelltext, auf den LinePos zeigt,
  245.    in Token zu verwandeln.
  246. */
  247.  
  248. extern  TOKBEF  TokBefDesc[];
  249.  
  250. int
  251. MakeToken ()
  252. {
  253. int     i,j;
  254. int     LineSym;
  255. char    *TokLine;
  256.                             /* Tokenpointer auf Zielzeile */
  257.   TokLine = ActLine->Zeile;
  258.   if (Scan () == UNEOL)       /* Lies nächstes Symbol ein */
  259.   return (ERROR);
  260.  
  261.             /* suche nach einem gültigen Interpreter-Befehl */
  262.   if (TestBefehl(&i) == 0) {           /* Befehl gefunden */
  263.                           /* Token in Zielzeile speichern */
  264.     *TokLine++ = i + TOKMIN;
  265.     *TokLine = '\0';
  266.     if (TokBefDesc[i].CopyRest) {
  267.                             /* kopiere den Rest der Zeile */
  268.       strcat (TokLine,LinePos);
  269.       return (OK);          /* das war's. Zeile fertig    */
  270.     }
  271.     else        /* anderenfalls alle Einzelsymbole holen  */
  272.       for (LineSym = TokBefDesc[i].ParaCount;
  273.            LineSym ; LineSym--) {
  274.                          /* nächste Zeichenkette einlesen */
  275.       if (Scan () == SCANOK)
  276.         if (TestBefehl(&i) == 0) {
  277.                           /* Token in Zielzeile speichern */
  278.           *TokLine++ = i + TOKMIN;
  279.           *TokLine = '\0';
  280.         }
  281.         else {
  282.           strcat (TokLine,ScanBuffer);
  283.                                  /* Zeiger ans Zeilenende */
  284.           TokLine = strchr (TokLine,'\0');
  285.         }
  286.       else
  287.         return (ERROR);
  288.     }
  289.   }
  290.   else
  291.     return (ERROR);
  292. return (OK);
  293. }
  294.  
  295. /*      TestBefehl
  296.         suche nach einem gültigen Interpreter-Befehl
  297. */
  298.  
  299. int
  300. TestBefehl (Befehl)
  301. int     *Befehl;
  302. {
  303. register int i,j;
  304.  
  305.   for (i = 0;
  306.        (TokBefDesc[i].function != NULL) &&
  307.        ((j = strcmp(TokBefDesc[i].Befehl,ScanBuffer)) != 0)
  308.        ; i++) {
  309.     }
  310.   *Befehl = i;
  311. return (j);
  312. }
  313.  
  314. /**************** Ende des Files INTERP.C *****************/
  315.