Skip to content

Commit 093def7

Browse files
committed
Implement dynamically-sized arrays.
1 parent 0b5ac83 commit 093def7

File tree

6 files changed

+74
-33
lines changed

6 files changed

+74
-33
lines changed

changes.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ Prior to the release of 3.7.1, the following items still need urgent attention:
4949
New Features
5050
------------
5151

52+
- Support for variable-size arrays has been added.
53+
5254
- A new data container, `dictionary`, has been added to support structured
5355
storage of data.
5456

source/base/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
#define OFFICIAL_VERSION_STRING "3.7.1"
4646
#define OFFICIAL_VERSION_NUMBER 371
4747

48-
#define POV_RAY_PRERELEASE "x.dictionary.8790989"
48+
#define POV_RAY_PRERELEASE "x.dictionary.8791118"
4949

5050
#if (POV_RAY_IS_AUTOBUILD == 1) && ((POV_RAY_IS_OFFICIAL == 1) || (POV_RAY_IS_SEMI_OFFICIAL == 1))
5151
#ifdef POV_RAY_PRERELEASE

source/parser/parser.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8865,9 +8865,9 @@ void Parser::Parse_Declare(bool is_local, bool after_hash)
88658865
(rvalue->Token_Number != ARRAY_ID_TOKEN))
88668866
Expectation_Error("array RValue");
88678867
POV_ARRAY *a = reinterpret_cast<POV_ARRAY *>(rvalue->Data);
8868-
if (lvalues.size() > a->Total)
8868+
if (lvalues.size() > a->DataPtrs.size())
88698869
Error ("array size mismatch");
8870-
if (a->DataPtrs == NULL)
8870+
if (a->DataPtrs.empty())
88718871
Error ("cannot assign from uninitialized array");
88728872

88738873
for (int i = 0; i < lvalues.size(); ++i)
@@ -9542,15 +9542,12 @@ void Parser::Destroy_Ident_Data(void *Data, int Type)
95429542
break;
95439543
case ARRAY_ID_TOKEN:
95449544
a = reinterpret_cast<POV_ARRAY *>(Data);
9545-
if(a->DataPtrs != NULL)
9545+
if(!a->DataPtrs.empty())
95469546
{
9547-
for(i=0; i<a->Total; i++)
9548-
{
9547+
for(i=0; i<a->DataPtrs.size(); i++)
95499548
Destroy_Ident_Data(a->DataPtrs[i], a->Type);
9550-
}
9551-
POV_FREE(a->DataPtrs);
95529549
}
9553-
POV_FREE(a);
9550+
delete a;
95549551
break;
95559552
case DICTIONARY_ID_TOKEN:
95569553
Destroy_Sym_Table (reinterpret_cast<SYM_TABLE *>(Data));
@@ -10620,11 +10617,17 @@ void *Parser::Copy_Identifier (void *Data, int Type)
1062010617
POV_MEMMOVE(reinterpret_cast<void *>(New), reinterpret_cast<void *>(Data), len * sizeof(UCS2));
1062110618
break;
1062210619
case ARRAY_ID_TOKEN:
10623-
a=reinterpret_cast<POV_ARRAY *>(Data);
10624-
na=reinterpret_cast<POV_ARRAY *>(POV_MALLOC(sizeof(POV_ARRAY),"array"));
10625-
*na=*a;
10626-
na->DataPtrs = reinterpret_cast<void **>(POV_MALLOC(sizeof(void *)*(a->Total),"array"));
10627-
for (i=0; i<a->Total; i++)
10620+
a = reinterpret_cast<POV_ARRAY *>(Data);
10621+
na = new POV_ARRAY;
10622+
na->Dims = a->Dims;
10623+
na->Type = a->Type;
10624+
for (i = 0; i < 5; ++i)
10625+
{
10626+
na->Sizes[i] = a->Sizes[i];
10627+
na->Mags[i] = a->Mags[i];
10628+
}
10629+
na->DataPtrs.resize(a->DataPtrs.size());
10630+
for (i=0; i<a->DataPtrs.size(); i++)
1062810631
{
1062910632
na->DataPtrs[i] = reinterpret_cast<void *>(Copy_Identifier (a->DataPtrs[i],a->Type));
1063010633
}

source/parser/parser.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,10 +273,11 @@ class Parser : public SceneTask
273273

274274
struct POV_ARRAY
275275
{
276-
int Dims, Type, Total;
276+
int Dims, Type;
277277
int Sizes[5];
278278
int Mags[5];
279-
void **DataPtrs;
279+
vector<void*> DataPtrs;
280+
bool resizable;
280281
};
281282

282283
struct POV_PARAM

source/parser/parser_tokenizer.cpp

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,7 +1404,14 @@ void Parser::Read_Symbol()
14041404

14051405
if (k >= a->Sizes[i])
14061406
{
1407-
Error("Array subscript out of range");
1407+
if (a->resizable)
1408+
{
1409+
POV_PARSER_ASSERT (a->Dims == 0);
1410+
a->DataPtrs.resize (k+1);
1411+
a->Sizes[0] = a->DataPtrs.size();
1412+
}
1413+
else
1414+
Error("Array subscript out of range");
14081415
}
14091416
j += k * a->Mags[i];
14101417
GET(RIGHT_SQUARE_TOKEN)
@@ -1434,6 +1441,12 @@ void Parser::Read_Symbol()
14341441

