Package org.lilystudio.smarty4j.statement

Source Code of org.lilystudio.smarty4j.statement.Function

package org.lilystudio.smarty4j.statement;

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

import java.util.HashMap;
import java.util.Map;

import org.lilystudio.smarty4j.INode;
import org.lilystudio.smarty4j.Operation;
import org.lilystudio.smarty4j.ParseException;
import org.lilystudio.smarty4j.Template;
import org.lilystudio.smarty4j.TemplateReader;
import org.lilystudio.smarty4j.Utilities;
import org.lilystudio.smarty4j.expression.IExpression;
import org.lilystudio.smarty4j.expression.NullExpression;
import org.lilystudio.smarty4j.expression.StringExpression;
import org.lilystudio.smarty4j.expression.check.FalseCheck;
import org.lilystudio.smarty4j.expression.check.TrueCheck;
import org.lilystudio.smarty4j.expression.number.ConstDouble;
import org.lilystudio.smarty4j.expression.number.ConstInteger;
import org.objectweb.asm.MethodVisitor;

/**
* 基本函数节点,表示一个完整的操作。
*
* @see org.lilystudio.smarty4j.statement.ParameterCharacter
* @see org.lilystudio.smarty4j.statement.function.$else
*
* @version 1.0.0, 2010/10/01
* @author 欧阳先伟
* @since Smarty 1.0
*/
public abstract class Function extends Parameter implements IFunction {

  /** 函数名 */
  private String name;

  /** 父节点 */
  private IBlockFunction parent;

  /**
   * 函数参数的赋值处理,需要对函数参数进行第二次处理的,
   * 或者函数参数有一些特别的语法规则的,需要重载这个方法。
   *
   * @param parameters
   *          函数的缺省参数信息
   * @param fields
   *          当前的参数列表
   * @throws ParseException
   *           参数错误将产生这个异常
   */
  public void process(ParameterCharacter[] definitions,
      Map<String, IExpression> fields) throws ParseException {
    if (definitions != null) {
      int len = definitions.length;
      IExpression[] parameters = new IExpression[len];
      for (int i = 0; i < len; i++) {
        ParameterCharacter definition = definitions[i];
        String name = (String) definition.getCustom();
        try {
          parameters[i] = definition.getExpression(fields.get(name));
        } catch (ParseException e) {
          throw new ParseException(name + e.getMessage());
        }
      }
      setParameters(parameters);
    }
  }

  public String getName() {
    return name;
  }

  public IBlockFunction getParent() {
    return parent;
  }

  public void init(Template template, String name) {
    this.name = name;
  }

  public void syntax(Template template, Object[] words, int wordSize)
      throws ParseException {
    ParameterCharacter[] parameters = getDefinitions();
    if (parameters != null) {
      Map<String, IExpression> fields = new HashMap<String, IExpression>();

      for (int index = 3; index + 2 < wordSize; index += 3) {
        Object name = words[index];
        if ((name instanceof String) && Operation.C_SET == words[index + 1]) {
          // 将函数值转换成指定的数据类型
          Object word = words[index + 2];
          IExpression value;
          if (word instanceof IExpression) {
            value = (IExpression) word;
          } else if (Operation.C_SUB == word) {
            word = words[index + 3];
            index++;
            if (word instanceof Integer) {
              value = new ConstInteger(-((Integer) word));
            } else if (word instanceof Double) {
              value = new ConstDouble(-((Double) word));
            } else {
              throw new ParseException("不能识别的函数参数值");
            }
          } else if (word instanceof Integer) {
            value = new ConstInteger((Integer) word);
          } else if (word instanceof Double) {
            value = new ConstDouble((Double) word);
          } else if ("true".equals(word) || "yes".equals(word)
              || "on".equals(word)) {
            value = new TrueCheck();
          } else if ("false".equals(word) || "no".equals(word)
              || "off".equals(word)) {
            value = new FalseCheck();
          } else if ("null".equals(word)) {
            value = new NullExpression();
          } else if (word instanceof String) {
            value = new StringExpression((String) word);
          } else {
            throw new ParseException("不能识别的函数参数值");
          }

          if (index + 3 < wordSize && words[index + 3] == Operation.C_B_OR) {

          }
          fields.put((String) name, value);
          continue;
        }
        throw new ParseException("函数参数语法错误");
      }
      process(parameters, fields);
    }
  }

  public boolean setParent(IBlockFunction parent) throws ParseException {
    ParentType parentType = (ParentType) getClass().getAnnotation(
        ParentType.class);

    if (parentType != null) {
      String name = parentType.name();
      if (!name.equals(parent.getName())) {
        throw new ParseException(getClass().getSimpleName().substring(1)
            + "只能位于" + name + "中");
      }
    }

    this.parent = parent;
    return true;
  }

  public void process(Template template, TemplateReader in, String left,
      String right) {
  }

  /**
   * 将函数对象放入语句栈中,提供给LineFunction与BlockFunction使用。
   *
   * @see org.lilystudio.smarty4j.statement.LineFunction
   * @see org.lilystudio.smarty4j.statement.BlockFunction
   *
   * @param mw
   *          ASM方法操作者
   * @param local
   *          ASM语句栈的局部变量起始位置
   * @param index
   *          函数在Template中保存的位置
   */
  protected void parseFunction(MethodVisitor mw, int local, int index) {
    mw.visitVarInsn(ALOAD, TEMPLATE);
    Utilities.visitILdcInsn(mw, index);
    mw.visitMethodInsn(INVOKEVIRTUAL, Template.NAME, "getNode", "(I)L"
        + INode.NAME + ";");
    mw.visitTypeInsn(CHECKCAST, this.getClass().getName().replace('.', '/'));
  }
}
TOP

Related Classes of org.lilystudio.smarty4j.statement.Function

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.