@@ -8213,13 +8213,16 @@ ObjectPtr Parser::Parse_Object_Id ()
82138213
82148214void Parser::Parse_Declare (bool is_local, bool after_hash)
82158215{
8216+ vector<Token_Struct> lvalues;
82168217 bool deprecated = false ;
82178218 bool deprecated_once = false ;
82188219 int Previous=-1 ;
8219- int Local_Index,Local_Flag ;
8220+ int Local_Index;
82208221 SYM_ENTRY *Temp_Entry = NULL ;
82218222 bool allow_redefine = true ;
82228223 UCS2 *deprecation_message;
8224+ bool tupleDeclare = false ;
8225+ bool lvectorDeclare = false ;
82238226
82248227 Ok_To_Declare = false ;
82258228
@@ -8229,8 +8232,7 @@ void Parser::Parse_Declare(bool is_local, bool after_hash)
82298232 " Future versions may not support 'declare' and may require '#declare'." );
82308233 }
82318234
8232- Local_Flag=(Token.Token_Id ==LOCAL_TOKEN);
8233- if (Local_Flag)
8235+ if (is_local)
82348236 {
82358237 Local_Index=Table_Index;
82368238 }
@@ -8242,117 +8244,199 @@ void Parser::Parse_Declare(bool is_local, bool after_hash)
82428244 LValue_Ok = true ;
82438245
82448246 EXPECT_ONE
8245- CASE (DEPRECATED_TOKEN)
8246- deprecated = true ;
8247- ALLOW (ONCE_TOKEN);
8248- if (Token.Token_Id == ONCE_TOKEN)
8249- deprecated_once = true ;
8250- deprecation_message = Parse_String (false , false );
8247+ CASE (LEFT_PAREN_TOKEN)
8248+ tupleDeclare = true ;
8249+ END_CASE
8250+ CASE (LEFT_ANGLE_TOKEN)
8251+ lvectorDeclare = true ;
82518252 END_CASE
8252-
82538253 OTHERWISE
82548254 UNGET
82558255 END_CASE
82568256 END_EXPECT
82578257
8258- EXPECT
8259- CASE (IDENTIFIER_TOKEN)
8260- allow_redefine = !Token.is_array_elem ;
8261- Temp_Entry = Add_Symbol (Local_Index,Token.Token_String ,IDENTIFIER_TOKEN);
8262- Token.NumberPtr = &(Temp_Entry->Token_Number );
8263- Token.DataPtr = &(Temp_Entry->Data );
8264- Previous = Token.Token_Id ;
8265- if (deprecated)
8266- {
8267- Temp_Entry->Flags |= TF_DEPRECATED;
8268- if (deprecated_once)
8269- Temp_Entry->Flags |= TF_DEPRECATED_ONCE;
8270- if (deprecation_message != NULL )
8258+ for (bool more = true ; more; /* body-controlled loop */ )
8259+ {
8260+ EXPECT_ONE
8261+ CASE (DEPRECATED_TOKEN)
8262+ deprecated = true ;
8263+ ALLOW (ONCE_TOKEN);
8264+ if (Token.Token_Id == ONCE_TOKEN)
8265+ deprecated_once = true ;
8266+ deprecation_message = Parse_String (false , false );
8267+ END_CASE
8268+
8269+ OTHERWISE
8270+ UNGET
8271+ END_CASE
8272+ END_EXPECT
8273+
8274+ EXPECT
8275+ CASE (IDENTIFIER_TOKEN)
8276+ allow_redefine = !Token.is_array_elem ;
8277+ Temp_Entry = Add_Symbol (Local_Index,Token.Token_String ,IDENTIFIER_TOKEN);
8278+ Token.NumberPtr = &(Temp_Entry->Token_Number );
8279+ Token.DataPtr = &(Temp_Entry->Data );
8280+ Previous = Token.Token_Id ;
8281+ if (deprecated)
8282+ {
8283+ Temp_Entry->Flags |= TF_DEPRECATED;
8284+ if (deprecated_once)
8285+ Temp_Entry->Flags |= TF_DEPRECATED_ONCE;
8286+ if (deprecation_message != NULL )
8287+ {
8288+ UCS2String str (deprecation_message);
8289+ POV_FREE (deprecation_message);
8290+ Temp_Entry->Deprecation_Message = POV_STRDUP (UCS2toASCIIString (str).c_str ());
8291+ }
8292+ else
8293+ {
8294+ char str[256 ];
8295+ sprintf (str, " Identifier '%.128s' was declared deprecated." , Token.Token_String );
8296+ Temp_Entry->Deprecation_Message = POV_STRDUP (str);
8297+ }
8298+ }
8299+ EXIT
8300+ END_CASE
8301+
8302+ CASE2 (FUNCT_ID_TOKEN, VECTFUNCT_ID_TOKEN)
8303+ if ((!Token.is_array_elem ) || (*(Token.DataPtr ) != NULL ))
8304+ Error (" Redeclaring functions is not allowed - #undef the function first!" );
8305+ // fall through
8306+
8307+ // These are also used in Parse_Directive UNDEF_TOKEN section, Parse_Macro, and and Parse_For_Param_Start,
8308+ // and all these functions should accept exactly the same identifiers! [trf]
8309+ CASE4 (TNORMAL_ID_TOKEN, FINISH_ID_TOKEN, TEXTURE_ID_TOKEN, OBJECT_ID_TOKEN)
8310+ CASE4 (COLOUR_MAP_ID_TOKEN, TRANSFORM_ID_TOKEN, CAMERA_ID_TOKEN, PIGMENT_ID_TOKEN)
8311+ CASE4 (SLOPE_MAP_ID_TOKEN, NORMAL_MAP_ID_TOKEN, TEXTURE_MAP_ID_TOKEN, COLOUR_ID_TOKEN)
8312+ CASE4 (PIGMENT_MAP_ID_TOKEN, MEDIA_ID_TOKEN, STRING_ID_TOKEN, INTERIOR_ID_TOKEN)
8313+ CASE4 (DENSITY_MAP_ID_TOKEN, ARRAY_ID_TOKEN, DENSITY_ID_TOKEN, UV_ID_TOKEN)
8314+ CASE4 (VECTOR_4D_ID_TOKEN, RAINBOW_ID_TOKEN, FOG_ID_TOKEN, SKYSPHERE_ID_TOKEN)
8315+ CASE2 (MATERIAL_ID_TOKEN, SPLINE_ID_TOKEN )
8316+ allow_redefine = !Token.is_array_elem ;
8317+ if (is_local && (Token.Table_Index != Table_Index))
82718318 {
8272- UCS2String str (deprecation_message);
8273- POV_FREE (deprecation_message);
8274- Temp_Entry->Deprecation_Message = POV_STRDUP (UCS2toASCIIString (str).c_str ());
8319+ Temp_Entry = Add_Symbol (Local_Index,Token.Token_String ,IDENTIFIER_TOKEN);
8320+ Token.NumberPtr = &(Temp_Entry->Token_Number );
8321+ Token.DataPtr = &(Temp_Entry->Data );
8322+ Previous = IDENTIFIER_TOKEN;
82758323 }
82768324 else
82778325 {
8278- char str[256 ];
8279- sprintf (str, " Identifier '%.128s' was declared deprecated." , Token.Token_String );
8280- Temp_Entry->Deprecation_Message = POV_STRDUP (str);
8326+ Previous = Token.Token_Id ;
82818327 }
8282- }
8283- EXIT
8284- END_CASE
8328+ EXIT
8329+ END_CASE
82858330
8286- CASE2 (FUNCT_ID_TOKEN, VECTFUNCT_ID_TOKEN)
8287- if ((!Token.is_array_elem ) || (*(Token.DataPtr ) != NULL ))
8288- Error (" Redeclaring functions is not allowed - #undef the function first!" );
8289- // fall through
8331+ CASE (EMPTY_ARRAY_TOKEN)
8332+ allow_redefine = !Token.is_array_elem ;
8333+ Previous = Token.Token_Id ;
8334+ EXIT
8335+ END_CASE
82908336
8291- // These are also used in Parse_Directive UNDEF_TOKEN section, Parse_Macro, and and Parse_For_Param_Start,
8292- // and all these functions should accept exactly the same identifiers! [trf]
8293- CASE4 (TNORMAL_ID_TOKEN, FINISH_ID_TOKEN, TEXTURE_ID_TOKEN, OBJECT_ID_TOKEN)
8294- CASE4 (COLOUR_MAP_ID_TOKEN, TRANSFORM_ID_TOKEN, CAMERA_ID_TOKEN, PIGMENT_ID_TOKEN)
8295- CASE4 (SLOPE_MAP_ID_TOKEN, NORMAL_MAP_ID_TOKEN, TEXTURE_MAP_ID_TOKEN, COLOUR_ID_TOKEN)
8296- CASE4 (PIGMENT_MAP_ID_TOKEN, MEDIA_ID_TOKEN, STRING_ID_TOKEN, INTERIOR_ID_TOKEN)
8297- CASE4 (DENSITY_MAP_ID_TOKEN, ARRAY_ID_TOKEN, DENSITY_ID_TOKEN, UV_ID_TOKEN)
8298- CASE4 (VECTOR_4D_ID_TOKEN, RAINBOW_ID_TOKEN, FOG_ID_TOKEN, SKYSPHERE_ID_TOKEN)
8299- CASE2 (MATERIAL_ID_TOKEN, SPLINE_ID_TOKEN )
8300- allow_redefine = !Token.is_array_elem ;
8301- if (Local_Flag && (Token.Table_Index != Table_Index))
8302- {
8303- Temp_Entry = Add_Symbol (Local_Index,Token.Token_String ,IDENTIFIER_TOKEN);
8304- Token.NumberPtr = &(Temp_Entry->Token_Number );
8305- Token.DataPtr = &(Temp_Entry->Data );
8306- Previous = IDENTIFIER_TOKEN;
8307- }
8308- else
8309- {
8310- Previous = Token.Token_Id ;
8311- }
8312- EXIT
8313- END_CASE
8337+ CASE2 (VECTOR_FUNCT_TOKEN, FLOAT_FUNCT_TOKEN)
8338+ allow_redefine = !Token.is_array_elem ;
8339+ switch (Token.Function_Id )
8340+ {
8341+ case VECTOR_ID_TOKEN:
8342+ case FLOAT_ID_TOKEN:
8343+ if (is_local && (Token.Table_Index != Table_Index))
8344+ {
8345+ Temp_Entry = Add_Symbol (Local_Index,Token.Token_String ,IDENTIFIER_TOKEN);
8346+ Token.NumberPtr = &(Temp_Entry->Token_Number );
8347+ Token.DataPtr = &(Temp_Entry->Data );
8348+ }
8349+ Previous = Token.Function_Id ;
8350+ break ;
83148351
8315- CASE (EMPTY_ARRAY_TOKEN)
8316- allow_redefine = !Token.is_array_elem ;
8317- Previous = Token.Token_Id ;
8318- EXIT
8319- END_CASE
8352+ default :
8353+ Parse_Error (IDENTIFIER_TOKEN);
8354+ break ;
8355+ }
8356+ EXIT
8357+ END_CASE
83208358
8321- CASE2 (VECTOR_FUNCT_TOKEN, FLOAT_FUNCT_TOKEN)
8322- allow_redefine = !Token.is_array_elem ;
8323- switch (Token.Function_Id )
8324- {
8325- case VECTOR_ID_TOKEN:
8326- case FLOAT_ID_TOKEN:
8327- if (Local_Flag && (Token.Table_Index != Table_Index))
8328- {
8329- Temp_Entry = Add_Symbol (Local_Index,Token.Token_String ,IDENTIFIER_TOKEN);
8330- Token.NumberPtr = &(Temp_Entry->Token_Number );
8331- Token.DataPtr = &(Temp_Entry->Data );
8332- }
8333- Previous = Token.Function_Id ;
8334- break ;
8359+ OTHERWISE
8360+ allow_redefine = !Token.is_array_elem ;
8361+ Parse_Error (IDENTIFIER_TOKEN);
8362+ END_CASE
8363+ END_EXPECT
83358364
8336- default :
8337- Parse_Error (IDENTIFIER_TOKEN);
8338- break ;
8339- }
8340- EXIT
8341- END_CASE
8365+ lvalues.push_back (Token);
83428366
8343- OTHERWISE
8344- allow_redefine = !Token.is_array_elem ;
8345- Parse_Error (IDENTIFIER_TOKEN);
8346- END_CASE
8347- END_EXPECT
8367+ if (lvectorDeclare && lvalues.size () >= 5 )
8368+ more = false ;
8369+ else if (tupleDeclare || lvectorDeclare)
8370+ {
8371+ EXPECT_ONE
8372+ CASE (COMMA_TOKEN)
8373+ more = true ;
8374+ END_CASE
8375+
8376+ OTHERWISE
8377+ more = false ;
8378+ UNGET
8379+ END_CASE
8380+ END_EXPECT
8381+
8382+ }
8383+ else
8384+ more = false ;
8385+ }
8386+
8387+ if (tupleDeclare)
8388+ {
8389+ GET (RIGHT_PAREN_TOKEN)
8390+ }
8391+ else if (lvectorDeclare)
8392+ {
8393+ GET (RIGHT_ANGLE_TOKEN)
8394+ }
83488395
83498396 LValue_Ok = false ;
83508397
8351- GET (EQUALS_TOKEN);
8398+ GET (EQUALS_TOKEN)
83528399 Ok_To_Declare = true ;
8353- if (!Parse_RValue (Previous, Token.NumberPtr , Token.DataPtr , Temp_Entry, false , true , is_local, allow_redefine, MAX_NUMBER_OF_TABLES))
8400+
8401+ if (lvectorDeclare)
8402+ {
8403+ EXPRESS expr;
8404+ int terms = 5 ;
8405+ Parse_Express (expr, &terms);
8406+ Promote_Express (expr,&terms,lvalues.size ());
8407+ for (int i = 0 ; i < lvalues.size (); ++i)
8408+ {
8409+ Token_Struct& t = lvalues[i];
8410+
8411+ *t.NumberPtr = FLOAT_ID_TOKEN;
8412+ Test_Redefine (Previous,t.NumberPtr ,*t.DataPtr , allow_redefine);
8413+ *t.DataPtr = reinterpret_cast <void *>(Create_Float ());
8414+ *(reinterpret_cast <DBL *>(*t.DataPtr )) = expr[i];
8415+ }
8416+ }
8417+ else
83548418 {
8355- Expectation_Error (" RValue to declare" );
8419+ if (tupleDeclare)
8420+ {
8421+ GET (LEFT_PAREN_TOKEN)
8422+ }
8423+ for (int i = 0 ; i < lvalues.size (); ++i)
8424+ {
8425+ Token_Struct& t = lvalues[i];
8426+
8427+ if (i > 0 )
8428+ {
8429+ GET (COMMA_TOKEN)
8430+ }
8431+ if (!Parse_RValue (Previous, t.NumberPtr , t.DataPtr , Temp_Entry, false , !tupleDeclare, is_local, allow_redefine, MAX_NUMBER_OF_TABLES))
8432+ {
8433+ Expectation_Error (" RValue to declare" );
8434+ }
8435+ }
8436+ if (tupleDeclare)
8437+ {
8438+ GET (RIGHT_PAREN_TOKEN)
8439+ }
83568440 }
83578441 if ( after_hash )
83588442 {
@@ -10109,9 +10193,13 @@ void Parser::SendFatalError(Exception& e)
1010910193void Parser::Warning (const char *format,...)
1011010194{
1011110195 va_list marker;
10196+ char localvsbuffer[1024 ];
10197+
1011210198 va_start (marker, format);
10113- Warning ( kWarningGeneral , format, marker);
10199+ vsnprintf (localvsbuffer, 1023 , format, marker);
1011410200 va_end (marker);
10201+
10202+ Warning (kWarningGeneral , localvsbuffer);
1011510203}
1011610204
1011710205void Parser::Warning (WarningLevel level, const char *format,...)
@@ -10136,10 +10224,13 @@ void Parser::VersionWarning(unsigned int sinceVersion, const char *format,...)
1013610224 if (sceneData->EffectiveLanguageVersion () >= sinceVersion)
1013710225 {
1013810226 va_list marker;
10227+ char localvsbuffer[1024 ];
1013910228
1014010229 va_start (marker, format);
10141- Warning ( kWarningLanguage , format, marker);
10230+ vsnprintf (localvsbuffer, 1023 , format, marker);
1014210231 va_end (marker);
10232+
10233+ Warning (kWarningLanguage , localvsbuffer);
1014310234 }
1014410235}
1014510236
0 commit comments