Improve name resolution in java code generator.
This commit is contained in:
@@ -6,6 +6,7 @@ import org.luaj.vm2.ast.Exp.NameExp;
|
||||
import org.luaj.vm2.ast.Exp.VarExp;
|
||||
import org.luaj.vm2.ast.NameScope.NamedVariable;
|
||||
import org.luaj.vm2.ast.Stat.Assign;
|
||||
import org.luaj.vm2.ast.Stat.FuncDef;
|
||||
import org.luaj.vm2.ast.Stat.GenericFor;
|
||||
import org.luaj.vm2.ast.Stat.LocalAssign;
|
||||
import org.luaj.vm2.ast.Stat.LocalFuncDef;
|
||||
@@ -41,13 +42,10 @@ public class NameResolver extends Visitor {
|
||||
pushScope();
|
||||
scope.functionNestingCount++;
|
||||
body.scope = scope;
|
||||
if ( body.parlist.names != null )
|
||||
for ( Name n : body.parlist.names )
|
||||
defineLocalVar(n);
|
||||
super.visit(body);
|
||||
popScope();
|
||||
}
|
||||
|
||||
|
||||
public void visit(LocalFuncDef stat) {
|
||||
defineLocalVar(stat.name);
|
||||
super.visit(stat);
|
||||
@@ -70,13 +68,22 @@ public class NameResolver extends Visitor {
|
||||
}
|
||||
|
||||
public void visit(NameExp exp) {
|
||||
NamedVariable v = scope.find(exp.name.name);
|
||||
exp.name.variable = v;
|
||||
if ( v.isLocal() && scope.functionNestingCount != v.definingScope.functionNestingCount )
|
||||
v.isupvalue = true;
|
||||
exp.name.variable = resolveNameReference(exp.name);
|
||||
super.visit(exp);
|
||||
}
|
||||
|
||||
public void visit(FuncDef stat) {
|
||||
stat.name.name.variable = resolveNameReference(stat.name.name);
|
||||
super.visit(stat);
|
||||
}
|
||||
|
||||
protected NamedVariable resolveNameReference(Name name) {
|
||||
NamedVariable v = scope.find(name.name);
|
||||
if ( v.isLocal() && scope.functionNestingCount != v.definingScope.functionNestingCount )
|
||||
v.isupvalue = true;
|
||||
return v;
|
||||
}
|
||||
|
||||
public void visit(Assign stat) {
|
||||
super.visit(stat);
|
||||
for ( VarExp v : stat.vars )
|
||||
@@ -88,6 +95,12 @@ public class NameResolver extends Visitor {
|
||||
super.visit(stat);
|
||||
}
|
||||
|
||||
public void visit(ParList pars) {
|
||||
if ( pars.names != null )
|
||||
defineLocalVars(pars.names);
|
||||
super.visit(pars);
|
||||
}
|
||||
|
||||
protected void defineLocalVars(List<Name> names) {
|
||||
for ( Name n : names )
|
||||
defineLocalVar(n);
|
||||
|
||||
@@ -235,7 +235,7 @@ public class JavaCodeGen {
|
||||
if ( exp.name.variable.isLocal() )
|
||||
singleLocalAssign(exp.name, valu);
|
||||
else
|
||||
outl( "env.set("+evalStringConstant(exp.name.name)+","+valu+");");
|
||||
outl( "env.set("+evalLuaValue(exp)+","+valu+");");
|
||||
}
|
||||
};
|
||||
if ( varOrName instanceof VarExp )
|
||||
@@ -550,9 +550,34 @@ public class JavaCodeGen {
|
||||
}
|
||||
|
||||
public void visit(FuncDef stat) {
|
||||
outi( "env.set("+evalStringConstant(stat.name.name.name)+",");
|
||||
Writer x = pushWriter();
|
||||
stat.body.accept(this);
|
||||
outr(");");
|
||||
String value = popWriter(x);
|
||||
int n = stat.name.dots!=null? stat.name.dots.size(): 0;
|
||||
boolean m = stat.name.method != null;
|
||||
if ( n>0 && !m && stat.name.name.variable.isLocal() )
|
||||
singleLocalAssign(stat.name.name,value);
|
||||
else if ( n==0 && !m ) {
|
||||
if ( stat.name.name.variable.isLocal() ) {
|
||||
outi( javascope.getJavaName(stat.name.name.variable) );
|
||||
if ( stat.name.name.variable.isupvalue )
|
||||
out( "[0]" );
|
||||
outr( " = "+value+";" );
|
||||
} else {
|
||||
outi( "env.set("+evalStringConstant(stat.name.name.name)+","+value+");" );
|
||||
}
|
||||
} else {
|
||||
if ( stat.name.name.variable.isLocal() ) {
|
||||
outi( javascope.getJavaName(stat.name.name.variable) );
|
||||
if ( stat.name.name.variable.isupvalue )
|
||||
out( "[0]" );
|
||||
} else {
|
||||
outi( "env.get("+evalStringConstant(stat.name.name.name)+")" );
|
||||
}
|
||||
for ( int i=0; i<n-1 || (m&&i<n); i++ )
|
||||
out( ".get("+evalStringConstant(stat.name.dots.get(i))+")" );
|
||||
outr( ".set("+evalStringConstant(m? stat.name.method: stat.name.dots.get(n))+", "+value+");" );
|
||||
}
|
||||
}
|
||||
|
||||
public void visit(LocalFuncDef stat) {
|
||||
|
||||
@@ -89,8 +89,9 @@ public class JavaScope extends NameScope {
|
||||
}
|
||||
|
||||
final String getJavaName(NamedVariable nv) {
|
||||
if ( astele2javaname.containsKey(nv) )
|
||||
return astele2javaname.get(nv);
|
||||
for ( JavaScope s = this; s != null; s = (JavaScope) s.outerScope )
|
||||
if ( s.astele2javaname.containsKey(nv) )
|
||||
return s.astele2javaname.get(nv);
|
||||
return allocateJavaName( nv, nv.name );
|
||||
}
|
||||
|
||||
@@ -129,9 +130,9 @@ public class JavaScope extends NameScope {
|
||||
String better = string.replaceAll("[^\\w]", "_");
|
||||
if ( better.length() > MAX_CONSTNAME_LEN )
|
||||
better = better.substring(0,MAX_CONSTNAME_LEN);
|
||||
// if ( !Character.isJavaIdentifierStart( better.charAt(0) ) )
|
||||
// better = "_"+better;
|
||||
return "$"+better;
|
||||
if ( better.length() == 0 || !Character.isJavaIdentifierStart( better.charAt(0) ) )
|
||||
better = "_"+better;
|
||||
return better;
|
||||
}
|
||||
|
||||
private JavaScope initialize(Block block, int nreturns) {
|
||||
|
||||
Reference in New Issue
Block a user