001: /*
002: * $Id: ForStatement.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.parser.Tag;
015: import anvil.codec.Code;
016: import anvil.codec.Source;
017: import anvil.codec.Target;
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.parser.ExpressionParser;
024: import java.io.IOException;
025:
026: /**
027: * class ForStatement
028: *
029: * @author: Jani Lehtimäki
030: */
031: public class ForStatement extends ScopedStatement implements Labeled {
032:
033: private Expression[] _init = null;
034: private Expression _condition = null;
035: private Expression[] _action = null;
036: private Statement _statement = EMPTY;
037: private String _label;
038: private Source _startscope;
039: private Source _endscope;
040:
041: public ForStatement(Statement parent, Location location) {
042: super (parent, location);
043: }
044:
045: public ForStatement(Statement parent, Location location,
046: Expression[] init, Expression condition,
047: Expression[] action, String label) {
048: super (parent, location);
049: _init = init;
050: _condition = condition;
051: _action = action;
052: _label = label;
053: }
054:
055: public int typeOf() {
056: return Statement.ST_FOR;
057: }
058:
059: public String name() {
060: return "for";
061: }
062:
063: public String getLabel() {
064: return _label;
065: }
066:
067: public void parse(TemplateParser parser, Tag tag) {
068: String expr = tag.getValue("expr");
069: if (expr == null) {
070: expr = tag.getValue("do");
071: }
072: if (expr != null) {
073: ExpressionParser p = new ExpressionParser(parser,
074: getLocation(), expr);
075: Object[] list = p.parseForExpressionList();
076: _init = (Expression[]) list[0];
077: _condition = (Expression) list[1];
078: _action = (Expression[]) list[2];
079: }
080: _label = parseLabel(parser, tag);
081: }
082:
083: public boolean onTag(TemplateParser parser, int type, Tag tag) {
084: switch (type) {
085: case ST_ENDFOR:
086: parser.pop();
087: break;
088:
089: default:
090: return super .onTag(parser, type, tag);
091: }
092:
093: return true;
094: }
095:
096: public Statement getChildStatement() {
097: return _statement;
098: }
099:
100: public void setChildStatement(Statement statement) {
101: _statement = statement;
102: }
103:
104: public void check(ErrorListener context) {
105: if (_init != null) {
106: int n = _init.length;
107: for (int i = 0; i < n; i++) {
108: _init[i].check(context);
109: }
110: }
111: if (_condition != null) {
112: _condition.check(context);
113: }
114: if (_action != null) {
115: int n = _action.length;
116: for (int i = 0; i < n; i++) {
117: _action[i].check(context);
118: }
119: }
120: _statement.check(context);
121: }
122:
123: public Jumps eliminate(ErrorListener context) {
124: Jumps jumps = _statement.eliminate(context);
125: if (_condition == null) {
126: jumps.setBlocked(!jumps.hasBreak());
127:
128: } else {
129: switch (_condition.conditionOf()) {
130: case Expression.IS_FALSE:
131: break;
132:
133: case Expression.IS_TRUE:
134: jumps.setBlocked(!jumps.hasBreak());
135: break;
136:
137: case Expression.IS_DYNAMIC:
138: jumps.setBlocked(false);
139: break;
140: }
141:
142: }
143: return jumps.shift();
144: }
145:
146: public Source getStartOfScope() {
147: return _startscope;
148: }
149:
150: public Source getEndOfScope() {
151: return _endscope;
152: }
153:
154: public void compile(ByteCompiler context) {
155: Code code = context.getCode();
156: context.location(getLocation());
157:
158: if (_init != null) {
159: int n = _init.length;
160: for (int i = 0; i < n; i++) {
161: _init[i].compile(context, Expression.GET);
162: code.pop();
163: }
164: }
165:
166: Source skip = null;
167: if (_action != null) {
168: skip = code.go_to();
169: }
170:
171: Target start = code.getTarget();
172: _startscope = code.getSource();
173: _endscope = code.getSource();
174:
175: if (_action != null) {
176: context.location(getLocation());
177: int n = _action.length;
178: for (int i = 0; i < n; i++) {
179: _action[i].compile(context, Expression.GET);
180: code.pop();
181: }
182: skip.bind();
183: }
184:
185: if (_condition != null) {
186: switch (_condition.conditionOf()) {
187: case Expression.IS_FALSE:
188: _endscope.bind();
189: _startscope.bind(start);
190: return;
191:
192: case Expression.IS_TRUE:
193: break;
194:
195: case Expression.IS_DYNAMIC:
196: _condition.compile(context, Expression.GET_BOOLEAN);
197: code.if_eq(_endscope);
198: break;
199: }
200: }
201:
202: _statement.compile(context);
203: code.go_to(_startscope);
204: _endscope.bind();
205: _startscope.bind(start);
206: }
207:
208: }
|