[PATCH] Allow constant expressions

php.internals

Sterling Hughes

23 years ago
Hi, The attached patch allows constant expressions within class variables and constants. I came into this problem when I wanted the following sequence: class foo { const A = 1<<0; const B = 1<<1; const C = 1<<2; } And the current parser doesn't allow such rules. I therefore added the attached patch which allows operators to be used on constants within these expressions (and also within array declarations). This is achieved by folding statements such as '1<<0' into their equivalent values at compile time. The following operators are supported: << >> | & + - * / . % ^ ~ xor Please review it, and let me know if its ok to commit. :) -Sterling
-- "People can have the Model T in any colour -- so long as it's black." - Henry Ford

Sterling Hughes

23 years ago
I've updated my patch (attached), which allows for parentheses groupings such as : const foo = (1<<2) | (2 & 5); -Sterling On Mon, 2003-04-07 at 21:06, Sterling Hughes wrote:
> Hi, > > The attached patch allows constant expressions within class variables > and constants. I came into this problem when I wanted the following > sequence: > > class foo { > const A = 1<<0; > const B = 1<<1; > const C = 1<<2; > } > > And the current parser doesn't allow such rules. I therefore added the > attached patch which allows operators to be used on constants within > these expressions (and also within array declarations). This is > achieved by folding statements such as '1<<0' into their equivalent > values at compile time. The following operators are supported: << >> | > & + - * / . % ^ ~ xor > > Please review it, and let me know if its ok to commit. :) > > -Sterling
-- "Science is like sex: sometimes something useful comes out, but that is not the reason we are doing it." - Richard Feynman

Sterling Hughes

23 years ago
Ok, attached is the updated patch, the result of a conversation between myself and Zeev. *) Class constants are allowed to be operands to constants. However, constants must exist within the current class only, and they must be defined before usage, so for example: class simple { const second = 1; const minute = 60 * second; const hour = 60 * minute; const day = 24 * hour; } Would work. However: class simple { const minute = second * 60; const second = 1; } Wouldn't, and neither would: class simple { const foo = "bar"; } class simple1 { const baz = "bar" . foo; } Currently, referencing the current class also doesn't work, ie, class simple { const bar = "baz"; const foo = simple::bar . "naz"; } Although that could be added. It is also important to note that const is now *fully* compile time, therefore const cannot, for example, reference a define() which is called above (because define() is runtime). Also, this patch removes the ability to use operators in array initialization, as a bunch of people seem to have found that behaviour distasteful. Patch attached. On Mon, 2003-04-07 at 22:43, Sterling Hughes wrote:
> I've updated my patch (attached), which allows for parentheses groupings > such as : > > const foo = (1<<2) | (2 & 5); > > -Sterling > > On Mon, 2003-04-07 at 21:06, Sterling Hughes wrote: > > Hi, > > > > The attached patch allows constant expressions within class variables > > and constants. I came into this problem when I wanted the following > > sequence: > > > > class foo { > > const A = 1<<0; > > const B = 1<<1; > > const C = 1<<2; > > } > > > > And the current parser doesn't allow such rules. I therefore added the > > attached patch which allows operators to be used on constants within > > these expressions (and also within array declarations). This is > > achieved by folding statements such as '1<<0' into their equivalent > > values at compile time. The following operators are supported: << >> | > > & + - * / . % ^ ~ xor > > > > Please review it, and let me know if its ok to commit. :) > > > > -Sterling
-- "Nothing is particularly hard if you divide it into small jobs." - Henry Ford

Sterling Hughes

23 years ago
Yargh, a little debug info got into the last patch. Attached is the last patch, minus my little debug stuff. On Tue, 2003-04-08 at 14:05, Sterling Hughes wrote:
> Ok, attached is the updated patch, the result of a conversation between > myself and Zeev. > > *) Class constants are allowed to be operands to constants. However, > constants must exist within the current class only, and they must be > defined before usage, so for example: > > class simple { > const second = 1; > const minute = 60 * second; > const hour = 60 * minute; > const day = 24 * hour; > } > > Would work. > > However: > > class simple { > const minute = second * 60; > const second = 1; > } > > Wouldn't, and neither would: > > class simple { > const foo = "bar"; > } > > class simple1 { > const baz = "bar" . foo; > } > > Currently, referencing the current class also doesn't work, ie, > > class simple { > const bar = "baz"; > const foo = simple::bar . "naz"; > } > > Although that could be added. > > It is also important to note that const is now *fully* compile time, > therefore const cannot, for example, reference a define() which is > called above (because define() is runtime). > > Also, this patch removes the ability to use operators in array > initialization, as a bunch of people seem to have found that behaviour > distasteful. Patch attached. > > > On Mon, 2003-04-07 at 22:43, Sterling Hughes wrote: > > I've updated my patch (attached), which allows for parentheses groupings > > such as : > > > > const foo = (1<<2) | (2 & 5); > > > > -Sterling > > > > On Mon, 2003-04-07 at 21:06, Sterling Hughes wrote: > > > Hi, > > > > > > The attached patch allows constant expressions within class variables > > > and constants. I came into this problem when I wanted the following > > > sequence: > > > > > > class foo { > > > const A = 1<<0; > > > const B = 1<<1; > > > const C = 1<<2; > > > } > > > > > > And the current parser doesn't allow such rules. I therefore added the > > > attached patch which allows operators to be used on constants within > > > these expressions (and also within array declarations). This is > > > achieved by folding statements such as '1<<0' into their equivalent > > > values at compile time. The following operators are supported: << >> | > > > & + - * / . % ^ ~ xor > > > > > > Please review it, and let me know if its ok to commit. :) > > > > > > -Sterling
-- "I can't give you a brain, so I'll give you a diploma" - The Great Oz, The Wizard of Oz

