comparison core/src/luan/impl/Closure.java @ 171:3dcb0f9bee82

add core component git-svn-id: https://luan-java.googlecode.com/svn/trunk@172 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Sun, 22 Jun 2014 05:41:22 +0000
parents src/luan/impl/Closure.java@4eaee12f6c65
children 24ede40ee0aa
comparison
equal deleted inserted replaced
170:7c792a328a83 171:3dcb0f9bee82
1 package luan.impl;
2
3 import luan.Luan;
4 import luan.LuanFunction;
5 import luan.LuanState;
6 import luan.LuanElement;
7 import luan.LuanException;
8 import luan.DeepCloner;
9 import luan.DeepCloneable;
10
11
12 final class Closure extends LuanFunction implements DeepCloneable<Closure> {
13 private final FnDef fnDef;
14 private UpValue[] upValues;
15
16 Closure(LuanStateImpl luan,FnDef fnDef) throws LuanException {
17 this.fnDef = fnDef;
18 UpValue.Getter[] upValueGetters = fnDef.upValueGetters;
19 upValues = new UpValue[upValueGetters.length];
20 for( int i=0; i<upValues.length; i++ ) {
21 upValues[i] = upValueGetters[i].get(luan);
22 }
23 }
24
25 private Closure(Closure c) {
26 this.fnDef = c.fnDef;
27 }
28
29 @Override public Closure shallowClone() {
30 return new Closure(this);
31 }
32
33 @Override public void deepenClone(Closure clone,DeepCloner cloner) {
34 clone.upValues = cloner.deepClone(upValues);
35 }
36
37 UpValue[] upValues() {
38 return upValues;
39 }
40
41 @Override public Object call(LuanState luan,Object[] args) throws LuanException {
42 return call(this,(LuanStateImpl)luan,args);
43 }
44
45 private static Object call(Closure closure,LuanStateImpl luan,Object[] args) throws LuanException {
46 while(true) {
47 FnDef fnDef = closure.fnDef;
48 Object[] varArgs = null;
49 if( fnDef.isVarArg ) {
50 if( args.length > fnDef.numArgs ) {
51 varArgs = new Object[ args.length - fnDef.numArgs ];
52 for( int i=0; i<varArgs.length; i++ ) {
53 varArgs[i] = args[fnDef.numArgs+i];
54 }
55 } else {
56 varArgs = LuanFunction.NOTHING;
57 }
58 }
59 Object[] stack = luan.newFrame(closure,fnDef.stackSize,varArgs);
60 final int n = Math.min(args.length,fnDef.numArgs);
61 for( int i=0; i<n; i++ ) {
62 stack[i] = args[i];
63 }
64 Object returnValues;
65 try {
66 fnDef.block.eval(luan);
67 } catch(ReturnException e) {
68 } finally {
69 returnValues = luan.returnValues;
70 closure = luan.tailFn;
71 luan.popFrame();
72 }
73 if( closure == null )
74 return returnValues;
75 args = Luan.array(returnValues);
76 }
77 }
78
79 }