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