Sterling Hughes

23 years ago
The last patch introduced a couple of bugs: 1) global constants weren't allowed, this includes true, false, null, etc. 2) it overrode the default behaviour for var $variable = someconstant; since we're folding these, such initialization cannot reasonably happen (big BC break). Attached is a new patch (hopefully the last one), which fixes these bugs and adds the new functionality. -Sterling On Tue, 2003-04-08 at 14:08, Sterling Hughes wrote:
> Yargh, a little debug info got into the last patch. > > Attached is the last patch, minus my little debug stuff. > > > On Tue, 2003-04-08 at 14:05, Sterling Hughes wrote: > > Ok, attached is the updated patch, the result of a conversation between > > myself and Zeev. > > > > *) Class constants are allowed to be operands to constants. However, > > constants must exist within the current class only, and they must be > > defined before usage, so for example: > > > > class simple { > > const second = 1; > > const minute = 60 * second; > > const hour = 60 * minute; > > const day = 24 * hour; > > } > > > > Would work. > > > > However: > > > > class simple { > > const minute = second * 60; > > const second = 1; > > } > > > > Wouldn't, and neither would: > > > > class simple { > > const foo = "bar"; > > } > > > > class simple1 { > > const baz = "bar" . foo; > > } > > > > Currently, referencing the current class also doesn't work, ie, > > > > class simple { > > const bar = "baz"; > > const foo = simple::bar . "naz"; > > } > > > > Although that could be added. > > > > It is also important to note that const is now *fully* compile time, > > therefore const cannot, for example, reference a define() which is > > called above (because define() is runtime). > > > > Also, this patch removes the ability to use operators in array > > initialization, as a bunch of people seem to have found that behaviour > > distasteful. Patch attached. > > > > > > On Mon, 2003-04-07 at 22:43, Sterling Hughes wrote: > > > I've updated my patch (attached), which allows for parentheses groupings > > > such as : > > > > > > const foo = (1<<2) | (2 & 5); > > > > > > -Sterling > > > > > > On Mon, 2003-04-07 at 21:06, Sterling Hughes wrote: > > > > Hi, > > > > > > > > The attached patch allows constant expressions within class variables > > > > and constants. I came into this problem when I wanted the following > > > > sequence: > > > > > > > > class foo { > > > > const A = 1<<0; > > > > const B = 1<<1; > > > > const C = 1<<2; > > > > } > > > > > > > > And the current parser doesn't allow such rules. I therefore added the > > > > attached patch which allows operators to be used on constants within > > > > these expressions (and also within array declarations). This is > > > > achieved by folding statements such as '1<<0' into their equivalent > > > > values at compile time. The following operators are supported: << >> | > > > > & + - * / . % ^ ~ xor > > > > > > > > Please review it, and let me know if its ok to commit. :) > > > > > > > > -Sterling
-- "Science is like sex: sometimes something useful comes out, but that is not the reason we are doing it." - Richard Feynman

Andrey Hristov

23 years ago
> > However: > > class simple { > const minute = second * 60; > const second = 1; > } > > Wouldn't, and neither would: > > class simple { > const foo = "bar"; > }
So, only scalars could be initialized consts? Andrey

Sterling Hughes

23 years ago
On Tue, 2003-04-08 at 14:34, Andrey Hristov wrote:
> > > > However: > > > > class simple { > > const minute = second * 60; > > const second = 1; > > } > > > > Wouldn't, and neither would: > > > > class simple { > > const foo = "bar"; > > } > > So, only scalars could be initialized consts? >
yes, that's how its always worked. -Sterling
-- "Reductionists like to take things apart. The rest of us are just trying to get it together." - Larry Wall, Programming Perl, 3rd Edition

Zeev Suraski

