home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1991 / 04 / txl / 3_preis / fast / intutil.c < prev    next >
Text File  |  1990-11-21  |  18KB  |  761 lines

  1. /* intutil.c
  2. Dieses File enthält Utility-Funktionen zum Erstellen eines neuen
  3. Interpreterbefehls oder dessen Ausführung.
  4. (c) 1990 Michael Beising & TOOLBOX
  5. */
  6.  
  7. #include <string.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include "interp.h"
  11.  
  12. /* Funktionsprototypen */
  13. void SetValue (VARDEF *Wert,VARDEF *NewVar,unsigned char Type, int neu);
  14. void GetValue (VARDEF *Wert,VARDEF *NewVar,unsigned char Type);
  15. void PushExp (void);
  16. void CalcResult (void);
  17. void SetResultValue (VAR *Result);
  18.  
  19. void     ReadValue (VAR    *Wert);
  20. EXPDEF    *PopExp (void);
  21.  
  22. int        CmpVar (void);
  23. int        Compare (void);
  24. void    ReadComp (void);
  25.  
  26. void    ClearProg (void);
  27.  
  28.  
  29. /* Benötigte Globalvariablen */
  30. extern    int            IntError;        /* Interpreterfehler */
  31. extern    PRGZEILE    *FirstLine;        /* erste Interpreterzeile */
  32. extern    PRGZEILE    *ActLine;        /* aktuelle interpretierte Zeile */
  33. extern    char        *LinePos;        /* Zeilenposition der aktuellen Zeile*/
  34. extern    int        Steuer;                /* der aufrufenden Routine wird mit-    */
  35.                                     /* geteilt, um was es sich handelt.         */
  36. extern    char    ScanBuffer[ZEILENLAENGE]; /* Ergebnisbuffer des Scanners */
  37.  
  38. extern    VAR        *FirstVar;            /* Zeiger auf die erste Variable */
  39.  
  40.  
  41. /*    ShowLine
  42.     Zeile wieder zurückwandeln und ausgeben.
  43. */
  44. extern    TOKBEF        TokBefDesc[];
  45.  
  46. void
  47. ShowLine (FindZeile)
  48. PRGZEILE *FindZeile;
  49. {
  50. char    *Line;
  51.  
  52.     Line = FindZeile->Zeile;
  53.     if (*Line) {            /* Ist die Programmzeile leer? */
  54.       printf ("\n%03d %s ",
  55.                  FindZeile->LineNumber,
  56.                  TokBefDesc[(*Line-TOKMIN)&0xff].Befehl
  57.                  );
  58.        Line++;
  59.        if (*Line) printf ("%s",Line);
  60.     }        
  61.  
  62. }
  63.  
  64.  
  65. /* "IsVariable" sucht nach einer Variablen mit gleichem Namen.
  66.     Gibt es keine, wird ein NULL-Zeiger zurückgeliefert.
  67. */
  68.  
  69. VAR *
  70. IsVariable (Name)
  71. char    *Name;
  72. {
  73. register    VAR  *i;
  74.  
  75.   for (i = FirstVar;
  76.        i && (strcmp(Name,i->VarName) != 0);
  77.        i = i->NextVar);
  78.  
  79. return (i);
  80. }
  81.  
  82. /* "SetVar" sieht nach, ob es die Varible schon gibt.
  83.    Wenn ja, wird ihr Wert verändert. Ansonsten wird
  84.    eine neue Variable angelegt.
  85. */
  86.  
  87. int
  88. SetVar (Wert)
  89. VAR        *Wert;
  90. {
  91. VAR        *Variable;
  92. VAR        Value;
  93.  
  94.         /* Lies den zu setzenden Wert ein */
  95.     if (CalcExpression (&Value) == ERROR)
  96.         return (ERROR);
  97.  
  98.         /* Gibt es eine Variable mit dem Namen, dann setze Zeiger */
  99.     if ((Variable = IsVariable (Wert->VarName)) != NULL)
  100.         {
  101.         SetValue (&Variable->VarWert,&Value.VarWert,Value.VarType,0);
  102.         return (OK);
  103.         }
  104.  
  105.     if ((Variable = malloc(sizeof (VAR))) == NULL)
  106.         {
  107.         fatal_error("\n<setvar>  Kein Speicherplatz mehr für die Variable! ");
  108.         return (FALSE);
  109.         }
  110.  
  111.     strcpy (Variable->VarName,Wert->VarName);    /* Variablennamen eintragen */
  112.     Variable->VarType = Value.VarType;                      /* Variablen-Type eintragen  */
  113.  
  114.     SetValue (&Variable->VarWert,&Value.VarWert,Value.VarType,1);
  115.     Variable->NextVar = FirstVar;
  116.     FirstVar = Variable;        /* Variable oben einfügen  */
  117.  
  118. return (OK);
  119. }
  120.  
  121. /*    Einlesen eines Ausdrucks von der gerade aktuellen Eingabeposition
  122.     ab.
  123. */
  124.  
  125. void
  126. ReadValue (Wert)
  127. VAR    *Wert;
  128. {
  129.  
  130.     Scan ();                        /* Nächster Ausdruck von Eingabezeile */
  131.  
  132.     switch (Steuer) {
  133.       case ZIFFER:
  134.         Wert->VarType = FIXNUM;
  135.         Wert->VarWert.variable.integer = atoi (ScanBuffer);
  136.       break;
  137.       case FLONUM:
  138.         Wert->VarType = FLONUM;
  139.         Wert->VarWert.variable.Flotype = atof (ScanBuffer);
  140.       break;
  141.       case STRING:
  142.         Wert->VarType = STRING;
  143.         if(Wert->VarWert.dim1 < strlen(ScanBuffer))
  144.         if( (Wert->VarWert.variable.text = realloc(Wert->VarWert.variable.text,strlen(ScanBuffer)+1)) == NULL )
  145.             {
  146.             printf("\n <ReadValue>  Nicht genügend Speicherplatz !");
  147.             break;
  148.             }
  149.         strcpy(Wert->VarWert.variable.text,ScanBuffer);
  150.         Wert->VarWert.dim1 = strlen(ScanBuffer);
  151.         break;
  152.       case ALPHA:
  153.         printf ("\n Variablenzuweisung noch nicht implementiert! ");
  154.         break;
  155.       case SONDER:
  156.         if (*ScanBuffer == '(') {
  157.  
  158.         }
  159.         else
  160.           printf ("\nUngültiges Zeichen in Ausdruck gefunden! ");
  161.     }
  162.  
  163. }
  164.  
  165.  
  166. /* SetValue Setze den Wert der Variable */
  167. void
  168. SetValue (NewVar,Wert,Type,neu)
  169. VARDEF    *NewVar,*Wert;
  170. unsigned char   Type;
  171. int neu;
  172. {
  173.     switch (Type) {
  174.       case    FIXNUM:
  175.         NewVar->variable.integer = Wert->variable.integer;
  176.       break;
  177.       case    FLONUM:
  178.         NewVar->variable.Flotype = Wert->variable.Flotype;
  179.       break;
  180.       case    ALPHA:
  181.         NewVar->variable.zeichen = Wert->variable.zeichen;
  182.       break;
  183.       case  STRING:
  184.         if (neu)
  185.         {
  186.         if( (NewVar->variable.text = malloc(strlen(Wert->variable.text)+1)) == NULL )
  187.           {
  188.           fatal_error("\n <ReadValue>  Nicht genügend Speicherplatz !");
  189.           break;
  190.           }
  191.         NewVar->dim1 = strlen(Wert->variable.text);
  192.         }
  193.  
  194.         else
  195.         {
  196.         if(NewVar->dim1 != strlen(Wert->variable.text))
  197.            {
  198.            if( (NewVar->variable.text = realloc(NewVar->variable.text,strlen(Wert->variable.text)+1)) == NULL )
  199.             {
  200.             fatal_error("\n <ReadValue>  Nicht genügend Speicherplatz !");
  201.             break;
  202.             }
  203.            }
  204.         }
  205.  
  206.         strcpy (NewVar->variable.text,Wert->variable.text);
  207.         NewVar->dim1 = strlen(Wert->variable.text);
  208.         free(Wert->variable.text);
  209.       break;
  210.       default:
  211.         printf ("\n Variablenzuweisung für diesen Typ nicht implementiert! ");
  212.       break;
  213.     }
  214.  
  215. }
  216.  
  217. void
  218. GetValue (Var,Wert,Type)
  219. VARDEF    *Var,*Wert;
  220. unsigned char    Type;
  221. {
  222.  
  223.     switch (Type) {
  224.       case  FIXNUM:
  225.         Wert->variable.integer = Var->variable.integer;
  226.         break;
  227.       case  FLONUM:
  228.         Wert->variable.Flotype = Var->variable.Flotype;
  229.         break;
  230.       case    ALPHA:
  231.         Wert->variable.zeichen = Var->variable.zeichen;
  232.         break;
  233.       case    STRING:
  234.         Wert->variable.text=Var->variable.text;
  235.         break;
  236.       default:
  237.         printf ("\n Variablenzuweisung für diesen Typ nicht implementiert! ");
  238.         break;
  239.     }
  240.  
  241. }
  242.  
  243.  
  244.  
  245. /*static*/ EXPDEF    *BotStack;
  246. static EXPDEF    *TopStack;
  247. static unsigned char     OpStckBot[OPSTACK];
  248. static unsigned char    *ActOp;
  249.  
  250. /*    CmpVar vergleicht zwei Variablen auf Größer, Kleiner oder Gleich */
  251.  
  252. int
  253. CmpVar ()
  254. {
  255.     int ret;
  256.     ActOp = OpStckBot;    /* Zeiger auf bottom OpStckBot stack */
  257.     if ( (BotStack = TopStack = malloc (EXPSTACK * sizeof(EXPDEF))) == NULL )
  258.         {
  259.         fatal_error("\n <CmpVar>  Nicht genügend Speicherplatz !");
  260.         return(FALSE);
  261.         }
  262.  
  263.     Scan ();            /* Erstes Argument lesen */
  264.     if ((Steuer == ZIFFER) || (Steuer == ALPHA))
  265.       PushExp ();
  266.     else {
  267.       serror ("Ungültiger 1. Ausdruck gefunden! ");
  268.       free(BotStack);       /* Speicher freigeben */
  269.       return (FALSE);    /* Bedingung fehlerhaft */
  270.     }
  271.  
  272.     Scan();                /* Vergleichsoperator lesen */
  273.     if (Steuer == SONDER)
  274.       ReadComp ();
  275.     else {
  276.       serror ("Vergleichsoperator erwartet! ");
  277.       free(BotStack);       /* Speicher freigeben */
  278.       return (FALSE);    /* Bedingung fehlerhaft */
  279.     }
  280.  
  281.     Scan();                  /* Zweites Argument lesen */
  282.     if ((Steuer == ZIFFER) || (Steuer == ALPHA))
  283.       PushExp ();
  284.     else {
  285.       serror ("Ungültiger 2. Ausdruck gefunden! ");
  286.       free(BotStack);       /* Speicher freigeben */
  287.       return (FALSE);    /* Bedingung fehlerhaft */
  288.     }
  289.  
  290.     ret=Compare();
  291.     free(BotStack);       /* Speicher freigeben */
  292.  
  293.     return (ret);
  294. }
  295.  
  296. /* ReadComp: lies Vergleichsoperator ein
  297. */
  298.  
  299. void
  300. ReadComp ()
  301. {
  302.  
  303.       switch (*ScanBuffer) {
  304.         case    '/':
  305.           Scan ();
  306.           if (*ScanBuffer == '=')
  307.             *ActOp++ = UNGL;
  308.           else {
  309.             SkipChar ();
  310.           }
  311.         break;
  312.         case    '>':
  313.           Scan ();
  314.             if (*ScanBuffer == '=')
  315.               *ActOp++ = GRGL;
  316.             else {
  317.               SkipChar ();
  318.               *ActOp++ = GR;
  319.             }
  320.         break;
  321.         case    '<':
  322.           Scan ();
  323.             if (*ScanBuffer == '=')
  324.               *ActOp++ = KLGL;
  325.             else {
  326.               SkipChar ();
  327.               *ActOp++ = KL;
  328.             }
  329.         break;
  330.         case    '=':
  331.           *ActOp++ = GL;
  332.         break;
  333.         default:
  334.           serror ("Ungültiger Vergleichsoperator! ");
  335.         break;
  336.       }
  337. }
  338.  
  339. /*    Compare
  340.     Vergleiche die Ausdrücke auf dem Stack.
  341. */
  342.  
  343. int
  344. Compare ()
  345. {
  346. EXPDEF    *Var1,*Var2;
  347. int        Op;
  348.  
  349.         /* solange beide Stacks noch Werte besitzen, ... */
  350.     while ((TopStack != BotStack) && (ActOp != OpStckBot)) {
  351.         if ((Var2 = PopExp()) == NULL) {
  352.           break;
  353.         }
  354.         if ((Var1 = PopExp()) == NULL) {
  355.           break;
  356.         }
  357.         if (Var1->type == Var2->type) {
  358.           ActOp--;
  359.           Op = *ActOp;
  360.           switch (Op) {            /* hier wird endlich verglichen */
  361.             case    GL:
  362.               return ((Var1->val.wert == Var2->val.wert) ?
  363.                        TRUE : FALSE);
  364.             case    GRGL:
  365.               return ((Var1->val.wert >= Var2->val.wert) ?
  366.                        TRUE : FALSE);
  367.             case    GR:
  368.               return ((Var1->val.wert > Var2->val.wert) ?
  369.                        TRUE : FALSE);
  370.             case    KLGL:
  371.               return ((Var1->val.wert <= Var2->val.wert) ?
  372.                        TRUE : FALSE);
  373.             case    KL:
  374.               return ((Var1->val.wert < Var2->val.wert) ?
  375.                        TRUE : FALSE);
  376.             case    UNGL:
  377.               return ((Var1->val.wert != Var2->val.wert) ?
  378.                        TRUE : FALSE);
  379.           }
  380.         }
  381.     }
  382. return (TRUE);
  383. }
  384.  
  385. /* druckt eine Variable aus */
  386.  
  387. void
  388. PrintVar (Name)
  389. char    *Name;
  390. {
  391. VAR        *Variable;
  392.  
  393.  
  394.  
  395.         /* wenn es eine Variable mit dem gesuchten Namen gibt, merken! */
  396.     if ((Variable = IsVariable (Name)) != NULL)
  397.       {
  398.  
  399.  
  400.       switch (Variable->VarType)
  401.         {
  402.         case    FIXNUM:
  403.           printf ("%ld",Variable->VarWert.variable.integer);
  404.           break;
  405.         case    FLONUM:
  406.           printf ("%lf",Variable->VarWert.variable.Flotype);
  407.           break;
  408.         case    STRING:
  409.           printf ("%s",Variable->VarWert.variable.text);
  410.           break;
  411.         default:
  412.           printf ("\n Variablen dieses Typs können nicht gedruckt werden! ");
  413.           break;
  414.         }
  415.       }
  416.     else
  417.       {
  418.       char buffer[40];
  419.       sprintf (buffer,"Variable <%s> unbekannt! ",Name);
  420.       fatal_error (buffer);
  421.       }
  422. }
  423.  
  424.  
  425. /* monadische Vorzeichen merker */
  426. static    int    Monadneg = FALSE;
  427.  
  428. /*    CalcExpression: berechnet das Ergebnis eines Ausdrucks
  429. */
  430.  
  431. int
  432. CalcExpression (Result)
  433. VAR *Result;
  434. {
  435. VAR    *Variable;
  436.  
  437.     Scan ();                /* den ersten Ausdruck einlesen */
  438.  
  439.     if (Steuer == STRING)   /* String zuweisung             */
  440.         {
  441.         if( (Result->VarWert.variable.text = malloc(strlen(ScanBuffer)+1)) == NULL )
  442.             {
  443.             fatal_error("\n <CalcExpression>  Nicht genügend Speicherplatz !");
  444.             return(ERROR);
  445.             }
  446.         strcpy(Result->VarWert.variable.text,ScanBuffer);
  447.         Result->VarWert.dim1 = strlen(ScanBuffer);
  448.         Result->VarType = STRING;
  449.         return(OK);
  450.         }
  451.  
  452.     ActOp = OpStckBot;      /* Zeiger auf bottom OpStckBot stack */
  453.     if ( (BotStack = TopStack = malloc (EXPSTACK * sizeof(EXPDEF))) == NULL )
  454.         {
  455.         fatal_error("\n <CalcExpression>  Nicht genügend Speicherplatz !");
  456.         return(ERROR);
  457.         }
  458.  
  459.  
  460.     if (Steuer == EOLCHAR)
  461.       {
  462.       free (BotStack);                /* Speicher wieder freigeben */
  463.       return (ERROR);
  464.       }
  465.  
  466.     if ((Steuer == SONDER) && (*ScanBuffer == '-'))
  467.       Monadneg = TRUE;
  468.  
  469.         /* gesamten Rechenausdruck auf den Stack */
  470.     do
  471.       {
  472.       if ((Steuer == ZIFFER) || (Steuer == ALPHA) || (Steuer == FLONUM) )
  473.         PushExp ();
  474.       else
  475.         {
  476.         if (Steuer == SONDER)
  477.           {
  478.           if ((*ScanBuffer == '+') || (*ScanBuffer == '-') ||
  479.           (*ScanBuffer == '*') || (*ScanBuffer == '/'))
  480.         {
  481.             *ActOp = *ScanBuffer;
  482.             ActOp++;
  483.         }
  484.           else
  485.         {
  486.         serror ("Ungültiger Operand gefunden! ");
  487.         free (BotStack);                /* Speicher wieder freigeben */
  488.             return (ERROR);
  489.         }
  490.           }
  491.         else
  492.           {
  493.           serror ("Operand erwartet!");
  494.           free (BotStack);                /* Speicher wieder freigeben */
  495.           return (ERROR);
  496.           }
  497.         }
  498.           /* nächsten Ausdruck einlesen */
  499.       if (Scan () == UNEOL)
  500.         {
  501.         fatal_error (" Unerwartetes Zeilenende! ");
  502.         free (BotStack);                /* Speicher wieder freigeben */
  503.         return (ERROR);
  504.         }
  505.  
  506.       }  while (Steuer != EOLCHAR) ;
  507.  
  508.     CalcResult ();            /* berechnet das Ergebnis und hinterläßt */
  509.                             /* es auf dem Stack                     */
  510.  
  511.     SetResultValue(Result);
  512.     if(IntError)
  513.         {
  514.         IntError=FALSE;
  515.         free (BotStack);        /* Speicher wieder freigeben */
  516.         return(ERROR);
  517.         }
  518.     else
  519.         free (BotStack);        /* Speicher wieder freigeben */
  520.  
  521. return (OK);
  522. }
  523.  
  524. /* SetResultValue: wandelt das Berechnungsergebnis in die Variablenstruktur
  525. */
  526.  
  527. void
  528. SetResultValue (Result)
  529. VAR *Result;
  530. {
  531.  
  532.     switch (BotStack->type) {
  533.       case  ZAHL:           /* Zahlen in interger */
  534.         Result->VarWert.variable.integer = BotStack->val.wert;
  535.         Result->VarType = FIXNUM;
  536.         break;
  537.       case  DEZ:           /* Zahlen in Fließkommadarstellung */
  538.         Result->VarWert.variable.Flotype = BotStack->val.dez;
  539.         Result->VarType = FLONUM;
  540.         break;
  541.       case  TEXT:
  542.         fatal_error("\n <SetResultValue> String nicht implementiert !");
  543.         break;
  544.       case    FELD:
  545.         fatal_error ("Arrayzuweisung noch nicht implementiert! ");
  546.         break;
  547.       default:
  548.         fatal_error ("Unbekannter Zahlentyp gefunden! ");
  549.         break;
  550.     }
  551. }
  552.  
  553.  
  554. /*    PushExp
  555.     welche in ScanBuffer steht auf Stack ablegen.
  556. */
  557. void
  558. PushExp ()
  559. {
  560. VAR    *Variable;
  561.  
  562.       switch (Steuer)
  563.         {
  564.  
  565.         case  FLONUM:
  566.           TopStack->type = DEZ;
  567.           TopStack->val.dez = atof (ScanBuffer);
  568.           if (Monadneg)
  569.         {
  570.         TopStack->val.dez *= -1;
  571.         Monadneg = FALSE;
  572.         }
  573.           break;
  574.  
  575.         case  ZIFFER:
  576.           TopStack->type = ZAHL;
  577.           TopStack->val.wert = atol (ScanBuffer);
  578.           if (Monadneg)
  579.         {
  580.             TopStack->val.wert *= -1;
  581.             Monadneg = FALSE;
  582.         }
  583.           break;
  584.  
  585.         case  ALPHA:
  586. /* Wenn es die gesuchte Variable gibt, Zeiger drauf und merken! */
  587.           if ((Variable = IsVariable (ScanBuffer)) != NULL)
  588.         {
  589.         switch (Variable->VarType)
  590.           {
  591.           case ZIFFER:
  592.                 TopStack->type = ZAHL;
  593.                 TopStack->val.wert = Variable->VarWert.variable.integer;
  594.             break;
  595.               case FLONUM:
  596.             TopStack->type = DEZ;
  597.             TopStack->val.dez = Variable->VarWert.variable.Flotype;
  598.             break;
  599.               default :
  600.                 serror ("Variablentyp für Operation nicht erlaubt! ");
  601.               break;
  602.           }
  603.         }
  604.           else
  605.             serror ("Variable nicht definiert! ");
  606.  
  607.           break;
  608.  
  609.         case        STRING:
  610.           serror ("Keine Operation für den Typ STRING vorhanden! ");
  611.           break;
  612.  
  613.         default:
  614.           serror ("Keine Operation für diesen Typ vorhanden! ");
  615.           break;
  616.         }
  617.       TopStack++;        /* Stackpointer an die nächste Position */
  618. }
  619.  
  620.  
  621. /* CalcResult: berechnet das Ergebnis eines Ausdrucks,
  622. der sich auf dem Stack befindet
  623. */
  624. void
  625. CalcResult ()
  626. {
  627. EXPDEF    *Var1,*Var2,Result;
  628. int        Op;
  629.  
  630. /* solange beide Stacks noch Werte besitzen, ... */
  631.     while ((TopStack != BotStack) && (ActOp != OpStckBot)) {
  632.         if ((Var1 = PopExp()) == NULL) {
  633.           break;
  634.         }
  635.         if ((Var2 = PopExp()) == NULL) {
  636.           break;
  637.         }
  638.  
  639.  
  640.         if (Var2->type == ZAHL && (Var1->type == ZAHL || Var1->type == DEZ))
  641.           {
  642.           ActOp--;
  643.           Op = *ActOp;        /* OpStckBot vom Stack holen */
  644.           switch (Op)
  645.             {
  646.  
  647.             case        '+':
  648.               if(Var1->type == ZAHL)
  649.             Result.val.wert = Var2->val.wert + Var1->val.wert;
  650.               else
  651.             Result.val.wert = Var1->val.dez + Var2->val.wert;
  652.               break;
  653.             case        '-':
  654.               if(Var1->type == ZAHL)
  655.             Result.val.wert = Var2->val.wert - Var1->val.wert;
  656.               else
  657.             Result.val.wert = Var1->val.dez - Var2->val.wert;
  658.               break;
  659.             case        '*':
  660.               if(Var1->type == ZAHL)
  661.             Result.val.wert = Var2->val.wert * Var1->val.wert;
  662.               else
  663.             Result.val.wert = Var1->val.dez * Var2->val.wert;
  664.               break;
  665.             case        '/':
  666.               if(Var1->type == ZAHL)
  667.             Result.val.wert = Var2->val.wert / Var1->val.wert;
  668.               else
  669.             Result.val.wert = Var1->val.dez / Var2->val.wert;
  670.               break;
  671.             }
  672.           }
  673.         else
  674.             {
  675.             if (Var2->type == DEZ && (Var1->type == ZAHL || Var1->type == DEZ))
  676.                 {
  677.                 ActOp--;
  678.                 Op = *ActOp;          /* OpStckBot vom Stack holen */
  679.                 switch (Op)
  680.                     {
  681.                     case        '+':
  682.                         if(Var1->type == ZAHL)
  683.                           Result.val.dez = Var2->val.dez + Var1->val.wert;
  684.                         else
  685.                           Result.val.dez = Var1->val.dez + Var2->val.dez;
  686.                         break;
  687.                     case        '-':
  688.                         if(Var1->type == ZAHL)
  689.                           Result.val.dez = Var2->val.dez - Var1->val.wert;
  690.                         else
  691.                           Result.val.dez = Var1->val.dez - Var2->val.dez;
  692.                         break;
  693.                     case        '*':
  694.                         if(Var1->type == ZAHL)
  695.                           Result.val.dez = Var2->val.dez * Var1->val.wert;
  696.                         else
  697.                           Result.val.dez = Var1->val.dez * Var2->val.dez;
  698.                         break;
  699.                     case        '/':
  700.                         if(Var1->type == ZAHL)
  701.                           Result.val.dez = Var2->val.dez / Var1->val.wert;
  702.                         else
  703.                           Result.val.dez = Var1->val.dez / Var2->val.dez;
  704.                         break;
  705.                     }
  706.                 }
  707.             else
  708.                 serror ("Operation für Variablentyp nicht implementiert! ");
  709.             }
  710.  
  711.         TopStack->type  = Var2->type;
  712.  
  713.         if(Var2->type == ZAHL)
  714.             TopStack->val.wert = Result.val.wert;
  715.  
  716.         if(Var2->type == DEZ)
  717.             TopStack->val.dez = Result.val.dez;
  718.  
  719.         TopStack ++;
  720.  
  721.     }
  722.  
  723. }
  724.  
  725.  
  726. /*    PopExp
  727.     Holt einen Ausdruck vom Variablenstack
  728. */
  729.  
  730. EXPDEF *
  731. PopExp ()
  732. {
  733.   if (TopStack-- != BotStack)
  734.     return (TopStack);
  735.   else
  736.     return (NULL);
  737. }
  738.  
  739. /* ClearProg: den Speicherplatz, der durch das Programm
  740. belegt ist, freigeben
  741. */
  742.  
  743. void
  744. ClearProg ()
  745. {
  746. PRGZEILE    *Memory;
  747.  
  748.     ActLine = FirstLine;        /* Zeiger auf erste Programmzeile */
  749.     while (ActLine) {
  750.       Memory = ActLine;            /* wird gleich benötigt */
  751.       ActLine = ActLine->NextZeile;    /* das ist die nächste Zeile */
  752.       free (Memory);            /* Speicherplatz freigeben */
  753.     }
  754.  
  755.     FirstLine = ActLine = NULL;     /* ProgZeile-Zeiger zurücksetzen */
  756.  
  757. }
  758.  
  759.  
  760. /* Ende des Files INTUTIL.C */
  761.