14351442
if (c =='.')
14361443
{
1444+
if (table == NULL)
1445+
{
1446+
POV_PARSER_ASSERT (Token.is_array_elem);
1447+
Error ("Attempt to access uninitialized array element.");
1448+
}
1449+
14371450
GET (PERIOD_TOKEN)
14381451
bool oldParseRawIdentifiers = parseRawIdentifiers;
14391452
parseRawIdentifiers = true;
@@ -1447,6 +1460,12 @@ void Parser::Read_Symbol()
14471460
}
14481461
else if (c == '[')
14491462
{
1463+
if (table == NULL)
1464+
{
1465+
POV_PARSER_ASSERT (Token.is_array_elem);
1466+
Error ("Attempt to access uninitialized array element.");
1467+
}
1468+
14501469
GET(LEFT_SQUARE_TOKEN)
14511470
dictIndex = Parse_C_String();
14521471
GET (RIGHT_SQUARE_TOKEN);
@@ -3534,7 +3553,8 @@ Parser::POV_ARRAY *Parser::Parse_Array_Declare (void)
35343553
POV_ARRAY *New;
35353554
int i,j;
35363555

3537-
New=reinterpret_cast<POV_ARRAY *>(POV_MALLOC(sizeof(POV_ARRAY),"array"));
3556+
New = new POV_ARRAY;
3557+
New->resizable = false;
35383558

35393559
i=0;
35403560
j=1;
@@ -3562,14 +3582,16 @@ Parser::POV_ARRAY *Parser::Parse_Array_Declare (void)
35623582
END_CASE
35633583
END_EXPECT
35643584

3565-
if ( i < 1 ) {
3566-
Error( "An array declaration must have at least one dimension");
3585+
if (i == 0) {
3586+
// new syntax: Dynamically sized one-dimensional array
3587+
i = 1;
3588+
New->Sizes[0] = 0;
3589+
New->resizable = true;
35673590
}
35683591

35693592
New->Dims = i-1;
3570-
New->Total = j;
35713593
New->Type = EMPTY_ARRAY_TOKEN;
3572-
New->DataPtrs = reinterpret_cast<void **>(POV_MALLOC(sizeof(void *)*j,"array"));
3594+
New->DataPtrs.resize (j);
35733595

35743596
j = 1;
35753597

@@ -3579,9 +3601,9 @@ Parser::POV_ARRAY *Parser::Parse_Array_Declare (void)
35793601
j *= New->Sizes[i];
35803602
}
35813603

3582-
for (i=0; i<New->Total; i++)
3604+
for (i=0; i<New->DataPtrs.size(); i++)
35833605
{
3584-
New->DataPtrs[i] = NULL;
3606+
POV_PARSER_ASSERT (New->DataPtrs[i] == NULL);
35853607
}
35863608

35873609
EXPECT
@@ -3672,9 +3694,17 @@ void Parser::Parse_Initalizer (int Sub, int Base, POV_ARRAY *a)
36723694
else
36733695
{
36743696
bool properlyDelimited = true;
3675-
for(i=0; i < a->Sizes[Sub]; i++)
3697+
bool finalParameter = (!a->resizable && (a->Sizes[Sub] == 0));
3698+
for(i=0; !finalParameter; i++)
36763699
{
3677-
bool finalParameter = (i == a->Sizes[Sub]-1);
3700+
if (a->resizable)
3701+
{
3702+
a->DataPtrs.push_back (NULL);
3703+
a->Sizes[Sub] = a->DataPtrs.size();
3704+
}
3705+
else
3706+
finalParameter = (i == (a->Sizes[Sub]-1));
3707+
36783708
if (!Parse_RValue (a->Type, &(a->Type), &(a->DataPtrs[Base+i]), NULL, false, false, true, false, true, MAX_NUMBER_OF_TABLES))
36793709
{
36803710
EXPECT_ONE
@@ -3685,12 +3715,17 @@ void Parser::Parse_Initalizer (int Sub, int Base, POV_ARRAY *a)
36853715
END_CASE
36863716

36873717
CASE (RIGHT_CURLY_TOKEN)
3688-
if (!(finalParameter && properlyDelimited))
3689-
// the parameter list was closed prematurely
3690-
Error("Expected %d initializers but only %d found.",a->Sizes[Sub],i);
3691-
// the parameter was left empty
3692-
if(!optional)
3693-
Error("Cannot omit elements of non-optional array initializer.");
3718+
if (a->resizable)
3719+
finalParameter = true;
3720+
else
3721+
{
3722+
if (!(finalParameter && properlyDelimited))
3723+
// the parameter list was closed prematurely
3724+
Error("Expected %d initializers but only %d found.",a->Sizes[Sub],i);
3725+
// the parameter was left empty
3726+
if(!optional)
3727+
Error("Cannot omit elements of non-optional array initializer.");
3728+
}
36943729
UNGET
36953730
END_CASE
36963731

unix/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.7.1-x.dictionary.8790989
1+
3.7.1-x.dictionary.8791118

0 commit comments

Comments
 (0)