1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.millscript.millscript.action;
22
23 import org.millscript.millscript.expr.LocalIdent;
24 import org.millscript.millscript.functions.ClosureFunction;
25 import org.millscript.millscript.functions.LambdaFunction;
26 import org.millscript.millscript.vm.Machine;
27 import org.millscript.millscript.vm.Ref;
28
29 /**
30 * This class represents an action that makes a closure function.
31 *
32 * @see org.millscript.millscript.expr.LambdaExpr
33 * @todo this class could really use a better description
34 */
35 public final class MakeClosureAction extends Action {
36
37 /**
38 * The function to make a closure with.
39 */
40 private final LambdaFunction lambda;
41
42 /**
43 * The set of local idents to save.
44 */
45 private final LocalIdent[] outerIds;
46
47 /**
48 * The set of references used by the local idents.
49 */
50 private final Ref[] outerRefs;
51
52 /**
53 * Constructs a new make closure action, to make a closure function from
54 * the specified function and local variables.
55 *
56 * @param a the local variables that need to be saved
57 * @param b the function to make a closure with
58 */
59 public MakeClosureAction( final LocalIdent[] a, final LambdaFunction b ) {
60 outerIds = a;
61 lambda = b;
62 int numOuters = a.length;
63 outerRefs = new Ref[ numOuters ];
64 for ( int i = 0; i < numOuters; i++ ) {
65 outerRefs[ i ] = outerIds[ i ].getRef();
66 }
67 }
68
69 /**
70 * @see org.millscript.millscript.action.Action#action(org.millscript.millscript.vm.Machine)
71 */
72 @Override
73 public void action( final Machine mc ) {
74 final int numOuters = outerRefs.length;
75 final Object[] outerVals = new Object[ numOuters ];
76 for ( int i = 0; i < numOuters; i++ ) {
77 outerVals[ i ] = outerRefs[ i ].value;
78 }
79 mc.pushObject( new ClosureFunction( outerVals, outerRefs, outerIds, lambda ) );
80 }
81
82 }