[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