1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jexl3.internal;
18
19 import java.util.ArrayDeque;
20 import java.util.Deque;
21
22
23
24
25
26 public class LexicalFrame extends LexicalScope {
27
28
29
30 private final Frame frame;
31
32
33
34 protected final LexicalFrame previous;
35
36
37
38 private Deque<Object> stack;
39
40
41
42
43
44
45
46 public LexicalFrame(final Frame scriptf, final LexicalFrame outerf) {
47 this.previous = outerf;
48 this.frame = scriptf;
49 }
50
51
52
53
54
55
56 public LexicalFrame(final LexicalFrame src) {
57 super(src);
58 frame = src.frame;
59 previous = src.previous;
60 stack = src.stack != null ? new ArrayDeque<>(src.stack) : null;
61 }
62
63
64
65
66
67
68 public LexicalFrame defineArgs() {
69 if (frame != null) {
70 final int argc = frame.getScope().getArgCount();
71 for (int a = 0; a < argc; ++a) {
72 super.addSymbol(a);
73 }
74 }
75 return this;
76 }
77
78
79
80
81
82
83
84
85 public boolean defineSymbol(final int symbol, final boolean capture) {
86 final boolean declared = addSymbol(symbol);
87 if (declared && capture) {
88 if (stack == null) {
89 stack = new ArrayDeque<>();
90 }
91 stack.push(symbol);
92 Object value = frame.get(symbol);
93 if (value == null) {
94 value = this;
95 }
96 stack.push(value);
97 }
98 return declared;
99 }
100
101
102
103
104
105
106 public LexicalFrame pop() {
107
108 clearSymbols(s -> frame.set(s, Scope.UNDEFINED) );
109
110 if (stack != null) {
111 while (!stack.isEmpty()) {
112 Object value = stack.pop();
113 if (value == Scope.UNDECLARED) {
114 value = Scope.UNDEFINED;
115 } else if (value == this) {
116 value = null;
117 }
118 final int symbol = (Integer) stack.pop();
119 frame.set(symbol, value);
120 }
121 }
122 return previous;
123 }
124
125 }