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