Identify constant variables during code generation.
This commit is contained in:
@@ -2,9 +2,10 @@ package org.luaj.vm2.ast;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.luaj.vm2.LuaValue;
|
||||||
|
import org.luaj.vm2.ast.Exp.Constant;
|
||||||
import org.luaj.vm2.ast.Exp.NameExp;
|
import org.luaj.vm2.ast.Exp.NameExp;
|
||||||
import org.luaj.vm2.ast.Exp.VarExp;
|
import org.luaj.vm2.ast.Exp.VarExp;
|
||||||
import org.luaj.vm2.ast.Exp.VarargsExp;
|
|
||||||
import org.luaj.vm2.ast.NameScope.NamedVariable;
|
import org.luaj.vm2.ast.NameScope.NamedVariable;
|
||||||
import org.luaj.vm2.ast.Stat.Assign;
|
import org.luaj.vm2.ast.Stat.Assign;
|
||||||
import org.luaj.vm2.ast.Stat.FuncDef;
|
import org.luaj.vm2.ast.Stat.FuncDef;
|
||||||
@@ -88,6 +89,17 @@ public class NameResolver extends Visitor {
|
|||||||
public void visit(LocalAssign stat) {
|
public void visit(LocalAssign stat) {
|
||||||
visitExps(stat.values);
|
visitExps(stat.values);
|
||||||
defineLocalVars( stat.names );
|
defineLocalVars( stat.names );
|
||||||
|
if ( stat.values != null ) {
|
||||||
|
int n = stat.names.size();
|
||||||
|
int m = stat.values.size();
|
||||||
|
boolean varlist = m>0 && stat.values.get(m-1).isvarargexp();
|
||||||
|
for ( int i=0; i<n && i<(varlist?m-1:m); i++ )
|
||||||
|
if ( stat.values.get(i) instanceof Constant )
|
||||||
|
stat.names.get(i).variable.initialValue = ((Constant) stat.values.get(i)).value;
|
||||||
|
if ( !varlist )
|
||||||
|
for ( int i=m+1; i<n; i++ )
|
||||||
|
stat.names.get(i).variable.initialValue = LuaValue.NIL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visit(ParList pars) {
|
public void visit(ParList pars) {
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import java.util.HashSet;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.luaj.vm2.LuaValue;
|
||||||
|
|
||||||
public class NameScope {
|
public class NameScope {
|
||||||
|
|
||||||
private static final Set<String> LUA_KEYWORDS = new HashSet<String>();
|
private static final Set<String> LUA_KEYWORDS = new HashSet<String>();
|
||||||
@@ -67,6 +69,7 @@ public class NameScope {
|
|||||||
public final NameScope definingScope;
|
public final NameScope definingScope;
|
||||||
public boolean isupvalue;
|
public boolean isupvalue;
|
||||||
public boolean hasassignments;
|
public boolean hasassignments;
|
||||||
|
public LuaValue initialValue;
|
||||||
/** Global is named variable not associated with a defining scope */
|
/** Global is named variable not associated with a defining scope */
|
||||||
public NamedVariable(String name) {
|
public NamedVariable(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@@ -80,5 +83,8 @@ public class NameScope {
|
|||||||
public boolean isLocal() {
|
public boolean isLocal() {
|
||||||
return this.definingScope != null;
|
return this.definingScope != null;
|
||||||
}
|
}
|
||||||
|
public boolean isConstant() {
|
||||||
|
return ! hasassignments && initialValue != null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -206,6 +206,8 @@ public class JavaCodeGen {
|
|||||||
int m = stat.values!=null? stat.values.size(): 0;
|
int m = stat.values!=null? stat.values.size(): 0;
|
||||||
if ( n == 1 && m<=1 ) {
|
if ( n == 1 && m<=1 ) {
|
||||||
Name name = stat.names.get(0);
|
Name name = stat.names.get(0);
|
||||||
|
if ( name.variable.isConstant() )
|
||||||
|
return;
|
||||||
String value = m>0? evalLuaValue(stat.values.get(0)): "NIL";
|
String value = m>0? evalLuaValue(stat.values.get(0)): "NIL";
|
||||||
singleLocalDeclareAssign(name,value);
|
singleLocalDeclareAssign(name,value);
|
||||||
} else {
|
} else {
|
||||||
@@ -271,6 +273,8 @@ public class JavaCodeGen {
|
|||||||
|
|
||||||
private void singleAssign(Name name, String valu) {
|
private void singleAssign(Name name, String valu) {
|
||||||
if ( name.variable.isLocal() ) {
|
if ( name.variable.isLocal() ) {
|
||||||
|
if ( name.variable.isConstant() )
|
||||||
|
return;
|
||||||
outi( "" );
|
outi( "" );
|
||||||
singleReference( name );
|
singleReference( name );
|
||||||
outr( " = "+valu+";" );
|
outr( " = "+valu+";" );
|
||||||
@@ -280,6 +284,10 @@ public class JavaCodeGen {
|
|||||||
|
|
||||||
private void singleReference(Name name) {
|
private void singleReference(Name name) {
|
||||||
if ( name.variable.isLocal() ) {
|
if ( name.variable.isLocal() ) {
|
||||||
|
if ( name.variable.isConstant() ) {
|
||||||
|
out( evalConstant(name.variable.initialValue) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
out( javascope.getJavaName(name.variable) );
|
out( javascope.getJavaName(name.variable) );
|
||||||
if ( name.variable.isupvalue && name.variable.hasassignments )
|
if ( name.variable.isupvalue && name.variable.hasassignments )
|
||||||
out( "[0]" );
|
out( "[0]" );
|
||||||
@@ -294,7 +302,9 @@ public class JavaCodeGen {
|
|||||||
|
|
||||||
private void singleLocalDeclareAssign(NamedVariable variable, String value) {
|
private void singleLocalDeclareAssign(NamedVariable variable, String value) {
|
||||||
String javaname = javascope.getJavaName(variable);
|
String javaname = javascope.getJavaName(variable);
|
||||||
if ( variable.isupvalue && variable.hasassignments )
|
if ( variable.isConstant() )
|
||||||
|
return;
|
||||||
|
else if ( variable.isupvalue && variable.hasassignments )
|
||||||
outl( "final LuaValue[] "+javaname+" = {"+value+"};" );
|
outl( "final LuaValue[] "+javaname+" = {"+value+"};" );
|
||||||
else if ( variable.isupvalue )
|
else if ( variable.isupvalue )
|
||||||
outl( "final LuaValue "+javaname+(value!=null? " = "+value: "")+";" );
|
outl( "final LuaValue "+javaname+(value!=null? " = "+value: "")+";" );
|
||||||
@@ -408,6 +418,10 @@ public class JavaCodeGen {
|
|||||||
out(evalLuaValue(exp)+".toboolean()");
|
out(evalLuaValue(exp)+".toboolean()");
|
||||||
}
|
}
|
||||||
public void visit(NameExp exp) {
|
public void visit(NameExp exp) {
|
||||||
|
if ( exp.name.variable.isConstant() ) {
|
||||||
|
out ( exp.name.variable.initialValue.toboolean()? "TRUE": "FALSE");
|
||||||
|
return;
|
||||||
|
}
|
||||||
out(evalLuaValue(exp)+".toboolean()");
|
out(evalLuaValue(exp)+".toboolean()");
|
||||||
}
|
}
|
||||||
public void visit(FuncCall exp) {
|
public void visit(FuncCall exp) {
|
||||||
@@ -471,6 +485,12 @@ public class JavaCodeGen {
|
|||||||
out(evalLuaValue(exp)+".todouble()");
|
out(evalLuaValue(exp)+".todouble()");
|
||||||
}
|
}
|
||||||
public void visit(NameExp exp) {
|
public void visit(NameExp exp) {
|
||||||
|
if ( exp.name.variable.isConstant() ) {
|
||||||
|
if ( exp.name.variable.initialValue.isnumber() ) {
|
||||||
|
out( evalNumberLiteral(exp.name.variable.initialValue.todouble()) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
out(evalLuaValue(exp)+".todouble()");
|
out(evalLuaValue(exp)+".todouble()");
|
||||||
}
|
}
|
||||||
public void visit(FuncCall exp) {
|
public void visit(FuncCall exp) {
|
||||||
@@ -528,23 +548,21 @@ public class JavaCodeGen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void visit(Constant exp) {
|
public void visit(Constant exp) {
|
||||||
switch ( exp.value.type() ) {
|
out( evalConstant(exp.value) );
|
||||||
case LuaValue.TSTRING: {
|
|
||||||
out( evalLuaStringConstant(exp.value.checkstring()) );
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String evalConstant(LuaValue value) {
|
||||||
|
switch ( value.type() ) {
|
||||||
|
case LuaValue.TSTRING:
|
||||||
|
return evalLuaStringConstant(value.checkstring());
|
||||||
case LuaValue.TNIL:
|
case LuaValue.TNIL:
|
||||||
out("NIL");
|
return "NIL";
|
||||||
break;
|
|
||||||
case LuaValue.TBOOLEAN:
|
case LuaValue.TBOOLEAN:
|
||||||
out(exp.value.toboolean()? "TRUE": "FALSE");
|
return value.toboolean()? "TRUE": "FALSE";
|
||||||
break;
|
case LuaValue.TNUMBER:
|
||||||
case LuaValue.TNUMBER: {
|
return evalNumberConstant(value.todouble());
|
||||||
out( evalNumberConstant(exp.value.todouble()) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("unknown constant type: "+exp.value.typename());
|
throw new IllegalStateException("unknown constant type: "+value.typename());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user