001: /**
002: * MVEL (The MVFLEX Expression Language)
003: *
004: * Copyright (C) 2007 Christopher Brock, MVFLEX/Valhalla Project and the Codehaus
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: *
018: */package org.mvel.util;
019:
020: import org.mvel.ast.ASTNode;
021:
022: public class ASTLinkedList implements ASTIterator {
023: private ASTNode firstASTNode;
024: private ASTNode current;
025: private ASTNode last;
026: private int size;
027:
028: public ASTLinkedList() {
029: }
030:
031: public ASTLinkedList(ASTIterator iter) {
032: this .current = this .firstASTNode = iter.firstNode();
033: }
034:
035: public ASTLinkedList(ASTNode firstASTNode) {
036: this .current = this .firstASTNode = firstASTNode;
037: }
038:
039: public ASTLinkedList(ASTNode firstASTNode, int size) {
040: this .current = this .firstASTNode = firstASTNode;
041: this .size = size;
042: }
043:
044: public void addTokenNode(ASTNode astNode) {
045: size++;
046:
047: if (this .firstASTNode == null) {
048: this .firstASTNode = this .current = astNode;
049: } else {
050: this .last = this .current = (this .current.nextASTNode = astNode);
051: }
052: }
053:
054: public void addTokenNode(ASTNode astNode, ASTNode token2) {
055: if (this .firstASTNode == null) {
056: this .last = this .current = ((this .firstASTNode = astNode).nextASTNode = token2);
057: } else {
058: this .last = this .current = (this .current.nextASTNode = astNode).nextASTNode = token2;
059: }
060: }
061:
062: public ASTNode firstNode() {
063: return firstASTNode;
064: }
065:
066: public void reset() {
067: this .current = firstASTNode;
068: }
069:
070: public boolean hasMoreNodes() {
071: return this .current != null;
072: }
073:
074: public ASTNode nextNode() {
075: if (current == null)
076: return null;
077: try {
078: return current;
079: } finally {
080: current = current.nextASTNode;
081: }
082: }
083:
084: public void skipNode() {
085: if (current != null)
086: current = current.nextASTNode;
087: }
088:
089: public ASTNode peekNext() {
090: if (current != null && current.nextASTNode != null)
091: return current.nextASTNode;
092: else
093: return null;
094: }
095:
096: public ASTNode peekNode() {
097: if (current == null)
098: return null;
099: return current;
100: }
101:
102: public void removeToken() {
103: if (current != null) {
104: current = current.nextASTNode;
105: }
106: }
107:
108: public ASTNode peekLast() {
109: return last;
110: }
111:
112: public ASTNode nodesBack(int offset) {
113: throw new RuntimeException("unimplemented");
114: }
115:
116: public void back() {
117: throw new RuntimeException("unimplemented");
118: }
119:
120: public String showNodeChain() {
121: throw new RuntimeException("unimplemented");
122: }
123:
124: public int size() {
125: return size;
126: }
127:
128: public int index() {
129: return -1;
130: }
131:
132: public void setCurrentNode(ASTNode node) {
133: this .current = node;
134: }
135:
136: public void finish() {
137: reset();
138:
139: ASTNode last = null;
140: ASTNode curr;
141:
142: while (hasMoreNodes()) {
143: curr = nextNode();
144:
145: if (curr.isDiscard()) {
146: if (last == null) {
147: firstASTNode = nextNode();
148: } else {
149: last.nextASTNode = nextNode();
150: }
151: continue;
152: }
153:
154: if (!hasMoreNodes())
155: break;
156:
157: if (nextNode().isDiscard()) {
158: curr.nextASTNode = nextNode();
159: }
160:
161: last = curr;
162: }
163:
164: this.last = last;
165:
166: reset();
167: }
168:
169: }
|