001: /*
002: * $Id: CatchStatement.java,v 1.18 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.ConstantPool;
016: import anvil.codec.Source;
017: import anvil.codec.ExceptionHandler;
018: import anvil.parser.Tag;
019: import anvil.ErrorListener;
020: import anvil.script.compiler.ByteCompiler;
021: import anvil.script.Context;
022: import anvil.script.parser.TemplateParser;
023: import anvil.script.expression.ExpressionList;
024: import anvil.script.expression.Expression;
025: import anvil.script.expression.Node;
026: import anvil.script.expression.TypeNode;
027: import java.io.IOException;
028:
029: /**
030: * class CatchStatement
031: *
032: * @author: Jani Lehtimäki
033: */
034: public class CatchStatement extends ScopedStatement {
035:
036: protected Statement _statement = EMPTY;
037: protected Expression _assignment;
038: protected ExpressionList _types;
039: protected String _paramname = null;
040:
041: public CatchStatement(Statement parent, Location location,
042: Expression assignment, ExpressionList types) {
043: super (parent, location);
044: _assignment = assignment;
045: _types = types;
046: }
047:
048: public int typeOf() {
049: return Statement.ST_CATCH;
050: }
051:
052: public String name() {
053: return "catch";
054: }
055:
056: public void parse(TemplateParser parser, Tag tag) {
057: }
058:
059: public boolean onTag(TemplateParser parser, int type, Tag tag) {
060: return true;
061: }
062:
063: public Statement getChildStatement() {
064: return _statement;
065: }
066:
067: public void setChildStatement(Statement statement) {
068: _statement = statement;
069: }
070:
071: public void check(ErrorListener context) {
072: _assignment.check(context);
073: if (!_assignment.isAssignable()) {
074: context.error(getLocation(),
075: "Catch variable is not assignable");
076: }
077: _statement.check(context);
078: if (_types != null) {
079: _types.check(context);
080: }
081: }
082:
083: public Jumps eliminate(ErrorListener context) {
084: Jumps jumps = _statement.eliminate(context);
085: return jumps;
086: }
087:
088: protected class DataNode extends Node {
089: private int _data;
090:
091: public DataNode(int data) {
092: _data = data;
093: }
094:
095: public void compile(ByteCompiler context, int operation) {
096: context.getCode().aload(_data);
097: }
098:
099: }
100:
101: public void compile(ByteCompiler context, ExceptionHandler handler,
102: int l_data) {
103: Code code = context.getCode();
104: ConstantPool pool = code.getPool();
105: DataNode datanode = new DataNode(l_data);
106:
107: if (_types != null) {
108: Source istrue = code.getSource();
109: Source isfalse = null;
110:
111: int n = _types.childs();
112:
113: boolean assigned = false;
114: for (int i = 0; i < n; i++) {
115: if (_types.getChild(i).typeOf() != Node.EXPR_TYPE) {
116: _assignment.compile(context, datanode);
117: code.pop();
118: assigned = true;
119: }
120: }
121:
122: for (int i = 0; i < n; i++) {
123: if (isfalse != null) {
124: isfalse.bind();
125: }
126: Node child = _types.getChild(i);
127: if (child.typeOf() == Node.EXPR_TYPE) {
128: code.aload(l_data);
129: child.compile(context, Node.GET_TYPE);
130: code.invokevirtual(pool.addMethodRef(
131: context.TYPE_ANY, "isInstanceOf",
132: "(Lanvil/script/Type;)Z"));
133: } else {
134: child.compile(context, Node.GET_BOOLEAN);
135: }
136: isfalse = code.if_eq();
137: code.go_to(istrue);
138: }
139:
140: istrue.bind();
141:
142: if (!assigned) {
143: _assignment.compile(context, datanode);
144: code.pop();
145: }
146:
147: _statement.compile(context);
148: handler.callFinally();
149: handler.jumpOut();
150:
151: isfalse.bind();
152:
153: } else {
154: _assignment.compile(context, datanode);
155: code.pop();
156: _statement.compile(context);
157: handler.callFinally();
158: handler.jumpOut();
159: }
160: }
161:
162: public boolean isTypeless() {
163: return _types == null;
164: }
165:
166: }
|