001: /*
002: * $Id: VariableNode.java,v 1.22 2002/09/16 08:05:05 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.expression;
011:
012: import anvil.core.Any;
013: import anvil.ErrorListener;
014: import anvil.codec.Code;
015: import anvil.codec.ConstantPool;
016: import anvil.script.compiler.ByteCompiler;
017: import anvil.script.Context;
018: import anvil.script.Type;
019: import anvil.script.statements.LocalVariableStatement;
020: import java.io.IOException;
021:
022: /**
023: * class VariableNode
024: *
025: * @author: Jani Lehtimäki
026: */
027: public class VariableNode extends Node {
028:
029: private LocalVariableStatement _local;
030:
031: public VariableNode(LocalVariableStatement local) {
032: super ();
033: _local = local;
034: }
035:
036: public int typeOf() {
037: return Node.EXPR_VARIABLE;
038: }
039:
040: public LocalVariableStatement getVariable() {
041: return _local;
042: }
043:
044: public boolean isConstant() {
045: return false;
046: }
047:
048: public Node optimize() {
049: return this ;
050: }
051:
052: public void compile(ByteCompiler context, Node child) {
053: Code code = context.getCode();
054: ConstantPool pool = code.getPool();
055: if (_local.isEscaped()) {
056: code.aload(_local.getFrameIndex());
057: code.iconst(_local.getSlot());
058: child.compile(context, GET);
059: code.invokevirtual(code.getPool().addMethodRef(
060: "anvil/script/StackFrame", "setLocal",
061: "(ILanvil/core/Any;)Lanvil/core/Any;"));
062: } else {
063: child.compile(context, GET);
064: code.dup();
065: code.astore(_local.getIndex());
066: }
067: }
068:
069: public void compile(ByteCompiler context, int operation) {
070: Code code = context.getCode();
071: ConstantPool pool = code.getPool();
072: if (_local.isEscaped()) {
073: switch (operation) {
074: case GET:
075: case CHECK:
076: code.aload(_local.getFrameIndex());
077: code.iconst(_local.getSlot());
078: code.invokevirtual(code.getPool().addMethodRef(
079: "anvil/script/StackFrame", "getLocal",
080: "(I)Lanvil/core/Any;"));
081: break;
082:
083: case GET_REF:
084: int refclass = pool.addClass("anvil/core/AnyLocalRef");
085: code.anew(refclass);
086: code.dup();
087: code.aload(_local.getFrameIndex());
088: code.iconst(_local.getSlot());
089: code.invokespecial(pool.addMethodRef(refclass,
090: "<init>", "(Lanvil/script/StackFrame;I)V"));
091: break;
092:
093: case GET_BOOLEAN:
094: code.aload(_local.getFrameIndex());
095: code.iconst(_local.getSlot());
096: code.invokevirtual(code.getPool().addMethodRef(
097: "anvil/script/StackFrame", "getLocal",
098: "(I)Lanvil/core/Any;"));
099: context.any2boolean();
100: break;
101:
102: case DELETE:
103: code.iconst(false);
104: break;
105: }
106:
107: } else {
108: switch (operation) {
109: case GET:
110: code.aload(_local.getIndex());
111: break;
112:
113: case GET_BOOLEAN:
114: code.aload(_local.getIndex());
115: context.any2boolean();
116: break;
117:
118: case CHECK:
119: code.aload(_local.getIndex());
120: break;
121:
122: case DELETE:
123: code.getstatic(code.getPool().addFieldRef(
124: "anvil/core/Any", "UNDEFINED",
125: "Lanvil/core/Any;"));
126: break;
127: }
128: }
129: }
130:
131: }
|