amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (09/04/90)
Submitted-by: David Schanen <mtv@milton.u.washington.edu> Posting-number: Volume 90, Issue 257 Archive-name: applications/dkbtrace-2.01/part09 #!/bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 9 (of 10)." # Contents: src/parse.c # Wrapped by tadguy@abcfd20 on Mon Sep 3 19:21:22 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'src/parse.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/parse.c'\" else echo shar: Extracting \"'src/parse.c'\" \(63678 characters\) sed "s/^X//" >'src/parse.c' <<'END_OF_FILE' X/***************************************************************************** X* X* parse.c X* X* from DKBTrace (c) 1990 David Buck X* X* This module implements a parser for the scene description files. X* X* This software is freely distributable. The source and/or object code may be X* copied or uploaded to communications services so long as this notice remains X* at the top of each file. If any changes are made to the program, you must X* clearly indicate in the documentation and in the programs startup message X* who it was who made the changes. The documentation should also describe what X* those changes were. This software may not be included in whole or in X* part into any commercial package without the express written consent of the X* author. It may, however, be included in other public domain or freely X* distributed software so long as the proper credit for the software is given. X* X* This software is provided as is without any guarantees or warranty. Although X* the author has attempted to find and correct any bugs in the software, he X* is not responsible for any damage caused by the use of the software. The X* author is under no obligation to provide service, corrections, or upgrades X* to this package. X* X* Despite all the legal stuff above, if you do find bugs, I would like to hear X* about them. Also, if you have any comments or questions, you may contact me X* at the following address: X* X* David Buck X* 22C Sonnet Cres. X* Nepean Ontario X* Canada, K2H 8W7 X* X* I can also be reached on the following bulleton boards: X* X* ATX (613) 526-4141 X* OMX (613) 731-3419 X* Mystic (613) 731-0088 or (613) 731-6698 X* X* Fidonet: 1:163/109.9 X* Internet: David_Buck@Carleton.CA X* X* IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es: X* X* Lattice BBS (708) 916-1200 X* The Information Exchange BBS (708) 945-5575 X* Stillwaters BBS (708) 403-2826 X* X*****************************************************************************/ X X#include "frame.h" X#include "vector.h" X#include "dkbproto.h" X X/* This file implements a simple recursive-descent parser for reading the Xinput file. */ X Xextern FILE *Token_File; XFRAME *Parsing_Frame_Ptr; Xchar Current_File_Name[20]; X Xextern METHODS Composite_Methods; Xextern METHODS Basic_Object_Methods; Xextern METHODS Sphere_Methods; Xextern METHODS Quadric_Methods; Xextern METHODS Viewpoint_Methods; Xextern METHODS Plane_Methods; Xextern METHODS Triangle_Methods; Xextern METHODS Smooth_Triangle_Methods; Xextern METHODS CSG_Union_Methods; Xextern METHODS CSG_Intersection_Methods; X Xextern struct Reserved_Word_Struct Reserved_Words []; Xextern DBL Antialias_Threshold; X Xstruct Token_Struct Token; X X#define MAX_CONSTANTS 100 Xstruct Constant_Struct Constants[MAX_CONSTANTS]; Xint Number_Of_Constants; XTEXTURE *Default_Texture; Xint Degenerate_Triangles; X X/* Here we create out own little language for doing the parsing. It Xmakes the code easier to read. */ X X#define EXPECT { int Exit_Flag; Exit_Flag = FALSE; \ X while (!Exit_Flag) {Get_Token(); switch (Token.Token_Id) { X#define CASE(x) case x: X#define CASE2(x, y) case x: case y: X#define CASE3(x, y, z) case x: case y: case z: X#define CASE4(w, x, y, z) case w: case x: case y: case z: X#define CASE5(v, w, x, y, z) case v: case w: case x: case y: case z: X#define END_CASE break; X#define EXIT Exit_Flag = TRUE; X#define OTHERWISE default: X#define END_EXPECT } } } X#define GET(x) Get_Token(); if (Token.Token_Id != x) Parse_Error (x) X#define UNGET Unget_Token(); X X/* Parse the file into the given frame. */ Xvoid Parse (File, Frame_Ptr) X FILE *File; X FRAME *Frame_Ptr; X { X Token_File = File; X Parsing_Frame_Ptr = Frame_Ptr; X X Degenerate_Triangles = FALSE; X Token_Init (); X Frame_Init (); X Parse_Frame (); X if (Degenerate_Triangles) { X printf ("Cannot continue due to degenerate triangles.\n"); X exit(1); X } X } X Xvoid Token_Init () X { X Token.Unget_Token = FALSE; X Token.End_Of_File = FALSE; X Number_Of_Constants = 0; X } X X/* Read a token from the input file and store it in the Token variable. XIf the token is an INCLUDE token, then set the include file name and Xread another token. */ X Xint Get_Token () X { X char *str_ptr; X int Token_Id; X X if (Token.Unget_Token) X { X Token.Unget_Token = FALSE; X return (TRUE); X } X X if (Token.End_Of_File) X { X return (FALSE); X } X X if (fscanf (Token_File, "%d %d", &Token_Id, &Token.Token_Line_No) X != 2) X { X Token.End_Of_File = TRUE; X Token.Token_Id = END_OF_FILE_TOKEN; X return (TRUE); X } X X Token.Token_Id = Token_Id; X X getc(Token_File); X if (fgets (Token.Token_String, FILE_NAME_LENGTH, Token_File) == NULL) X { X Token.End_Of_File = TRUE; X Token.Token_Id = END_OF_FILE_TOKEN; X return (TRUE); X } X X if ((str_ptr = strchr(Token.Token_String, '\n')) != NULL) X *str_ptr = '\0'; X X if (Token.Token_Id == FLOAT_TOKEN) X if (sscanf (Token.Token_String, DBL_FORMAT_STRING, &(Token.Token_Float)) != 1) X { X printf ("Premature end of file in token file\n"); X printf ("Could not read float: %s\n", Token.Token_String); X Token.End_Of_File = TRUE; X Token.Token_Id = END_OF_FILE_TOKEN; X return (TRUE); X } X X if (Token.Token_Id == INCLUDE_TOKEN) { X strcpy (Current_File_Name, Token.Token_String); X return (Get_Token()); X } X X if (Token.Token_Id > LAST_TOKEN) X { X Token.Identifier_Number = (int) Token.Token_Id - (int) LAST_TOKEN; X Token.Token_Id = IDENTIFIER_TOKEN; X } X X return (TRUE); X } X X X/* Mark that the token has been put back into the input stream. The next Xcall to Get_Token will return the last-read token instead of reading a Xnew one from the file. */ X Xvoid Unget_Token () X { X Token.Unget_Token = TRUE; X } X X/* Set up the fields in the frame to default values. */ Xvoid Frame_Init () X { X Default_Texture = Get_Texture(); X Init_Viewpoint(&(Parsing_Frame_Ptr -> View_Point)); X Parsing_Frame_Ptr -> Light_Sources = NULL; X Parsing_Frame_Ptr -> Objects = NULL; X Parsing_Frame_Ptr -> Atmosphere_IOR = 1.0; X Parsing_Frame_Ptr -> Antialias_Threshold = Antialias_Threshold; X Parsing_Frame_Ptr -> Fog_Distance = 0.0; X Make_Colour (&(Parsing_Frame_Ptr->Fog_Colour), 0.0, 0.0, 0.0); X } X X/* Allocate and initialize a composite object. */ XCOMPOSITE *Get_Composite_Object() X { X COMPOSITE *New_Composite; X X if ((New_Composite = (COMPOSITE *) malloc (sizeof (COMPOSITE))) X == NULL) X Error ("Cannot allocate object"); X X New_Composite -> Objects = NULL; X New_Composite -> Next_Object = NULL; X New_Composite -> Next_Light_Source = NULL; X New_Composite -> Bounding_Shapes = NULL; X New_Composite -> Type = COMPOSITE_TYPE; X New_Composite -> Methods = &Composite_Methods; X return (New_Composite); X } X X/* Allocate and initialize a sphere. */ XSPHERE *Get_Sphere_Shape() X { X SPHERE *New_Shape; X X if ((New_Shape = (SPHERE *) malloc (sizeof (SPHERE))) == NULL) X Error ("Cannot allocate shape"); X X Make_Vector (&(New_Shape -> Center), 0.0, 0.0, 0.0); X New_Shape->Radius = 1.0; X New_Shape->Radius_Squared = 1.0; X New_Shape->Inverse_Radius = 1.0; X New_Shape -> Type = SPHERE_TYPE; X New_Shape -> Next_Object = NULL; X New_Shape -> Methods = &Sphere_Methods; X New_Shape -> VPCached = FALSE; X New_Shape -> Inverted = FALSE; X return (New_Shape); X } X X/* Allocate and initialize a quadric surface. */ XQUADRIC *Get_Quadric_Shape() X { X QUADRIC *New_Shape; X X if ((New_Shape = (QUADRIC *) malloc (sizeof (QUADRIC))) == NULL) X Error ("Cannot allocate shape"); X X Make_Vector (&(New_Shape -> Object_2_Terms), 1.0, 1.0, 1.0); X Make_Vector (&(New_Shape -> Object_Mixed_Terms), 0.0, 0.0, 0.0); X Make_Vector (&(New_Shape -> Object_Terms), 0.0, 0.0, 0.0); X New_Shape -> Object_Constant = 1.0; X New_Shape -> Object_VP_Constant = HUGE_VAL; X New_Shape -> Constant_Cached = FALSE; X New_Shape -> Non_Zero_Square_Term = FALSE; X New_Shape -> Type = QUADRIC_TYPE; X New_Shape -> Next_Object = NULL; X New_Shape -> Methods = &Quadric_Methods; X return (New_Shape); X } X X/* Allocate and initialize a plane. */ XPLANE *Get_Plane_Shape() X { X PLANE *New_Shape; X X if ((New_Shape = (PLANE *) malloc (sizeof (PLANE))) == NULL) X Error ("Cannot allocate shape"); X X Make_Vector (&(New_Shape -> Normal_Vector), 0.0, 1.0, 0.0); X New_Shape->Distance = 0.0; X New_Shape -> Type = PLANE_TYPE; X New_Shape -> Next_Object = NULL; X New_Shape -> Methods = &Plane_Methods; X New_Shape -> VPCached = 0; X return (New_Shape); X } X X/* Allocate and initialize a triangle. */ XTRIANGLE *Get_Triangle_Shape() X { X TRIANGLE *New_Shape; X X if ((New_Shape = (TRIANGLE *) malloc (sizeof (TRIANGLE))) == NULL) X Error ("Cannot allocate shape"); X X Make_Vector (&(New_Shape -> Normal_Vector), 0.0, 1.0, 0.0); X Make_Vector (&(New_Shape -> P1), 0.0, 0.0, 0.0); X Make_Vector (&(New_Shape -> P2), 1.0, 0.0, 0.0); X Make_Vector (&(New_Shape -> P3), 0.0, 1.0, 0.0); X New_Shape->Distance = 0.0; X New_Shape->Inverted = FALSE; X New_Shape -> Type = TRIANGLE_TYPE; X New_Shape -> Next_Object = NULL; X New_Shape -> Methods = &Triangle_Methods; X New_Shape -> VPCached = FALSE; X return (New_Shape); X } X X/* Allocate and initialize a smooth triangle. */ XSMOOTH_TRIANGLE *Get_Smooth_Triangle_Shape() X { X SMOOTH_TRIANGLE *New_Shape; X X if ((New_Shape = (SMOOTH_TRIANGLE *) malloc (sizeof (SMOOTH_TRIANGLE))) == NULL) X Error ("Cannot allocate shape"); X X Make_Vector (&(New_Shape -> Normal_Vector), 0.0, 1.0, 0.0); X Make_Vector (&(New_Shape -> P1), 0.0, 0.0, 0.0); X Make_Vector (&(New_Shape -> P2), 1.0, 0.0, 0.0); X Make_Vector (&(New_Shape -> P3), 0.0, 1.0, 0.0); X Make_Vector (&(New_Shape -> N1), 0.0, 1.0, 0.0); X Make_Vector (&(New_Shape -> DN12), 0.0, 1.0, 0.0); X Make_Vector (&(New_Shape -> DN13), 0.0, 1.0, 0.0); X New_Shape->Distance = 0.0; X New_Shape -> Type = SMOOTH_TRIANGLE_TYPE; X New_Shape->Inverted = FALSE; X New_Shape -> Next_Object = NULL; X New_Shape -> Methods = &Smooth_Triangle_Methods; X New_Shape -> VPCached = 0; X return (New_Shape); X } X XCSG_SHAPE *Get_CSG_Shape() X { X CSG_SHAPE *New_Shape; X X if ((New_Shape = (CSG_SHAPE *) malloc (sizeof (CSG_SHAPE))) == NULL) X Error ("Cannot allocate shape"); X X New_Shape -> Parent_Object = NULL; X New_Shape -> Next_Object = NULL; X New_Shape -> Shapes = NULL; X return (New_Shape); X } X XCSG_SHAPE *Get_CSG_Union() X { X CSG_SHAPE *New_Shape; X X New_Shape = Get_CSG_Shape(); X New_Shape -> Methods = &CSG_Union_Methods; X New_Shape -> Type = CSG_UNION_TYPE; X return (New_Shape); X } X XCSG_SHAPE *Get_CSG_Intersection() X { X CSG_SHAPE *New_Shape; X X New_Shape = Get_CSG_Shape(); X New_Shape -> Methods = &CSG_Intersection_Methods; X New_Shape -> Type = CSG_INTERSECTION_TYPE; X return (New_Shape); X } X XOBJECT *Get_Object () X { X OBJECT *New_Object; X X if ((New_Object = (OBJECT *) malloc (sizeof (OBJECT))) == NULL) X Error ("Cannot allocate object"); X X Make_Vector (&(New_Object -> Object_Center), 0.0, 0.0, 0.0); X X New_Object -> Next_Object = NULL; X New_Object -> Next_Light_Source = NULL; X New_Object -> Shape = NULL; X New_Object -> Bounding_Shapes = NULL; X New_Object -> Object_Texture = Default_Texture; X X Make_Colour (&New_Object->Object_Colour, 0.0, 0.0, 0.0); X X New_Object -> Light_Source_Flag = FALSE; X New_Object -> Transparency = FALSE; X New_Object -> Type = OBJECT_TYPE; X New_Object -> Methods = &Basic_Object_Methods; X return (New_Object); X } X XTEXTURE *Get_Texture () X { X TEXTURE *New_Texture; X X if ((New_Texture = (TEXTURE *) malloc (sizeof (TEXTURE))) == NULL) X Error ("Cannot allocate object"); X X New_Texture -> Object_Reflection = 0.0; X New_Texture -> Object_Ambient = 0.3; X New_Texture -> Object_Diffuse = 0.7; X New_Texture -> Object_Brilliance = 1.0; X New_Texture -> Object_Specular = 0.0; X New_Texture -> Object_Roughness = 0.05; X New_Texture -> Object_Phong = 0.0; X New_Texture -> Object_PhongSize = 40; X X New_Texture -> Texture_Randomness= 0.0; X New_Texture -> Bump_Amount = 0.0; X New_Texture -> Phase = 0.0; X New_Texture -> Frequency = 1.0; X New_Texture -> Texture_Number = 0; X New_Texture -> Texture_Transformation = NULL; X New_Texture -> Bump_Number = NO_BUMPS; X New_Texture -> Turbulence = 0.0; X New_Texture -> Colour_Map = NULL; X New_Texture -> Once_Flag = FALSE; X Make_Colour (&New_Texture -> Colour1, 0.0, 0.0, 0.0); X Make_Colour (&New_Texture -> Colour2, 0.0, 0.0, 0.0); X Make_Vector (&New_Texture->Texture_Gradient, 0.0, 0.0, 0.0); X X New_Texture -> Object_Index_Of_Refraction = 1.0; X New_Texture -> Object_Refraction = 0.0; X X return (New_Texture); X } X XVIEWPOINT *Get_Viewpoint () X { X VIEWPOINT *New_Viewpoint; X X if ((New_Viewpoint = (VIEWPOINT *)malloc (sizeof (VIEWPOINT))) X == NULL) X Error ("Cannot allocate viewpoint"); X X Init_Viewpoint (New_Viewpoint); X return (New_Viewpoint); X } X XCOLOUR *Get_Colour () X { X COLOUR *New_Colour; X X if ((New_Colour = (COLOUR *) malloc (sizeof (COLOUR))) == NULL) X Error ("Cannot allocate colour"); X X Make_Colour (New_Colour, 0.0, 0.0, 0.0); X return (New_Colour); X } X XVECTOR *Get_Vector () X { X VECTOR *New_Vector; X X if ((New_Vector = (VECTOR *) malloc (sizeof (VECTOR))) == NULL) X Error ("Cannot allocate vector"); X X New_Vector -> x = 0.0; X New_Vector -> y = 0.0; X New_Vector -> z = 0.0; X return (New_Vector); X } X XDBL *Get_Float () X { X DBL *New_Float; X X if ((New_Float = (DBL *) malloc (sizeof (DBL))) == NULL) X Error ("Cannot allocate float"); X X *New_Float = 0.0; X return (New_Float); X } X XTRANSFORMATION *Get_Transformation() X { X TRANSFORMATION *New_Transformation; X X if ((New_Transformation = X (TRANSFORMATION *) malloc (sizeof (TRANSFORMATION))) == NULL) X Error ("Cannot allocate transformation"); X X MIdentity ((MATRIX *) &(New_Transformation -> matrix[0][0])); X MIdentity ((MATRIX *) &(New_Transformation -> inverse[0][0])); X return (New_Transformation); X } X X/* Parse a float. Doesn't handle exponentiation. */ XDBL Parse_Float () X { X DBL Local_Float; X CONSTANT Constant_Id; X register int Negative, Sign_Parsed; X X Negative = FALSE; X Sign_Parsed = FALSE; X X EXPECT X CASE (IDENTIFIER_TOKEN) X if ((Constant_Id = Find_Constant()) != -1) X if (Constants[(int)Constant_Id].Constant_Type == FLOAT_CONSTANT) X { X Local_Float = *((DBL *) Constants[(int)Constant_Id].Constant_Data); X if (Negative) X Local_Float *= -1.0; X } X else X Type_Error (); X else X Undeclared (); X EXIT X END_CASE X X CASE (PLUS_TOKEN) X if (Sign_Parsed) X Parse_Error (FLOAT_TOKEN); X Sign_Parsed = TRUE; X END_CASE X X CASE (DASH_TOKEN) X if (Sign_Parsed) X Parse_Error (FLOAT_TOKEN); X Negative = TRUE; X Sign_Parsed = TRUE; X END_CASE X X CASE (FLOAT_TOKEN) X Local_Float = Token.Token_Float; X if (Negative) X Local_Float *= -1.0; X EXIT X END_CASE X X OTHERWISE X Parse_Error (FLOAT_TOKEN); X END_CASE X END_EXPECT X X return (Local_Float); X } X Xvoid Parse_Vector (Given_Vector) X VECTOR *Given_Vector; X { X CONSTANT Constant_Id; X X EXPECT X CASE (IDENTIFIER_TOKEN) X if ((Constant_Id = Find_Constant()) != -1) X if (Constants[(int)Constant_Id].Constant_Type == VECTOR_CONSTANT) X *Given_Vector = *((VECTOR *) Constants[(int)Constant_Id].Constant_Data); X else X Type_Error (); X else X Undeclared (); X EXIT X END_CASE X X CASE (LEFT_ANGLE_TOKEN) X (Given_Vector -> x) = Parse_Float(); X (Given_Vector -> y) = Parse_Float(); X (Given_Vector -> z) = Parse_Float(); X GET (RIGHT_ANGLE_TOKEN); X EXIT X END_CASE X X OTHERWISE X Parse_Error (LEFT_ANGLE_TOKEN); X END_CASE X END_EXPECT X } X Xvoid Parse_Colour (Given_Colour) X COLOUR *Given_Colour; X { X CONSTANT Constant_Id; X X Make_Colour (Given_Colour, 0.0, 0.0, 0.0); X EXPECT X CASE (IDENTIFIER_TOKEN) X if ((Constant_Id = Find_Constant()) != -1) X if (Constants[(int)Constant_Id].Constant_Type == COLOUR_CONSTANT) X *Given_Colour = *((COLOUR *) Constants[(int)Constant_Id].Constant_Data); X else X Type_Error (); X else X Undeclared (); X END_CASE X X CASE (RED_TOKEN) X (Given_Colour -> Red) = Parse_Float(); X END_CASE X X CASE (GREEN_TOKEN) X (Given_Colour -> Green) = Parse_Float(); X END_CASE X X CASE (BLUE_TOKEN) X (Given_Colour -> Blue) = Parse_Float(); X END_CASE X X CASE (ALPHA_TOKEN) X (Given_Colour -> Alpha) = Parse_Float(); X END_CASE X X OTHERWISE X UNGET X EXIT X END_CASE X END_EXPECT X } X XCOLOUR_MAP *Parse_Colour_Map () X { X#define MAX_ENTRIES 20 X COLOUR_MAP *New_Colour_Map; X register int i; X X New_Colour_Map = (COLOUR_MAP *) X malloc (sizeof (COLOUR_MAP)); X X if (New_Colour_Map == NULL) X Error ("Not enough memory for colour map"); X X New_Colour_Map -> Colour_Map_Entries = (COLOUR_MAP_ENTRY *) X malloc(MAX_ENTRIES * sizeof (COLOUR_MAP_ENTRY)); X X if (New_Colour_Map -> Colour_Map_Entries == NULL) X Error ("Not enough memory for colour map"); X X i = 0; X EXPECT X CASE (LEFT_SQUARE_TOKEN) X New_Colour_Map -> Colour_Map_Entries [i].start = Parse_Float(); X New_Colour_Map -> Colour_Map_Entries [i].end = Parse_Float(); X GET (COLOUR_TOKEN); X Parse_Colour (&(New_Colour_Map->Colour_Map_Entries[i].Start_Colour)); X GET (COLOUR_TOKEN); X Parse_Colour (&(New_Colour_Map->Colour_Map_Entries[i].End_Colour)); X i++; X if (i > MAX_ENTRIES) X Error ("Colour_Map too long"); X GET (RIGHT_SQUARE_TOKEN); X END_CASE X X CASE2 (END_COLOUR_MAP_TOKEN, END_COLOR_MAP_TOKEN) X New_Colour_Map -> Number_Of_Entries = i; X EXIT X END_CASE X X OTHERWISE X Parse_Error (END_COLOUR_MAP_TOKEN); X END_CASE X END_EXPECT X return (New_Colour_Map); X } X XTEXTURE *Copy_Texture (Texture) X TEXTURE *Texture; X { X TEXTURE *New_Texture; X New_Texture = Get_Texture(); X *New_Texture = *Texture; X if (New_Texture->Texture_Transformation) { X New_Texture->Texture_Transformation = (TRANSFORMATION *) malloc (sizeof (TRANSFORMATION)); X *New_Texture->Texture_Transformation = *Texture->Texture_Transformation; X } X return (New_Texture); X } X XTEXTURE *Parse_Texture (Old_Texture) X TEXTURE *Old_Texture; X { X VECTOR Local_Vector; X TRANSFORMATION Local_Transformation; X CONSTANT Constant_Id; X TEXTURE *Texture; X int Texture_Constant; X X Texture = Old_Texture; X Texture_Constant = TRUE; X X EXPECT X CASE (IDENTIFIER_TOKEN) X if ((Constant_Id = Find_Constant()) != -1) X if (Constants[(int)Constant_Id].Constant_Type == TEXTURE_CONSTANT) { X Texture = ((TEXTURE *) Constants[(int)Constant_Id].Constant_Data); X Texture_Constant = TRUE; X } X else X Type_Error (); X else X Undeclared (); X END_CASE X X CASE (FLOAT_TOKEN) X UNGET X if (Texture_Constant) { X Texture = Copy_Texture(Texture); X Texture_Constant = FALSE; X } X Texture -> Texture_Randomness = Parse_Float(); X END_CASE X X CASE (ONCE_TOKEN) X if (Texture_Constant) { X Texture = Copy_Texture(Texture); X Texture_Constant = FALSE; X } X Texture->Once_Flag = TRUE; X END_CASE X X CASE (TURBULENCE_TOKEN) X if (Texture_Constant) { X Texture = Copy_Texture(Texture); X Texture_Constant = FALSE; X } X Texture -> Turbulence = Parse_Float(); X END_CASE X X CASE (BOZO_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Texture -> Texture_Number = BOZO_TEXTURE; X END_CASE X X CASE (CHECKER_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Texture -> Texture_Number = CHECKER_TEXTURE; X EXPECT X CASE (COLOUR_TOKEN) X Parse_Colour (&(Texture -> Colour1)); X GET (COLOUR_TOKEN); X Parse_Colour (&(Texture -> Colour2)); X END_CASE X X OTHERWISE X UNGET X EXIT X END_CASE X END_EXPECT X END_CASE X X CASE (MARBLE_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Texture -> Texture_Number = MARBLE_TEXTURE; X END_CASE X X CASE (WOOD_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Texture -> Texture_Number = WOOD_TEXTURE; X END_CASE X X CASE (SPOTTED_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Texture -> Texture_Number = SPOTTED_TEXTURE; X END_CASE X X CASE (AGATE_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Texture -> Texture_Number = AGATE_TEXTURE; X END_CASE X X CASE (GRANITE_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Texture -> Texture_Number = GRANITE_TEXTURE; X END_CASE X X CASE (GRADIENT_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Texture -> Texture_Number = GRADIENT_TEXTURE; X Parse_Vector (&(Texture -> Texture_Gradient)); X END_CASE X X CASE (AMBIENT_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X (Texture -> Object_Ambient) = Parse_Float (); X END_CASE X X CASE (BRILLIANCE_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X (Texture -> Object_Brilliance) = Parse_Float (); X END_CASE X X CASE (ROUGHNESS_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X (Texture -> Object_Roughness) = Parse_Float (); X if (Texture -> Object_Roughness > 1.0) X Texture -> Object_Roughness = 1.0; X if (Texture -> Object_Roughness < 0.001) X Texture -> Object_Roughness = 0.001; X END_CASE X X CASE (PHONGSIZE_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X (Texture -> Object_PhongSize) = Parse_Float (); X if (Texture -> Object_PhongSize < 1.0) X Texture -> Object_PhongSize = 1.0; X if (Texture -> Object_PhongSize > 100) X Texture -> Object_PhongSize = 100; X END_CASE X X CASE (DIFFUSE_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X (Texture -> Object_Diffuse) = Parse_Float (); X END_CASE X X CASE (SPECULAR_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X (Texture -> Object_Specular) = Parse_Float (); X END_CASE X X CASE (PHONG_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X (Texture -> Object_Phong) = Parse_Float (); X END_CASE X X CASE (IOR_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X (Texture -> Object_Index_Of_Refraction) = Parse_Float (); X END_CASE X X CASE (REFRACTION_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X (Texture -> Object_Refraction) = Parse_Float (); X END_CASE X X CASE (REFLECTION_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X (Texture -> Object_Reflection) = Parse_Float (); X END_CASE X X CASE (IMAGEMAP_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Texture -> Texture_Number = IMAGEMAP_TEXTURE; X Texture->Image = (IMAGE *)malloc(sizeof(IMAGE)); X Make_Vector (&Texture->Texture_Gradient, 1.0, -1.0, 0.0); X EXPECT X CASE (LEFT_ANGLE_TOKEN) X UNGET X Parse_Vector (&(Texture -> Texture_Gradient)); X END_CASE X X CASE (IFF_TOKEN) X GET (STRING_TOKEN); X read_iff_image(Texture->Image, Token.Token_String); X EXIT X END_CASE X X CASE (GIF_TOKEN) X GET (STRING_TOKEN); X read_gif_image(Texture->Image, Token.Token_String); X EXIT X END_CASE X X CASE (RAW_TOKEN) X GET (STRING_TOKEN); X read_raw_image(Texture->Image, Token.Token_String); X EXIT X END_CASE X X OTHERWISE X Parse_Error (RAW_TOKEN); X END_CASE X END_EXPECT X END_CASE X X CASE (WAVES_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Texture -> Bump_Number = WAVES; X Texture -> Bump_Amount = Parse_Float (); X EXPECT X CASE (PHASE_TOKEN) X Texture -> Phase = Parse_Float(); X EXIT X END_CASE X X OTHERWISE X UNGET X EXIT X END_CASE X END_EXPECT X END_CASE X X CASE (FREQUENCY_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Texture -> Frequency = Parse_Float(); X END_CASE X X CASE (PHASE_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Texture -> Phase = Parse_Float(); X END_CASE X X CASE (RIPPLES_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Texture -> Bump_Number = RIPPLES; X Texture -> Bump_Amount = Parse_Float (); X END_CASE X X CASE (WRINKLES_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Texture -> Bump_Number = WRINKLES; X Texture -> Bump_Amount = Parse_Float (); X END_CASE X X CASE (BUMPS_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Texture -> Bump_Number = BUMPS; X Texture -> Bump_Amount = Parse_Float (); X END_CASE X X CASE (DENTS_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Texture -> Bump_Number = DENTS; X Texture -> Bump_Amount = Parse_Float (); X END_CASE X X CASE (TRANSLATE_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Parse_Vector (&Local_Vector); X if (!Texture -> Texture_Transformation) X Texture -> Texture_Transformation = Get_Transformation (); X Get_Translation_Transformation (&Local_Transformation, X &Local_Vector); X Compose_Transformations (Texture -> Texture_Transformation, X &Local_Transformation); X END_CASE X X CASE (ROTATE_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Parse_Vector (&Local_Vector); X if (!Texture -> Texture_Transformation) X Texture -> Texture_Transformation = Get_Transformation (); X Get_Rotation_Transformation (&Local_Transformation, X &Local_Vector); X Compose_Transformations (Texture -> Texture_Transformation, X &Local_Transformation); X END_CASE X X CASE (SCALE_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Parse_Vector (&Local_Vector); X if (!Texture -> Texture_Transformation) X Texture -> Texture_Transformation = Get_Transformation (); X Get_Scaling_Transformation (&Local_Transformation, X &Local_Vector); X Compose_Transformations (Texture -> Texture_Transformation, X &Local_Transformation); X END_CASE X X CASE2 (COLOUR_MAP_TOKEN, COLOR_MAP_TOKEN) X if (Texture_Constant) { X Texture_Constant = FALSE; X Texture = Copy_Texture (Texture); X } X Texture -> Colour_Map = Parse_Colour_Map(); X END_CASE X X CASE (END_TEXTURE_TOKEN) X EXIT X END_CASE X X OTHERWISE X Parse_Error (END_TEXTURE_TOKEN); X END_CASE X END_EXPECT X return (Texture); X } X XSHAPE *Parse_Sphere () X { X SPHERE *Local_Shape; X CONSTANT Constant_Id; X VECTOR Local_Vector; X X Local_Shape = NULL; X X EXPECT X CASE (LEFT_ANGLE_TOKEN) X UNGET X Local_Shape = Get_Sphere_Shape(); X Parse_Vector(&(Local_Shape -> Center)); X Local_Shape -> Radius = Parse_Float(); X Local_Shape -> Radius_Squared = Local_Shape -> Radius * Local_Shape -> Radius; X Local_Shape -> Inverse_Radius = 1.0 / Local_Shape -> Radius; X EXIT X END_CASE X X CASE (IDENTIFIER_TOKEN) X if ((Constant_Id = Find_Constant()) != -1) X if (Constants[(int)Constant_Id].Constant_Type == SPHERE_CONSTANT) X Local_Shape = (SPHERE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data); X else X Type_Error (); X else X Undeclared (); X EXIT X END_CASE X X OTHERWISE X Parse_Error (LEFT_ANGLE_TOKEN); X END_CASE X END_EXPECT X X EXPECT X CASE (END_SPHERE_TOKEN) X EXIT X END_CASE X X CASE (TRANSLATE_TOKEN) X Parse_Vector (&Local_Vector); X Translate ((OBJECT *) Local_Shape, &Local_Vector); X END_CASE X X CASE (ROTATE_TOKEN) X Parse_Vector (&Local_Vector); X Rotate ((OBJECT *) Local_Shape, &Local_Vector); X END_CASE X X CASE (SCALE_TOKEN) X Parse_Vector (&Local_Vector); X Scale ((OBJECT *) Local_Shape, &Local_Vector); X END_CASE X X CASE (INVERSE_TOKEN) X Invert ((OBJECT *) Local_Shape); X END_CASE X X OTHERWISE X Parse_Error (END_SPHERE_TOKEN); X END_CASE X END_EXPECT X X return ((SHAPE *) Local_Shape); X } X XSHAPE *Parse_Plane () X { X PLANE *Local_Shape; X CONSTANT Constant_Id; X VECTOR Local_Vector; X X Local_Shape = NULL; X X EXPECT X CASE (LEFT_ANGLE_TOKEN) X UNGET X Local_Shape = Get_Plane_Shape(); X Parse_Vector(&(Local_Shape -> Normal_Vector)); X Local_Shape->Distance = Parse_Float(); X Local_Shape->Distance *= -1.0; X EXIT X END_CASE X X CASE (IDENTIFIER_TOKEN) X if ((Constant_Id = Find_Constant()) != -1) X if (Constants[(int)Constant_Id].Constant_Type == PLANE_CONSTANT) X Local_Shape = (PLANE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data); X else X Type_Error (); X else X Undeclared (); X EXIT X END_CASE X X OTHERWISE X Parse_Error (LEFT_ANGLE_TOKEN); X END_CASE X END_EXPECT X X EXPECT X CASE (END_PLANE_TOKEN) X EXIT X END_CASE X X CASE (TRANSLATE_TOKEN) X Parse_Vector (&Local_Vector); X Translate ((OBJECT *) Local_Shape, &Local_Vector); X END_CASE X X CASE (ROTATE_TOKEN) X Parse_Vector (&Local_Vector); X Rotate ((OBJECT *) Local_Shape, &Local_Vector); X END_CASE X X CASE (SCALE_TOKEN) X Parse_Vector (&Local_Vector); X Scale ((OBJECT *) Local_Shape, &Local_Vector); X END_CASE X X CASE (INVERSE_TOKEN) X Invert ((OBJECT *) Local_Shape); X END_CASE X X OTHERWISE X Parse_Error (END_PLANE_TOKEN); X END_CASE X END_EXPECT X X return ((SHAPE *) Local_Shape); X } X XSHAPE *Parse_Triangle () X { X TRIANGLE *Local_Shape; X CONSTANT Constant_Id; X VECTOR Local_Vector; X X Local_Shape = NULL; X X EXPECT X CASE (LEFT_ANGLE_TOKEN) X UNGET X Local_Shape = Get_Triangle_Shape(); X Parse_Vector (&Local_Shape->P1); X Parse_Vector (&Local_Shape->P2); X Parse_Vector (&Local_Shape->P3); X if (!Compute_Triangle (Local_Shape)) { X printf ("Degenerate triangle on line %d. Please remove.\n", X Token.Token_Line_No); X Degenerate_Triangles = TRUE; X } X EXIT X END_CASE X X CASE (IDENTIFIER_TOKEN) X if ((Constant_Id = Find_Constant()) != -1) X if (Constants[(int)Constant_Id].Constant_Type == TRIANGLE_CONSTANT) X Local_Shape = (TRIANGLE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data); X else X Type_Error (); X else X Undeclared (); X EXIT X END_CASE X X OTHERWISE X Parse_Error (LEFT_ANGLE_TOKEN); X END_CASE X END_EXPECT X X EXPECT X CASE (END_TRIANGLE_TOKEN) X EXIT X END_CASE X X CASE (TRANSLATE_TOKEN) X Parse_Vector (&Local_Vector); X Translate ((OBJECT *) Local_Shape, &Local_Vector); X END_CASE X X CASE (ROTATE_TOKEN) X Parse_Vector (&Local_Vector); X Rotate ((OBJECT *) Local_Shape, &Local_Vector); X END_CASE X X CASE (SCALE_TOKEN) X Parse_Vector (&Local_Vector); X Scale ((OBJECT *) Local_Shape, &Local_Vector); X END_CASE X X CASE (INVERSE_TOKEN) X Invert ((OBJECT *) Local_Shape); X END_CASE X X OTHERWISE X Parse_Error (END_TRIANGLE_TOKEN); X END_CASE X END_EXPECT X X return ((SHAPE *) Local_Shape); X } X XSHAPE *Parse_Smooth_Triangle () X { X SMOOTH_TRIANGLE *Local_Shape; X CONSTANT Constant_Id; X VECTOR Local_Vector; X X Local_Shape = NULL; X X EXPECT X CASE (LEFT_ANGLE_TOKEN) X UNGET X Local_Shape = (SMOOTH_TRIANGLE *) Get_Smooth_Triangle_Shape(); X Parse_Vector (&Local_Shape->P1); X Parse_Vector (&Local_Shape->N1); X Parse_Vector (&Local_Shape->P2); X Parse_Vector (&Local_Vector); X VSub (Local_Shape->DN12, Local_Vector, Local_Shape->N1); X Parse_Vector (&Local_Shape->P3); X Parse_Vector (&Local_Vector); X VSub (Local_Shape->DN13, Local_Vector, Local_Shape->N1); X if (!Compute_Triangle ((TRIANGLE *) Local_Shape)) { X printf ("Degenerate triangle on line %d. Please remove.\n", X Token.Token_Line_No); X Degenerate_Triangles = TRUE; X } X EXIT X END_CASE X X CASE (IDENTIFIER_TOKEN) X if ((Constant_Id = Find_Constant()) != -1) X if (Constants[(int)Constant_Id].Constant_Type == SMOOTH_TRIANGLE_CONSTANT) X Local_Shape = (SMOOTH_TRIANGLE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data); X else X Type_Error (); X else X Undeclared (); X EXIT X END_CASE X X CASE (TRANSLATE_TOKEN) X Parse_Vector (&Local_Vector); X Translate ((OBJECT *) Local_Shape, &Local_Vector); X END_CASE X X CASE (ROTATE_TOKEN) X Parse_Vector (&Local_Vector); X Rotate ((OBJECT *) Local_Shape, &Local_Vector); X END_CASE X X CASE (SCALE_TOKEN) X Parse_Vector (&Local_Vector); X Scale ((OBJECT *) Local_Shape, &Local_Vector); X END_CASE X X CASE (INVERSE_TOKEN) X Invert ((OBJECT *) Local_Shape); X END_CASE X X OTHERWISE X Parse_Error (LEFT_ANGLE_TOKEN); X END_CASE X END_EXPECT X X EXPECT X CASE (END_TRIANGLE_TOKEN) X EXIT X END_CASE X X OTHERWISE X Parse_Error (END_TRIANGLE_TOKEN); X END_CASE X END_EXPECT X X return ((SHAPE *) Local_Shape); X } X XSHAPE *Parse_Quadric () X { X QUADRIC *Local_Shape; X VECTOR Local_Vector; X CONSTANT Constant_Id; X X Local_Shape = NULL; X X EXPECT X CASE (LEFT_ANGLE_TOKEN) X UNGET X Local_Shape = Get_Quadric_Shape(); X Parse_Vector(&(Local_Shape -> Object_2_Terms)); X Parse_Vector(&(Local_Shape -> Object_Mixed_Terms)); X Parse_Vector(&(Local_Shape -> Object_Terms)); X (Local_Shape -> Object_Constant) = Parse_Float(); X Local_Shape -> Non_Zero_Square_Term = X !((Local_Shape -> Object_2_Terms.x == 0.0) X && (Local_Shape -> Object_2_Terms.y == 0.0) X && (Local_Shape -> Object_2_Terms.z == 0.0) X && (Local_Shape -> Object_Mixed_Terms.x == 0.0) X && (Local_Shape -> Object_Mixed_Terms.y == 0.0) X && (Local_Shape -> Object_Mixed_Terms.z == 0.0)); X EXIT X END_CASE X X CASE (IDENTIFIER_TOKEN) X if ((Constant_Id = Find_Constant()) != -1) X if (Constants[(int)Constant_Id].Constant_Type == QUADRIC_CONSTANT) X Local_Shape = (QUADRIC *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data); X else X Type_Error (); X else X Undeclared (); X EXIT X END_CASE X X OTHERWISE X Parse_Error (LEFT_ANGLE_TOKEN); X END_CASE X END_EXPECT X X EXPECT X CASE (END_QUADRIC_TOKEN) X EXIT X END_CASE X X CASE (TRANSLATE_TOKEN) X Parse_Vector (&Local_Vector); X Translate ((OBJECT *) Local_Shape, &Local_Vector); X END_CASE X X CASE (ROTATE_TOKEN) X Parse_Vector (&Local_Vector); X Rotate ((OBJECT *) Local_Shape, &Local_Vector); X END_CASE X X CASE (SCALE_TOKEN) X Parse_Vector (&Local_Vector); X Scale ((OBJECT *) Local_Shape, &Local_Vector); X END_CASE X X CASE (INVERSE_TOKEN) X Invert ((OBJECT *) Local_Shape); X END_CASE X X OTHERWISE X Parse_Error (END_QUADRIC_TOKEN); X END_CASE X END_EXPECT X X return ((SHAPE *) Local_Shape); X } X XCSG_SHAPE *Parse_CSG (type, Parent_Object) X int type; X OBJECT *Parent_Object; X { X CSG_SHAPE *Container; X SHAPE *Local_Shape; X VECTOR Local_Vector; X CONSTANT Constant_Id; X int First_Shape_Parsed = FALSE; X X if (type == CSG_UNION_TYPE) X Container = Get_CSG_Union (); X X else if ((type == CSG_INTERSECTION_TYPE) || (type == CSG_DIFFERENCE_TYPE)) X Container = Get_CSG_Intersection (); X X Container -> Parent_Object = Parent_Object; X X EXPECT X CASE (IDENTIFIER_TOKEN) X if ((Constant_Id = Find_Constant()) != -1) X if ((Constants[(int)Constant_Id].Constant_Type == CSG_INTERSECTION_CONSTANT) X || (Constants[(int)Constant_Id].Constant_Type == CSG_UNION_CONSTANT) X || (Constants[(int)Constant_Id].Constant_Type == CSG_DIFFERENCE_CONSTANT)) { X free (Container); X Container = (CSG_SHAPE *) Copy ((OBJECT *) Constants[(int)Constant_Id].Constant_Data); X Set_CSG_Parents(Container, Parent_Object); X } X else X Type_Error (); X else X Undeclared (); X END_CASE X X CASE (SPHERE_TOKEN) X Local_Shape = Parse_Sphere (); X Local_Shape -> Parent_Object = Parent_Object; X if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed) X Invert ((OBJECT *) Local_Shape); X First_Shape_Parsed = TRUE; X Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object), X (OBJECT **) &(Container -> Shapes)); X END_CASE X X CASE (PLANE_TOKEN) X Local_Shape = Parse_Plane (); X Local_Shape -> Parent_Object = Parent_Object; X if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed) X Invert ((OBJECT *) Local_Shape); X First_Shape_Parsed = TRUE; X Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object), X (OBJECT **) &(Container -> Shapes)); X END_CASE X X CASE (TRIANGLE_TOKEN) X Local_Shape = Parse_Triangle (); X Local_Shape -> Parent_Object = Parent_Object; X if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed) X Invert ((OBJECT *) Local_Shape); X First_Shape_Parsed = TRUE; X Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object), X (OBJECT **) &(Container -> Shapes)); X END_CASE X X CASE (SMOOTH_TRIANGLE_TOKEN) X Local_Shape = Parse_Smooth_Triangle (); X Local_Shape -> Parent_Object = Parent_Object; X if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed) X Invert ((OBJECT *) Local_Shape); X First_Shape_Parsed = TRUE; X Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object), X (OBJECT **) &(Container -> Shapes)); X END_CASE X X CASE (QUADRIC_TOKEN) X Local_Shape = Parse_Quadric (); X Local_Shape -> Parent_Object = Parent_Object; X if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed) X Invert ((OBJECT *) Local_Shape); X First_Shape_Parsed = TRUE; X Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object), X (OBJECT **) &(Container -> Shapes)); X END_CASE X X CASE (UNION_TOKEN) X Local_Shape = (SHAPE *) Parse_CSG (CSG_UNION_TYPE, Parent_Object); X if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed) X Invert ((OBJECT *) Local_Shape); X First_Shape_Parsed = TRUE; X Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object), X (OBJECT **) &(Container -> Shapes)); X END_CASE X X CASE (INTERSECTION_TOKEN) X Local_Shape = (SHAPE *) Parse_CSG (CSG_INTERSECTION_TYPE, Parent_Object); X if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed) X Invert ((OBJECT *) Local_Shape); X First_Shape_Parsed = TRUE; X Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object), X (OBJECT **) &(Container -> Shapes)); X END_CASE X X CASE (DIFFERENCE_TOKEN) X Local_Shape = (SHAPE *) Parse_CSG (CSG_DIFFERENCE_TYPE, Parent_Object); X if ((type == CSG_DIFFERENCE_TYPE) && First_Shape_Parsed) X Invert ((OBJECT *) Local_Shape); X First_Shape_Parsed = TRUE; X Link((OBJECT *) Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object), X (OBJECT **) &(Container -> Shapes)); X END_CASE X X OTHERWISE X UNGET X EXIT X END_CASE X END_EXPECT X X EXPECT X CASE3 (END_UNION_TOKEN, END_INTERSECTION_TOKEN, END_DIFFERENCE_TOKEN) X EXIT X END_CASE X X CASE (TRANSLATE_TOKEN) X Parse_Vector (&Local_Vector); X Translate((OBJECT *) Container, &Local_Vector); X END_CASE X X CASE (ROTATE_TOKEN) X Parse_Vector (&Local_Vector); X Rotate ((OBJECT *) Container, &Local_Vector); X END_CASE X X CASE (SCALE_TOKEN) X Parse_Vector (&Local_Vector); X Scale ((OBJECT *) Container, &Local_Vector); X END_CASE X X CASE (INVERSE_TOKEN) X Invert ((OBJECT *) Container); X END_CASE X X OTHERWISE X Parse_Error (END_QUADRIC_TOKEN); X END_CASE X END_EXPECT X X return ((CSG_SHAPE *) Container); X } X XSHAPE *Parse_Shape (Object) X OBJECT *Object; X { X SHAPE *Local_Shape; X X EXPECT X CASE (SPHERE_TOKEN) X Local_Shape = Parse_Sphere (); X Local_Shape -> Parent_Object = Object; X EXIT X END_CASE X X CASE (PLANE_TOKEN) X Local_Shape = Parse_Plane (); X Local_Shape -> Parent_Object = Object; X EXIT X END_CASE X X CASE (TRIANGLE_TOKEN) X Local_Shape = Parse_Triangle (); X Local_Shape -> Parent_Object = Object; X EXIT X END_CASE X X CASE (SMOOTH_TRIANGLE_TOKEN) X Local_Shape = Parse_Smooth_Triangle (); X Local_Shape -> Parent_Object = Object; X EXIT X END_CASE X X CASE (QUADRIC_TOKEN) X Local_Shape = Parse_Quadric (); X Local_Shape -> Parent_Object = Object; X EXIT X END_CASE X X CASE (UNION_TOKEN) X Local_Shape = (SHAPE *) Parse_CSG (CSG_UNION_TYPE, Object); X EXIT X END_CASE X X CASE (INTERSECTION_TOKEN) X Local_Shape = (SHAPE *) Parse_CSG (CSG_INTERSECTION_TYPE, Object); X EXIT X END_CASE X X CASE (DIFFERENCE_TOKEN) X Local_Shape = (SHAPE *) Parse_CSG (CSG_DIFFERENCE_TYPE, Object); X EXIT X END_CASE X X OTHERWISE X Parse_Error (QUADRIC_TOKEN); X END_CASE X END_EXPECT X return (Local_Shape); X } X XOBJECT *Parse_Object () X { X OBJECT *Object; X SHAPE *Local_Shape; X VECTOR Local_Vector; X CONSTANT Constant_Id; X int i; X X Object = NULL; X X EXPECT X CASE (IDENTIFIER_TOKEN) X if ((Constant_Id = Find_Constant()) != -1) X if (Constants[(int)Constant_Id].Constant_Type == OBJECT_CONSTANT) X Object = (OBJECT *) Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data); X else X Type_Error (); X else X Undeclared (); X EXIT X END_CASE X X CASE5 (SPHERE_TOKEN, QUADRIC_TOKEN, UNION_TOKEN, X INTERSECTION_TOKEN, DIFFERENCE_TOKEN) X CASE3 (TRIANGLE_TOKEN, SMOOTH_TRIANGLE_TOKEN, PLANE_TOKEN) X UNGET X if (Object == NULL) X Object = Get_Object(); X X Local_Shape = Parse_Shape(Object); X Link((OBJECT *)Local_Shape, (OBJECT **) &(Local_Shape -> Next_Object), X (OBJECT **) &(Object -> Shape)); X EXIT X END_CASE X X OTHERWISE X Parse_Error (QUADRIC_TOKEN); X EXIT X END_CASE X END_EXPECT X X EXPECT X CASE (BOUNDED_TOKEN) X EXPECT X CASE (END_BOUNDED_TOKEN) X EXIT X END_CASE X X OTHERWISE X UNGET X Local_Shape = Parse_Shape(Object); X Link((OBJECT *) Local_Shape, X (OBJECT **) &(Local_Shape -> Next_Object), X (OBJECT **) &(Object -> Bounding_Shapes)); X END_CASE X END_EXPECT X END_CASE X X CASE2 (COLOR_TOKEN, COLOUR_TOKEN) X Parse_Colour (&(Object -> Object_Colour)); X if (Object->Object_Colour.Alpha != 0.0) X Object->Transparency = TRUE; X END_CASE X X CASE (TEXTURE_TOKEN) X Object -> Object_Texture = Parse_Texture (Object->Object_Texture); X if ((Object->Object_Texture->Colour1.Alpha != 0.0) || X (Object->Object_Texture->Colour2.Alpha != 0.0)) X Object->Transparency = TRUE; X else X if (Object->Object_Texture->Colour_Map != NULL) X for (i = 0 ; i < Object->Object_Texture->Colour_Map->Number_Of_Entries ; i++) X if ((Object->Object_Texture->Colour_Map->Colour_Map_Entries[i].Start_Colour.Alpha != 0.0) || X (Object->Object_Texture->Colour_Map->Colour_Map_Entries[i].Start_Colour.Alpha != 0.0)) { X Object->Transparency = TRUE; X break; X } X END_CASE X X CASE (LIGHT_SOURCE_TOKEN) X Object -> Light_Source_Flag = TRUE; X END_CASE X X CASE (TRANSLATE_TOKEN) X Parse_Vector (&Local_Vector); X Translate (Object, &Local_Vector); X END_CASE X X CASE (ROTATE_TOKEN) X Parse_Vector (&Local_Vector); X Rotate (Object, &Local_Vector); X END_CASE X X CASE (SCALE_TOKEN) X Parse_Vector (&Local_Vector); X Scale (Object, &Local_Vector); X END_CASE X X CASE (INVERSE_TOKEN) X Invert (Object); X END_CASE X X CASE (AMBIENT_TOKEN) X if (Object -> Object_Texture == Default_Texture) X Object -> Object_Texture = Get_Texture(); X X (Object -> Object_Texture -> Object_Ambient) = Parse_Float (); X END_CASE X X CASE (BRILLIANCE_TOKEN) X if (Object -> Object_Texture == Default_Texture) X Object -> Object_Texture = Get_Texture(); X X (Object -> Object_Texture -> Object_Brilliance) = Parse_Float (); X END_CASE X X CASE (ROUGHNESS_TOKEN) X if (Object -> Object_Texture == Default_Texture) X Object -> Object_Texture = Get_Texture(); X X (Object -> Object_Texture -> Object_Roughness) = Parse_Float (); X if (Object -> Object_Texture -> Object_Roughness > 1.0) X Object -> Object_Texture -> Object_Roughness = 1.0; X if (Object -> Object_Texture -> Object_Roughness < 0.001) X Object -> Object_Texture -> Object_Roughness = 0.001; X END_CASE X X CASE (PHONGSIZE_TOKEN) X if (Object -> Object_Texture == Default_Texture) X Object -> Object_Texture = Get_Texture(); X X (Object -> Object_Texture -> Object_PhongSize) = Parse_Float (); X if (Object -> Object_Texture -> Object_PhongSize < 1.0) X Object -> Object_Texture -> Object_PhongSize = 1.0; X if (Object -> Object_Texture -> Object_PhongSize > 100) X Object -> Object_Texture -> Object_PhongSize = 100; X END_CASE X X CASE (DIFFUSE_TOKEN) X if (Object -> Object_Texture == Default_Texture) X Object -> Object_Texture = Get_Texture(); X X (Object -> Object_Texture -> Object_Diffuse) = Parse_Float (); X END_CASE X X CASE (SPECULAR_TOKEN) X if (Object -> Object_Texture == Default_Texture) X Object -> Object_Texture = Get_Texture(); X X (Object -> Object_Texture -> Object_Specular) = Parse_Float (); X END_CASE X X CASE (PHONG_TOKEN) X if (Object -> Object_Texture == Default_Texture) X Object -> Object_Texture = Get_Texture(); X X (Object -> Object_Texture -> Object_Phong) = Parse_Float (); X END_CASE X X CASE (IOR_TOKEN) X if (Object -> Object_Texture == Default_Texture) X Object -> Object_Texture = Get_Texture(); X X (Object -> Object_Texture -> Object_Index_Of_Refraction) = Parse_Float (); X END_CASE X X CASE (REFRACTION_TOKEN) X if (Object -> Object_Texture == Default_Texture) X Object -> Object_Texture = Get_Texture(); X X (Object -> Object_Texture -> Object_Refraction) = Parse_Float (); X END_CASE X X CASE (REFLECTION_TOKEN) X if (Object -> Object_Texture == Default_Texture) X Object -> Object_Texture = Get_Texture(); X X (Object -> Object_Texture -> Object_Reflection) = Parse_Float (); X END_CASE X X CASE (END_OBJECT_TOKEN) X EXIT X END_CASE X X OTHERWISE X Parse_Error (END_OBJECT_TOKEN); X END_CASE X X END_EXPECT X X return (Object); X } X XOBJECT *Parse_Composite () X { X COMPOSITE *Local_Composite; X OBJECT *Local_Object; X SHAPE *Local_Shape; X CONSTANT Constant_Id; X VECTOR Local_Vector; X X Local_Composite = NULL; X X EXPECT X CASE (IDENTIFIER_TOKEN) X if ((Constant_Id = Find_Constant()) != -1) X if (Constants[(int)Constant_Id].Constant_Type == COMPOSITE_CONSTANT) X Local_Composite = (COMPOSITE *)Copy((OBJECT *) Constants[(int)Constant_Id].Constant_Data); X else X Type_Error (); X else X Undeclared (); X END_CASE X X CASE (COMPOSITE_TOKEN) X if (Local_Composite == NULL) X Local_Composite = Get_Composite_Object(); X X Local_Object = Parse_Composite(); X Link((OBJECT *) Local_Object,(OBJECT **) &(Local_Object -> Next_Object), X (OBJECT **) &(Local_Composite -> Objects)); X END_CASE X X CASE (OBJECT_TOKEN) X if (Local_Composite == NULL) X Local_Composite = Get_Composite_Object(); X X Local_Object = Parse_Object(); X Link(Local_Object, &(Local_Object -> Next_Object), X &(Local_Composite -> Objects)); X X if (Local_Object -> Light_Source_Flag) X Link(Local_Object, &(Local_Object -> Next_Light_Source), X &(Parsing_Frame_Ptr -> Light_Sources)); X END_CASE X X CASE (END_COMPOSITE_TOKEN) X UNGET X if (Local_Composite == NULL) X Local_Composite = Get_Composite_Object(); X X EXIT X END_CASE X X OTHERWISE X UNGET X EXIT X END_CASE X END_EXPECT X X EXPECT X CASE (END_COMPOSITE_TOKEN) X EXIT X END_CASE X X CASE (BOUNDED_TOKEN) X EXPECT X CASE (END_BOUNDED_TOKEN) X EXIT X END_CASE X X OTHERWISE X UNGET X Local_Shape = Parse_Shape((OBJECT *) Local_Composite); X Link((OBJECT *) Local_Shape, X (OBJECT **) &(Local_Shape -> Next_Object), X (OBJECT **) &(Local_Composite -> Bounding_Shapes)); X END_CASE X END_EXPECT X END_CASE X X CASE (TRANSLATE_TOKEN) X Parse_Vector (&Local_Vector); X Translate ((OBJECT *) Local_Composite, &Local_Vector); X END_CASE X X CASE (ROTATE_TOKEN) X Parse_Vector (&Local_Vector); X Rotate ((OBJECT *) Local_Composite, &Local_Vector); X END_CASE X X CASE (SCALE_TOKEN) X Parse_Vector (&Local_Vector); X Scale ((OBJECT *) Local_Composite, &Local_Vector); X END_CASE X X CASE (INVERSE_TOKEN) X Invert ((OBJECT *) Local_Composite); X END_CASE X X OTHERWISE X Parse_Error (END_COMPOSITE_TOKEN); X END_CASE X END_EXPECT X X return ((OBJECT *) Local_Composite); X } X Xvoid Parse_Fog () X { X EXPECT X CASE (COLOUR_TOKEN) X Parse_Colour (&Parsing_Frame_Ptr->Fog_Colour); X END_CASE X X CASE (FLOAT_TOKEN) X Parsing_Frame_Ptr->Fog_Distance = Token.Token_Float; X END_CASE X X CASE (END_FOG_TOKEN) X EXIT X END_CASE X X OTHERWISE X Parse_Error (END_FOG_TOKEN); X END_CASE X END_EXPECT X } X Xvoid Parse_Frame () X { X OBJECT *Local_Object; X X EXPECT X CASE (FOG_TOKEN) X Parse_Fog(); X END_CASE X X CASE (OBJECT_TOKEN) X Local_Object = Parse_Object(); X Link(Local_Object, &(Local_Object -> Next_Object), X &(Parsing_Frame_Ptr -> Objects)); X X if (Local_Object -> Light_Source_Flag) X Link(Local_Object, &(Local_Object -> Next_Light_Source), X &(Parsing_Frame_Ptr -> Light_Sources)); X END_CASE X X CASE (COMPOSITE_TOKEN) X Local_Object = Parse_Composite(); X Link(Local_Object, &(Local_Object -> Next_Object), X &(Parsing_Frame_Ptr -> Objects)); X END_CASE X X CASE (VIEW_POINT_TOKEN) X Parse_Viewpoint(&(Parsing_Frame_Ptr -> View_Point)); X END_CASE X X CASE (DECLARE_TOKEN) X Parse_Declare (); X END_CASE X X CASE (END_OF_FILE_TOKEN) X EXIT X END_CASE X X OTHERWISE X Parse_Error (OBJECT_TOKEN); X END_CASE X END_EXPECT X } X Xvoid Parse_Viewpoint (Given_Vp) X VIEWPOINT *Given_Vp; X { X CONSTANT Constant_Id; X VECTOR Local_Vector, Temp_Vector; X DBL Direction_Length, Up_Length, Right_Length, Handedness; X X Init_Viewpoint (Given_Vp); X X EXPECT X CASE (IDENTIFIER_TOKEN) X if ((Constant_Id = Find_Constant()) != -1) X if (Constants[(int)Constant_Id].Constant_Type == VIEW_POINT_CONSTANT) X *Given_Vp = X *((VIEWPOINT*) Constants[(int)Constant_Id].Constant_Data); X else X Type_Error (); X else X Undeclared (); X END_CASE X X CASE (LOCATION_TOKEN) X Parse_Vector(&(Given_Vp -> Location)); X END_CASE X X CASE (DIRECTION_TOKEN) X Parse_Vector(&(Given_Vp -> Direction)); X END_CASE X X CASE (UP_TOKEN) X Parse_Vector(&(Given_Vp -> Up)); X END_CASE X X CASE (RIGHT_TOKEN) X Parse_Vector(&(Given_Vp -> Right)); X END_CASE X X CASE (SKY_TOKEN) X Parse_Vector(&(Given_Vp -> Sky)); X END_CASE X X CASE (LOOK_AT_TOKEN) X VLength (Direction_Length, Given_Vp->Direction); X VLength (Up_Length, Given_Vp->Up); X VLength (Right_Length, Given_Vp->Right); X VCross (Temp_Vector, Given_Vp->Direction, Given_Vp->Up); X VDot (Handedness, Temp_Vector, Given_Vp->Right); X Parse_Vector(&Given_Vp->Direction); X X VSub (Given_Vp->Direction, Given_Vp->Direction, Given_Vp->Location); X VNormalize (Given_Vp->Direction, Given_Vp->Direction); X VCross(Given_Vp->Right, Given_Vp->Direction, Given_Vp->Sky); X VNormalize (Given_Vp->Right, Given_Vp->Right); X VCross (Given_Vp->Up, Given_Vp->Right, Given_Vp->Direction); X VScale (Given_Vp->Direction, Given_Vp->Direction, Direction_Length); X if (Handedness >= 0.0) { X VScale (Given_Vp->Right, Given_Vp->Right, Right_Length); X } X else { X VScale (Given_Vp->Right, Given_Vp->Right, -Right_Length); X } X X VScale (Given_Vp->Up, Given_Vp->Up, Up_Length); X END_CASE X X CASE (TRANSLATE_TOKEN) X Parse_Vector (&Local_Vector); X Translate ((OBJECT *) Given_Vp, &Local_Vector); X END_CASE X X CASE (ROTATE_TOKEN) X Parse_Vector (&Local_Vector); X Rotate ((OBJECT *) Given_Vp, &Local_Vector); X END_CASE X X CASE (SCALE_TOKEN) X Parse_Vector (&Local_Vector); X Scale ((OBJECT *) Given_Vp, &Local_Vector); X END_CASE X X CASE (END_VIEW_POINT_TOKEN) X EXIT X END_CASE X X OTHERWISE X Parse_Error (END_VIEW_POINT_TOKEN); X END_CASE X END_EXPECT X } X Xvoid Parse_Declare () X { X CONSTANT Constant_Id; X X struct Constant_Struct *Constant_Ptr; X X GET (IDENTIFIER_TOKEN); X if ((Constant_Id = Find_Constant()) == -1) X if (++Number_Of_Constants >= MAX_CONSTANTS) X Error ("Too many constants"); X else X Constant_Id = Number_Of_Constants; X X Constant_Ptr = &(Constants[(int)Constant_Id]); X GET (EQUALS_TOKEN); X X EXPECT X CASE (OBJECT_TOKEN) X Constant_Ptr -> Identifier_Number = Token.Identifier_Number; X Constant_Ptr -> Constant_Data = (char *) Parse_Object(); X Constant_Ptr -> Constant_Type = OBJECT_CONSTANT; X EXIT X END_CASE X X CASE (SPHERE_TOKEN) X Constant_Ptr -> Identifier_Number = Token.Identifier_Number; X Constant_Ptr -> Constant_Data = (char *) Parse_Sphere (); X Constant_Ptr -> Constant_Type = SPHERE_CONSTANT; X EXIT X END_CASE X X CASE (PLANE_TOKEN) X Constant_Ptr -> Identifier_Number = Token.Identifier_Number; X Constant_Ptr -> Constant_Data = (char *) Parse_Plane (); X Constant_Ptr -> Constant_Type = PLANE_CONSTANT; X EXIT X END_CASE X X CASE (TRIANGLE_TOKEN) X Constant_Ptr -> Identifier_Number = Token.Identifier_Number; X Constant_Ptr -> Constant_Data = (char *) Parse_Triangle (); X Constant_Ptr -> Constant_Type = TRIANGLE_CONSTANT; X EXIT X END_CASE X X CASE (SMOOTH_TRIANGLE_TOKEN) X Constant_Ptr -> Identifier_Number = Token.Identifier_Number; X Constant_Ptr -> Constant_Data = (char *) Parse_Smooth_Triangle (); X Constant_Ptr -> Constant_Type = SMOOTH_TRIANGLE_CONSTANT; X EXIT X END_CASE X X CASE (QUADRIC_TOKEN) X Constant_Ptr -> Identifier_Number = Token.Identifier_Number; X Constant_Ptr -> Constant_Data = (char *) Parse_Quadric (); X Constant_Ptr -> Constant_Type = QUADRIC_CONSTANT; X EXIT X END_CASE X X CASE (INTERSECTION_TOKEN) X Constant_Ptr -> Identifier_Number = Token.Identifier_Number; X Constant_Ptr -> Constant_Data = (char *) Parse_CSG(CSG_INTERSECTION_TYPE, NULL); X Constant_Ptr -> Constant_Type = CSG_INTERSECTION_CONSTANT; X EXIT X END_CASE X X CASE (UNION_TOKEN) X Constant_Ptr -> Identifier_Number = Token.Identifier_Number; X Constant_Ptr -> Constant_Data = (char *) Parse_CSG(CSG_UNION_TYPE, NULL); X Constant_Ptr -> Constant_Type = CSG_UNION_CONSTANT; X EXIT X END_CASE X X CASE (DIFFERENCE_TOKEN) X Constant_Ptr -> Identifier_Number = Token.Identifier_Number; X Constant_Ptr -> Constant_Data = (char *) Parse_CSG(CSG_DIFFERENCE_TYPE, NULL); X Constant_Ptr -> Constant_Type = CSG_DIFFERENCE_CONSTANT; X EXIT X END_CASE X X CASE (COMPOSITE_TOKEN) X Constant_Ptr -> Identifier_Number = Token.Identifier_Number; X Constant_Ptr -> Constant_Data = (char *) Parse_Composite(); X Constant_Ptr -> Constant_Type = COMPOSITE_CONSTANT; X EXIT X END_CASE X X CASE (TEXTURE_TOKEN) X Constant_Ptr -> Identifier_Number = Token.Identifier_Number; X Constant_Ptr -> Constant_Data = (char *) Parse_Texture(Default_Texture); X Constant_Ptr -> Constant_Type = TEXTURE_CONSTANT; X EXIT X END_CASE X X CASE (VIEW_POINT_TOKEN) X Constant_Ptr -> Identifier_Number = Token.Identifier_Number; X Constant_Ptr -> Constant_Data = (char *) Get_Viewpoint(); X Constant_Ptr -> Constant_Type = VIEW_POINT_CONSTANT; X Parse_Viewpoint((VIEWPOINT *) Constant_Ptr -> Constant_Data); X EXIT X END_CASE X X CASE2 (COLOR_TOKEN, COLOUR_TOKEN) X Constant_Ptr -> Identifier_Number = Token.Identifier_Number; X Constant_Ptr -> Constant_Data = (char *) Get_Colour(); X Constant_Ptr -> Constant_Type = COLOUR_CONSTANT; X Parse_Colour ((COLOUR *) Constant_Ptr -> Constant_Data); X EXIT X END_CASE X X CASE (LEFT_ANGLE_TOKEN) X UNGET X Constant_Ptr -> Identifier_Number = Token.Identifier_Number; X Constant_Ptr -> Constant_Data = (char *) Get_Vector(); X Constant_Ptr -> Constant_Type = VECTOR_CONSTANT; X Parse_Vector((VECTOR *) Constant_Ptr -> Constant_Data); X EXIT X END_CASE X X CASE3 (DASH_TOKEN, PLUS_TOKEN, FLOAT_TOKEN) X UNGET X Constant_Ptr -> Identifier_Number = Token.Identifier_Number; X Constant_Ptr -> Constant_Data = (char *) Get_Float(); X Constant_Ptr -> Constant_Type = FLOAT_CONSTANT; X *(Constant_Ptr -> Constant_Data) = Parse_Float(); X EXIT X END_CASE X X OTHERWISE X Parse_Error (OBJECT_TOKEN); X END_CASE X END_EXPECT X } X Xvoid Init_Viewpoint (vp) X VIEWPOINT *vp; X { X vp -> Methods = (void *) &Viewpoint_Methods; X vp -> Type = VIEWPOINT_TYPE; X Make_Vector (&vp->Location, 0.0, 0.0, 0.0); X Make_Vector (&vp->Direction, 0.0, 0.0, 1.0); X Make_Vector (&vp->Up, 0.0, 1.0, 0.0); X Make_Vector (&vp->Right, 1.0, 0.0, 0.0); X Make_Vector (&vp->Sky, 0.0, 1.0, 0.0); X } X Xvoid Link (New_Object, Field, Old_Object_List) X OBJECT *New_Object, **Field, **Old_Object_List; X { X *Field = *Old_Object_List; X *Old_Object_List = New_Object; X } X XCONSTANT Find_Constant() X { X register int i; X X for (i = 1 ; i <= Number_Of_Constants ; i++) X if (Constants [i].Identifier_Number == Token.Identifier_Number) X return (i); X X return (-1); X } X X Xchar *Get_Token_String (Token_Id) X TOKEN Token_Id; X { X register int i; X X for (i = 0 ; i < LAST_TOKEN ; i++) X if (Reserved_Words[i].Token_Number == Token_Id) X return (Reserved_Words[i].Token_Name); X return (""); X } X Xvoid Parse_Error (Token_Id) X TOKEN Token_Id; X { X char *expected, *found; X X fprintf (stderr, "Error in file %s line %d\n", Current_File_Name, X Token.Token_Line_No); X expected = Get_Token_String (Token_Id); X found = Get_Token_String (Token.Token_Id); X fprintf (stderr, "%s expected but %s found instead\n", expected, found); X exit(0); X } X Xvoid Type_Error () X { X fprintf (stderr, "Error in file %s line %d\n", Current_File_Name, X Token.Token_Line_No); X fprintf (stderr, "Identifier %s is the wrong type\n", X &Token.Token_String[0]); X exit (0); X } X Xvoid Undeclared () X { X fprintf (stderr, "Error in file %s line %d\n", Current_File_Name, X Token.Token_Line_No); X fprintf (stderr, "Undeclared identifier %s\n", &Token.Token_String[0]); X exit (0); X } X Xvoid Error (str) X char *str; X { X fprintf (stderr, "Error in file %s line %d\n", Current_File_Name, X Token.Token_Line_No); X fputs (str, stderr); X exit (0); X } X END_OF_FILE if test 63678 -ne `wc -c <'src/parse.c'`; then echo shar: \"'src/parse.c'\" unpacked with wrong size! fi # end of 'src/parse.c' fi echo shar: End of archive 9 \(of 10\). cp /dev/null ark9isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 10 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mail submissions (sources or binaries) to <amiga@uunet.uu.net>. Mail comments to the moderator at <amiga-request@uunet.uu.net>. Post requests for sources, and general discussion to comp.sys.amiga.