Package org.lilystudio.smarty4j.statement.function

Source Code of org.lilystudio.smarty4j.statement.function.$break

package org.lilystudio.smarty4j.statement.function;

import static org.objectweb.asm.Opcodes.*;

import java.util.Map;

import org.lilystudio.smarty4j.ParseException;
import org.lilystudio.smarty4j.Template;
import org.lilystudio.smarty4j.TemplateReader;
import org.lilystudio.smarty4j.Utilities;
import org.lilystudio.smarty4j.statement.Function;
import org.lilystudio.smarty4j.statement.ILoop;
import org.lilystudio.smarty4j.statement.ParameterCharacter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;

/**
* break函数,支持跳出一个区块函数,被支持的区块函数需要实现ILoop接口,
* 函数支持一个整数做为参数,表示需要跳出多少层区块函数,不设置时仅跳出一层。
*
* <pre>
* {break 2}
* </pre>
*
* @see org.lilystudio.smarty4j.statement.ILoop
*
* @version 1.0.0, 2010/10/01
* @author 欧阳先伟
* @since Smarty 1.0
*/
public class $break extends Function {

  /** 需要跳转的层数 */
  private int floor;

  /** 需要跳转到的循环体结束位置 */
  private Label endLabel;

  /** 需要依次恢复状态的循环体, 不包括需要跳出的那一层, 数量比floor减一 */
  private ILoop[] blocks;

  @Override
  public void syntax(Template template, Object[] words, int wordSize)
      throws ParseException {
    if (wordSize == 3) {
      floor = 1;
      return;
    } else if (wordSize == 4) {
      Object value = words[3];
      if (value instanceof Integer) {
        floor = (Integer) value;
        if (floor > 0) {
          return;
        }
      }
    }
    throw new ParseException("参数错误");
  }

  @Override
  public void process(Template template, TemplateReader in, String left,
      String right) {
    blocks = new ILoop[floor - 1];
    ILoop now = (ILoop) Utilities.find(getParent(), ILoop.class);
    int i = 1;
    while (true) {
      if (now == null) {
        in.addMessage("没有需要跳转的位置");
        return;
      }
      if (i == floor) {
        break;
      }
      blocks[i - 1] = now;
      now = (ILoop) Utilities.find(now.getParent(), ILoop.class);
      i++;
    }
    endLabel = now.getEndLabel();
  }

  public ParameterCharacter[] getDefinitions() {
    return null;
  }

  public void parse(MethodVisitor mw, int local,
      Map<String, Integer> variableNames) {
    for (ILoop block : blocks) {
      block.restore(mw, variableNames);
    }
    mw.visitJumpInsn(GOTO, endLabel);
  }
}
TOP

Related Classes of org.lilystudio.smarty4j.statement.function.$break

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.