001: /*
002: * $Id: IfStatement.java,v 1.13 2002/09/16 08:05:06 jkl Exp $
003: *
004: * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
005: *
006: * Use is subject to license terms, as defined in
007: * Anvil Sofware License, Version 1.1. See LICENSE
008: * file, or http://njet.org/license-1.1.txt
009: */
010: package anvil.script.statements;
011:
012: import anvil.core.Any;
013: import anvil.Location;
014: import anvil.parser.Tag;
015: import anvil.codec.Code;
016: import anvil.codec.Source;
017: import anvil.ErrorListener;
018: import anvil.script.compiler.ByteCompiler;
019: import anvil.script.Context;
020: import anvil.script.expression.Expression;
021: import anvil.script.parser.TemplateParser;
022: import anvil.script.Grammar;
023: import java.io.IOException;
024:
025: /**
026: * class IfStatement
027: *
028: * @author: Jani Lehtimäki
029: */
030: public class IfStatement extends ScopedStatement {
031:
032: private Expression _condition;
033: private Statement _thenStatements = EMPTY;
034: private Statement _elseStatements;
035: private boolean _onthen = true;
036:
037: public IfStatement(Statement parent, Location location) {
038: super (parent, location);
039: }
040:
041: public IfStatement(Statement parent, Location location,
042: Expression condition) {
043: super (parent, location);
044: _condition = condition;
045: }
046:
047: public int typeOf() {
048: return Statement.ST_IF;
049: }
050:
051: public String name() {
052: return "if";
053: }
054:
055: public boolean isOnThen() {
056: return _onthen;
057: }
058:
059: public void onElse() {
060: _onthen = false;
061: }
062:
063: public Statement getChildStatement() {
064: if (_onthen) {
065: return _thenStatements;
066: } else {
067: return _elseStatements;
068: }
069: }
070:
071: public void setChildStatement(Statement statement) {
072: if (_onthen) {
073: _thenStatements = statement;
074: } else {
075: _elseStatements = statement;
076: }
077: }
078:
079: public void parse(TemplateParser parser, Tag tag) {
080: boolean negate = false;
081: String s = tag.getValue("expr");
082: if (s == null) {
083: s = tag.getValue("true");
084: if (s == null) {
085: s = tag.getValue("false");
086: if (s != null) {
087: negate = true;
088: }
089: }
090: }
091: _condition = Grammar.parseStandaloneExpression(s,
092: getLocation(), parser);
093: if (negate) {
094: _condition.createNegation();
095: }
096: }
097:
098: public boolean onTag(TemplateParser parser, int type, Tag tag) {
099: switch (type) {
100: case ST_ELSE:
101: if (isOnThen()) {
102: onElse();
103: ImplicitBlockStatement block = new ImplicitBlockStatement(
104: this , parser.getLocation());
105: setChildStatement(block);
106: return true;
107: } else {
108: return false;
109: }
110:
111: case ST_ELSEIF:
112: if (isOnThen()) {
113: parser.pop();
114: onElse();
115: ImplicitBlockStatement elseblock = new ImplicitBlockStatement(
116: this , parser.getLocation());
117: setChildStatement(elseblock);
118: IfStatement ifstmt = new IfStatement(
119: getParentStatement(), parser.getLocation());
120: elseblock.add(ifstmt);
121: ifstmt.parse(parser, tag);
122: ImplicitBlockStatement thenblock = new ImplicitBlockStatement(
123: ifstmt, parser.getLocation());
124: ifstmt.setChildStatement(thenblock);
125: parser.push(ifstmt);
126: return true;
127: } else {
128: return false;
129: }
130:
131: case ST_ENDIF:
132: parser.pop();
133: return true;
134:
135: default:
136: return super .onTag(parser, type, tag);
137: }
138:
139: }
140:
141: public void check(ErrorListener context) {
142: boolean blocking = false;
143: int mask = 0;
144: int condition = _condition.conditionOf();
145: _condition.check(context);
146: _thenStatements.check(context);
147: if (_elseStatements != null) {
148: _elseStatements.check(context);
149: }
150: }
151:
152: public Jumps eliminate(ErrorListener context) {
153: Jumps jumps = null;
154: switch (_condition.conditionOf()) {
155: case Expression.IS_FALSE:
156: _thenStatements.eliminate(context);
157: if (_elseStatements != null) {
158: jumps = _elseStatements.eliminate(context);
159: } else {
160: jumps = new Jumps();
161: }
162: break;
163:
164: case Expression.IS_DYNAMIC:
165: if (_elseStatements != null) {
166: Jumps _then = _thenStatements.eliminate(context);
167: Jumps _else = _elseStatements.eliminate(context);
168: boolean blocked = _then.isBlocked()
169: && _else.isBlocked();
170: jumps = _then;
171: jumps.merge(_else);
172: jumps.setBlocked(blocked);
173:
174: } else {
175: jumps = _thenStatements.eliminate(context);
176: jumps.setBlocked(false);
177:
178: }
179: break;
180:
181: case Expression.IS_TRUE:
182: jumps = _thenStatements.eliminate(context);
183: if (_elseStatements != null) {
184: _elseStatements.eliminate(context);
185: }
186: break;
187: }
188: return jumps;
189: }
190:
191: public void compile(ByteCompiler context) {
192: Code code = context.getCode();
193: switch (_condition.conditionOf()) {
194: case Expression.IS_FALSE:
195: if (_elseStatements != null) {
196: _elseStatements.compile(context);
197: }
198: break;
199:
200: case Expression.IS_TRUE:
201: _thenStatements.compile(context);
202: break;
203:
204: case Expression.IS_DYNAMIC:
205: if (_condition.needLineNumbers()) {
206: context.location(_condition.getLocation());
207: }
208: _condition.compile(context, Expression.GET_BOOLEAN);
209: Source to_then = code.if_eq();
210: _thenStatements.compile(context);
211: if (_elseStatements != null) {
212: Source to_end = code.go_to();
213: to_then.bind();
214: _elseStatements.compile(context);
215: to_end.bind();
216: } else {
217: to_then.bind();
218: }
219: break;
220: }
221:
222: }
223:
224: public boolean isBlocked() {
225: boolean blocked = _thenStatements.isBlocked();
226: if (_elseStatements != null) {
227: blocked = blocked && _elseStatements.isBlocked();
228: }
229: return blocked;
230: }
231:
232: }
|