home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff397.lzh / DKBTrace / DKBSource.LZH / parse.c < prev    next >
C/C++ Source or Header  |  1990-08-26  |  64KB  |  2,285 lines

  1. /*****************************************************************************
  2. *
  3. *                                    parse.c
  4. *
  5. *   from DKBTrace (c) 1990  David Buck
  6. *
  7. *  This module implements a parser for the scene description files.
  8. *
  9. * This software is freely distributable. The source and/or object code may be
  10. * copied or uploaded to communications services so long as this notice remains
  11. * at the top of each file.  If any changes are made to the program, you must
  12. * clearly indicate in the documentation and in the programs startup message
  13. * who it was who made the changes. The documentation should also describe what
  14. * those changes were. This software may not be included in whole or in
  15. * part into any commercial package without the express written consent of the
  16. * author.  It may, however, be included in other public domain or freely
  17. * distributed software so long as the proper credit for the software is given.
  18. *
  19. * This software is provided as is without any guarantees or warranty. Although
  20. * the author has attempted to find and correct any bugs in the software, he
  21. * is not responsible for any damage caused by the use of the software.  The
  22. * author is under no obligation to provide service, corrections, or upgrades
  23. * to this package.
  24. *
  25. * Despite all the legal stuff above, if you do find bugs, I would like to hear
  26. * about them.  Also, if you have any comments or questions, you may contact me
  27. * at the following address:
  28. *
  29. *     David Buck
  30. *     22C Sonnet Cres.
  31. *     Nepean Ontario
  32. *     Canada, K2H 8W7
  33. *
  34. *  I can also be reached on the following bulleton boards:
  35. *
  36. *     ATX              (613) 526-4141
  37. *     OMX              (613) 731-3419
  38. *     Mystic           (613) 731-0088 or (613) 731-6698
  39. *
  40. *  Fidonet:   1:163/109.9
  41. *  Internet:  David_Buck@Carleton.CA
  42. *
  43. *  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  44. *
  45. *     Lattice BBS                      (708) 916-1200
  46. *     The Information Exchange BBS     (708) 945-5575
  47. *     Stillwaters BBS                  (708) 403-2826
  48. *
  49. *****************************************************************************/
  50.  
  51. #include "frame.h"
  52. #include "vector.h"
  53. #include "dkbproto.h"
  54.  
  55. /* This file implements a simple recursive-descent parser for reading the
  56. input file.  */
  57.  
  58. extern FILE *Token_File;
  59. FRAME *Parsing_Frame_Ptr;
  60. char Current_File_Name[20];
  61.  
  62. extern METHODS Composite_Methods;
  63. extern METHODS Basic_Object_Methods;
  64. extern METHODS Sphere_Methods;
  65. extern METHODS Quadric_Methods;
  66. extern METHODS Viewpoint_Methods;
  67. extern METHODS Plane_Methods;
  68. extern METHODS Triangle_Methods;
  69. extern METHODS Smooth_Triangle_Methods;
  70. extern METHODS CSG_Union_Methods;
  71. extern METHODS CSG_Intersection_Methods;
  72.  
  73. extern struct Reserved_Word_Struct Reserved_Words [];
  74. extern DBL Antialias_Threshold;
  75.  
  76. struct Token_Struct Token;
  77.  
  78. #define MAX_CONSTANTS 100
  79. struct Constant_Struct Constants[MAX_CONSTANTS];
  80. int Number_Of_Constants;
  81. TEXTURE *Default_Texture;
  82. int Degenerate_Triangles;
  83.  
  84. /* Here we create out own little language for doing the parsing.  It
  85. makes the code easier to read. */
  86.  
  87. #define EXPECT { int Exit_Flag; Exit_Flag = FALSE; \
  88.  while (!Exit_Flag) {Get_Token();  switch (Token.Token_Id) {
  89. #define CASE(x) case x:
  90. #define CASE2(x, y) case x: case y:
  91. #define CASE3(x, y, z) case x: case y: case z:
  92. #define CASE4(w, x, y, z) case w: case x: case y: case z:
  93. #define CASE5(v, w, x, y, z) case v: case w: case x: case y: case z:
  94. #define END_CASE break;
  95. #define EXIT Exit_Flag = TRUE;
  96. #define OTHERWISE default:
  97. #define END_EXPECT } } }
  98. #define GET(x) Get_Token(); if (Token.Token_Id != x) Parse_Error (x)
  99. #define UNGET Unget_Token();
  100.  
  101. /* Parse the file into the given frame. */
  102. void Parse (File, Frame_Ptr)
  103.   FILE *File;
  104.   FRAME *Frame_Ptr;
  105.   {
  106.   Token_File = File;
  107.   Parsing_Frame_Ptr = Frame_Ptr;
  108.  
  109.   Degenerate_Triangles = FALSE;
  110.   Token_Init ();
  111.   Frame_Init ();
  112.   Parse_Frame ();
  113.   if (Degenerate_Triangles) {
  114.      printf ("Cannot continue due to degenerate triangles.\n");
  115.      exit(1);
  116.      }
  117.   }
  118.  
  119. void Token_Init ()
  120.   {
  121.   Token.Unget_Token = FALSE;
  122.   Token.End_Of_File = FALSE;
  123.   Number_Of_Constants = 0;
  124.   }
  125.  
  126. /* Read a token from the input file and store it in the Token variable.
  127. If the token is an INCLUDE token, then set the include file name and
  128. read another token. */
  129.  
  130. int Get_Token ()
  131.   {
  132.   char *str_ptr;
  133.   int Token_Id;
  134.  
  135.   if (Token.Unget_Token)
  136.     {
  137.     Token.Unget_Token = FALSE;
  138.     return (TRUE);
  139.     }
  140.  
  141.   if (Token.End_Of_File)
  142.     {
  143.     return (FALSE);
  144.     }
  145.   
  146.   if (fscanf (Token_File, "%d %d", &Token_Id, &Token.Token_Line_No)
  147.        != 2)
  148.     {
  149.     Token.End_Of_File = TRUE;
  150.     Token.Token_Id    = END_OF_FILE_TOKEN;
  151.     return (TRUE);
  152.     }
  153.  
  154.   Token.Token_Id = Token_Id;
  155.  
  156.   getc(Token_File);
  157.   if (fgets (Token.Token_String, FILE_NAME_LENGTH, Token_File) == NULL)
  158.     {
  159.     Token.End_Of_File = TRUE;
  160.     Token.Token_Id    = END_OF_FILE_TOKEN;
  161.     return (TRUE);
  162.     }
  163.  
  164.   if ((str_ptr = strchr(Token.Token_String, '\n')) != NULL)
  165.      *str_ptr = '\0';
  166.  
  167.   if (Token.Token_Id == FLOAT_TOKEN)
  168.     if (sscanf (Token.Token_String, DBL_FORMAT_STRING, &(Token.Token_Float)) != 1)
  169.       {
  170.       printf ("Premature end of file in token file\n");
  171.       printf ("Could not read float: %s\n", Token.Token_String);
  172.       Token.End_Of_File = TRUE;
  173.       Token.Token_Id    = END_OF_FILE_TOKEN;
  174.       return (TRUE);
  175.       }
  176.  
  177.   if (Token.Token_Id == INCLUDE_TOKEN) {
  178.      strcpy (Current_File_Name, Token.Token_String);
  179.      return (Get_Token());
  180.      }
  181.  
  182.   if (Token.Token_Id > LAST_TOKEN)
  183.     {
  184.     Token.Identifier_Number = (int) Token.Token_Id - (int) LAST_TOKEN;
  185.     Token.Token_Id = IDENTIFIER_TOKEN;
  186.     }
  187.  
  188.   return (TRUE);
  189.   }
  190.  
  191.  
  192. /* Mark that the token has been put back into the input stream.  The next
  193. call to Get_Token will return the last-read token instead of reading a
  194. new one from the file. */
  195.  
  196. void Unget_Token ()
  197.   {
  198.   Token.Unget_Token = TRUE;
  199.   }
  200.  
  201. /* Set up the fields in the frame to default values. */
  202. void Frame_Init ()
  203.   {
  204.   Default_Texture = Get_Texture();
  205.   Init_Viewpoint(&(Parsing_Frame_Ptr -> View_Point));
  206.   Parsing_Frame_Ptr -> Light_Sources = NULL;
  207.   Parsing_Frame_Ptr -> Objects = NULL;
  208.   Parsing_Frame_Ptr -> Atmosphere_IOR = 1.0;
  209.   Parsing_Frame_Ptr -> Antialias_Threshold = Antialias_Threshold;
  210.   Parsing_Frame_Ptr -> Fog_Distance = 0.0;
  211.   Make_Colour (&(Parsing_Frame_Ptr->Fog_Colour), 0.0, 0.0, 0.0);
  212.   }
  213.  
  214. /* Allocate and initialize a composite object. */
  215. COMPOSITE *Get_Composite_Object()
  216.   {
  217.   COMPOSITE *New_Composite;
  218.  
  219.   if ((New_Composite = (COMPOSITE *) malloc (sizeof (COMPOSITE)))
  220.         == NULL)
  221.     Error ("Cannot allocate object");
  222.  
  223.   New_Composite -> Objects = NULL;
  224.   New_Composite -> Next_Object = NULL;
  225.   New_Composite -> Next_Light_Source = NULL;
  226.   New_Composite -> Bounding_Shapes = NULL;
  227.   New_Composite -> Type = COMPOSITE_TYPE;
  228.   New_Composite -> Methods = &Composite_Methods;
  229.   return (New_Composite);
  230.   }
  231.  
  232. /* Allocate and initialize a sphere. */
  233. SPHERE *Get_Sphere_Shape()
  234.   {
  235.   SPHERE *New_Shape;
  236.  
  237.   if ((New_Shape = (SPHERE *) malloc (sizeof (SPHERE))) == NULL)
  238.     Error ("Cannot allocate shape");
  239.  
  240.   Make_Vector (&(New_Shape -> Center), 0.0, 0.0, 0.0);
  241.   New_Shape->Radius = 1.0;
  242.   New_Shape->Radius_Squared = 1.0;
  243.   New_Shape->Inverse_Radius = 1.0;
  244.   New_Shape -> Type = SPHERE_TYPE;
  245.   New_Shape -> Next_Object = NULL;
  246.   New_Shape -> Methods = &Sphere_Methods;
  247.   New_Shape -> VPCached = FALSE;
  248.   New_Shape -> Inverted = FALSE;
  249.   return (New_Shape);
  250.   }
  251.  
  252. /* Allocate and initialize a quadric surface. */
  253. QUADRIC *Get_Quadric_Shape()
  254.   {
  255.   QUADRIC *New_Shape;
  256.  
  257.   if ((New_Shape = (QUADRIC *) malloc (sizeof (QUADRIC))) == NULL)
  258.     Error ("Cannot allocate shape");
  259.  
  260.   Make_Vector (&(New_Shape -> Object_2_Terms), 1.0, 1.0, 1.0);
  261.   Make_Vector (&(New_Shape -> Object_Mixed_Terms), 0.0, 0.0, 0.0);
  262.   Make_Vector (&(New_Shape -> Object_Terms), 0.0, 0.0, 0.0);
  263.   New_Shape -> Object_Constant = 1.0;
  264.   New_Shape -> Object_VP_Constant = HUGE_VAL;
  265.   New_Shape -> Constant_Cached = FALSE;
  266.   New_Shape -> Non_Zero_Square_Term = FALSE;
  267.   New_Shape -> Type = QUADRIC_TYPE;
  268.   New_Shape -> Next_Object = NULL;
  269.   New_Shape -> Methods = &Quadric_Methods;
  270.   return (New_Shape);
  271.   }
  272.  
  273. /* Allocate and initialize a plane. */
  274. PLANE *Get_Plane_Shape()
  275.   {
  276.   PLANE *New_Shape;
  277.  
  278.   if ((New_Shape = (PLANE *) malloc (sizeof (PLANE))) == NULL)
  279.     Error ("Cannot allocate shape");
  280.  
  281.   Make_Vector (&(New_Shape -> Normal_Vector), 0.0, 1.0, 0.0);
  282.   New_Shape->Distance = 0.0;
  283.   New_Shape -> Type = PLANE_TYPE;
  284.   New_Shape -> Next_Object = NULL;
  285.   New_Shape -> Methods = &Plane_Methods;
  286.   New_Shape -> VPCached = 0;
  287.   return (New_Shape);
  288.   }
  289.  
  290. /* Allocate and initialize a triangle. */
  291. TRIANGLE *Get_Triangle_Shape()
  292.   {
  293.   TRIANGLE *New_Shape;
  294.  
  295.   if ((New_Shape = (TRIANGLE *) malloc (sizeof (TRIANGLE))) == NULL)
  296.     Error ("Cannot allocate shape");
  297.  
  298.   Make_Vector (&(New_Shape -> Normal_Vector), 0.0, 1.0, 0.0);
  299.   Make_Vector (&(New_Shape -> P1), 0.0, 0.0, 0.0);
  300.   Make_Vector (&(New_Shape -> P2), 1.0, 0.0, 0.0);
  301.   Make_Vector (&(New_Shape -> P3), 0.0, 1.0, 0.0);
  302.   New_Shape->Distance = 0.0;
  303.   New_Shape->Inverted = FALSE;
  304.   New_Shape -> Type = TRIANGLE_TYPE;
  305.   New_Shape -> Next_Object = NULL;
  306.   New_Shape -> Methods = &Triangle_Methods;
  307.   New_Shape -> VPCached = FALSE;
  308.   return (New_Shape);
  309.   }
  310.  
  311. /* Allocate and initialize a smooth triangle. */
  312. SMOOTH_TRIANGLE *Get_Smooth_Triangle_Shape()
  313.   {
  314.   SMOOTH_TRIANGLE *New_Shape;
  315.  
  316.   if ((New_Shape = (SMOOTH_TRIANGLE *) malloc (sizeof (SMOOTH_TRIANGLE))) == NULL)
  317.     Error ("Cannot allocate shape");
  318.  
  319.   Make_Vector (&(New_Shape -> Normal_Vector), 0.0, 1.0, 0.0);
  320.   Make_Vector (&(New_Shape -> P1), 0.0, 0.0, 0.0);
  321.   Make_Vector (&(New_Shape -> P2), 1.0, 0.0, 0.0);
  322.   Make_Vector (&(New_Shape -> P3), 0.0, 1.0, 0.0);
  323.   Make_Vector (&(New_Shape -> N1), 0.0, 1.0, 0.0);
  324.   Make_Vector (&(New_Shape -> DN12), 0.0, 1.0, 0.0);
  325.   Make_Vector (&(New_Shape -> DN13), 0.0, 1.0, 0.0);
  326.   New_Shape->Distance = 0.0;
  327.   New_Shape -> Type = SMOOTH_TRIANGLE_TYPE;
  328.   New_Shape->Inverted = FALSE;
  329.   New_Shape -> Next_Object = NULL;
  330.   New_Shape -> Methods = &Smooth_Triangle_Methods;
  331.   New_Shape -> VPCached = 0;
  332.   return (New_Shape);
  333.   }
  334.  
  335. CSG_SHAPE *Get_CSG_Shape()
  336.   {
  337.   CSG_SHAPE *New_Shape;
  338.  
  339.   if ((New_Shape = (CSG_SHAPE *) malloc (sizeof (CSG_SHAPE))) == NULL)
  340.     Error ("Cannot allocate shape");
  341.  
  342.   New_Shape -> Parent_Object = NULL;
  343.   New_Shape -> Next_Object = NULL;
  344.   New_Shape -> Shapes = NULL;
  345.   return (New_Shape);
  346.   }
  347.  
  348. CSG_SHAPE *Get_CSG_Union()
  349.   {
  350.   CSG_SHAPE *New_Shape;
  351.  
  352.   New_Shape = Get_CSG_Shape();
  353.   New_Shape -> Methods = &CSG_Union_Methods;
  354.   New_Shape -> Type = CSG_UNION_TYPE;
  355.   return (New_Shape);
  356.   }
  357.  
  358. CSG_SHAPE *Get_CSG_Intersection()
  359.   {
  360.   CSG_SHAPE *New_Shape;
  361.  
  362.   New_Shape = Get_CSG_Shape();
  363.   New_Shape -> Methods = &CSG_Intersection_Methods;
  364.   New_Shape -> Type = CSG_INTERSECTION_TYPE;
  365.   return (New_Shape);
  366.   }
  367.  
  368. OBJECT *Get_Object ()
  369.   {
  370.   OBJECT *New_Object;
  371.  
  372.   if ((New_Object = (OBJECT *) malloc (sizeof (OBJECT))) == NULL)
  373.     Error ("Cannot allocate object");
  374.  
  375.   Make_Vector (&(New_Object -> Object_Center), 0.0, 0.0, 0.0);
  376.  
  377.   New_Object -> Next_Object = NULL;
  378.   New_Object -> Next_Light_Source = NULL;
  379.   New_Object -> Shape = NULL;
  380.   New_Object -> Bounding_Shapes = NULL;
  381.   New_Object -> Object_Texture = Default_Texture;
  382.  
  383.   Make_Colour (&New_Object->Object_Colour, 0.0, 0.0, 0.0);
  384.  
  385.   New_Object -> Light_Source_Flag = FALSE;
  386.   New_Object -> Transparency = FALSE;
  387.   New_Object -> Type = OBJECT_TYPE;
  388.   New_Object -> Methods = &Basic_Object_Methods;
  389.   return (New_Object);
  390.   }
  391.  
  392. TEXTURE *Get_Texture ()
  393.    {
  394.    TEXTURE *New_Texture;
  395.  
  396.    if ((New_Texture = (TEXTURE *) malloc (sizeof (TEXTURE))) == NULL)
  397.      Error ("Cannot allocate object");
  398.  
  399.    New_Texture -> Object_Reflection = 0.0;
  400.    New_Texture -> Object_Ambient = 0.3;
  401.    New_Texture -> Object_Diffuse = 0.7;
  402.    New_Texture -> Object_Brilliance = 1.0;
  403.    New_Texture -> Object_Specular = 0.0;
  404.    New_Texture -> Object_Roughness = 0.05;
  405.    New_Texture -> Object_Phong = 0.0;
  406.    New_Texture -> Object_PhongSize = 40;
  407.  
  408.    New_Texture -> Texture_Randomness= 0.0;
  409.    New_Texture -> Bump_Amount = 0.0;
  410.    New_Texture -> Phase = 0.0;
  411.    New_Texture -> Frequency = 1.0;
  412.    New_Texture -> Texture_Number = 0;
  413.    New_Texture -> Texture_Transformation = NULL;
  414.    New_Texture -> Bump_Number = NO_BUMPS;
  415.    New_Texture -> Turbulence = 0.0;
  416.    New_Texture -> Colour_Map = NULL;
  417.    New_Texture -> Once_Flag = FALSE;
  418.    Make_Colour (&New_Texture -> Colour1, 0.0, 0.0, 0.0);
  419.    Make_Colour (&New_Texture -> Colour2, 0.0, 0.0, 0.0);
  420.    Make_Vector (&New_Texture->Texture_Gradient, 0.0, 0.0, 0.0);
  421.  
  422.    New_Texture -> Object_Index_Of_Refraction = 1.0;
  423.    New_Texture -> Object_Refraction = 0.0;
  424.  
  425.    return (New_Texture);
  426.    }
  427.  
  428. VIEWPOINT *Get_Viewpoint ()
  429.   {
  430.   VIEWPOINT *New_Viewpoint;
  431.  
  432.   if ((New_Viewpoint = (VIEWPOINT *)malloc (sizeof (VIEWPOINT)))
  433.         == NULL)
  434.     Error ("Cannot allocate viewpoint");
  435.  
  436.   Init_Viewpoint (New_Viewpoint);
  437.   return (New_Viewpoint);
  438.   }
  439.  
  440. COLOUR *Get_Colour ()
  441.   {
  442.   COLOUR *New_Colour;
  443.  
  444.   if ((New_Colour = (COLOUR *) malloc (sizeof (COLOUR))) == NULL)
  445.     Error ("Cannot allocate colour");
  446.  
  447.   Make_Colour (New_Colour, 0.0, 0.0, 0.0);
  448.   return (New_Colour);
  449.   }
  450.  
  451. VECTOR *Get_Vector ()
  452.   {
  453.   VECTOR *New_Vector;
  454.  
  455.   if ((New_Vector = (VECTOR *) malloc (sizeof (VECTOR))) == NULL)
  456.     Error ("Cannot allocate vector");
  457.  
  458.   New_Vector -> x = 0.0;
  459.   New_Vector -> y = 0.0;
  460.   New_Vector -> z = 0.0;
  461.   return (New_Vector);
  462.   }
  463.  
  464. DBL *Get_Float ()
  465.   {
  466.   DBL *New_Float;
  467.  
  468.   if ((New_Float = (DBL *) malloc (sizeof (DBL))) == NULL)
  469.     Error ("Cannot allocate float");
  470.  
  471.   *New_Float = 0.0;
  472.   return (New_Float);
  473.   }
  474.  
  475. TRANSFORMATION *Get_Transformation()
  476.   {
  477.   TRANSFORMATION *New_Transformation;
  478.  
  479.   if ((New_Transformation =
  480.         (TRANSFORMATION *) malloc (sizeof (TRANSFORMATION))) == NULL)
  481.     Error ("Cannot allocate transformation");
  482.  
  483.   MIdentity ((MATRIX *) &(New_Transformation -> matrix[0][0]));
  484.   MIdentity ((MATRIX *) &(New_Transformation -> inverse[0][0]));
  485.   return (New_Transformation);
  486.   }
  487.  
  488. /* Parse a float.  Doesn't handle exponentiation. */
  489. DBL Parse_Float ()
  490.   {
  491.   DBL Local_Float;
  492.   CONSTANT Constant_Id;
  493.   register int Negative, Sign_Parsed;
  494.  
  495.   Negative = FALSE;
  496.   Sign_Parsed = FALSE;
  497.  
  498.   EXPECT
  499.     CASE (IDENTIFIER_TOKEN)
  500.       if ((Constant_Id = Find_Constant()) != -1)
  501.         if (Constants[(int)Constant_Id].Constant_Type == FLOAT_CONSTANT)
  502.           {
  503.           Local_Float = *((DBL *) Constants[(int)Constant_Id].Constant_Data);
  504.           if (Negative)
  505.             Local_Float *= -1.0;
  506.           }
  507.         else
  508.           Type_Error ();
  509.       else
  510.         Undeclared ();
  511.       EXIT
  512.     END_CASE
  513.  
  514.     CASE (PLUS_TOKEN)
  515.       if (Sign_Parsed)
  516.         Parse_Error (FLOAT_TOKEN);
  517.       Sign_Parsed = TRUE;
  518.     END_CASE
  519.  
  520.     CASE (DASH_TOKEN)
  521.       if (Sign_Parsed)
  522.         Parse_Error (FLOAT_TOKEN);
  523.       Negative = TRUE;
  524.       Sign_Parsed = TRUE;
  525.     END_CASE
  526.  
  527.     CASE (FLOAT_TOKEN)
  528.       Local_Float = Token.Token_Float;
  529.       if (Negative)
  530.         Local_Float *= -1.0;
  531.       EXIT
  532.     END_CASE
  533.  
  534.     OTHERWISE
  535.       Parse_Error (FLOAT_TOKEN);
  536.     END_CASE
  537.   END_EXPECT
  538.  
  539.   return (Local_Float);
  540.   }
  541.  
  542. void Parse_Vector (Given_Vector)
  543.   VECTOR *Given_Vector;
  544.   {
  545.   CONSTANT Constant_Id;
  546.  
  547.   EXPECT
  548.     CASE (IDENTIFIER_TOKEN)
  549.       if ((Constant_Id = Find_Constant()) != -1)
  550.         if (Constants[(int)Constant_Id].Constant_Type == VECTOR_CONSTANT)
  551.           *Given_Vector = *((VECTOR *) Constants[(int)Constant_Id].Constant_Data);
  552.         else
  553.           Type_Error ();
  554.       else
  555.         Undeclared ();
  556.       EXIT
  557.     END_CASE
  558.  
  559.     CASE (LEFT_ANGLE_TOKEN)
  560.       (Given_Vector -> x) = Parse_Float();
  561.       (Given_Vector -> y) = Parse_Float();
  562.       (Given_Vector -> z) = Parse_Float();
  563.       GET (RIGHT_ANGLE_TOKEN);
  564.       EXIT
  565.     END_CASE
  566.  
  567.     OTHERWISE 
  568.       Parse_Error (LEFT_ANGLE_TOKEN);
  569.     END_CASE
  570.   END_EXPECT
  571.   }
  572.  
  573. void Parse_Colour (Given_Colour)
  574.   COLOUR *Given_Colour;
  575.   {
  576.   CONSTANT Constant_Id;
  577.  
  578.   Make_Colour (Given_Colour, 0.0, 0.0, 0.0);
  579.   EXPECT
  580.     CASE (IDENTIFIER_TOKEN)
  581.       if ((Constant_Id = Find_Constant()) != -1)
  582.         if (Constants[(int)Constant_Id].Constant_Type == COLOUR_CONSTANT)
  583.           *Given_Colour = *((COLOUR *) Constants[(int)Constant_Id].Constant_Data);
  584.         else
  585.           Type_Error ();
  586.       else
  587.         Undeclared ();
  588.     END_CASE
  589.  
  590.     CASE (RED_TOKEN)
  591.       (Given_Colour -> Red) = Parse_Float();
  592.     END_CASE
  593.  
  594.     CASE (GREEN_TOKEN)
  595.       (Given_Colour -> Green) = Parse_Float();
  596.     END_CASE
  597.  
  598.     CASE (BLUE_TOKEN)
  599.       (Given_Colour -> Blue) = Parse_Float();
  600.     END_CASE
  601.  
  602.     CASE (ALPHA_TOKEN)
  603.       (Given_Colour -> Alpha) = Parse_Float();
  604.     END_CASE
  605.  
  606.     OTHERWISE
  607.       UNGET
  608.       EXIT
  609.     END_CASE
  610.   END_EXPECT
  611.   }
  612.  
  613. COLOUR_MAP *Parse_Colour_Map ()
  614.    {
  615. #define MAX_ENTRIES 20
  616.    COLOUR_MAP *New_Colour_Map;
  617.    register int i;
  618.  
  619.    New_Colour_Map = (COLOUR_MAP *)
  620.                         malloc (sizeof (COLOUR_MAP));
  621.  
  622.    if (New_Colour_Map == NULL)
  623.       Error ("Not enough memory for colour map");
  624.  
  625.    New_Colour_Map -> Colour_Map_Entries = (COLOUR_MAP_ENTRY *)
  626.                   malloc(MAX_ENTRIES * sizeof (COLOUR_MAP_ENTRY));
  627.  
  628.    if (New_Colour_Map -> Colour_Map_Entries == NULL)
  629.       Error ("Not enough memory for colour map");
  630.  
  631.    i = 0;
  632.    EXPECT
  633.       CASE (LEFT_SQUARE_TOKEN)
  634.          New_Colour_Map -> Colour_Map_Entries [i].start = Parse_Float();
  635.          New_Colour_Map -> Colour_Map_Entries [i].end = Parse_Float();
  636.          GET (COLOUR_TOKEN);
  637.          Parse_Colour (&(New_Colour_Map->Colour_Map_Entries[i].Start_Colour));
  638.          GET (COLOUR_TOKEN);
  639.          Parse_Colour (&(New_Colour_Map->Colour_Map_Entries[i].End_Colour));
  640.          i++;
  641.          if (i > MAX_ENTRIES)
  642.             Error ("Colour_Map too long");
  643.          GET (RIGHT_SQUARE_TOKEN);
  644.       END_CASE
  645.  
  646.       CASE2 (END_COLOUR_MAP_TOKEN, END_COLOR_MAP_TOKEN)
  647.           New_Colour_Map -> Number_Of_Entries = i;
  648.           EXIT
  649.       END_CASE
  650.  
  651.       OTHERWISE
  652.          Parse_Error (END_COLOUR_MAP_TOKEN);
  653.       END_CASE
  654.    END_EXPECT
  655.    return (New_Colour_Map);
  656.    }
  657.  
  658. TEXTURE *Copy_Texture (Texture)
  659.    TEXTURE *Texture;
  660.    {
  661.    TEXTURE *New_Texture;
  662.    New_Texture = Get_Texture();
  663.    *New_Texture = *Texture;
  664.    if (New_Texture->Texture_Transformation) {
  665.       New_Texture->Texture_Transformation = (TRANSFORMATION *) malloc (sizeof (TRANSFORMATION));
  666.       *New_Texture->Texture_Transformation = *Texture->Texture_Transformation;
  667.       }
  668.    return (New_Texture);
  669.    }
  670.  
  671. TEXTURE *Parse_Texture (Old_Texture)
  672.    TEXTURE *Old_Texture;
  673.    {
  674.    VECTOR Local_Vector;
  675.    TRANSFORMATION Local_Transformation;
  676.    CONSTANT Constant_Id;
  677.    TEXTURE *Texture;
  678.    int Texture_Constant;
  679.  
  680.    Texture = Old_Texture;
  681.    Texture_Constant = TRUE;
  682.  
  683.    EXPECT
  684.       CASE (IDENTIFIER_TOKEN)
  685.          if ((Constant_Id = Find_Constant()) != -1)
  686.             if (Constants[(int)Constant_Id].Constant_Type == TEXTURE_CONSTANT) {
  687.                Texture = ((TEXTURE *) Constants[(int)Constant_Id].Constant_Data);
  688.                Texture_Constant = TRUE;
  689.                }
  690.             else
  691.                Type_Error ();
  692.          else
  693.             Undeclared ();
  694.       END_CASE
  695.  
  696.       CASE (FLOAT_TOKEN)
  697.          UNGET
  698.          if (Texture_Constant) {
  699.             Texture = Copy_Texture(Texture);
  700.             Texture_Constant = FALSE;
  701.             }
  702.          Texture -> Texture_Randomness = Parse_Float();
  703.       END_CASE
  704.  
  705.       CASE (ONCE_TOKEN)
  706.          if (Texture_Constant) {
  707.             Texture = Copy_Texture(Texture);
  708.             Texture_Constant = FALSE;
  709.             }
  710.          Texture->Once_Flag = TRUE;
  711.       END_CASE
  712.  
  713.       CASE (TURBULENCE_TOKEN)
  714.          if (Texture_Constant) {
  715.             Texture = Copy_Texture(Texture);
  716.             Texture_Constant = FALSE;
  717.             }
  718.           Texture -> Turbulence = Parse_Float();
  719.       END_CASE
  720.  
  721.       CASE (BOZO_TOKEN)
  722.          if (Texture_Constant) {
  723.             Texture_Constant = FALSE;
  724.             Texture = Copy_Texture (Texture);
  725.             }
  726.          Texture -> Texture_Number = BOZO_TEXTURE;
  727.       END_CASE
  728.  
  729.       CASE (CHECKER_TOKEN)
  730.          if (Texture_Constant) {
  731.             Texture_Constant = FALSE;
  732.             Texture = Copy_Texture (Texture);
  733.             }
  734.          Texture -> Texture_Number = CHECKER_TEXTURE;
  735.          EXPECT
  736.             CASE (COLOUR_TOKEN)
  737.                Parse_Colour (&(Texture -> Colour1));
  738.                GET (COLOUR_TOKEN);
  739.                Parse_Colour (&(Texture -> Colour2));
  740.             END_CASE
  741.  
  742.             OTHERWISE
  743.                UNGET
  744.                EXIT
  745.             END_CASE
  746.          END_EXPECT
  747.       END_CASE
  748.  
  749.       CASE (MARBLE_TOKEN)
  750.          if (Texture_Constant) {
  751.             Texture_Constant = FALSE;
  752.             Texture = Copy_Texture (Texture);
  753.             }
  754.          Texture -> Texture_Number = MARBLE_TEXTURE;
  755.       END_CASE
  756.  
  757.       CASE (WOOD_TOKEN)
  758.          if (Texture_Constant) {
  759.             Texture_Constant = FALSE;
  760.             Texture = Copy_Texture (Texture);
  761.             }
  762.          Texture -> Texture_Number = WOOD_TEXTURE;
  763.       END_CASE
  764.  
  765.       CASE (SPOTTED_TOKEN)
  766.          if (Texture_Constant) {
  767.             Texture_Constant = FALSE;
  768.             Texture = Copy_Texture (Texture);
  769.             }
  770.          Texture -> Texture_Number = SPOTTED_TEXTURE;
  771.       END_CASE
  772.  
  773.       CASE (AGATE_TOKEN)
  774.          if (Texture_Constant) {
  775.             Texture_Constant = FALSE;
  776.             Texture = Copy_Texture (Texture);
  777.             }
  778.          Texture -> Texture_Number = AGATE_TEXTURE;
  779.       END_CASE
  780.  
  781.       CASE (GRANITE_TOKEN)
  782.          if (Texture_Constant) {
  783.             Texture_Constant = FALSE;
  784.             Texture = Copy_Texture (Texture);
  785.             }
  786.          Texture -> Texture_Number = GRANITE_TEXTURE;
  787.       END_CASE
  788.  
  789.        CASE (GRADIENT_TOKEN)
  790.          if (Texture_Constant) {
  791.             Texture_Constant = FALSE;
  792.             Texture = Copy_Texture (Texture);
  793.             }
  794.      Texture -> Texture_Number = GRADIENT_TEXTURE;
  795.      Parse_Vector (&(Texture -> Texture_Gradient));
  796.        END_CASE
  797.  
  798.       CASE (AMBIENT_TOKEN)
  799.          if (Texture_Constant) {
  800.             Texture_Constant = FALSE;
  801.             Texture = Copy_Texture (Texture);
  802.             }
  803.          (Texture -> Object_Ambient) = Parse_Float ();
  804.       END_CASE
  805.  
  806.       CASE (BRILLIANCE_TOKEN)
  807.          if (Texture_Constant) {
  808.             Texture_Constant = FALSE;
  809.             Texture = Copy_Texture (Texture);
  810.             }
  811.          (Texture -> Object_Brilliance) = Parse_Float ();
  812.       END_CASE
  813.  
  814.       CASE (ROUGHNESS_TOKEN)
  815.          if (Texture_Constant) {
  816.             Texture_Constant = FALSE;
  817.             Texture = Copy_Texture (Texture);
  818.             }
  819.          (Texture -> Object_Roughness) = Parse_Float ();
  820.          if (Texture -> Object_Roughness > 1.0)
  821.             Texture -> Object_Roughness = 1.0;
  822.          if (Texture -> Object_Roughness < 0.001)
  823.             Texture -> Object_Roughness = 0.001;
  824.       END_CASE
  825.  
  826.       CASE (PHONGSIZE_TOKEN)
  827.          if (Texture_Constant) {
  828.             Texture_Constant = FALSE;
  829.             Texture = Copy_Texture (Texture);
  830.             }
  831.          (Texture -> Object_PhongSize) = Parse_Float ();
  832.          if (Texture -> Object_PhongSize < 1.0)
  833.             Texture -> Object_PhongSize = 1.0;
  834.          if (Texture -> Object_PhongSize > 100)
  835.             Texture -> Object_PhongSize = 100;
  836.       END_CASE
  837.  
  838.       CASE (DIFFUSE_TOKEN)
  839.          if (Texture_Constant) {
  840.             Texture_Constant = FALSE;
  841.             Texture = Copy_Texture (Texture);
  842.             }
  843.          (Texture -> Object_Diffuse) = Parse_Float ();
  844.       END_CASE
  845.  
  846.       CASE (SPECULAR_TOKEN)
  847.          if (Texture_Constant) {
  848.             Texture_Constant = FALSE;
  849.             Texture = Copy_Texture (Texture);
  850.             }
  851.          (Texture -> Object_Specular) = Parse_Float ();
  852.       END_CASE
  853.  
  854.       CASE (PHONG_TOKEN)
  855.          if (Texture_Constant) {
  856.             Texture_Constant = FALSE;
  857.             Texture = Copy_Texture (Texture);
  858.             }
  859.          (Texture -> Object_Phong) = Parse_Float ();
  860.       END_CASE
  861.  
  862.       CASE (IOR_TOKEN)
  863.          if (Texture_Constant) {
  864.             Texture_Constant = FALSE;
  865.             Texture = Copy_Texture (Texture);
  866.             }
  867.          (Texture -> Object_Index_Of_Refraction) = Parse_Float ();
  868.       END_CASE
  869.  
  870.       CASE (REFRACTION_TOKEN)
  871.          if (Texture_Constant) {
  872.             Texture_Constant = FALSE;
  873.             Texture = Copy_Texture (Texture);
  874.             }
  875.          (Texture -> Object_Refraction) = Parse_Float ();
  876.       END_CASE
  877.  
  878.       CASE (REFLECTION_TOKEN)
  879.          if (Texture_Constant) {
  880.             Texture_Constant = FALSE;
  881.             Texture = Copy_Texture (Texture);
  882.             }
  883.          (Texture -> Object_Reflection) = Parse_Float ();
  884.       END_CASE
  885.  
  886.       CASE (IMAGEMAP_TOKEN)
  887.          if (Texture_Constant) {
  888.             Texture_Constant = FALSE;
  889.             Texture = Copy_Texture (Texture);
  890.             }
  891.          Texture -> Texture_Number = IMAGEMAP_TEXTURE;
  892.          Texture->Image = (IMAGE *)malloc(sizeof(IMAGE));
  893.          Make_Vector (&Texture->Texture_Gradient, 1.0, -1.0, 0.0);
  894.          EXPECT
  895.             CASE (LEFT_ANGLE_TOKEN)
  896.                  UNGET
  897.                  Parse_Vector (&(Texture -> Texture_Gradient));
  898.             END_CASE
  899.  
  900.             CASE (IFF_TOKEN)
  901.                GET (STRING_TOKEN);
  902.                read_iff_image(Texture->Image, Token.Token_String);
  903.                EXIT
  904.             END_CASE
  905.  
  906.             CASE (GIF_TOKEN)
  907.                GET (STRING_TOKEN);
  908.                read_gif_image(Texture->Image, Token.Token_String);
  909.                EXIT
  910.             END_CASE
  911.  
  912.             CASE (RAW_TOKEN)
  913.                GET (STRING_TOKEN);
  914.                read_raw_image(Texture->Image, Token.Token_String);
  915.                EXIT
  916.             END_CASE
  917.  
  918.             OTHERWISE
  919.                Parse_Error (RAW_TOKEN);
  920.             END_CASE
  921.          END_EXPECT
  922.       END_CASE
  923.  
  924.       CASE (WAVES_TOKEN)
  925.          if (Texture_Constant) {
  926.             Texture_Constant = FALSE;
  927.             Texture = Copy_Texture (Texture);
  928.             }
  929.          Texture -> Bump_Number = WAVES;
  930.          Texture -> Bump_Amount = Parse_Float ();
  931.          EXPECT
  932.             CASE (PHASE_TOKEN)
  933.                Texture -> Phase = Parse_Float();
  934.                EXIT
  935.             END_CASE
  936.  
  937.             OTHERWISE
  938.                UNGET
  939.                EXIT
  940.             END_CASE
  941.          END_EXPECT
  942.       END_CASE
  943.  
  944.       CASE (FREQUENCY_TOKEN)
  945.          if (Texture_Constant) {
  946.             Texture_Constant = FALSE;
  947.             Texture = Copy_Texture (Texture);
  948.             }
  949.          Texture -> Frequency = Parse_Float();
  950.       END_CASE
  951.  
  952.       CASE (PHASE_TOKEN)
  953.          if (Texture_Constant) {
  954.             Texture_Constant = FALSE;
  955.             Texture = Copy_Texture (Texture);
  956.             }
  957.          Texture -> Phase = Parse_Float();
  958.       END_CASE
  959.  
  960.       CASE (RIPPLES_TOKEN)
  961.          if (Texture_Constant) {
  962.             Texture_Constant = FALSE;
  963.             Texture = Copy_Texture (Texture);
  964.             }
  965.          Texture -> Bump_Number = RIPPLES;
  966.          Texture -> Bump_Amount = Parse_Float ();
  967.       END_CASE
  968.  
  969.       CASE (WRINKLES_TOKEN)
  970.          if (Texture_Constant) {
  971.             Texture_Constant = FALSE;
  972.             Texture = Copy_Texture (Texture);
  973.             }
  974.          Texture -> Bump_Number = WRINKLES;
  975.          Texture -> Bump_Amount = Parse_Float ();
  976.       END_CASE
  977.  
  978.       CASE (BUMPS_TOKEN)
  979.          if (Texture_Constant) {
  980.             Texture_Constant = FALSE;
  981.             Texture = Copy_Texture (Texture);
  982.             }
  983.          Texture -> Bump_Number = BUMPS;
  984.          Texture -> Bump_Amount = Parse_Float ();
  985.       END_CASE
  986.  
  987.       CASE (DENTS_TOKEN)
  988.          if (Texture_Constant) {
  989.             Texture_Constant = FALSE;
  990.             Texture = Copy_Texture (Texture);
  991.             }
  992.          Texture -> Bump_Number = DENTS;
  993.          Texture -> Bump_Amount = Parse_Float ();
  994.       END_CASE
  995.  
  996.       CASE (TRANSLATE_TOKEN)
  997.          if (Texture_Constant) {
  998.             Texture_Constant = FALSE;
  999.             Texture = Copy_Texture (Texture);
  1000.             }
  1001.          Parse_Vector (&Local_Vector);
  1002.          if (!Texture -> Texture_Transformation)
  1003.             Texture -> Texture_Transformation = Get_Transformation ();
  1004.          Get_Translation_Transformation (&Local_Transformation,
  1005.                                          &Local_Vector);
  1006.          Compose_Transformations (Texture -> Texture_Transformation,
  1007.                                   &Local_Transformation);
  1008.       END_CASE
  1009.  
  1010.       CASE (ROTATE_TOKEN)
  1011.          if (Texture_Constant) {
  1012.             Texture_Constant = FALSE;
  1013.             Texture = Copy_Texture (Texture);
  1014.             }
  1015.          Parse_Vector (&Local_Vector);
  1016.          if (!Texture -> Texture_Transformation)
  1017.             Texture -> Texture_Transformation = Get_Transformation ();
  1018.          Get_Rotation_Transformation (&Local_Transformation,
  1019.                                       &Local_Vector);
  1020.          Compose_Transformations (Texture -> Texture_Transformation,
  1021.                                   &Local_Transformation);
  1022.       END_CASE
  1023.  
  1024.       CASE (SCALE_TOKEN)
  1025.          if (Texture_Constant) {
  1026.             Texture_Constant = FALSE;
  1027.             Texture = Copy_Texture (Texture);
  1028.             }
  1029.          Parse_Vector (&Local_Vector);
  1030.          if (!Texture -> Texture_Transformation)
  1031.              Texture -> Texture_Transformation = Get_Transformation ();
  1032.          Get_Scaling_Transformation (&Local_Transformation,
  1033.                                      &Local_Vector);
  1034.          Compose_Transformations (Texture -> Texture_Transformation,
  1035.                                   &Local_Transformation);
  1036.       END_CASE
  1037.  
  1038.       CASE2 (COLOUR_MAP_TOKEN, COLOR_MAP_TOKEN)
  1039.          if (Texture_Constant) {
  1040.             Texture_Constant = FALSE;
  1041.             Texture = Copy_Texture (Texture);
  1042.             }
  1043.          Texture -> Colour_Map = Parse_Colour_Map();
  1044.       END_CASE
  1045.  
  1046.       CASE (END_TEXTURE_TOKEN)
  1047.          EXIT
  1048.       END_CASE
  1049.  
  1050.       OTHERWISE
  1051.          Parse_Error (END_TEXTURE_TOKEN);
  1052.       END_CASE
  1053.    END_EXPECT
  1054.    return (Texture);
  1055.    }
  1056.  
  1057. SHAPE *Parse_Sphere ()
  1058.   {
  1059.   SPHERE *Local_Shape;
  1060.   CONSTANT Constant_Id;
  1061.   VECTOR Local_Vector;
  1062.  
  1063.   Local_Shape = NULL;
  1064.  
  1065.   EXPECT
  1066.      CASE (LEFT_ANGLE_TOKEN)
  1067.        UNGET
  1068.        Local_Shape = Get_Sphere_Shape();
  1069.        Parse_Vector(&(Local_Shape -> Center));
  1070.        Local_Shape -> Radius = Parse_Float();
  1071.        Local_Shape -> Radius_Squared = Local_Shape -> Radius * Local_Shape -> Radius;
  1072.        Local_Shape -> Inverse_Radius = 1.0 / Local_Shape -> Radius;
  1073.        EXIT
  1074.      END_CASE
  1075.  
  1076.      CASE (IDENTIFIER_TOKEN)
  1077.        if ((Constant_Id = Find_Constant()) != -1)
  1078.          if (Constants[(int)Constant_Id].Constant_Type == SPHERE_CONSTANT)
  1079.            Local_Shape = (SPHERE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1080.          else
  1081.            Type_Error ();
  1082.        else
  1083.          Undeclared ();
  1084.        EXIT
  1085.      END_CASE
  1086.  
  1087.      OTHERWISE
  1088.         Parse_Error (LEFT_ANGLE_TOKEN);
  1089.      END_CASE
  1090.   END_EXPECT
  1091.  
  1092.   EXPECT
  1093.      CASE (END_SPHERE_TOKEN)
  1094.         EXIT
  1095.      END_CASE
  1096.  
  1097.      CASE (TRANSLATE_TOKEN)
  1098.         Parse_Vector (&Local_Vector);
  1099.         Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1100.      END_CASE
  1101.  
  1102.      CASE (ROTATE_TOKEN)
  1103.         Parse_Vector (&Local_Vector);
  1104.         Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1105.      END_CASE
  1106.  
  1107.      CASE (SCALE_TOKEN)
  1108.         Parse_Vector (&Local_Vector);
  1109.         Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1110.      END_CASE
  1111.  
  1112.      CASE (INVERSE_TOKEN)
  1113.         Invert ((OBJECT *) Local_Shape);
  1114.      END_CASE
  1115.  
  1116.      OTHERWISE
  1117.         Parse_Error (END_SPHERE_TOKEN);
  1118.      END_CASE
  1119.   END_EXPECT
  1120.  
  1121.   return ((SHAPE *) Local_Shape);
  1122.   }
  1123.  
  1124. SHAPE *Parse_Plane ()
  1125.   {
  1126.   PLANE *Local_Shape;
  1127.   CONSTANT Constant_Id;
  1128.   VECTOR Local_Vector;
  1129.  
  1130.   Local_Shape = NULL;
  1131.  
  1132.   EXPECT
  1133.      CASE (LEFT_ANGLE_TOKEN)
  1134.        UNGET
  1135.        Local_Shape = Get_Plane_Shape();
  1136.        Parse_Vector(&(Local_Shape -> Normal_Vector));
  1137.        Local_Shape->Distance = Parse_Float();
  1138.        Local_Shape->Distance *= -1.0;
  1139.        EXIT
  1140.      END_CASE
  1141.  
  1142.      CASE (IDENTIFIER_TOKEN)
  1143.        if ((Constant_Id = Find_Constant()) != -1)
  1144.          if (Constants[(int)Constant_Id].Constant_Type == PLANE_CONSTANT)
  1145.            Local_Shape = (PLANE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1146.          else
  1147.            Type_Error ();
  1148.        else
  1149.          Undeclared ();
  1150.        EXIT
  1151.      END_CASE
  1152.  
  1153.      OTHERWISE
  1154.         Parse_Error (LEFT_ANGLE_TOKEN);
  1155.      END_CASE
  1156.   END_EXPECT
  1157.  
  1158.   EXPECT
  1159.      CASE (END_PLANE_TOKEN)
  1160.         EXIT
  1161.      END_CASE
  1162.  
  1163.      CASE (TRANSLATE_TOKEN)
  1164.         Parse_Vector (&Local_Vector);
  1165.         Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1166.      END_CASE
  1167.  
  1168.      CASE (ROTATE_TOKEN)
  1169.         Parse_Vector (&Local_Vector);
  1170.         Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1171.      END_CASE
  1172.  
  1173.      CASE (SCALE_TOKEN)
  1174.         Parse_Vector (&Local_Vector);
  1175.         Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1176.      END_CASE
  1177.  
  1178.      CASE (INVERSE_TOKEN)
  1179.         Invert ((OBJECT *) Local_Shape);
  1180.      END_CASE
  1181.  
  1182.      OTHERWISE
  1183.         Parse_Error (END_PLANE_TOKEN);
  1184.      END_CASE
  1185.   END_EXPECT
  1186.  
  1187.   return ((SHAPE *) Local_Shape);
  1188.   }
  1189.  
  1190. SHAPE *Parse_Triangle ()
  1191.   {
  1192.   TRIANGLE *Local_Shape;
  1193.   CONSTANT Constant_Id;
  1194.   VECTOR Local_Vector;
  1195.  
  1196.   Local_Shape = NULL;
  1197.  
  1198.   EXPECT
  1199.      CASE (LEFT_ANGLE_TOKEN)
  1200.        UNGET
  1201.        Local_Shape = Get_Triangle_Shape();
  1202.        Parse_Vector (&Local_Shape->P1);
  1203.        Parse_Vector (&Local_Shape->P2);
  1204.        Parse_Vector (&Local_Shape->P3);
  1205.        if (!Compute_Triangle (Local_Shape)) {
  1206.           printf ("Degenerate triangle on line %d.  Please remove.\n",
  1207.                   Token.Token_Line_No);
  1208.           Degenerate_Triangles = TRUE;
  1209.           }
  1210.        EXIT
  1211.      END_CASE
  1212.  
  1213.      CASE (IDENTIFIER_TOKEN)
  1214.        if ((Constant_Id = Find_Constant()) != -1)
  1215.          if (Constants[(int)Constant_Id].Constant_Type == TRIANGLE_CONSTANT)
  1216.            Local_Shape = (TRIANGLE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1217.          else
  1218.            Type_Error ();
  1219.        else
  1220.          Undeclared ();
  1221.        EXIT
  1222.      END_CASE
  1223.  
  1224.      OTHERWISE
  1225.         Parse_Error (LEFT_ANGLE_TOKEN);
  1226.      END_CASE
  1227.   END_EXPECT
  1228.  
  1229.   EXPECT
  1230.      CASE (END_TRIANGLE_TOKEN)
  1231.         EXIT
  1232.      END_CASE
  1233.  
  1234.      CASE (TRANSLATE_TOKEN)
  1235.         Parse_Vector (&Local_Vector);
  1236.         Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1237.      END_CASE
  1238.  
  1239.      CASE (ROTATE_TOKEN)
  1240.         Parse_Vector (&Local_Vector);
  1241.         Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1242.      END_CASE
  1243.  
  1244.      CASE (SCALE_TOKEN)
  1245.         Parse_Vector (&Local_Vector);
  1246.         Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1247.      END_CASE
  1248.  
  1249.      CASE (INVERSE_TOKEN)
  1250.         Invert ((OBJECT *) Local_Shape);
  1251.      END_CASE
  1252.  
  1253.      OTHERWISE
  1254.         Parse_Error (END_TRIANGLE_TOKEN);
  1255.      END_CASE
  1256.   END_EXPECT
  1257.  
  1258.   return ((SHAPE *) Local_Shape);
  1259.   }
  1260.  
  1261. SHAPE *Parse_Smooth_Triangle ()
  1262.   {
  1263.   SMOOTH_TRIANGLE *Local_Shape;
  1264.   CONSTANT Constant_Id;
  1265.   VECTOR Local_Vector;
  1266.  
  1267.   Local_Shape = NULL;
  1268.  
  1269.   EXPECT
  1270.      CASE (LEFT_ANGLE_TOKEN)
  1271.        UNGET
  1272.        Local_Shape = (SMOOTH_TRIANGLE *) Get_Smooth_Triangle_Shape();
  1273.        Parse_Vector (&Local_Shape->P1);
  1274.        Parse_Vector (&Local_Shape->N1);
  1275.        Parse_Vector (&Local_Shape->P2);
  1276.        Parse_Vector (&Local_Vector);
  1277.        VSub (Local_Shape->DN12, Local_Vector, Local_Shape->N1);
  1278.        Parse_Vector (&Local_Shape->P3);
  1279.        Parse_Vector (&Local_Vector);
  1280.        VSub (Local_Shape->DN13, Local_Vector, Local_Shape->N1);
  1281.        if (!Compute_Triangle ((TRIANGLE *) Local_Shape)) {
  1282.           printf ("Degenerate triangle on line %d.  Please remove.\n",
  1283.                   Token.Token_Line_No);
  1284.           Degenerate_Triangles = TRUE;
  1285.           }
  1286.        EXIT
  1287.      END_CASE
  1288.  
  1289.      CASE (IDENTIFIER_TOKEN)
  1290.        if ((Constant_Id = Find_Constant()) != -1)
  1291.          if (Constants[(int)Constant_Id].Constant_Type == SMOOTH_TRIANGLE_CONSTANT)
  1292.            Local_Shape = (SMOOTH_TRIANGLE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1293.          else
  1294.            Type_Error ();
  1295.        else
  1296.          Undeclared ();
  1297.        EXIT
  1298.      END_CASE
  1299.  
  1300.      CASE (TRANSLATE_TOKEN)
  1301.         Parse_Vector (&Local_Vector);
  1302.         Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1303.      END_CASE
  1304.  
  1305.      CASE (ROTATE_TOKEN)
  1306.         Parse_Vector (&Local_Vector);
  1307.         Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1308.      END_CASE
  1309.  
  1310.      CASE (SCALE_TOKEN)
  1311.         Parse_Vector (&Local_Vector);
  1312.         Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1313.      END_CASE
  1314.  
  1315.      CASE (INVERSE_TOKEN)
  1316.         Invert ((OBJECT *) Local_Shape);
  1317.      END_CASE
  1318.  
  1319.      OTHERWISE
  1320.         Parse_Error (LEFT_ANGLE_TOKEN);
  1321.      END_CASE
  1322.   END_EXPECT
  1323.  
  1324.   EXPECT
  1325.      CASE (END_TRIANGLE_TOKEN)
  1326.         EXIT
  1327.      END_CASE
  1328.  
  1329.      OTHERWISE
  1330.         Parse_Error (END_TRIANGLE_TOKEN);
  1331.      END_CASE
  1332.   END_EXPECT
  1333.  
  1334.   return ((SHAPE *) Local_Shape);
  1335.   }
  1336.  
  1337. SHAPE *Parse_Quadric ()
  1338.   {
  1339.   QUADRIC *Local_Shape;
  1340.   VECTOR Local_Vector;
  1341.   CONSTANT Constant_Id;
  1342.  
  1343.   Local_Shape = NULL;
  1344.  
  1345.   EXPECT
  1346.      CASE (LEFT_ANGLE_TOKEN)
  1347.        UNGET
  1348.        Local_Shape = Get_Quadric_Shape();
  1349.        Parse_Vector(&(Local_Shape -> Object_2_Terms));
  1350.        Parse_Vector(&(Local_Shape -> Object_Mixed_Terms));
  1351.        Parse_Vector(&(Local_Shape -> Object_Terms));
  1352.        (Local_Shape -> Object_Constant) = Parse_Float();
  1353.        Local_Shape -> Non_Zero_Square_Term = 
  1354.          !((Local_Shape -> Object_2_Terms.x == 0.0)
  1355.           && (Local_Shape -> Object_2_Terms.y == 0.0)
  1356.           && (Local_Shape -> Object_2_Terms.z == 0.0)
  1357.           && (Local_Shape -> Object_Mixed_Terms.x == 0.0)
  1358.           && (Local_Shape -> Object_Mixed_Terms.y == 0.0)
  1359.           && (Local_Shape -> Object_Mixed_Terms.z == 0.0));
  1360.        EXIT
  1361.      END_CASE
  1362.  
  1363.      CASE (IDENTIFIER_TOKEN)
  1364.        if ((Constant_Id = Find_Constant()) != -1)
  1365.          if (Constants[(int)Constant_Id].Constant_Type == QUADRIC_CONSTANT)
  1366.            Local_Shape = (QUADRIC *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1367.          else
  1368.            Type_Error ();
  1369.        else
  1370.          Undeclared ();
  1371.        EXIT
  1372.      END_CASE
  1373.  
  1374.      OTHERWISE
  1375.         Parse_Error (LEFT_ANGLE_TOKEN);
  1376.      END_CASE
  1377.   END_EXPECT
  1378.  
  1379.   EXPECT
  1380.      CASE (END_QUADRIC_TOKEN)
  1381.         EXIT
  1382.      END_CASE
  1383.  
  1384.      CASE (TRANSLATE_TOKEN)
  1385.         Parse_Vector (&Local_Vector);
  1386.         Translate ((OBJECT *) Local_Shape, &Local_Vector);
  1387.      END_CASE
  1388.  
  1389.      CASE (ROTATE_TOKEN)
  1390.         Parse_Vector (&Local_Vector);
  1391.         Rotate ((OBJECT *) Local_Shape, &Local_Vector);
  1392.      END_CASE
  1393.  
  1394.      CASE (SCALE_TOKEN)
  1395.         Parse_Vector (&Local_Vector);
  1396.         Scale ((OBJECT *) Local_Shape, &Local_Vector);
  1397.      END_CASE
  1398.  
  1399.      CASE (INVERSE_TOKEN)
  1400.         Invert ((OBJECT *) Local_Shape);
  1401.      END_CASE
  1402.  
  1403.      OTHERWISE
  1404.         Parse_Error (END_QUADRIC_TOKEN);
  1405.      END_CASE
  1406.   END_EXPECT
  1407.  
  1408.   return ((SHAPE *) Local_Shape);
  1409.   }
  1410.  
  1411. CSG_SHAPE *Parse_CSG (type, Parent_Object)
  1412.   int type;
  1413.   OBJECT *Parent_Object;
  1414.   {
  1415.   CSG_SHAPE *Container;
  1416.   SHAPE *Local_Shape;
  1417.   VECTOR Local_Vector;
  1418.   CONSTANT Constant_Id;
  1419.   int First_Shape_Parsed = FALSE;
  1420.  
  1421.   if (type == CSG_UNION_TYPE)
  1422.     Container = Get_CSG_Union ();
  1423.  
  1424.   else if ((type == CSG_INTERSECTION_TYPE) || (type == CSG_DIFFERENCE_TYPE))
  1425.     Container = Get_CSG_Intersection ();
  1426.  
  1427.   Container -> Parent_Object = Parent_Object;
  1428.  
  1429.   EXPECT
  1430.      CASE (IDENTIFIER_TOKEN)
  1431.        if ((Constant_Id = Find_Constant()) != -1)
  1432.          if ((Constants[(int)Constant_Id].Constant_Type == CSG_INTERSECTION_CONSTANT)
  1433.              || (Constants[(int)Constant_Id].Constant_Type == CSG_UNION_CONSTANT)
  1434.              || (Constants[(int)Constant_Id].Constant_Type == CSG_DIFFERENCE_CONSTANT)) {
  1435.            free (Container);
  1436.            Container = (CSG_SHAPE *) Copy ((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1437.            Set_CSG_Parents(Container, Parent_Object);
  1438.            }
  1439.          else
  1440.            Type_Error ();
  1441.        else
  1442.          Undeclared ();
  1443.      END_CASE
  1444.  
  1445.      CASE (SPHERE_TOKEN)
  1446.        Local_Shape = Parse_Sphere ();
  1447.        Local_Shape -> Parent_Object = Parent_Object;
  1448.        if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1449.           Invert ((OBJECT *) Local_Shape);
  1450.        First_Shape_Parsed = TRUE;
  1451.        Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1452.                (OBJECT **) &(Container -> Shapes));
  1453.      END_CASE
  1454.  
  1455.      CASE (PLANE_TOKEN)
  1456.        Local_Shape = Parse_Plane ();
  1457.        Local_Shape -> Parent_Object = Parent_Object;
  1458.        if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1459.           Invert ((OBJECT *) Local_Shape);
  1460.        First_Shape_Parsed = TRUE;
  1461.        Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1462.                (OBJECT **) &(Container -> Shapes));
  1463.      END_CASE
  1464.  
  1465.      CASE (TRIANGLE_TOKEN)
  1466.        Local_Shape = Parse_Triangle ();
  1467.        Local_Shape -> Parent_Object = Parent_Object;
  1468.        if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1469.           Invert ((OBJECT *) Local_Shape);
  1470.        First_Shape_Parsed = TRUE;
  1471.        Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1472.                (OBJECT **) &(Container -> Shapes));
  1473.      END_CASE
  1474.  
  1475.      CASE (SMOOTH_TRIANGLE_TOKEN)
  1476.        Local_Shape = Parse_Smooth_Triangle ();
  1477.        Local_Shape -> Parent_Object = Parent_Object;
  1478.        if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1479.           Invert ((OBJECT *) Local_Shape);
  1480.        First_Shape_Parsed = TRUE;
  1481.        Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1482.                (OBJECT **) &(Container -> Shapes));
  1483.      END_CASE
  1484.  
  1485.      CASE (QUADRIC_TOKEN)
  1486.        Local_Shape = Parse_Quadric ();
  1487.        Local_Shape -> Parent_Object = Parent_Object;
  1488.        if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1489.           Invert ((OBJECT *) Local_Shape);
  1490.        First_Shape_Parsed = TRUE;
  1491.        Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1492.                (OBJECT **) &(Container -> Shapes));
  1493.      END_CASE
  1494.  
  1495.      CASE (UNION_TOKEN)
  1496.        Local_Shape = (SHAPE *) Parse_CSG (CSG_UNION_TYPE, Parent_Object);
  1497.        if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1498.           Invert ((OBJECT *) Local_Shape);
  1499.        First_Shape_Parsed = TRUE;
  1500.        Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1501.                (OBJECT **) &(Container -> Shapes));
  1502.      END_CASE
  1503.  
  1504.      CASE (INTERSECTION_TOKEN)
  1505.        Local_Shape = (SHAPE *) Parse_CSG (CSG_INTERSECTION_TYPE, Parent_Object);
  1506.        if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1507.           Invert ((OBJECT *) Local_Shape);
  1508.        First_Shape_Parsed = TRUE;
  1509.        Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1510.                (OBJECT **) &(Container -> Shapes));
  1511.      END_CASE
  1512.  
  1513.      CASE (DIFFERENCE_TOKEN)
  1514.        Local_Shape = (SHAPE *) Parse_CSG (CSG_DIFFERENCE_TYPE, Parent_Object);
  1515.        if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed)
  1516.           Invert ((OBJECT *) Local_Shape);
  1517.        First_Shape_Parsed = TRUE;
  1518.        Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1519.                (OBJECT **) &(Container -> Shapes));
  1520.      END_CASE
  1521.  
  1522.      OTHERWISE
  1523.         UNGET
  1524.         EXIT
  1525.      END_CASE
  1526.   END_EXPECT
  1527.  
  1528.   EXPECT
  1529.      CASE3 (END_UNION_TOKEN, END_INTERSECTION_TOKEN, END_DIFFERENCE_TOKEN)
  1530.         EXIT
  1531.      END_CASE
  1532.  
  1533.      CASE (TRANSLATE_TOKEN)
  1534.         Parse_Vector (&Local_Vector);
  1535.         Translate((OBJECT *) Container, &Local_Vector);
  1536.      END_CASE
  1537.  
  1538.      CASE (ROTATE_TOKEN)
  1539.         Parse_Vector (&Local_Vector);
  1540.         Rotate ((OBJECT *) Container, &Local_Vector);
  1541.      END_CASE
  1542.  
  1543.      CASE (SCALE_TOKEN)
  1544.         Parse_Vector (&Local_Vector);
  1545.         Scale ((OBJECT *) Container, &Local_Vector);
  1546.      END_CASE
  1547.  
  1548.      CASE (INVERSE_TOKEN)
  1549.         Invert ((OBJECT *) Container);
  1550.      END_CASE
  1551.  
  1552.      OTHERWISE
  1553.         Parse_Error (END_QUADRIC_TOKEN);
  1554.      END_CASE
  1555.   END_EXPECT
  1556.  
  1557.   return ((CSG_SHAPE *) Container);
  1558.   }
  1559.  
  1560. SHAPE *Parse_Shape (Object)
  1561.   OBJECT *Object;
  1562.   {
  1563.   SHAPE *Local_Shape;
  1564.  
  1565.   EXPECT
  1566.     CASE (SPHERE_TOKEN)
  1567.       Local_Shape = Parse_Sphere ();
  1568.       Local_Shape -> Parent_Object = Object;
  1569.       EXIT
  1570.     END_CASE
  1571.  
  1572.     CASE (PLANE_TOKEN)
  1573.       Local_Shape = Parse_Plane ();
  1574.       Local_Shape -> Parent_Object = Object;
  1575.       EXIT
  1576.     END_CASE
  1577.  
  1578.     CASE (TRIANGLE_TOKEN)
  1579.       Local_Shape = Parse_Triangle ();
  1580.       Local_Shape -> Parent_Object = Object;
  1581.       EXIT
  1582.     END_CASE
  1583.  
  1584.     CASE (SMOOTH_TRIANGLE_TOKEN)
  1585.       Local_Shape = Parse_Smooth_Triangle ();
  1586.       Local_Shape -> Parent_Object = Object;
  1587.       EXIT
  1588.     END_CASE
  1589.  
  1590.     CASE (QUADRIC_TOKEN)
  1591.       Local_Shape = Parse_Quadric ();
  1592.       Local_Shape -> Parent_Object = Object;
  1593.       EXIT
  1594.     END_CASE
  1595.  
  1596.     CASE (UNION_TOKEN)
  1597.       Local_Shape = (SHAPE *) Parse_CSG (CSG_UNION_TYPE, Object);
  1598.       EXIT
  1599.     END_CASE
  1600.  
  1601.     CASE (INTERSECTION_TOKEN)
  1602.       Local_Shape = (SHAPE *) Parse_CSG (CSG_INTERSECTION_TYPE, Object);
  1603.       EXIT
  1604.     END_CASE
  1605.  
  1606.     CASE (DIFFERENCE_TOKEN)
  1607.       Local_Shape = (SHAPE *) Parse_CSG (CSG_DIFFERENCE_TYPE, Object);
  1608.       EXIT
  1609.     END_CASE
  1610.  
  1611.     OTHERWISE
  1612.        Parse_Error (QUADRIC_TOKEN);
  1613.     END_CASE
  1614.   END_EXPECT
  1615.   return (Local_Shape);
  1616.   }
  1617.  
  1618. OBJECT *Parse_Object ()
  1619.   {
  1620.   OBJECT *Object;
  1621.   SHAPE *Local_Shape;
  1622.   VECTOR Local_Vector;
  1623.   CONSTANT Constant_Id;
  1624.   int i;
  1625.  
  1626.   Object = NULL;
  1627.  
  1628.   EXPECT
  1629.     CASE (IDENTIFIER_TOKEN)
  1630.       if ((Constant_Id = Find_Constant()) != -1)
  1631.         if (Constants[(int)Constant_Id].Constant_Type == OBJECT_CONSTANT)
  1632.           Object = (OBJECT *) Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1633.         else
  1634.           Type_Error ();
  1635.       else
  1636.         Undeclared ();
  1637.       EXIT
  1638.     END_CASE
  1639.  
  1640.     CASE5 (SPHERE_TOKEN, QUADRIC_TOKEN, UNION_TOKEN,
  1641.            INTERSECTION_TOKEN, DIFFERENCE_TOKEN)
  1642.     CASE3 (TRIANGLE_TOKEN, SMOOTH_TRIANGLE_TOKEN, PLANE_TOKEN)
  1643.         UNGET
  1644.         if (Object == NULL)
  1645.            Object = Get_Object();
  1646.  
  1647.         Local_Shape = Parse_Shape(Object);
  1648.         Link((OBJECT *)Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object),
  1649.                 (OBJECT **) &(Object -> Shape));
  1650.         EXIT
  1651.     END_CASE
  1652.  
  1653.     OTHERWISE
  1654.         Parse_Error (QUADRIC_TOKEN);
  1655.         EXIT
  1656.     END_CASE
  1657.   END_EXPECT
  1658.  
  1659.   EXPECT
  1660.     CASE (BOUNDED_TOKEN)
  1661.        EXPECT
  1662.           CASE (END_BOUNDED_TOKEN)
  1663.              EXIT
  1664.           END_CASE
  1665.  
  1666.           OTHERWISE
  1667.              UNGET
  1668.              Local_Shape = Parse_Shape(Object);
  1669.              Link((OBJECT *) Local_Shape,
  1670.                   (OBJECT **) &(Local_Shape -> Next_Object),
  1671.                   (OBJECT **) &(Object -> Bounding_Shapes));
  1672.           END_CASE
  1673.        END_EXPECT       
  1674.     END_CASE
  1675.  
  1676.     CASE2 (COLOR_TOKEN, COLOUR_TOKEN)
  1677.        Parse_Colour (&(Object -> Object_Colour));
  1678.        if (Object->Object_Colour.Alpha != 0.0)
  1679.           Object->Transparency = TRUE;
  1680.     END_CASE
  1681.  
  1682.     CASE (TEXTURE_TOKEN)
  1683.       Object -> Object_Texture = Parse_Texture (Object->Object_Texture);
  1684.       if ((Object->Object_Texture->Colour1.Alpha != 0.0) ||
  1685.           (Object->Object_Texture->Colour2.Alpha != 0.0))
  1686.          Object->Transparency = TRUE;
  1687.       else
  1688.          if (Object->Object_Texture->Colour_Map != NULL)
  1689.             for (i = 0 ; i < Object->Object_Texture->Colour_Map->Number_Of_Entries ; i++)
  1690.                if ((Object->Object_Texture->Colour_Map->Colour_Map_Entries[i].Start_Colour.Alpha != 0.0) ||
  1691.                    (Object->Object_Texture->Colour_Map->Colour_Map_Entries[i].Start_Colour.Alpha != 0.0)) {
  1692.                   Object->Transparency = TRUE;
  1693.                   break;
  1694.                   }
  1695.     END_CASE
  1696.  
  1697.     CASE (LIGHT_SOURCE_TOKEN)
  1698.       Object -> Light_Source_Flag = TRUE;
  1699.     END_CASE
  1700.  
  1701.     CASE (TRANSLATE_TOKEN)
  1702.        Parse_Vector (&Local_Vector);
  1703.        Translate (Object, &Local_Vector);
  1704.     END_CASE
  1705.  
  1706.     CASE (ROTATE_TOKEN)
  1707.        Parse_Vector (&Local_Vector);
  1708.        Rotate (Object, &Local_Vector);
  1709.     END_CASE
  1710.  
  1711.     CASE (SCALE_TOKEN)
  1712.        Parse_Vector (&Local_Vector);
  1713.        Scale (Object, &Local_Vector);
  1714.     END_CASE
  1715.  
  1716.     CASE (INVERSE_TOKEN)
  1717.        Invert (Object);
  1718.     END_CASE
  1719.  
  1720.     CASE (AMBIENT_TOKEN)
  1721.       if (Object -> Object_Texture == Default_Texture)
  1722.          Object -> Object_Texture = Get_Texture();
  1723.  
  1724.       (Object -> Object_Texture -> Object_Ambient) = Parse_Float ();
  1725.     END_CASE
  1726.  
  1727.     CASE (BRILLIANCE_TOKEN)
  1728.       if (Object -> Object_Texture == Default_Texture)
  1729.          Object -> Object_Texture = Get_Texture();
  1730.  
  1731.       (Object -> Object_Texture -> Object_Brilliance) = Parse_Float ();
  1732.     END_CASE
  1733.  
  1734.     CASE (ROUGHNESS_TOKEN)
  1735.       if (Object -> Object_Texture == Default_Texture)
  1736.          Object -> Object_Texture = Get_Texture();
  1737.  
  1738.       (Object -> Object_Texture -> Object_Roughness) = Parse_Float ();
  1739.       if (Object -> Object_Texture -> Object_Roughness > 1.0)
  1740.          Object -> Object_Texture -> Object_Roughness = 1.0;
  1741.       if (Object -> Object_Texture -> Object_Roughness < 0.001)
  1742.          Object -> Object_Texture -> Object_Roughness = 0.001;
  1743.     END_CASE
  1744.  
  1745.     CASE (PHONGSIZE_TOKEN)
  1746.       if (Object -> Object_Texture == Default_Texture)
  1747.          Object -> Object_Texture = Get_Texture();
  1748.  
  1749.       (Object -> Object_Texture -> Object_PhongSize) = Parse_Float ();
  1750.       if (Object -> Object_Texture -> Object_PhongSize < 1.0)
  1751.          Object -> Object_Texture -> Object_PhongSize = 1.0;
  1752.       if (Object -> Object_Texture -> Object_PhongSize > 100)
  1753.          Object -> Object_Texture -> Object_PhongSize = 100;
  1754.     END_CASE
  1755.  
  1756.     CASE (DIFFUSE_TOKEN)
  1757.       if (Object -> Object_Texture == Default_Texture)
  1758.          Object -> Object_Texture = Get_Texture();
  1759.  
  1760.       (Object -> Object_Texture -> Object_Diffuse) = Parse_Float ();
  1761.     END_CASE
  1762.  
  1763.     CASE (SPECULAR_TOKEN)
  1764.       if (Object -> Object_Texture == Default_Texture)
  1765.          Object -> Object_Texture = Get_Texture();
  1766.  
  1767.       (Object -> Object_Texture -> Object_Specular) = Parse_Float ();
  1768.     END_CASE
  1769.  
  1770.     CASE (PHONG_TOKEN)
  1771.       if (Object -> Object_Texture == Default_Texture)
  1772.          Object -> Object_Texture = Get_Texture();
  1773.  
  1774.       (Object -> Object_Texture -> Object_Phong) = Parse_Float ();
  1775.     END_CASE
  1776.  
  1777.     CASE (IOR_TOKEN)
  1778.       if (Object -> Object_Texture == Default_Texture)
  1779.          Object -> Object_Texture = Get_Texture();
  1780.  
  1781.       (Object -> Object_Texture -> Object_Index_Of_Refraction) = Parse_Float ();
  1782.     END_CASE
  1783.  
  1784.     CASE (REFRACTION_TOKEN)
  1785.       if (Object -> Object_Texture == Default_Texture)
  1786.          Object -> Object_Texture = Get_Texture();
  1787.  
  1788.       (Object -> Object_Texture -> Object_Refraction) = Parse_Float ();
  1789.     END_CASE
  1790.  
  1791.     CASE (REFLECTION_TOKEN)
  1792.       if (Object -> Object_Texture == Default_Texture)
  1793.          Object -> Object_Texture = Get_Texture();
  1794.  
  1795.       (Object -> Object_Texture -> Object_Reflection) = Parse_Float ();
  1796.     END_CASE
  1797.  
  1798.     CASE (END_OBJECT_TOKEN)
  1799.       EXIT
  1800.     END_CASE
  1801.  
  1802.     OTHERWISE
  1803.       Parse_Error (END_OBJECT_TOKEN);
  1804.     END_CASE
  1805.  
  1806.   END_EXPECT
  1807.  
  1808.   return (Object);
  1809.   }
  1810.  
  1811. OBJECT *Parse_Composite ()
  1812.   {
  1813.   COMPOSITE *Local_Composite;
  1814.   OBJECT *Local_Object;
  1815.   SHAPE *Local_Shape;
  1816.   CONSTANT Constant_Id;
  1817.   VECTOR Local_Vector;
  1818.  
  1819.   Local_Composite = NULL;
  1820.  
  1821.   EXPECT
  1822.     CASE (IDENTIFIER_TOKEN)
  1823.       if ((Constant_Id = Find_Constant()) != -1)
  1824.         if (Constants[(int)Constant_Id].Constant_Type == COMPOSITE_CONSTANT)
  1825.           Local_Composite = (COMPOSITE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data);
  1826.         else          
  1827.           Type_Error ();
  1828.       else
  1829.         Undeclared ();
  1830.     END_CASE
  1831.  
  1832.     CASE (COMPOSITE_TOKEN)
  1833.       if (Local_Composite == NULL)       
  1834.            Local_Composite = Get_Composite_Object();
  1835.  
  1836.       Local_Object = Parse_Composite();
  1837.       Link((OBJECT *) Local_Object,(OBJECT **) &(Local_Object -> Next_Object),
  1838.               (OBJECT **) &(Local_Composite -> Objects));
  1839.     END_CASE
  1840.  
  1841.     CASE (OBJECT_TOKEN)
  1842.       if (Local_Composite == NULL)       
  1843.            Local_Composite = Get_Composite_Object();
  1844.  
  1845.       Local_Object = Parse_Object();
  1846.       Link(Local_Object, &(Local_Object -> Next_Object),
  1847.                &(Local_Composite -> Objects));
  1848.  
  1849.       if (Local_Object -> Light_Source_Flag)
  1850.          Link(Local_Object, &(Local_Object -> Next_Light_Source),
  1851.                &(Parsing_Frame_Ptr -> Light_Sources));
  1852.     END_CASE
  1853.  
  1854.     CASE (END_COMPOSITE_TOKEN)
  1855.       UNGET
  1856.       if (Local_Composite == NULL)       
  1857.         Local_Composite = Get_Composite_Object();
  1858.  
  1859.       EXIT
  1860.     END_CASE
  1861.  
  1862.     OTHERWISE
  1863.        UNGET
  1864.        EXIT
  1865.     END_CASE
  1866.   END_EXPECT
  1867.  
  1868.   EXPECT
  1869.     CASE (END_COMPOSITE_TOKEN)
  1870.        EXIT
  1871.     END_CASE
  1872.  
  1873.     CASE (BOUNDED_TOKEN)
  1874.        EXPECT
  1875.           CASE (END_BOUNDED_TOKEN)
  1876.              EXIT
  1877.           END_CASE
  1878.  
  1879.           OTHERWISE
  1880.              UNGET
  1881.              Local_Shape = Parse_Shape((OBJECT *) Local_Composite);
  1882.              Link((OBJECT *) Local_Shape,
  1883.                   (OBJECT **) &(Local_Shape -> Next_Object),
  1884.                   (OBJECT **) &(Local_Composite -> Bounding_Shapes));
  1885.           END_CASE
  1886.        END_EXPECT       
  1887.     END_CASE
  1888.  
  1889.     CASE (TRANSLATE_TOKEN)
  1890.        Parse_Vector (&Local_Vector);
  1891.        Translate ((OBJECT *) Local_Composite, &Local_Vector);
  1892.     END_CASE
  1893.  
  1894.     CASE (ROTATE_TOKEN)
  1895.        Parse_Vector (&Local_Vector);
  1896.        Rotate ((OBJECT *) Local_Composite, &Local_Vector);
  1897.     END_CASE
  1898.  
  1899.     CASE (SCALE_TOKEN)
  1900.        Parse_Vector (&Local_Vector);
  1901.        Scale ((OBJECT *) Local_Composite, &Local_Vector);
  1902.     END_CASE
  1903.  
  1904.      CASE (INVERSE_TOKEN)
  1905.         Invert ((OBJECT *) Local_Composite);
  1906.      END_CASE
  1907.  
  1908.     OTHERWISE
  1909.        Parse_Error (END_COMPOSITE_TOKEN);
  1910.     END_CASE
  1911.   END_EXPECT
  1912.  
  1913.   return ((OBJECT *) Local_Composite);
  1914.   }
  1915.  
  1916. void Parse_Fog ()
  1917.    {
  1918.    EXPECT
  1919.       CASE (COLOUR_TOKEN)
  1920.          Parse_Colour (&Parsing_Frame_Ptr->Fog_Colour);
  1921.       END_CASE
  1922.  
  1923.       CASE (FLOAT_TOKEN)
  1924.          Parsing_Frame_Ptr->Fog_Distance = Token.Token_Float;
  1925.       END_CASE
  1926.  
  1927.       CASE (END_FOG_TOKEN)
  1928.          EXIT
  1929.       END_CASE
  1930.  
  1931.       OTHERWISE
  1932.          Parse_Error (END_FOG_TOKEN);
  1933.       END_CASE
  1934.    END_EXPECT
  1935.    }
  1936.  
  1937. void Parse_Frame ()
  1938.   {
  1939.   OBJECT *Local_Object;
  1940.  
  1941.   EXPECT
  1942.     CASE (FOG_TOKEN)
  1943.        Parse_Fog();
  1944.     END_CASE
  1945.  
  1946.     CASE (OBJECT_TOKEN)
  1947.       Local_Object = Parse_Object();
  1948.       Link(Local_Object, &(Local_Object -> Next_Object),
  1949.              &(Parsing_Frame_Ptr -> Objects));
  1950.  
  1951.       if (Local_Object -> Light_Source_Flag)
  1952.          Link(Local_Object, &(Local_Object -> Next_Light_Source),
  1953.                &(Parsing_Frame_Ptr -> Light_Sources));
  1954.     END_CASE
  1955.  
  1956.     CASE (COMPOSITE_TOKEN)
  1957.       Local_Object = Parse_Composite();
  1958.       Link(Local_Object, &(Local_Object -> Next_Object),
  1959.             &(Parsing_Frame_Ptr -> Objects));
  1960.     END_CASE
  1961.  
  1962.     CASE (VIEW_POINT_TOKEN)
  1963.       Parse_Viewpoint(&(Parsing_Frame_Ptr -> View_Point));
  1964.     END_CASE
  1965.  
  1966.     CASE (DECLARE_TOKEN)
  1967.       Parse_Declare ();
  1968.     END_CASE
  1969.  
  1970.     CASE (END_OF_FILE_TOKEN)
  1971.       EXIT
  1972.     END_CASE
  1973.  
  1974.     OTHERWISE 
  1975.       Parse_Error (OBJECT_TOKEN);
  1976.     END_CASE
  1977.   END_EXPECT
  1978.   }
  1979.  
  1980. void Parse_Viewpoint (Given_Vp)
  1981.   VIEWPOINT *Given_Vp;
  1982.   {
  1983.   CONSTANT Constant_Id;
  1984.   VECTOR Local_Vector, Temp_Vector;
  1985.   DBL Direction_Length, Up_Length, Right_Length, Handedness;
  1986.  
  1987.   Init_Viewpoint (Given_Vp);
  1988.  
  1989.   EXPECT
  1990.     CASE (IDENTIFIER_TOKEN)
  1991.       if ((Constant_Id = Find_Constant()) != -1)
  1992.         if (Constants[(int)Constant_Id].Constant_Type == VIEW_POINT_CONSTANT)
  1993.           *Given_Vp = 
  1994.              *((VIEWPOINT*) Constants[(int)Constant_Id].Constant_Data);
  1995.         else
  1996.           Type_Error ();
  1997.       else
  1998.         Undeclared ();
  1999.     END_CASE
  2000.  
  2001.     CASE (LOCATION_TOKEN)
  2002.       Parse_Vector(&(Given_Vp -> Location));
  2003.     END_CASE
  2004.  
  2005.     CASE (DIRECTION_TOKEN)
  2006.       Parse_Vector(&(Given_Vp -> Direction));
  2007.     END_CASE
  2008.  
  2009.     CASE (UP_TOKEN)
  2010.       Parse_Vector(&(Given_Vp -> Up));
  2011.     END_CASE
  2012.  
  2013.     CASE (RIGHT_TOKEN)
  2014.       Parse_Vector(&(Given_Vp -> Right));
  2015.     END_CASE
  2016.  
  2017.     CASE (SKY_TOKEN)
  2018.       Parse_Vector(&(Given_Vp -> Sky));
  2019.     END_CASE
  2020.  
  2021.     CASE (LOOK_AT_TOKEN)
  2022.        VLength (Direction_Length, Given_Vp->Direction);
  2023.        VLength (Up_Length, Given_Vp->Up);
  2024.        VLength (Right_Length, Given_Vp->Right);
  2025.        VCross (Temp_Vector, Given_Vp->Direction, Given_Vp->Up);
  2026.        VDot (Handedness, Temp_Vector, Given_Vp->Right);
  2027.        Parse_Vector(&Given_Vp->Direction);
  2028.  
  2029.        VSub (Given_Vp->Direction, Given_Vp->Direction, Given_Vp->Location);
  2030.        VNormalize (Given_Vp->Direction, Given_Vp->Direction);
  2031.        VCross(Given_Vp->Right, Given_Vp->Direction, Given_Vp->Sky);
  2032.        VNormalize (Given_Vp->Right, Given_Vp->Right);
  2033.        VCross (Given_Vp->Up, Given_Vp->Right, Given_Vp->Direction);
  2034.        VScale (Given_Vp->Direction, Given_Vp->Direction, Direction_Length);
  2035.        if (Handedness >= 0.0) {
  2036.           VScale (Given_Vp->Right, Given_Vp->Right, Right_Length);
  2037.           }
  2038.        else {
  2039.           VScale (Given_Vp->Right, Given_Vp->Right, -Right_Length);
  2040.           }
  2041.  
  2042.        VScale (Given_Vp->Up, Given_Vp->Up, Up_Length);       
  2043.     END_CASE
  2044.  
  2045.     CASE (TRANSLATE_TOKEN)
  2046.        Parse_Vector (&Local_Vector);
  2047.        Translate ((OBJECT *) Given_Vp, &Local_Vector);
  2048.     END_CASE
  2049.  
  2050.     CASE (ROTATE_TOKEN)
  2051.        Parse_Vector (&Local_Vector);
  2052.        Rotate ((OBJECT *) Given_Vp, &Local_Vector);
  2053.     END_CASE
  2054.  
  2055.     CASE (SCALE_TOKEN)
  2056.        Parse_Vector (&Local_Vector);
  2057.        Scale ((OBJECT *) Given_Vp, &Local_Vector);
  2058.     END_CASE
  2059.  
  2060.     CASE (END_VIEW_POINT_TOKEN)
  2061.       EXIT
  2062.     END_CASE
  2063.  
  2064.     OTHERWISE
  2065.       Parse_Error (END_VIEW_POINT_TOKEN);
  2066.     END_CASE
  2067.   END_EXPECT
  2068.   }
  2069.  
  2070. void Parse_Declare ()
  2071.   {
  2072.   CONSTANT Constant_Id;
  2073.  
  2074.   struct Constant_Struct *Constant_Ptr;
  2075.  
  2076.   GET (IDENTIFIER_TOKEN);
  2077.   if ((Constant_Id = Find_Constant()) == -1)
  2078.     if (++Number_Of_Constants >= MAX_CONSTANTS)
  2079.       Error ("Too many constants");
  2080.     else
  2081.       Constant_Id = Number_Of_Constants;
  2082.  
  2083.   Constant_Ptr = &(Constants[(int)Constant_Id]);
  2084.   GET (EQUALS_TOKEN);
  2085.  
  2086.   EXPECT
  2087.     CASE (OBJECT_TOKEN)
  2088.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2089.       Constant_Ptr -> Constant_Data = (char *) Parse_Object();
  2090.       Constant_Ptr -> Constant_Type = OBJECT_CONSTANT;
  2091.       EXIT
  2092.     END_CASE
  2093.  
  2094.     CASE (SPHERE_TOKEN)
  2095.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2096.       Constant_Ptr -> Constant_Data = (char *) Parse_Sphere ();
  2097.       Constant_Ptr -> Constant_Type = SPHERE_CONSTANT;
  2098.       EXIT
  2099.     END_CASE
  2100.  
  2101.     CASE (PLANE_TOKEN)
  2102.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2103.       Constant_Ptr -> Constant_Data = (char *) Parse_Plane ();
  2104.       Constant_Ptr -> Constant_Type = PLANE_CONSTANT;
  2105.       EXIT
  2106.     END_CASE
  2107.  
  2108.     CASE (TRIANGLE_TOKEN)
  2109.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2110.       Constant_Ptr -> Constant_Data = (char *) Parse_Triangle ();
  2111.       Constant_Ptr -> Constant_Type = TRIANGLE_CONSTANT;
  2112.       EXIT
  2113.     END_CASE
  2114.  
  2115.     CASE (SMOOTH_TRIANGLE_TOKEN)
  2116.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2117.       Constant_Ptr -> Constant_Data = (char *) Parse_Smooth_Triangle ();
  2118.       Constant_Ptr -> Constant_Type = SMOOTH_TRIANGLE_CONSTANT;
  2119.       EXIT
  2120.     END_CASE
  2121.  
  2122.     CASE (QUADRIC_TOKEN)
  2123.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2124.       Constant_Ptr -> Constant_Data = (char *) Parse_Quadric ();
  2125.       Constant_Ptr -> Constant_Type = QUADRIC_CONSTANT;
  2126.       EXIT
  2127.     END_CASE
  2128.  
  2129.     CASE (INTERSECTION_TOKEN)
  2130.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2131.       Constant_Ptr -> Constant_Data = (char *) Parse_CSG(CSG_INTERSECTION_TYPE, NULL);
  2132.       Constant_Ptr -> Constant_Type = CSG_INTERSECTION_CONSTANT;
  2133.       EXIT
  2134.     END_CASE
  2135.  
  2136.     CASE (UNION_TOKEN)
  2137.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2138.       Constant_Ptr -> Constant_Data = (char *) Parse_CSG(CSG_UNION_TYPE, NULL);
  2139.       Constant_Ptr -> Constant_Type = CSG_UNION_CONSTANT;
  2140.       EXIT
  2141.     END_CASE
  2142.  
  2143.     CASE (DIFFERENCE_TOKEN)
  2144.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2145.       Constant_Ptr -> Constant_Data = (char *) Parse_CSG(CSG_DIFFERENCE_TYPE, NULL);
  2146.       Constant_Ptr -> Constant_Type = CSG_DIFFERENCE_CONSTANT;
  2147.       EXIT
  2148.     END_CASE
  2149.  
  2150.     CASE (COMPOSITE_TOKEN)
  2151.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2152.       Constant_Ptr -> Constant_Data = (char *) Parse_Composite();
  2153.       Constant_Ptr -> Constant_Type = COMPOSITE_CONSTANT;
  2154.       EXIT
  2155.     END_CASE
  2156.  
  2157.     CASE (TEXTURE_TOKEN)
  2158.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2159.       Constant_Ptr -> Constant_Data = (char *) Parse_Texture(Default_Texture);
  2160.       Constant_Ptr -> Constant_Type = TEXTURE_CONSTANT;
  2161.       EXIT
  2162.     END_CASE
  2163.  
  2164.     CASE (VIEW_POINT_TOKEN)
  2165.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2166.       Constant_Ptr -> Constant_Data = (char *) Get_Viewpoint();
  2167.       Constant_Ptr -> Constant_Type = VIEW_POINT_CONSTANT;
  2168.       Parse_Viewpoint((VIEWPOINT *) Constant_Ptr -> Constant_Data);
  2169.       EXIT
  2170.     END_CASE
  2171.  
  2172.     CASE2 (COLOR_TOKEN, COLOUR_TOKEN)
  2173.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2174.       Constant_Ptr -> Constant_Data = (char *) Get_Colour();
  2175.       Constant_Ptr -> Constant_Type = COLOUR_CONSTANT;
  2176.       Parse_Colour ((COLOUR *) Constant_Ptr -> Constant_Data);
  2177.       EXIT
  2178.     END_CASE
  2179.  
  2180.     CASE (LEFT_ANGLE_TOKEN)
  2181.       UNGET
  2182.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2183.       Constant_Ptr -> Constant_Data = (char *) Get_Vector();
  2184.       Constant_Ptr -> Constant_Type = VECTOR_CONSTANT;
  2185.       Parse_Vector((VECTOR *) Constant_Ptr -> Constant_Data);
  2186.       EXIT
  2187.     END_CASE
  2188.  
  2189.     CASE3 (DASH_TOKEN, PLUS_TOKEN, FLOAT_TOKEN)
  2190.       UNGET
  2191.       Constant_Ptr -> Identifier_Number = Token.Identifier_Number;
  2192.       Constant_Ptr -> Constant_Data = (char *) Get_Float();
  2193.       Constant_Ptr -> Constant_Type = FLOAT_CONSTANT;
  2194.       *(Constant_Ptr -> Constant_Data) = Parse_Float();
  2195.       EXIT
  2196.     END_CASE
  2197.  
  2198.     OTHERWISE
  2199.       Parse_Error (OBJECT_TOKEN);
  2200.     END_CASE
  2201.   END_EXPECT
  2202.   }
  2203.  
  2204. void Init_Viewpoint (vp)
  2205.   VIEWPOINT *vp;
  2206.   {
  2207.   vp -> Methods = (void *) &Viewpoint_Methods;
  2208.   vp -> Type = VIEWPOINT_TYPE;
  2209.   Make_Vector (&vp->Location, 0.0, 0.0, 0.0);
  2210.   Make_Vector (&vp->Direction, 0.0, 0.0, 1.0);
  2211.   Make_Vector (&vp->Up, 0.0, 1.0, 0.0);
  2212.   Make_Vector (&vp->Right, 1.0, 0.0, 0.0);
  2213.   Make_Vector (&vp->Sky, 0.0, 1.0, 0.0);
  2214.   }
  2215.  
  2216. void Link (New_Object, Field, Old_Object_List)
  2217.   OBJECT *New_Object, **Field, **Old_Object_List;
  2218.   {
  2219.   *Field = *Old_Object_List;
  2220.   *Old_Object_List = New_Object;
  2221.   }
  2222.  
  2223. CONSTANT Find_Constant()
  2224.   {
  2225.   register int i;
  2226.  
  2227.   for (i = 1 ; i <= Number_Of_Constants ; i++)
  2228.     if (Constants [i].Identifier_Number == Token.Identifier_Number)
  2229.       return (i);
  2230.  
  2231.   return (-1);
  2232.   }
  2233.  
  2234.  
  2235. char *Get_Token_String (Token_Id)
  2236.   TOKEN Token_Id;
  2237.   {
  2238.   register int i;
  2239.  
  2240.   for (i = 0 ; i < LAST_TOKEN ; i++)
  2241.      if (Reserved_Words[i].Token_Number == Token_Id)
  2242.         return (Reserved_Words[i].Token_Name);
  2243.   return ("");
  2244.   }
  2245.  
  2246. void Parse_Error (Token_Id)
  2247.   TOKEN Token_Id;
  2248.   {
  2249.   char *expected, *found;
  2250.  
  2251.   fprintf (stderr, "Error in file %s line %d\n", Current_File_Name,
  2252.                                                  Token.Token_Line_No);
  2253.   expected = Get_Token_String (Token_Id);
  2254.   found = Get_Token_String (Token.Token_Id);
  2255.   fprintf (stderr, "%s expected but %s found instead\n", expected, found);
  2256.   exit(0);
  2257.   }
  2258.  
  2259. void Type_Error ()
  2260.   {
  2261.   fprintf (stderr, "Error in file %s line %d\n", Current_File_Name,
  2262.                                                  Token.Token_Line_No);
  2263.   fprintf (stderr, "Identifier %s is the wrong type\n",
  2264.             &Token.Token_String[0]);
  2265.   exit (0);
  2266.   }
  2267.  
  2268. void Undeclared ()
  2269.   {
  2270.   fprintf (stderr, "Error in file %s line %d\n", Current_File_Name,
  2271.                                                  Token.Token_Line_No);
  2272.   fprintf (stderr, "Undeclared identifier %s\n", &Token.Token_String[0]);
  2273.   exit (0);
  2274.   }
  2275.  
  2276. void Error (str)
  2277.   char *str;
  2278.   {
  2279.   fprintf (stderr, "Error in file %s line %d\n", Current_File_Name,
  2280.                                                  Token.Token_Line_No);
  2281.   fputs (str, stderr);
  2282.   exit (0);
  2283.   }
  2284.  
  2285.