View Javadoc

1   /*
2   	Copyright (c) 2009 Olivier Chafik, All Rights Reserved
3   	
4   	This file is part of JNAerator (http://jnaerator.googlecode.com/).
5   	
6   	JNAerator is free software: you can redistribute it and/or modify
7   	it under the terms of the GNU Lesser General Public License as published by
8   	the Free Software Foundation, either version 3 of the License, or
9   	(at your option) any later version.
10  	
11  	JNAerator is distributed in the hope that it will be useful,
12  	but WITHOUT ANY WARRANTY; without even the implied warranty of
13  	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  	GNU Lesser General Public License for more details.
15  	
16  	You should have received a copy of the GNU Lesser General Public License
17  	along with JNAerator.  If not, see <http://www.gnu.org/licenses/>.
18  */
19  package com.ochafik.lang.jnaerator.parser;
20  
21  import java.util.ArrayList;
22  import java.util.Arrays;
23  import java.util.List;
24  
25  public abstract class Statement extends Element {
26  	
27  	public static class Throw extends Statement {
28  		Expression expression;
29  		public Expression getExpression() {
30  			return expression;
31  		}
32  		public void setExpression(Expression expression) {
33  			this.expression = changeValue(this, this.expression, expression);
34  		}
35  		public Throw() {}
36  		public Throw(Expression expression) {
37  			setExpression(expression);
38  		}
39  		@Override
40  		public void accept(Visitor visitor) {
41  			visitor.visitThrow(this);
42  		}
43  
44  		@Override
45  		public Element getNextChild(Element child) {
46  			return null;
47  		}
48  
49  		@Override
50  		public Element getPreviousChild(Element child) {
51  			return null;
52  		}
53  
54  		@Override
55  		public boolean replaceChild(Element child, Element by) {
56  			if (child == getExpression()) {
57  				setExpression((Expression)by);
58  				return true;
59  			}
60  			return false;
61  		}
62  
63  		@Override
64  		public String toString(CharSequence indent) {
65  			return "throw " + getExpression().toString(indent) + ";";
66  		}
67  
68  	}
69  	public static class DeclarationStatement extends Statement {
70  		Declaration declaration;
71  		public void setDeclaration(Declaration declaration) {
72  			this.declaration = changeValue(this, this.declaration, declaration);
73  		}
74  		public Declaration getDeclaration() {
75  			return declaration;
76  		}
77  		public DeclarationStatement() {}
78  		public DeclarationStatement(Declaration declaration) {
79  			setDeclaration(declaration);
80  		}
81  		@Override
82  		public void accept(Visitor visitor) {
83  			visitor.visitDeclarationStatement(this);
84  		}
85  		@Override
86  		public Element getNextChild(Element child) {
87  			return null;
88  		}
89  		@Override
90  		public Element getPreviousChild(Element child) {
91  			return null;
92  		}
93  		@Override
94  		public boolean replaceChild(Element child, Element by) {
95  			if (child == getDeclaration()) {
96  				setDeclaration((Declaration)by);
97  				return true;
98  			}
99  			return false;
100 		}
101 		@Override
102 		public String toString(CharSequence indent) {
103 			return getDeclaration() == null ? "" : getDeclaration().toString(indent);
104 		}
105 	}
106 	public static class Return extends Statement {
107 		Expression value;
108 		
109 		public Return() {}
110 		public Return(Expression value) {
111 			setValue(value);
112 		}
113 
114 		public void setValue(Expression value) {
115 			this.value = changeValue(this, this.value, value);
116 		}
117 		public Expression getValue() {
118 			return value;
119 		}
120 		@Override
121 		public void accept(Visitor visitor) {
122 			visitor.visitReturn(this);
123 		}
124 
125 		@Override
126 		public Element getNextChild(Element child) {
127 			return null;
128 		}
129 
130 		@Override
131 		public Element getPreviousChild(Element child) {
132 			return null;
133 		}
134 
135 		@Override
136 		public boolean replaceChild(Element child, Element by) {
137 			if (child == getValue()) {
138 				setValue((Expression)by);
139 				return true;
140 			}
141 			return false;
142 		}
143 
144 		@Override
145 		public String toString(CharSequence indent) {
146 			return "return " + (getValue() == null ? "<null>" : getValue().toString(indent)) + ";";
147 		}
148 
149 	}
150 	public static class If extends Statement {
151 		public If() {}
152 		public If(Expression condition, Statement thenBranch, Statement elseBranch) {
153 			setCondition(condition);
154 			setThenBranch(thenBranch);
155 			setElseBranch(elseBranch);
156 		}
157 		Expression condition;
158 		Statement thenBranch, elseBranch;
159 		
160 		public void setElseBranch(Statement elseBranch) {
161 			this.elseBranch = changeValue(this, this.elseBranch, elseBranch);
162 		}
163 		public void setCondition(Expression condition) {
164 			this.condition = changeValue(this, this.condition, condition);
165 		}
166 		public void setThenBranch(Statement thenBranch) {
167 			this.thenBranch = changeValue(this, this.thenBranch, thenBranch);
168 		}
169 		public Statement getElseBranch() {
170 			return elseBranch;
171 		}
172 		public Statement getThenBranch() {
173 			return thenBranch;
174 		}
175 		public Expression getCondition() {
176 			return condition;
177 		}
178 		@Override
179 		public void accept(Visitor visitor) {
180 			visitor.visitIf(this);
181 		}
182 		@Override
183 		public Element getNextChild(Element child) {
184 			return null;
185 		}
186 		@Override
187 		public Element getPreviousChild(Element child) {
188 			return null;
189 		}
190 		@Override
191 		public boolean replaceChild(Element child, Element by) {
192 			if (child == getCondition()) {
193 				setCondition((Expression)by);
194 				return true;
195 			}
196 			if (child == getThenBranch()) {
197 				setThenBranch((Statement)by);
198 				return true;
199 			}
200 			if (child == getElseBranch()) {
201 				setElseBranch((Statement)by);
202 				return true;
203 			}
204 			return false;
205 		}
206 		@Override
207 		public String toString(CharSequence indent) {
208 			StringBuffer b = new StringBuffer("if (");
209 			if (getCondition() == null)
210 				b.append("<null>");
211 			else
212 				b.append(getCondition().toString(indent));
213 			String indent2 = indent + "\t";
214 			b.append(") ");
215 			if (getThenBranch() == null)
216 				b.append("<null>");
217 			else {
218 				if (getThenBranch() instanceof Block) {
219 					b.append(getThenBranch().toString(indent));
220 					if (getElseBranch() != null)
221 						b.append(" ");
222 				} else {
223 					b.append("\n");
224 					b.append(indent2);
225 					b.append(getThenBranch().toString(indent2));
226 					if (getElseBranch() != null)
227 						b.append("\n" + indent);
228 				}
229 			}
230 			
231 			if (getElseBranch() != null) {
232 				b.append("else ");
233 				if (getElseBranch() instanceof Block) {
234 					b.append(getElseBranch().toString(indent));
235 				} else {
236 					b.append("\n");
237 					b.append(indent2);
238 					b.append(getElseBranch().toString(indent2));
239 				}
240 			}
241 			return b.toString();
242 		}
243 	}
244 	public static class ExpressionStatement extends Statement {
245 
246 		public ExpressionStatement() {}
247 		public ExpressionStatement(Expression expression) {
248 			setExpression(expression);
249 		}
250 
251 		Expression expression;
252 		
253 		public Expression getExpression() {
254 			return expression;
255 		}
256 		public void setExpression(Expression expression) {
257 			this.expression = changeValue(this, this.expression, expression);
258 		}
259 		
260 		@Override
261 		public void accept(Visitor visitor) {
262 			visitor.visitExpressionStatement(this);
263 		}
264 
265 		@Override
266 		public Element getNextChild(Element child) {
267 			return null;
268 		}
269 
270 		@Override
271 		public Element getPreviousChild(Element child) {
272 			return null;
273 		}
274 
275 		@Override
276 		public boolean replaceChild(Element child, Element by) {
277 			if (getExpression() == child) {
278 				setExpression((Expression)by);
279 				return true;
280 			}
281 			return false;
282 		}
283 
284 		@Override
285 		public String toString(CharSequence indent) {
286 			return expression == null ? null : expression.toString(indent) + ";";
287 		}
288 		
289 	}
290 	
291 	public static class Block extends Statement {
292 		final List<Statement> statements = new ArrayList<Statement>();
293 		@Override
294 		public void accept(Visitor visitor) {
295 			visitor.visitBlock(this);
296 		}
297 
298 		boolean compact;
299 		
300 		@Override
301 		public Block clone() {
302 			return (Block)super.clone();
303 		}
304 		
305 		public Block setCompact(boolean compact) {
306 			this.compact = compact;
307 			return this;
308 		}
309 		public boolean isCompact() {
310 			return compact;
311 		}
312 		public Block() {}
313 		public Block(Statement... statements) {
314 			addStatements(statements);
315 		}
316 		public Block(List<Statement> statements) {
317 			setStatements(statements);
318 		}
319 		public void addStatement(Statement statement) {
320 			if (statement != null) {
321 				statement.setParentElement(this);
322 				statements.add(statement);
323 			}
324 		}
325 		public void setStatements(List<Statement> statements) {
326 			changeValue(this, this.statements, statements);
327 		}
328 		public void addStatements(Statement... statements) {
329 			setStatements(Arrays.asList(statements));
330 		}
331 		public List<Statement> getStatements() {
332 			return unmodifiableList(statements);
333 		}
334 		@Override
335 		public Element getNextChild(Element child) {
336 			return getNextSibling(statements, child);
337 		}
338 
339 		@Override
340 		public Element getPreviousChild(Element child) {
341 			return getPreviousSibling(statements, child);
342 		}
343 
344 		@Override
345 		public boolean replaceChild(Element child, Element by) {
346 			return replaceChild(statements, Statement.class, this, child, by);
347 		}
348 
349 		@Override
350 		public String toString(CharSequence indent) {
351 			String nindent = indent + "\t";
352 //			if (statements.size() == 1 && !(getParentElement() instanceof Function))
353 //				return "\t" + statements.get(0).toString(nindent);
354 			
355 			StringBuilder b = new StringBuilder();
356 			b.append('{');
357 			if (!statements.isEmpty()) {
358 				if (isCompact()) {
359 					b.append(' ');
360 					b.append(implode(statements, ", ", indent));
361 					b.append(' ');
362 				} else {
363 					String lnindent = "\n" + nindent;
364 					b.append(lnindent);
365 					b.append(implode(statements, lnindent, nindent));
366 					b.append('\n');
367 					b.append(indent);
368 				}
369 			}
370 			b.append('}');
371 			return b.toString();
372 		}
373 
374 	}
375 }