@@ -8501,6 +8501,18 @@ bool Parser::Parse_Comma (void)
85018501
85028502// ******************************************************************************
85038503
8504+ bool Parser::AllowToken (TOKEN tokenId)
8505+ {
8506+ Get_Token ();
8507+ bool tokenMatches = ((Token.Token_Id == tokenId) ||
8508+ (Token.Function_Id == tokenId));
8509+ if (!tokenMatches)
8510+ Unget_Token ();
8511+ return tokenMatches;
8512+ }
8513+
8514+ // ******************************************************************************
8515+
85048516bool Parser::Peek_Token (TOKEN tokenId)
85058517{
85068518 Get_Token ();
@@ -8743,33 +8755,42 @@ void Parser::Parse_Declare(bool is_local, bool after_hash)
87438755 CASE (IDENTIFIER_TOKEN)
87448756 POV_PARSER_ASSERT (!Token.is_array_elem || Token.is_mixed_array_elem );
87458757 allow_redefine = true ; // should actually be irrelevant downstream, thanks to Previous==IDENTIFIER_TOKEN
8746- if (Token.is_array_elem || Token. is_dictionary_elem )
8758+ if (Token.is_array_elem )
87478759 {
8748- if (is_local && ( Token.context != Table_Index))
8749- Error ( " Cannot use '#local' to assign a non-local array or dictionary element. " ) ;
8750- Temp_Entry = Add_Symbol ( Token.table , Token. Token_String , IDENTIFIER_TOKEN) ;
8760+ numberPtr = Token.NumberPtr ;
8761+ dataPtr = Token. DataPtr ;
8762+ Previous = Token.Token_Id ;
87518763 }
87528764 else
8753- Temp_Entry = Add_Symbol (Local_Index, Token.Token_String , IDENTIFIER_TOKEN);
8754- numberPtr = &(Temp_Entry->Token_Number );
8755- dataPtr = &(Temp_Entry->Data );
8756- Previous = Token.Token_Id ;
8757- if (deprecated)
87588765 {
8759- Temp_Entry->deprecated = true ;;
8760- if (deprecated_once)
8761- Temp_Entry->deprecatedOnce = true ;
8762- if (deprecation_message != nullptr )
8766+ if (Token.is_dictionary_elem )
87638767 {
8764- UCS2String str (deprecation_message);
8765- POV_FREE (deprecation_message );
8766- Temp_Entry-> Deprecation_Message = POV_STRDUP ( UCS2toASCIIString (str). c_str () );
8768+ if (is_local && (Token. context != Table_Index))
8769+ Error ( " Cannot use '#local' to assign a non-local array or dictionary element. " );
8770+ Temp_Entry = Add_Symbol (Token. table , Token. Token_String , IDENTIFIER_TOKEN );
87678771 }
87688772 else
8773+ Temp_Entry = Add_Symbol (Local_Index, Token.Token_String , IDENTIFIER_TOKEN);
8774+ numberPtr = &(Temp_Entry->Token_Number );
8775+ dataPtr = &(Temp_Entry->Data );
8776+ Previous = Token.Token_Id ;
8777+ if (deprecated)
87698778 {
8770- char str[256 ];
8771- sprintf (str, " Identifier '%.128s' was declared deprecated." , Token.Token_String );
8772- Temp_Entry->Deprecation_Message = POV_STRDUP (str);
8779+ Temp_Entry->deprecated = true ;;
8780+ if (deprecated_once)
8781+ Temp_Entry->deprecatedOnce = true ;
8782+ if (deprecation_message != nullptr )
8783+ {
8784+ UCS2String str (deprecation_message);
8785+ POV_FREE (deprecation_message);
8786+ Temp_Entry->Deprecation_Message = POV_STRDUP (UCS2toASCIIString (str).c_str ());
8787+ }
8788+ else
8789+ {
8790+ char str[256 ];
8791+ sprintf (str, " Identifier '%.128s' was declared deprecated." , Token.Token_String );
8792+ Temp_Entry->Deprecation_Message = POV_STRDUP (str);
8793+ }
87738794 }
87748795 }
87758796 END_CASE
@@ -8952,14 +8973,16 @@ void Parser::Parse_Declare(bool is_local, bool after_hash)
89528973 (rvalue->Token_Number != ARRAY_ID_TOKEN))
89538974 Expectation_Error (" array RValue" );
89548975 POV_ARRAY *a = reinterpret_cast <POV_ARRAY *>(rvalue->Data );
8955- if (lvalues.size () > a->DataPtrs .size ())
8976+ if (a->maxDim != 0 )
8977+ Error (" cannot bulk-assign from multi-dimensional array" );
8978+ if (lvalues.size () > a->Sizes [0 ])
89568979 Error (" array size mismatch" );
89578980 if (a->DataPtrs .empty ())
89588981 Error (" cannot assign from uninitialized array" );
89598982
89608983 for (int i = 0 ; i < lvalues.size (); ++i)
89618984 {
8962- if (a->DataPtrs [i] == nullptr )
8985+ if (! a->HasElement (i) )
89638986 Error (" cannot assign from partially uninitialized array" );
89648987
89658988 numberPtr = lvalues[i].numberPtr ;
@@ -8968,9 +8991,9 @@ void Parser::Parse_Declare(bool is_local, bool after_hash)
89688991 Temp_Entry = lvalues[i].symEntry ;
89698992 allow_redefine = lvalues[i].allowRedefine ;
89708993
8971- *numberPtr = a->Type ;
8994+ *numberPtr = a->ElementType (i) ;
89728995 Test_Redefine (Previous, numberPtr, *dataPtr, allow_redefine);
8973- *dataPtr = Copy_Identifier (a->DataPtrs [i], a->Type );
8996+ *dataPtr = Copy_Identifier (a->DataPtrs [i], a->ElementType (i) );
89748997 }
89758998
89768999 Destroy_Entry (rvalue, false );
@@ -9609,16 +9632,8 @@ void Parser::Destroy_Ident_Data(void *Data, int Type)
96099632 break ;
96109633 case ARRAY_ID_TOKEN:
96119634 a = reinterpret_cast <POV_ARRAY *>(Data);
9612- if (!a->DataPtrs .empty ())
9613- {
9614- for (i=0 ; i<a->DataPtrs .size (); i++)
9615- {
9616- if (a->Types .empty ())
9617- Destroy_Ident_Data (a->DataPtrs [i], a->Type );
9618- else
9619- Destroy_Ident_Data (a->DataPtrs [i], a->Types [i]);
9620- }
9621- }
9635+ for (i = 0 ; i < a->DataPtrs .size (); ++i)
9636+ Destroy_Ident_Data (a->DataPtrs [i], a->ElementType (i));
96229637 delete a;
96239638 break ;
96249639 case DICTIONARY_ID_TOKEN:
@@ -10579,7 +10594,7 @@ void Parser::Set_CSG_Tree_Flag(ObjectPtr Object, unsigned int f, int val)
1057910594
1058010595void *Parser::Copy_Identifier (void *Data, int Type)
1058110596{
10582- int i;
10597+ size_t i;
1058310598 POV_ARRAY *a, *na;
1058410599 Vector3d *vp;
1058510600 DBL *dp;
@@ -10683,23 +10698,19 @@ void *Parser::Copy_Identifier (void *Data, int Type)
1068310698 case ARRAY_ID_TOKEN:
1068410699 a = reinterpret_cast <POV_ARRAY *>(Data);
1068510700 na = new POV_ARRAY;
10686- na->Dims = a->Dims ;
10687- na->Type = a->Type ;
10701+ na->maxDim = a->maxDim ;
10702+ na->Type_ = a->Type_ ;
1068810703 na->resizable = a->resizable ;
10689- for (i = 0 ; i < 5 ; ++i)
10704+ na->mixedType = a->mixedType ;
10705+ for (i = 0 ; i < POV_ARRAY::kMaxDimensions ; ++i)
1069010706 {
1069110707 na->Sizes [i] = a->Sizes [i];
1069210708 na->Mags [i] = a->Mags [i];
1069310709 }
1069410710 na->DataPtrs .resize (a->DataPtrs .size ());
10695- na->Types = a->Types ;
1069610711 for (i=0 ; i<a->DataPtrs .size (); i++)
10697- {
10698- if (a->Types .empty ())
10699- na->DataPtrs [i] = reinterpret_cast <void *>(Copy_Identifier (a->DataPtrs [i],a->Type ));
10700- else
10701- na->DataPtrs [i] = reinterpret_cast <void *>(Copy_Identifier (a->DataPtrs [i], a->Types [i]));
10702- }
10712+ na->DataPtrs [i] = reinterpret_cast <void *>(Copy_Identifier (a->DataPtrs [i], a->ElementType (i)));
10713+ na->Types = a->Types ;
1070310714 New = reinterpret_cast <void *>(na);
1070410715 break ;
1070510716 case DICTIONARY_ID_TOKEN:
@@ -11198,4 +11209,84 @@ void Parser::SignalProgress(POV_LONG elapsedTime, POV_LONG tokenCount)
1119811209 RenderBackend::SendSceneOutput (backendSceneData->sceneId , backendSceneData->frontendAddress , kPOVMsgIdent_Progress , obj);
1119911210}
1120011211
11212+ /* ****************************************************************************/
11213+
11214+ bool Parser::POV_ARRAY::IsInitialized () const
11215+ {
11216+ POV_PARSER_ASSERT (resizable || !DataPtrs.empty ());
11217+ return !DataPtrs.empty ();
11218+ }
11219+
11220+ bool Parser::POV_ARRAY::HasElement (size_t i) const
11221+ {
11222+ return ((i < DataPtrs.size ()) && (DataPtrs[i] != nullptr ));
11223+ }
11224+
11225+ const int & Parser::POV_ARRAY::ElementType (size_t i) const
11226+ {
11227+ POV_PARSER_ASSERT (i < DataPtrs.size ());
11228+ return (mixedType ? Types[i] : Type_);
11229+ }
11230+
11231+ int & Parser::POV_ARRAY::ElementType (size_t i)
11232+ {
11233+ POV_PARSER_ASSERT (i < DataPtrs.size ());
11234+ return (mixedType ? Types[i] : Type_);
11235+ }
11236+
11237+ size_t Parser::POV_ARRAY::GetLinearSize () const
11238+ {
11239+ POV_PARSER_ASSERT (!resizable || ((maxDim == 0 ) && (Sizes[0 ] == DataPtrs.size ())));
11240+ POV_PARSER_ASSERT (!mixedType || (Types.size () == DataPtrs.size ()));
11241+ return DataPtrs.size ();
11242+ }
11243+
11244+ void Parser::POV_ARRAY::Grow ()
11245+ {
11246+ POV_PARSER_ASSERT (resizable && (maxDim == 0 ));
11247+ ++Sizes[0 ];
11248+ DataPtrs.push_back (nullptr );
11249+ POV_PARSER_ASSERT (DataPtrs.size () == Sizes[0 ]);
11250+ if (mixedType)
11251+ {
11252+ Types.push_back (IDENTIFIER_TOKEN);
11253+ POV_PARSER_ASSERT (Types.size () == Sizes[0 ]);
11254+ }
11255+ }
11256+
11257+ void Parser::POV_ARRAY::GrowBy (size_t delta)
11258+ {
11259+ POV_PARSER_ASSERT (resizable && (maxDim == 0 ));
11260+ Sizes[0 ] += delta;
11261+ DataPtrs.insert (DataPtrs.end (), delta, nullptr );
11262+ if (mixedType)
11263+ {
11264+ Types.insert (Types.end (), delta, IDENTIFIER_TOKEN);
11265+ POV_PARSER_ASSERT (Types.size () == Sizes[0 ]);
11266+ }
11267+ }
11268+
11269+ void Parser::POV_ARRAY::GrowTo (size_t delta)
11270+ {
11271+ POV_PARSER_ASSERT (resizable && (maxDim == 0 ));
11272+ POV_PARSER_ASSERT (delta > Sizes[0 ]);
11273+ GrowBy (delta - Sizes[0 ]);
11274+ }
11275+
11276+ void Parser::POV_ARRAY::Shrink ()
11277+ {
11278+ POV_PARSER_ASSERT (resizable && (maxDim == 0 ));
11279+ POV_PARSER_ASSERT (Sizes[0 ] > 0 );
11280+ --Sizes[0 ];
11281+ POV_PARSER_ASSERT (DataPtrs.back () == nullptr );
11282+ DataPtrs.pop_back ();
11283+ POV_PARSER_ASSERT (DataPtrs.size () == Sizes[0 ]);
11284+ if (mixedType)
11285+ {
11286+ POV_PARSER_ASSERT (Types.back () == IDENTIFIER_TOKEN);
11287+ Types.pop_back ();
11288+ POV_PARSER_ASSERT (Types.size () == Sizes[0 ]);
11289+ }
11290+ }
11291+
1120111292}
0 commit comments