Mercurial Hosting > luan
comparison src/luan/interp/LuaClosure.java @ 32:c3eab5a3ce3c
implement closures
git-svn-id: https://luan-java.googlecode.com/svn/trunk@33 21e917c8-12df-6dd8-5cb6-c86387c605b9
author | fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9> |
---|---|
date | Fri, 14 Dec 2012 05:40:35 +0000 |
parents | 5cf15507d77e |
children | e3624b7cd603 |
comparison
equal
deleted
inserted
replaced
31:5cf15507d77e | 32:c3eab5a3ce3c |
---|---|
5 import luan.LuaException; | 5 import luan.LuaException; |
6 | 6 |
7 | 7 |
8 final class LuaClosure extends LuaFunction { | 8 final class LuaClosure extends LuaFunction { |
9 private final Chunk chunk; | 9 private final Chunk chunk; |
10 final UpValue[] upValues; | |
11 private final static UpValue[] NO_UP_VALUES = new UpValue[0]; | |
10 | 12 |
11 LuaClosure(Chunk chunk,LuaStateImpl lua) { | 13 LuaClosure(Chunk chunk,LuaStateImpl lua) { |
12 this.chunk = chunk; | 14 this.chunk = chunk; |
15 UpValue.Getter[] upValueGetters = chunk.upValueGetters; | |
16 if( upValueGetters.length==0 ) { | |
17 upValues = NO_UP_VALUES; | |
18 } else { | |
19 upValues = new UpValue[upValueGetters.length]; | |
20 for( int i=0; i<upValues.length; i++ ) { | |
21 upValues[i] = upValueGetters[i].get(lua); | |
22 } | |
23 } | |
13 } | 24 } |
14 | 25 |
15 public Object[] call(LuaState luaState,Object... args) throws LuaException { | 26 public Object[] call(LuaState lua,Object... args) throws LuaException { |
16 LuaStateImpl lua = (LuaStateImpl)luaState; | 27 return call(this,(LuaStateImpl)lua,args); |
17 Chunk chunk = this.chunk; | 28 } |
29 | |
30 private static Object[] call(LuaClosure closure,LuaStateImpl lua,Object[] args) throws LuaException { | |
18 while(true) { | 31 while(true) { |
32 Chunk chunk = closure.chunk; | |
19 Object[] varArgs = null; | 33 Object[] varArgs = null; |
20 if( chunk.isVarArg ) { | 34 if( chunk.isVarArg ) { |
21 if( args.length > chunk.numArgs ) { | 35 if( args.length > chunk.numArgs ) { |
22 varArgs = new Object[ args.length - chunk.numArgs ]; | 36 varArgs = new Object[ args.length - chunk.numArgs ]; |
23 for( int i=0; i<varArgs.length; i++ ) { | 37 for( int i=0; i<varArgs.length; i++ ) { |
25 } | 39 } |
26 } else { | 40 } else { |
27 varArgs = LuaFunction.EMPTY_RTN; | 41 varArgs = LuaFunction.EMPTY_RTN; |
28 } | 42 } |
29 } | 43 } |
30 Object[] stack = lua.newStack(chunk.stackSize,varArgs); | 44 Object[] stack = lua.newFrame(closure,chunk.stackSize,varArgs); |
31 final int n = Math.min(args.length,chunk.numArgs); | 45 final int n = Math.min(args.length,chunk.numArgs); |
32 for( int i=0; i<n; i++ ) { | 46 for( int i=0; i<n; i++ ) { |
33 stack[i] = args[i]; | 47 stack[i] = args[i]; |
34 } | 48 } |
35 Object[] returnValues; | 49 Object[] returnValues; |
37 try { | 51 try { |
38 chunk.block.eval(lua); | 52 chunk.block.eval(lua); |
39 } catch(ReturnException e) { | 53 } catch(ReturnException e) { |
40 } finally { | 54 } finally { |
41 returnValues = lua.returnValues; | 55 returnValues = lua.returnValues; |
42 tailFn = lua.tailFn; | 56 closure = lua.tailFn; |
43 lua.popStack(); | 57 lua.popFrame(); |
44 } | 58 } |
45 if( tailFn == null ) | 59 if( closure == null ) |
46 return returnValues; | 60 return returnValues; |
47 chunk = tailFn.chunk; | |
48 args = returnValues; | 61 args = returnValues; |
49 } | 62 } |
50 } | 63 } |
51 | 64 |
52 } | 65 } |