From ee0271c70dbb4f33dd21f685c5b954e971cbcc1a Mon Sep 17 00:00:00 2001 From: James Roseborough Date: Wed, 21 Jul 2010 15:31:15 +0000 Subject: [PATCH] Improve name resolution in java code generator. --- src/jse/org/luaj/vm2/ast/NameResolver.java | 29 ++++++++++++----- .../org/luaj/vm2/lua2java/JavaCodeGen.java | 31 +++++++++++++++++-- src/jse/org/luaj/vm2/lua2java/JavaScope.java | 11 ++++--- 3 files changed, 55 insertions(+), 16 deletions(-) diff --git a/src/jse/org/luaj/vm2/ast/NameResolver.java b/src/jse/org/luaj/vm2/ast/NameResolver.java index ce572349..e69bc646 100644 --- a/src/jse/org/luaj/vm2/ast/NameResolver.java +++ b/src/jse/org/luaj/vm2/ast/NameResolver.java @@ -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 names) { for ( Name n : names ) defineLocalVar(n); diff --git a/src/jse/org/luaj/vm2/lua2java/JavaCodeGen.java b/src/jse/org/luaj/vm2/lua2java/JavaCodeGen.java index 29fe1022..be60b841 100644 --- a/src/jse/org/luaj/vm2/lua2java/JavaCodeGen.java +++ b/src/jse/org/luaj/vm2/lua2java/JavaCodeGen.java @@ -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 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) {