[sldev] A proposed change to the LSL compiler.
Argent Stonecutter
secret.argent at gmail.com
Mon Jan 22 12:54:14 PST 2007
I haven't had time to pull together all the bits and pieces to get
this compiling on OSX yet, so I haven't been able to test this, but
I've written several compilers for small real-time languages like LSL
over the past 20 years and I'm pretty confident about this change.
The first thing is: no legal LSL programs should be effected. Some
programs containing illegal floating point constants may error out on
compile, though, instead of simply producing incorrect values.
The second thing: Many statements that were previously errors (often
inexplicably) will now become legal.
The first thing I noted is that in indra.l, {D} is used a lot of
places where {N} should be... which makes things like "a-1" illegal,
and also messes up parsing for floats. For example, "3.-4" would be
lexxed as a float (matching the {D}*"."{D}+... line), then atof()
returns "3.0". There are meny other places this is a problem. After
going through the code I thing {D} is really superfluous.
On the other hand the way {D} is used means that "-1" is
INTEGER_CONSTANT. Which is (I assume) where this came from... to
allow things like -1 to be used as globals. It's a quick fx to the
lexxer, but really in the wrong place.
A better fix, I thing, might be to define fp_constant and
integer_constant in indra.y and use them instead of FP_CONSTANT and
INTEGER_CONSTANT in the rule for constant. The indra.y patch is
conservative about FP_CONSTANT but goes ahead and allows pretty much
any integer constant expression.
First, in indra.l:
1d0
< D [-]?[0-9]
5c4
< E [Ee][+-]?{D}+
---
> E [Ee][+-]?{N}+
114c113
< {D}+ { count(); yylval.ival = strtoul(yytext, NULL, 10); return
(INTEGER_CONSTANT); }
---
> {N}+ { count(); yylval.ival = strtoul(yytext, NULL, 10); return
(INTEGER_CONSTANT); }
564,566c563,565
< {D}+{E} { count(); yylval.fval = (F32)atof(yytext); return
(FP_CONSTANT); }
< {D}*"."{D}+({E})?{FS}? { count(); yylval.fval = (F32)atof(yytext);
return(FP_CONSTANT); }
< {D}+"."{D}*({E})?{FS}? { count(); yylval.fval = (F32)atof(yytext);
return(FP_CONSTANT); }
---
> {N}+{E} { count(); yylval.fval = (F32)atof(yytext); return
(FP_CONSTANT); }
> {N}*"."{N}+({E})?{FS}? { count(); yylval.fval = (F32)atof(yytext);
return(FP_CONSTANT); }
> {N}+"."{N}*({E})?{FS}? { count(); yylval.fval = (F32)atof(yytext);
return(FP_CONSTANT); }
Second, in indra.y:
*** indra.y Mon Jan 22 14:29:29 2007
--- indra.y.new Mon Jan 22 14:29:59 2007
***************
*** 143,148 ****
--- 143,151 ----
%type <assignable> simple_assignable
%type <assignable> simple_assignable_no_list
%type <constant> constant
+ %type <ival> integer_constant
+ %type <ival> unary_integer_constant
+ %type <fval> fp_constant
%type <assignable> special_constant
%type <assignable> vector_constant
%type <assignable> quaternion_constant
***************
*** 352,373 ****
;
constant
! : INTEGER_CONSTANT
! {
! $$ = new LLScriptConstantInteger(gLine, gColumn, $1);
! gAllocationManager->addAllocation($$);
! }
! | INTEGER_TRUE
! {
! $$ = new LLScriptConstantInteger(gLine, gColumn, $1);
! gAllocationManager->addAllocation($$);
! }
! | INTEGER_FALSE
{
$$ = new LLScriptConstantInteger(gLine, gColumn, $1);
gAllocationManager->addAllocation($$);
}
! | FP_CONSTANT
{
$$ = new LLScriptConstantFloat(gLine, gColumn, $1);
gAllocationManager->addAllocation($$);
--- 355,366 ----
;
constant
! : integer_constant
{
$$ = new LLScriptConstantInteger(gLine, gColumn, $1);
gAllocationManager->addAllocation($$);
}
! : fp_constant
{
$$ = new LLScriptConstantFloat(gLine, gColumn, $1);
gAllocationManager->addAllocation($$);
***************
*** 379,384 ****
--- 372,485 ----
}
;
+ /* Added to make up for pulling {D} out of indra.l AS 20060122 */
+ fp_constant
+ : FP_CONSTANT
+ {
+ $$ = $1;
+ }
+ | '-' FP_CONSTANT
+ {
+ $$ = -$1;
+ }
+ ;
+
+ /* Added to make up for pulling {D} out of indra.l AS 20060122 */
+ integer_constant
+ : unary_integer_constant
+ {
+ $$ = $1;
+ }
+ | integer_constant EQ integer_constant
+ {
+ $$ = $1 == $3;
+ }
+ | integer_constant NEQ integer_constant
+ {
+ $$ = $1 != $3;
+ }
+ | integer_constant LEQ integer_constant
+ {
+ $$ = $1 <= $3;
+ }
+ | integer_constant GEQ integer_constant
+ {
+ $$ = $1 >= $3;
+ }
+ | integer_constant '<' integer_constant
+ {
+ $$ = $1 < $3;
+ }
+ | integer_constant '>' integer_constant
+ {
+ $$ = $1 > $3;
+ }
+ | integer_constant '+' integer_constant
+ {
+ $$ = $1 + $3;
+ }
+ | integer_constant '-' integer_constant
+ {
+ $$ = $1 - $3;
+ }
+ | integer_constant '*' integer_constant
+ {
+ $$ = $1 * $3;
+ }
+ | integer_constant '/' integer_constant
+ {
+ $$ = $1 / $3;
+ }
+ | integer_constant '%' integer_constant
+ {
+ $$ = $1 % $3;
+ }
+ | integer_constant '&' integer_constant
+ {
+ $$ = $1 & $3;
+ }
+ | integer_constant '|' integer_constant
+ {
+ $$ = $1 | $3;
+ }
+ | integer_constant '^' integer_constant
+ {
+ $$ = $1 ^ $3;
+ }
+ ;
+
+ /* Added to make up for pulling {D} out of indra.l AS 20060122 */
+ unary_integer_constant
+ : INTEGER_CONSTANT
+ {
+ $$ = $1;
+ }
+ | INTEGER_TRUE
+ {
+ $$ = $1;
+ }
+ | INTEGER_FALSE
+ {
+ $$ = $1;
+ }
+ | '-' integer_constant
+ {
+ $$ = -$2;
+ }
+ | '~' integer_constant
+ {
+ $$ = ~$2;
+ }
+ | '!' integer_constant
+ {
+ $$ = !$2;
+ }
+ | '(' integer_constant ')'
+ {
+ $$ = $2;
+ }
+ ;
+
special_constant
: vector_constant
{
More information about the SLDev
mailing list