/*
* $Id: TypeNode.java,v 1.9 2002/09/16 08:05:05 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.script.expression;
import anvil.core.Any;
import anvil.core.runtime.AnyNamespace;
import anvil.ErrorListener;
import anvil.ErrorListener;
import anvil.codec.Code;
import anvil.codec.ConstantPool;
import anvil.script.compiler.ByteCompiler;
import anvil.script.statements.FunctionStatement;
import anvil.script.statements.ClassStatement;
import anvil.script.ClassType;
import anvil.script.Context;
import anvil.script.Type;
import anvil.script.Import;
import anvil.script.Grammar;
import anvil.script.NativeJava;
import java.io.IOException;
/**
* class TypeNode
*
* @author: Jani Lehtim�ki
*/
public class TypeNode extends Node
{
protected Type _type;
public TypeNode(Type type)
{
super();
_type = type;
}
public int typeOf()
{
return Node.EXPR_TYPE;
}
public boolean isConstant()
{
return false;
}
public Node optimize()
{
return this;
}
public Type getType()
{
return _type;
}
public void compile(ByteCompiler context, int operation)
{
boolean get_type = (operation == GET_TYPE);
Code code = context.getCode();
ConstantPool pool = code.getPool();
if (_type instanceof NativeJava) {
switch(_type.getType()) {
case Type.FUNCTION:
{
code.getstatic(pool.addFieldRef(_type.getParent().getTypeRef(pool),
"__module__", "Lanvil/script/compiler/NativeNamespace;"));
code.aload_first();
code.astring(_type.getName());
int method;
if (get_type) {
method = pool.addMethodRef("anvil/script/compiler/NativeNamespace",
"getDeclaration", "(Lanvil/script/Context;Ljava/lang/String;)Lanvil/script/Type;");
} else {
method = pool.addMethodRef("anvil/script/compiler/NativeNamespace", "getFunction",
"(Lanvil/script/Context;Ljava/lang/String;)Lanvil/core/Any;");
}
code.invokevirtual(method);
}
break;
case Type.CLASS:
{
code.getstatic(pool.addFieldRef(_type.getTypeRef(pool),
"__class__", "Lanvil/script/compiler/NativeClass;"));
if (!get_type) {
code.invokevirtual(pool.addMethodRef("anvil/script/compiler/NativeClass",
"getWrapper", "()Lanvil/core/Any;"));
}
}
break;
case Type.NAMESPACE:
{
code.getstatic(pool.addFieldRef(_type.getTypeRef(pool),
"__module__", "Lanvil/script/compiler/NativeNamespace;"));
if (!get_type) {
code.invokevirtual(pool.addMethodRef("anvil/script/compiler/NativeNamespace",
"getWrapper", "()Lanvil/core/Any;"));
}
}
break;
case Type.METHOD:
{
code.getstatic(pool.addFieldRef(_type.getParent().getTypeRef(pool),
"__class__", "Lanvil/script/compiler/NativeClass;"));
int method;
code.aload_first();
code.astring(_type.getName());
if (get_type) {
method = pool.addMethodRef("anvil/script/compiler/NativeClass",
"getDeclaration", "(Lanvil/script/Context;Ljava/lang/String;)Lanvil/script/Type;");
} else {
method = pool.addMethodRef("anvil/script/compiler/NativeClass", "getMethod",
"(Lanvil/script/Context;Ljava/lang/String;)Lanvil/core/Any;");
}
code.invokevirtual(method);
}
break;
}
} else {
switch(_type.getType()) {
case Type.FUNCTION:
{
int field = pool.addFieldRef(_type.getParent().getTypeRef(pool),
(get_type ? "f_" : "F_") + _type.getName(),
get_type ? "Lanvil/script/Function;" : "Lanvil/core/Any;");
code.getstatic(field);
}
break;
case Type.MEMBER_VARIABLE:
{
Type parent = _type.getParent();
int field = pool.addFieldRef(parent.getTypeRef(pool), "_class",
"Lanvil/script/compiler/CompiledClassType;");
code.getstatic(field);
code.aload_first();
code.astring(_type.getName());
code.invokevirtual(pool.addMethodRef(
"anvil/script/compiler/CompiledClassType",
get_type ?
"getMember" :
"getMemberType",
get_type ?
"(Lanvil/script/Context;Ljava/lang/String;)Lanvil/script/Type;" :
"(Lanvil/script/Context;Ljava/lang/String;)Lanvil/core/Any;"));
}
break;
case Type.INTERFACE_METHOD:
case Type.METHOD:
case Type.CONSTRUCTOR:
{
int field = pool.addFieldRef(_type.getParent().getTypeRef(pool),
(get_type ? "m_" : "M_") + _type.getName(),
get_type ? "Lanvil/script/Function;" : "Lanvil/core/Any;");
code.getstatic(field);
}
break;
case Type.CLASS:
{
if (get_type) {
int field = pool.addFieldRef(_type.getTypeRef(pool), "_class",
"Lanvil/script/compiler/CompiledClassType;");
code.getstatic(field);
} else {
int field = pool.addFieldRef(_type.getTypeRef(pool),
"_type", "Lanvil/core/Any;");
code.getstatic(field);
}
}
break;
case Type.INTERFACE:
{
int field = pool.addFieldRef(_type.getTypeRef(pool),
get_type ? "_class" : "_type",
get_type ? "Lanvil/script/compiler/CompiledInterfaceType;" : "Lanvil/core/Any;");
code.getstatic(field);
}
break;
case Type.NAMESPACE:
{
int field = pool.addFieldRef(_type.getTypeRef(pool),
get_type ? "_class" : "_type",
get_type ? "Lanvil/script/compiler/CompiledNamespace;" : "Lanvil/core/Any;");
code.getstatic(field);
}
break;
case Type.MODULE:
{
int field = code.getPool().addFieldRef(_type.getTypeRef(pool),
get_type ? "_module" : "_type",
get_type ? "Lanvil/script/compiler/CompiledModule;" : "Lanvil/core/Any;");
code.getstatic(field);
}
break;
}
}
if (operation == GET_BOOLEAN) {
context.any2boolean();
}
}
}