23 years ago
I think there's one broken thing in this patch (I haven't tested it, so I could be wrong) - it removes some functionality that we did have in the past. static_scalar can no longer contain a constant (one that was defined with define()). That means that constant initializers for arrays, default arguments, etc - lose a big chunk of functionality. (again, I arrived at that conclusion by briefly going over the parser patch, if you took this into account and it does work - go ahead and commit it, it looks good). Zeev At 21:05 08/04/2003, Sterling Hughes wrote:

Sterling Hughes

23 years ago
On Thu, 2003-04-10 at 02:59, Zeev Suraski wrote:
> I think there's one broken thing in this patch (I haven't tested it, so I > could be wrong) - it removes some functionality that we did have in the > past. static_scalar can no longer contain a constant (one that was defined > with define()). That means that constant initializers for arrays, default > arguments, etc - lose a big chunk of functionality. (again, I arrived at > that conclusion by briefly going over the parser patch, if you took this > into account and it does work - go ahead and commit it, it looks good). >
It does,kinda. Because I was doing folding the last patch adds a new type (const_sclar i believe, i'm becoming senile), which doesn't support define'd constants, etc. Normal functionality remains untouched. I personally think that's a reasonable 90%, and its nice to also have a compile time constant. -Sterling
-- "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, it blows away your whole leg." - Bjarne Stroustrup

Zeev Suraski

23 years ago
At 11:21 10/04/2003, Sterling Hughes wrote:
>On Thu, 2003-04-10 at 02:59, Zeev Suraski wrote: > > I think there's one broken thing in this patch (I haven't tested it, so I > > could be wrong) - it removes some functionality that we did have in the > > past. static_scalar can no longer contain a constant (one that was > defined > > with define()). That means that constant initializers for arrays, default > > arguments, etc - lose a big chunk of functionality. (again, I arrived at > > that conclusion by briefly going over the parser patch, if you took this > > into account and it does work - go ahead and commit it, it looks good). > > > >It does,kinda. Because I was doing folding the last patch adds a new >type (const_sclar i believe, i'm becoming senile), which doesn't support >define'd constants, etc. Normal functionality remains untouched.
Please look again, I think you're wrong: static_scalar: /* compile-time evaluated scalars */ common_scalar { $$ = $1; } - | T_STRING { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_CT TSRMLS_CC); } + | T_STRING { zend_do_fold_constant(&$$, &$1 TSRMLS_CC); } | '+' static_scalar { $$ = $2; } - | '-' static_scalar { zval minus_one; minus_one.type = IS_LONG; minus_one.value.lval = -1; mul_function(&$2.u.constant, &$2.u.constant, &minus_one TSRMLS_CC); $$ = $2; } + | '-' static_scalar { zval minus_one; minus_one.type = IS_LONG; minus_one.value.lval = -1; mul_function(&$2.u.constant, &$2.u.constant, &minus_one TSRMLS_CC); $$ = $2; } | T_ARRAY '(' static_array_pair_list ')' { $$ = $3; $$.u.constant.type = IS_CONSTANT_ARRAY; } | class_or_namespace_constant { /* FIXME */ } ;
>I personally think that's a reasonable 90%, and its nice to also have a >compile time constant.
Not sure what you're talking about here :) Zeev

Sterling Hughes

23 years ago
*Arg* I knew I sent one too many patch. :) http://news.php.net/article.php?group=php.internals&article=811 Is the revised patch I was talking about. I did this one, as I realized it b0rked PEAR otherwise. -Sterling
-- "A business that makes nothing but money is a poor kind of business." - Henry Ford

Zeev Suraski

23 years ago
Nice patch, but one problem - it allows users to use constants as a part of those expressions... Since the values of those are not known until compile time, we have an issue there. Technically we can disallow such constants from being used in those expressions, but I'm not sure how well we can explain this (you can use constants, but not in expressions?) I don't know, maybe it's an ok thing to say. Zeev At 04:06 08/04/2003, Sterling Hughes wrote:

Sterling Hughes

23 years ago
On Tue, 2003-04-08 at 06:37, Zeev Suraski wrote:
> Nice patch, but one problem - it allows users to use constants as a part of > those expressions... Since the values of those are not known until compile > time, we have an issue there. Technically we can disallow such constants > from being used in those expressions, but I'm not sure how well we can > explain this (you can use constants, but not in expressions?) I don't > know, maybe it's an ok thing to say. >
Hah. I have a second patch pending (just this problem) which folds constants into their corresponding values, but I left it out because I felt it more controversial. I think that if you use a constant in an assignment to another constant, that constant should "lookupable" a compile time, and neatly folded into the constant definition itself. If this is something people are ok with, I'll add that to the patch. -Sterling
-- "Programming today is a race between software engineers stirring to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning." - Unknown