001: /*
002: * $Id: WhileStatement.java,v 1.14 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.codec.Code;
015: import anvil.codec.Source;
016: import anvil.codec.Target;
017: import anvil.parser.Tag;
018: import anvil.ErrorListener;
019: import anvil.script.compiler.ByteCompiler;
020: import anvil.script.Context;
021: import anvil.script.expression.Expression;
022: import anvil.script.parser.TemplateParser;
023: import anvil.script.Grammar;
024: import java.io.IOException;
025:
026: /**
027: * class WhileStatement
028: *
029: * @author: Jani Lehtimäki
030: */
031: public class WhileStatement extends ScopedStatement implements Labeled {
032:
033: private Expression _condition;
034: private Statement _statement = EMPTY;
035: private String _label;
036: private Source _startscope;
037: private Source _endscope;
038:
039: public WhileStatement(Statement parent, Location location) {
040: super (parent, location);
041: }
042:
043: public WhileStatement(Statement parent, Location location,
044: Expression condition, String label) {
045: super (parent, location);
046: _condition = condition;
047: _label = label;
048: }
049:
050: public int typeOf() {
051: return Statement.ST_WHILE;
052: }
053:
054: public String name() {
055: return "while";
056: }
057:
058: public String getLabel() {
059: return _label;
060: }
061:
062: public void parse(TemplateParser parser, Tag tag) {
063: boolean negate = false;
064: String s = tag.getValue("expr");
065: if (s == null) {
066: s = tag.getValue("true");
067: if (s == null) {
068: s = tag.getValue("false");
069: if (s != null) {
070: negate = true;
071: }
072: }
073: }
074: _condition = Grammar.parseStandaloneExpression(s,
075: getLocation(), parser);
076: if (negate) {
077: _condition.createNegation();
078: }
079: _label = parseLabel(parser, tag);
080: }
081:
082: public boolean onTag(TemplateParser parser, int type, Tag tag) {
083: switch (type) {
084: case ST_ENDWHILE:
085: parser.pop();
086: break;
087:
088: default:
089: return super .onTag(parser, type, tag);
090: }
091:
092: return true;
093: }
094:
095: public Statement getChildStatement() {
096: return _statement;
097: }
098:
099: public void setChildStatement(Statement statement) {
100: _statement = statement;
101: }
102:
103: public void check(ErrorListener context) {
104: _condition.check(context);
105: _statement.check(context);
106: }
107:
108: public Jumps eliminate(ErrorListener context) {
109: Jumps jumps = _statement.eliminate(context);
110: switch (_condition.conditionOf()) {
111: case Expression.IS_FALSE:
112: jumps = new Jumps();
113: break;
114:
115: case Expression.IS_DYNAMIC:
116: jumps.setBlocked(false);
117: break;
118:
119: case Expression.IS_TRUE:
120: jumps.setBlocked(!jumps.hasBreak());
121: break;
122:
123: }
124: //jumps.print("while");
125: return jumps.shift();
126: }
127:
128: public Source getStartOfScope() {
129: return _startscope;
130: }
131:
132: public Source getEndOfScope() {
133: return _endscope;
134: }
135:
136: public void compile(ByteCompiler context) {
137: Code code = context.getCode();
138: Target start = code.getTarget();
139:
140: switch (_condition.conditionOf()) {
141: case Expression.IS_FALSE:
142: return;
143:
144: case Expression.IS_TRUE:
145: _startscope = code.getSource();
146: _endscope = code.getSource();
147: _statement.compile(context);
148: code.go_to(_startscope);
149: _startscope.bind(start);
150: _endscope.bind();
151: break;
152:
153: case Expression.IS_DYNAMIC:
154: _startscope = code.getSource();
155: _endscope = code.getSource();
156: if (_condition.needLineNumbers()) {
157: context.location(_condition.getLocation());
158: }
159: _condition.compile(context, Expression.GET_BOOLEAN);
160: code.if_eq(_endscope);
161: _statement.compile(context);
162: if (!_statement.isBlocked()) {
163: code.go_to(_startscope);
164: }
165: _startscope.bind(start);
166: _endscope.bind();
167: break;
168: }
169:
170: }
171:
172: }
|