@@ -198,12 +198,12 @@ void Parser::Run()
198198 if (i->second [0 ] == ' \" ' )
199199 {
200200 string tmp (i->second , 1 , i->second .length () - 2 );
201- Temp_Entry = Add_Symbol (1 , const_cast <char *>(i->first .c_str ()), STRING_ID_TOKEN);
201+ Temp_Entry = Add_Symbol (SYM_TABLE_GLOBAL , const_cast <char *>(i->first .c_str ()), STRING_ID_TOKEN);
202202 Temp_Entry->Data = String_Literal_To_UCS2 (const_cast <char *>(tmp.c_str ()), false );
203203 }
204204 else
205205 {
206- Temp_Entry = Add_Symbol (1 , const_cast <char *>(i->first .c_str ()), FLOAT_ID_TOKEN);
206+ Temp_Entry = Add_Symbol (SYM_TABLE_GLOBAL , const_cast <char *>(i->first .c_str ()), FLOAT_ID_TOKEN);
207207 Temp_Entry->Data = Create_Float ();
208208 *(reinterpret_cast <DBL *>(Temp_Entry->Data )) = atof (i->second .c_str ());
209209 }
@@ -8556,7 +8556,7 @@ void Parser::Parse_Declare(bool is_local, bool after_hash)
85568556 }
85578557 else
85588558 {
8559- Local_Index= 1 ;
8559+ Local_Index = SYM_TABLE_GLOBAL ;
85608560 }
85618561
85628562 LValue_Ok = true ;
@@ -8608,9 +8608,16 @@ void Parser::Parse_Declare(bool is_local, bool after_hash)
86088608
86098609 EXPECT_ONE
86108610 CASE (IDENTIFIER_TOKEN)
8611- POV_PARSER_ASSERT (!Token.is_array_elem );
8611+ POV_PARSER_ASSERT (!Token.is_array_elem || Token. is_mixed_array_elem );
86128612 allow_redefine = true ; // should actually be irrelevant downstream, thanks to Previous==IDENTIFIER_TOKEN
8613- Temp_Entry = Add_Symbol (Local_Index,Token.Token_String ,IDENTIFIER_TOKEN);
8613+ if (Token.is_array_elem || Token.is_dictionary_elem )
8614+ {
8615+ if (is_local && (Token.context != Table_Index))
8616+ Error (" Cannot use '#local' to assign a non-local array or dictionary element." );
8617+ Temp_Entry = Add_Symbol (Token.table , Token.Token_String , IDENTIFIER_TOKEN);
8618+ }
8619+ else
8620+ Temp_Entry = Add_Symbol (Local_Index, Token.Token_String , IDENTIFIER_TOKEN);
86148621 numberPtr = &(Temp_Entry->Token_Number );
86158622 dataPtr = &(Temp_Entry->Data );
86168623 Previous = Token.Token_Id ;
@@ -8648,11 +8655,11 @@ void Parser::Parse_Declare(bool is_local, bool after_hash)
86488655 CASE4 (PIGMENT_MAP_ID_TOKEN, MEDIA_ID_TOKEN, STRING_ID_TOKEN, INTERIOR_ID_TOKEN)
86498656 CASE4 (DENSITY_MAP_ID_TOKEN, ARRAY_ID_TOKEN, DENSITY_ID_TOKEN, UV_ID_TOKEN)
86508657 CASE4 (VECTOR_4D_ID_TOKEN, RAINBOW_ID_TOKEN, FOG_ID_TOKEN, SKYSPHERE_ID_TOKEN)
8651- CASE2 (MATERIAL_ID_TOKEN, SPLINE_ID_TOKEN )
8652- if (is_local && (Token.Table_Index != Table_Index))
8658+ CASE3 (MATERIAL_ID_TOKEN, SPLINE_ID_TOKEN, DICTIONARY_ID_TOKEN )
8659+ if (is_local && (Token.context != Table_Index))
86538660 {
8654- if (Token.is_array_elem )
8655- Error (" Cannot use '#local' to assign a non-local array element." );
8661+ if (Token.is_array_elem || Token. is_dictionary_elem )
8662+ Error (" Cannot use '#local' to assign a non-local array or dictionary element." );
86568663 allow_redefine = true ; // should actually be irrelevant downstream, thanks to Previous==IDENTIFIER_TOKEN
86578664 Temp_Entry = Add_Symbol (Local_Index,Token.Token_String ,IDENTIFIER_TOKEN);
86588665 numberPtr = &(Temp_Entry->Token_Number );
@@ -8661,7 +8668,7 @@ void Parser::Parse_Declare(bool is_local, bool after_hash)
86618668 }
86628669 else
86638670 {
8664- allow_redefine = !Token.is_array_elem ;
8671+ allow_redefine = !Token.is_array_elem || Token. is_mixed_array_elem ;
86658672 numberPtr = Token.NumberPtr ;
86668673 dataPtr = Token.DataPtr ;
86678674 Previous = Token.Token_Id ;
@@ -8681,10 +8688,10 @@ void Parser::Parse_Declare(bool is_local, bool after_hash)
86818688 {
86828689 case VECTOR_ID_TOKEN:
86838690 case FLOAT_ID_TOKEN:
8684- if (is_local && (Token.Table_Index != Table_Index))
8691+ if (is_local && (Token.context != Table_Index))
86858692 {
8686- if (Token.is_array_elem )
8687- Error (" Cannot use '#local' to assign a non-local array element." );
8693+ if (Token.is_array_elem || Token. is_dictionary_elem )
8694+ Error (" Cannot use '#local' to assign a non-local array or dictionary element." );
86888695 allow_redefine = true ; // should actually be irrelevant downstream, thanks to Previous==IDENTIFIER_TOKEN
86898696 Temp_Entry = Add_Symbol (Local_Index,Token.Token_String ,IDENTIFIER_TOKEN);
86908697 numberPtr = &(Temp_Entry->Token_Number );
@@ -8693,7 +8700,7 @@ void Parser::Parse_Declare(bool is_local, bool after_hash)
86938700 }
86948701 else
86958702 {
8696- allow_redefine = !Token.is_array_elem ;
8703+ allow_redefine = !Token.is_array_elem || Token. is_mixed_array_elem ;
86978704 numberPtr = Token.NumberPtr ;
86988705 dataPtr = Token.DataPtr ;
86998706 Previous = Token.Function_Id ;
@@ -8714,7 +8721,7 @@ void Parser::Parse_Declare(bool is_local, bool after_hash)
87148721 // the resulting value.
87158722 // We do this by assigning the resulting value to a dummy symbol entry.
87168723 allow_redefine = true ; // should actually be irrelevant downstream, thanks to Previous=IDENTIFIER_TOKEN
8717- Temp_Entry = Create_Entry (0 , " " , DUMMY_SYMBOL_TOKEN);
8724+ Temp_Entry = Create_Entry (" " , DUMMY_SYMBOL_TOKEN, false );
87188725 numberPtr = &(Temp_Entry->Token_Number );
87198726 dataPtr = &(Temp_Entry->Data );
87208727 optional = true ;
@@ -8801,14 +8808,14 @@ void Parser::Parse_Declare(bool is_local, bool after_hash)
88018808 }
88028809 else if (larrayDeclare)
88038810 {
8804- SYM_ENTRY *rvalue = Create_Entry (0 , " " , DUMMY_SYMBOL_TOKEN);
8811+ SYM_ENTRY *rvalue = Create_Entry (" " , DUMMY_SYMBOL_TOKEN, false );
88058812 if (!Parse_RValue (IDENTIFIER_TOKEN, &(rvalue->Token_Number ), &(rvalue->Data ), NULL , false , false , true , true , false , MAX_NUMBER_OF_TABLES) ||
88068813 (rvalue->Token_Number != ARRAY_ID_TOKEN))
88078814 Expectation_Error (" array RValue" );
88088815 POV_ARRAY *a = reinterpret_cast <POV_ARRAY *>(rvalue->Data );
8809- if (lvalues.size () > a->Total )
8816+ if (lvalues.size () > a->DataPtrs . size () )
88108817 Error (" array size mismatch" );
8811- if (a->DataPtrs == NULL )
8818+ if (a->DataPtrs . empty () )
88128819 Error (" cannot assign from uninitialized array" );
88138820
88148821 for (int i = 0 ; i < lvalues.size (); ++i)
@@ -8827,7 +8834,7 @@ void Parser::Parse_Declare(bool is_local, bool after_hash)
88278834 *dataPtr = Copy_Identifier (a->DataPtrs [i], a->Type );
88288835 }
88298836
8830- Destroy_Entry (0 , rvalue );
8837+ Destroy_Entry (rvalue, false );
88318838 }
88328839 else
88338840 {
@@ -8892,7 +8899,7 @@ void Parser::Parse_Declare(bool is_local, bool after_hash)
88928899 for (vector<LValue>::iterator i = lvalues.begin (); i != lvalues.end (); ++i)
88938900 {
88948901 if ((i->symEntry != NULL ) && (i->symEntry ->Token_Number == DUMMY_SYMBOL_TOKEN))
8895- Destroy_Entry (0 , i->symEntry );
8902+ Destroy_Entry (i->symEntry , false );
88968903 }
88978904
88988905 if ( after_hash )
@@ -8903,6 +8910,18 @@ void Parser::Parse_Declare(bool is_local, bool after_hash)
89038910 }
89048911}
89058912
8913+ bool Parser::PassParameterByReference (int callingContext)
8914+ {
8915+ if (Token.is_dictionary_elem )
8916+ {
8917+ return true ;
8918+ }
8919+ else
8920+ {
8921+ return (Token.context <= callingContext);
8922+ }
8923+ }
8924+
89068925bool Parser::Parse_RValue (int Previous, int *NumberPtr, void **DataPtr, SYM_ENTRY *sym, bool ParFlag, bool SemiFlag, bool is_local, bool allow_redefine, bool allowUndefined, int old_table_index)
89078926{
89088927 EXPRESS Local_Express;
@@ -8928,21 +8947,21 @@ bool Parser::Parse_RValue (int Previous, int *NumberPtr, void **DataPtr, SYM_ENT
89288947 bool callable_identifier;
89298948 bool had_callable_identifier;
89308949 SYM_ENTRY* symbol_entry;
8950+ SYM_TABLE* symbol_entry_table;
89318951
89328952 EXPECT_ONE
89338953 CASE4 (NORMAL_ID_TOKEN, FINISH_ID_TOKEN, TEXTURE_ID_TOKEN, OBJECT_ID_TOKEN)
89348954 CASE4 (COLOUR_MAP_ID_TOKEN, TRANSFORM_ID_TOKEN, CAMERA_ID_TOKEN, PIGMENT_ID_TOKEN)
89358955 CASE4 (SLOPE_MAP_ID_TOKEN,NORMAL_MAP_ID_TOKEN,TEXTURE_MAP_ID_TOKEN,ARRAY_ID_TOKEN)
89368956 CASE4 (PIGMENT_MAP_ID_TOKEN, MEDIA_ID_TOKEN,INTERIOR_ID_TOKEN,DENSITY_ID_TOKEN)
89378957 CASE4 (DENSITY_MAP_ID_TOKEN, RAINBOW_ID_TOKEN, FOG_ID_TOKEN, SKYSPHERE_ID_TOKEN)
8938- CASE2 (MATERIAL_ID_TOKEN, STRING_ID_TOKEN)
8939- if ((ParFlag) && (Token. Table_Index <= old_table_index))
8958+ CASE3 (MATERIAL_ID_TOKEN, STRING_ID_TOKEN, DICTIONARY_ID_TOKEN )
8959+ if ((ParFlag) && PassParameterByReference ( old_table_index))
89408960 {
89418961 // pass by reference
89428962 New_Par = reinterpret_cast <POV_PARAM *>(POV_MALLOC (sizeof (POV_PARAM)," parameter" ));
89438963 New_Par->NumberPtr = Token.NumberPtr ;
89448964 New_Par->DataPtr = Token.DataPtr ;
8945- New_Par->Table_Index = Token.Table_Index ;
89468965 *NumberPtr = PARAMETER_ID_TOKEN;
89478966 *DataPtr = reinterpret_cast <void *>(New_Par);
89488967 }
@@ -9024,9 +9043,12 @@ bool Parser::Parse_RValue (int Previous, int *NumberPtr, void **DataPtr, SYM_ENT
90249043 if ((Token.Token_Id ==FUNCT_ID_TOKEN) || (Token.Token_Id ==VECTFUNCT_ID_TOKEN) || (Token.Token_Id ==SPLINE_ID_TOKEN) ||
90259044 (Token.Token_Id ==UV_ID_TOKEN) || (Token.Token_Id ==VECTOR_4D_ID_TOKEN) || (Token.Token_Id ==COLOUR_ID_TOKEN))
90269045 {
9027- symbol_entry = Find_Symbol (Token.Table_Index , Token.Token_String );
9046+ symbol_entry = Find_Symbol (Token.table , Token.Token_String );
90289047 if (symbol_entry)
9048+ {
9049+ symbol_entry_table = Token.table ;
90299050 Acquire_Entry_Reference (symbol_entry);
9051+ }
90309052 }
90319053 else
90329054 {
@@ -9048,7 +9070,7 @@ bool Parser::Parse_RValue (int Previous, int *NumberPtr, void **DataPtr, SYM_ENT
90489070 Error (" Identifier expected, incomplete function call or spline call found instead." );
90499071
90509072 // only one identifier token has been found so pass it by reference
9051- if (((Temp_Count==-1 ) || (Temp_Count==TOKEN_OVERFLOW_RESET_COUNT)) && (Token. Table_Index <= old_table_index))
9073+ if (((Temp_Count==-1 ) || (Temp_Count==TOKEN_OVERFLOW_RESET_COUNT)) && PassParameterByReference ( old_table_index))
90529074 {
90539075 // It is important that functions are passed by value and not by reference! [trf]
90549076 if (!(ParFlag) || (ParFlag && function_identifier))
@@ -9065,7 +9087,6 @@ bool Parser::Parse_RValue (int Previous, int *NumberPtr, void **DataPtr, SYM_ENT
90659087 New_Par = reinterpret_cast <POV_PARAM *>(POV_MALLOC (sizeof (POV_PARAM)," parameter" ));
90669088 New_Par->NumberPtr = Token.NumberPtr ;
90679089 New_Par->DataPtr = Token.DataPtr ;
9068- New_Par->Table_Index = Token.Table_Index ;
90699090
90709091 *NumberPtr = PARAMETER_ID_TOKEN;
90719092 *DataPtr = reinterpret_cast <void *>(New_Par);
@@ -9110,7 +9131,7 @@ bool Parser::Parse_RValue (int Previous, int *NumberPtr, void **DataPtr, SYM_ENT
91109131 }
91119132 }
91129133 if (symbol_entry)
9113- Release_Entry_Reference (Token. Table_Index , symbol_entry);
9134+ Release_Entry_Reference (symbol_entry_table , symbol_entry);
91149135
91159136 // allow #declares again
91169137 Ok_To_Declare = true ;
@@ -9329,6 +9350,13 @@ bool Parser::Parse_RValue (int Previous, int *NumberPtr, void **DataPtr, SYM_ENT
93299350 *DataPtr = Temp_Data;
93309351 END_CASE
93319352
9353+ CASE (DICTIONARY_TOKEN)
9354+ Temp_Data = reinterpret_cast <void *>(Parse_Dictionary_Declare ());
9355+ *NumberPtr = DICTIONARY_ID_TOKEN;
9356+ Test_Redefine (Previous,NumberPtr,*DataPtr, allow_redefine);
9357+ *DataPtr = Temp_Data;
9358+ END_CASE
9359+
93329360 OTHERWISE
93339361 UNGET
93349362 Local_Object = Parse_Object ();
@@ -9438,15 +9466,20 @@ void Parser::Destroy_Ident_Data(void *Data, int Type)
94389466 break ;
94399467 case ARRAY_ID_TOKEN:
94409468 a = reinterpret_cast <POV_ARRAY *>(Data);
9441- if (a->DataPtrs != NULL )
9469+ if (! a->DataPtrs . empty () )
94429470 {
9443- for (i=0 ; i<a->Total ; i++)
9471+ for (i=0 ; i<a->DataPtrs . size () ; i++)
94449472 {
9445- Destroy_Ident_Data (a->DataPtrs [i], a->Type );
9473+ if (a->Types .empty ())
9474+ Destroy_Ident_Data (a->DataPtrs [i], a->Type );
9475+ else
9476+ Destroy_Ident_Data (a->DataPtrs [i], a->Types [i]);
94469477 }
9447- POV_FREE (a->DataPtrs );
94489478 }
9449- POV_FREE (a);
9479+ delete a;
9480+ break ;
9481+ case DICTIONARY_ID_TOKEN:
9482+ Destroy_Sym_Table (reinterpret_cast <SYM_TABLE *>(Data));
94509483 break ;
94519484 case PARAMETER_ID_TOKEN:
94529485 POV_FREE (Data);
@@ -10519,16 +10552,30 @@ void *Parser::Copy_Identifier (void *Data, int Type)
1051910552 POV_MEMMOVE (reinterpret_cast <void *>(New), reinterpret_cast <void *>(Data), len * sizeof (UCS2));
1052010553 break ;
1052110554 case ARRAY_ID_TOKEN:
10522- a=reinterpret_cast <POV_ARRAY *>(Data);
10523- na=reinterpret_cast <POV_ARRAY *>(POV_MALLOC (sizeof (POV_ARRAY)," array" ));
10524- *na=*a;
10525- na->DataPtrs = reinterpret_cast <void **>(POV_MALLOC (sizeof (void *)*(a->Total )," array" ));
10526- for (i=0 ; i<a->Total ; i++)
10555+ a = reinterpret_cast <POV_ARRAY *>(Data);
10556+ na = new POV_ARRAY;
10557+ na->Dims = a->Dims ;
10558+ na->Type = a->Type ;
10559+ na->resizable = a->resizable ;
10560+ for (i = 0 ; i < 5 ; ++i)
10561+ {
10562+ na->Sizes [i] = a->Sizes [i];
10563+ na->Mags [i] = a->Mags [i];
10564+ }
10565+ na->DataPtrs .resize (a->DataPtrs .size ());
10566+ na->Types = a->Types ;
10567+ for (i=0 ; i<a->DataPtrs .size (); i++)
1052710568 {
10528- na->DataPtrs [i] = reinterpret_cast <void *>(Copy_Identifier (a->DataPtrs [i],a->Type ));
10569+ if (a->Types .empty ())
10570+ na->DataPtrs [i] = reinterpret_cast <void *>(Copy_Identifier (a->DataPtrs [i],a->Type ));
10571+ else
10572+ na->DataPtrs [i] = reinterpret_cast <void *>(Copy_Identifier (a->DataPtrs [i], a->Types [i]));
1052910573 }
1053010574 New = reinterpret_cast <void *>(na);
1053110575 break ;
10576+ case DICTIONARY_ID_TOKEN:
10577+ New = reinterpret_cast <void *>(Copy_Sym_Table (reinterpret_cast <SYM_TABLE *>(Data)));
10578+ break ;
1053210579 case FUNCT_ID_TOKEN:
1053310580 case VECTFUNCT_ID_TOKEN:
1053410581 New = reinterpret_cast <void *>(fnVMContext->functionvm ->CopyFunction ((FUNCTION_PTR )Data));
0 commit comments