home *** CD-ROM | disk | FTP | other *** search
/ Chestnut's Multimedia Mania / MM_MANIA.ISO / graphics / povsrc20 / express.c < prev    next >
C/C++ Source or Header  |  1993-07-08  |  13KB  |  553 lines

  1. /****************************************************************************
  2. *                express.c
  3. *
  4. *  This module implements an expression parser for the floats, vectors and
  5. *  colours in scene description files.
  6. *
  7. *  from Persistence of Vision Raytracer
  8. *  Copyright 1993 Persistence of Vision Team
  9. *---------------------------------------------------------------------------
  10. *  NOTICE: This source code file is provided so that users may experiment
  11. *  with enhancements to POV-Ray and to port the software to platforms other 
  12. *  than those supported by the POV-Ray Team.  There are strict rules under
  13. *  which you are permitted to use this file.  The rules are in the file
  14. *  named POVLEGAL.DOC which should be distributed with this file. If 
  15. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  16. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  17. *  Forum.  The latest version of POV-Ray may be found there as well.
  18. *
  19. * This program is based on the popular DKB raytracer version 2.12.
  20. * DKBTrace was originally written by David K. Buck.
  21. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  22. *
  23. *****************************************************************************/
  24.  
  25. #include "frame.h"
  26. #include "vector.h"
  27. #include "povproto.h"
  28. #include "parse.h"
  29.  
  30. /* This file implements a simple recursive-descent parser for reading the
  31. input file.  */
  32.  
  33. extern DBL Max_Trace_Level;
  34. extern char VerboseFormat;
  35. extern unsigned int Options;
  36. extern char Stat_File_Name[FILE_NAME_LENGTH];
  37.  
  38. extern struct Reserved_Word_Struct Reserved_Words [];
  39. extern DBL Antialias_Threshold;
  40.  
  41. extern struct Token_Struct Token;
  42. extern char String[MAX_STRING_INDEX];
  43.  
  44. extern COLOUR_MAP_ENTRY *Build_Entries;
  45. extern FRAME Frame;
  46. extern DBL Clock_Value;
  47. extern char **Symbol_Table;
  48. extern int Max_Intersections;
  49. extern DBL Language_Version;
  50. extern METHODS Csg_Height_Field_Methods;
  51.  
  52. static DBL Parse_Float_Factor PARAMS((void));
  53. static DBL Parse_Float_Term PARAMS((void));
  54. static void Parse_Vector_Factor PARAMS((VECTOR *Vector));
  55. static void Parse_Vector_Term PARAMS((VECTOR *Vector));
  56.  
  57. extern struct Constant_Struct Constants[MAX_CONSTANTS];
  58.  
  59. extern int Number_Of_Constants;
  60. extern int Previous;
  61. extern short Have_Vector;
  62. extern short Not_In_Default;
  63.  
  64. extern TOKEN *Brace_Stack;
  65. extern int Brace_Index;
  66.  
  67. static DBL Parse_Float_Factor ()
  68.   {
  69.    DBL Local_Float;
  70.  
  71.    EXPECT
  72.      CASE (FLOAT_TOKEN)
  73.        Local_Float = Token.Token_Float;
  74.        EXIT
  75.      END_CASE
  76.  
  77.      CASE (FLOAT_ID_TOKEN)
  78.        Local_Float = *((DBL *) Token.Constant_Data);
  79.        EXIT
  80.      END_CASE
  81.  
  82.      CASE (CLOCK_TOKEN)
  83.        Local_Float = Clock_Value;
  84.        EXIT
  85.      END_CASE
  86.  
  87.      CASE (PLUS_TOKEN)
  88.      END_CASE
  89.  
  90.      CASE (DASH_TOKEN)
  91.        Local_Float = - Parse_Float_Factor();
  92.        EXIT
  93.      END_CASE
  94.  
  95.      CASE (LEFT_PAREN_TOKEN)
  96.        Local_Float = Parse_Float();
  97.        GET(RIGHT_PAREN_TOKEN);
  98.        EXIT
  99.      END_CASE
  100.  
  101.      CASE (VERSION_TOKEN)
  102.        Local_Float = Language_Version;
  103.        EXIT
  104.      END_CASE
  105.  
  106.      OTHERWISE
  107.        Parse_Error_Str ("float factor");
  108.      END_CASE
  109.    END_EXPECT
  110.  
  111.    return (Local_Float);
  112.   }
  113.  
  114. static DBL Parse_Float_Term ()
  115.   {
  116.    DBL Local_Float;
  117.  
  118.    Local_Float = Parse_Float_Factor();
  119.  
  120.    EXPECT
  121.      CASE (STAR_TOKEN)
  122.        Local_Float *= Parse_Float_Factor();
  123.      END_CASE
  124.  
  125.      CASE (SLASH_TOKEN)
  126.        Local_Float /= Parse_Float_Factor();
  127.      END_CASE
  128.  
  129.      OTHERWISE
  130.        UNGET
  131.        EXIT
  132.      END_CASE
  133.    END_EXPECT
  134.  
  135.    return (Local_Float);
  136.   }
  137.  
  138. DBL Parse_Float ()
  139.   {
  140.    DBL Local_Float;
  141.  
  142.    if (Language_Version < 1.5)
  143.      return(Parse_Float_Factor());
  144.  
  145.    Local_Float = Parse_Float_Term();
  146.  
  147.    EXPECT
  148.      CASE (PLUS_TOKEN)
  149.        Local_Float += Parse_Float_Term();
  150.      END_CASE
  151.  
  152.      CASE (DASH_TOKEN)
  153.        Local_Float -= Parse_Float_Term();
  154.      END_CASE
  155.  
  156.      OTHERWISE
  157.        UNGET
  158.        EXIT
  159.      END_CASE
  160.    END_EXPECT
  161.  
  162.    return (Local_Float);
  163.   }
  164.  
  165. static void Parse_Vector_Factor (Vector)
  166.   VECTOR *Vector;
  167.   {
  168.  
  169.    EXPECT
  170.      CASE (LEFT_ANGLE_TOKEN)
  171.        Have_Vector = TRUE;
  172.        Vector -> x = Parse_Float();   Parse_Comma();
  173.        Vector -> y = Parse_Float();   Parse_Comma();
  174.        Vector -> z = Parse_Float();
  175.        GET (RIGHT_ANGLE_TOKEN);
  176.        EXIT
  177.      END_CASE
  178.  
  179.      CASE (VECTOR_ID_TOKEN)
  180.        Have_Vector = TRUE;
  181.        *Vector = *((VECTOR *) Token.Constant_Data);
  182.        EXIT
  183.      END_CASE
  184.  
  185.      CASE (X_TOKEN)
  186.        Have_Vector = TRUE;
  187.        Make_Vector(Vector,1.0,0.0,0.0)
  188.        EXIT
  189.      END_CASE
  190.  
  191.      CASE (Y_TOKEN)
  192.        Have_Vector = TRUE;
  193.        Make_Vector(Vector,0.0,1.0,0.0)
  194.        EXIT
  195.      END_CASE
  196.  
  197.      CASE (Z_TOKEN)
  198.        Have_Vector = TRUE;
  199.        Make_Vector(Vector,0.0,0.0,1.0)
  200.        EXIT
  201.      END_CASE
  202.  
  203.      CASE (PLUS_TOKEN)              /* uniary plus */
  204.      END_CASE
  205.  
  206.      CASE (DASH_TOKEN)              /* uniary minus */
  207.        Parse_Vector_Factor(Vector);
  208.        Vector -> x *= -1.0;
  209.        Vector -> y *= -1.0;
  210.        Vector -> z *= -1.0;
  211.        EXIT
  212.      END_CASE
  213.  
  214.      CASE (LEFT_PAREN_TOKEN)
  215.        Parse_Vector_Float(Vector);
  216.        GET(RIGHT_PAREN_TOKEN);
  217.        EXIT
  218.      END_CASE
  219.  
  220.      CASE4 (FLOAT_TOKEN, FLOAT_ID_TOKEN, CLOCK_TOKEN, VERSION_TOKEN)
  221.        UNGET
  222.        (Vector->x) =
  223.        (Vector->y) =
  224.        (Vector->z) = Parse_Float_Factor ();
  225.        EXIT
  226.      END_CASE
  227.  
  228.      OTHERWISE
  229.        Parse_Error_Str ("vector factor");
  230.      END_CASE
  231.    END_EXPECT
  232.  
  233.   }
  234.  
  235. static void Parse_Vector_Term (Vector)
  236.   VECTOR *Vector;
  237.   {
  238.    VECTOR Local_Vector;
  239.  
  240.    Parse_Vector_Factor(Vector);
  241.  
  242.    EXPECT
  243.      CASE (STAR_TOKEN)
  244.        Parse_Vector_Factor(&Local_Vector);
  245.        Vector->x *= Local_Vector.x;
  246.        Vector->y *= Local_Vector.y;
  247.        Vector->z *= Local_Vector.z;
  248.      END_CASE
  249.  
  250.      CASE (SLASH_TOKEN)
  251.        Parse_Vector_Factor(&Local_Vector);
  252.        Vector->x /= Local_Vector.x;
  253.        Vector->y /= Local_Vector.y;
  254.        Vector->z /= Local_Vector.z;
  255.      END_CASE
  256.  
  257.      OTHERWISE
  258.        UNGET
  259.        EXIT
  260.      END_CASE
  261.    END_EXPECT
  262.  
  263.   }
  264.  
  265. void Parse_Vector_Float (Vector)
  266.   VECTOR *Vector;
  267.   {
  268.    VECTOR Local_Vector;
  269.  
  270.    Parse_Vector_Term(Vector);
  271.  
  272.    EXPECT
  273.      CASE (PLUS_TOKEN)
  274.        Parse_Vector_Term(&Local_Vector);
  275.        Vector->x += Local_Vector.x;
  276.        Vector->y += Local_Vector.y;
  277.        Vector->z += Local_Vector.z;
  278.      END_CASE
  279.  
  280.      CASE (DASH_TOKEN)
  281.        Parse_Vector_Term(&Local_Vector);
  282.        Vector->x -= Local_Vector.x;
  283.        Vector->y -= Local_Vector.y;
  284.        Vector->z -= Local_Vector.z;
  285.      END_CASE
  286.  
  287.      OTHERWISE
  288.        UNGET
  289.        EXIT
  290.      END_CASE
  291.    END_EXPECT
  292.  
  293.   }
  294.  
  295. void Parse_Scale_Vector (Vector)
  296.   VECTOR *Vector;
  297.   {
  298.    Parse_Vector_Float(Vector);
  299.  
  300.    if (Vector->x == 0.0)
  301.     {
  302.      Vector->x = 1.0;
  303.      Warn("Illegal Value: Scale X by 0.0. Changed to 1.0\n",0.0);
  304.     }
  305.    if (Vector->y == 0.0)
  306.     {
  307.      Vector->y = 1.0;
  308.      Warn("Illegal Value: Scale Y by 0.0. Changed to 1.0\n",0.0);
  309.     }
  310.    if (Vector->z == 0.0)
  311.     {
  312.      Vector->z = 1.0;
  313.      Warn("Illegal Value: Scale Z by 0.0. Changed to 1.0\n",0.0);
  314.     }
  315.   }
  316.  
  317. void Parse_Vector (Vector)
  318.   VECTOR *Vector;
  319.   {
  320.    Have_Vector = FALSE;
  321.  
  322.    if (Language_Version < 1.5)
  323.      {
  324.       Parse_Vector_Factor(Vector);
  325.      }
  326.    else
  327.      {
  328.       Parse_Vector_Float (Vector);
  329.       if (!Have_Vector)
  330.          Error ("Vector expected but float only expression found");
  331.      }
  332.   }
  333.  
  334. void Parse_Colour (Colour)
  335.   COLOUR *Colour;
  336.   {
  337.    EXPECT
  338.      CASE (COLOUR_ID_TOKEN)
  339.        *Colour = *((COLOUR *) Token.Constant_Data);
  340.        EXIT
  341.      END_CASE
  342.  
  343.      CASE (RGB_TOKEN)
  344.        GET (LEFT_ANGLE_TOKEN);
  345.        (Colour -> Red)   = Parse_Float();    Parse_Comma();
  346.        (Colour -> Green) = Parse_Float();    Parse_Comma();
  347.        (Colour -> Blue)  = Parse_Float();
  348.        (Colour -> Filter) = 0.0;
  349.        GET (RIGHT_ANGLE_TOKEN);
  350.        EXIT
  351.      END_CASE
  352.  
  353.      CASE (RGBF_TOKEN)
  354.        GET (LEFT_ANGLE_TOKEN);
  355.        (Colour -> Red)   = Parse_Float();    Parse_Comma();
  356.        (Colour -> Green) = Parse_Float();    Parse_Comma();
  357.        (Colour -> Blue)  = Parse_Float();    Parse_Comma();
  358.        (Colour -> Filter) = Parse_Float();
  359.        GET (RIGHT_ANGLE_TOKEN);
  360.        EXIT
  361.      END_CASE
  362.  
  363.      OTHERWISE
  364.        Make_Colour (Colour, 0.0, 0.0, 0.0);
  365.        UNGET
  366.        EXIT
  367.      END_CASE
  368.    END_EXPECT
  369.  
  370.    EXPECT
  371.      CASE (COLOUR_ID_TOKEN)
  372.        *Colour = *((COLOUR *) Token.Constant_Data);
  373.        Warn("Previous color overwritten.",1.5);
  374.      END_CASE
  375.  
  376.      CASE (RED_TOKEN)
  377.        (Colour -> Red) = Parse_Float();
  378.      END_CASE
  379.  
  380.      CASE (GREEN_TOKEN)
  381.        (Colour -> Green) = Parse_Float();
  382.      END_CASE
  383.  
  384.      CASE (BLUE_TOKEN)
  385.        (Colour -> Blue) = Parse_Float();
  386.      END_CASE
  387.  
  388.      CASE (ALPHA_TOKEN)
  389.        Warn("Keyword ALPHA discontinued.  Use FILTER instead.",1.55);
  390.        
  391.      CASE (FILTER_TOKEN)
  392.        (Colour -> Filter) = Parse_Float();
  393.      END_CASE
  394.  
  395.      OTHERWISE
  396.        UNGET
  397.        EXIT
  398.      END_CASE
  399.    END_EXPECT
  400.   }
  401.  
  402. COLOUR_MAP *Parse_Colour_Map ()
  403.   {
  404.    COLOUR_MAP *New;
  405.    short Flag;
  406.    int i,j,c,p;
  407.  
  408.    Parse_Begin ();
  409.  
  410.    EXPECT
  411.      CASE (COLOUR_MAP_ID_TOKEN)
  412.        New = Copy_Colour_Map ((COLOUR_MAP *) Token.Constant_Data);
  413.        EXIT
  414.      END_CASE
  415.  
  416.      OTHERWISE
  417.        UNGET
  418.        if (Build_Entries == NULL)
  419.          Build_Entries = Create_CMap_Entries(MAX_COLOUR_MAP_ENTRIES);
  420.        i = 0;
  421.        j = 1;
  422.        Flag = FALSE;
  423.  
  424.        EXPECT
  425.          CASE (LEFT_SQUARE_TOKEN)
  426.            Build_Entries[i].value = Parse_Float();  Parse_Comma();
  427.  
  428.            EXPECT
  429.              CASE (COLOUR_TOKEN);
  430.                Parse_Colour (&(Build_Entries[i].Colour));
  431.                Flag |= (Build_Entries[i].Colour.Filter == 0.0);
  432.                i++;
  433.                j++;
  434.                EXIT
  435.              END_CASE
  436.              
  437.              OTHERWISE
  438.                UNGET
  439.                Build_Entries[j].value = Parse_Float();
  440.  
  441.                GET (COLOUR_TOKEN);
  442.                Parse_Colour (&(Build_Entries[i].Colour));
  443.                Flag |= (Build_Entries[i].Colour.Filter == 0.0);
  444.  
  445.                GET (COLOUR_TOKEN);
  446.                Parse_Colour (&(Build_Entries[j].Colour));
  447.                Flag |= (Build_Entries[j].Colour.Filter == 0.0);
  448.                i += 2;
  449.                j += 2;
  450.                EXIT
  451.              END_CASE
  452.            END_EXPECT
  453.              
  454.            if (j > MAX_COLOUR_MAP_ENTRIES)
  455.              Error ("Colour_Map too long");
  456.  
  457.            GET (RIGHT_SQUARE_TOKEN);
  458.          END_CASE
  459.  
  460.          OTHERWISE
  461.            UNGET
  462.            if (i < 1)
  463.              Error ("Must have at least one color in colour map");
  464.  
  465.            /* Eliminate duplicates */
  466.            for (c = 1, p = 0; c<i; c++)
  467.              {
  468.               if (memcmp(&(Build_Entries[p]),
  469.                          &(Build_Entries[c]),sizeof(COLOUR_MAP_ENTRY)) == 0)
  470.                 p--;
  471.  
  472.               Build_Entries[++p] = Build_Entries[c];
  473.              }
  474.            p++;
  475.            New = Create_Colour_Map ();
  476.            New->Number_Of_Entries = p;
  477.            New->Colour_Map_Entries = Copy_CMap_Entries (Build_Entries,p);
  478.            New->Transparency_Flag = Flag;
  479.            EXIT
  480.          END_CASE
  481.        END_EXPECT
  482.        EXIT
  483.      END_CASE
  484.    END_EXPECT
  485.  
  486.    Parse_End ();
  487.  
  488.    return (New);
  489.   }
  490.  
  491. COLOUR_MAP *Parse_Colour_List (MinCount)
  492.   int MinCount;
  493.   {
  494.    COLOUR_MAP *New;
  495.    short Flag;
  496.    int i;
  497.  
  498.    if (Build_Entries == NULL)
  499.       Build_Entries = Create_CMap_Entries(MAX_COLOUR_MAP_ENTRIES);
  500.    i = 0;
  501.    Flag = FALSE;
  502.  
  503.    EXPECT
  504.      CASE (COLOUR_TOKEN);
  505.        Parse_Colour (&(Build_Entries[i].Colour));
  506.        Build_Entries[i].value = (DBL)i;
  507.        Flag |= (Build_Entries[i].Colour.Filter == 0.0);
  508.        i++;
  509.      END_CASE
  510.              
  511.      OTHERWISE
  512.        UNGET
  513.        EXIT
  514.      END_CASE
  515.    END_EXPECT
  516.              
  517.    if (i > MAX_COLOUR_MAP_ENTRIES)
  518.       Error ("Too many colors");
  519.    
  520.    /* the follow code assumes MinCount of 2 or 3 */
  521.    
  522.    if (i < MinCount)
  523.      {
  524.       if (MinCount == 3)
  525.         {
  526.          Make_Colour(&(Build_Entries[2].Colour),1.0,0.0,0.0);
  527.          Build_Entries[2].value = 2.0;
  528.         }
  529.       if (i < 2)
  530.         {
  531.          Make_Colour(&(Build_Entries[1].Colour),0.0,1.0,0.0);
  532.          Build_Entries[1].value = 1.0;
  533.         }
  534.       if (i == 0)
  535.         {
  536.          Make_Colour(&(Build_Entries[0].Colour),0.0,0.0,1.0);
  537.          Build_Entries[0].value = 0.0;
  538.         }
  539.       i=MinCount;
  540.      }
  541.  
  542.    if (i == 0)
  543.       return (NULL);
  544.    
  545.    New = Create_Colour_Map ();
  546.    New->Number_Of_Entries = i;
  547.    New->Colour_Map_Entries = Copy_CMap_Entries (Build_Entries,i);
  548.    New->Transparency_Flag = Flag;
  549.  
  550.    return (New);
  551.   }
  552.  
  553.