001: /*
002: * $Id: NewNode.java,v 1.19 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.script.ClassType;
015: import anvil.script.CompilableFunction;
016: import anvil.codec.Code;
017: import anvil.codec.ConstantPool;
018: import anvil.script.compiler.ByteCompiler;
019: import anvil.script.Context;
020: import anvil.script.Type;
021: import anvil.script.Module;
022: import anvil.script.Grammar;
023: import anvil.script.NativeJava;
024: import java.io.IOException;
025:
026: /**
027: * class NewNode
028: *
029: * @author: Jani Lehtimäki
030: */
031: public class NewNode extends MultiParent {
032:
033: protected ClassType _context;
034: protected ClassType _class;
035: protected CompilableFunction _constructor = null;
036:
037: public NewNode(ClassType context, ClassType clazz,
038: CompilableFunction ctor, Parent parameters) {
039: super (parameters);
040: _context = context;
041: _class = clazz;
042: _constructor = ctor;
043: }
044:
045: public int typeOf() {
046: return Node.EXPR_NEW;
047: }
048:
049: public boolean isConstant() {
050: return false;
051: }
052:
053: public Node optimize() {
054: optimizeChilds();
055: return this ;
056: }
057:
058: public void compile(ByteCompiler context, int operation) {
059: Code code = context.getCode();
060: ConstantPool pool = code.getPool();
061: if (_class instanceof NativeJava) {
062: if (hasSplices()) {
063: code.getstatic(pool.addFieldRef(
064: _class.getTypeRef(pool), "__class__",
065: "Lanvil/script/compiler/NativeClass;"));
066: code.aload_first();
067: context.compileArgumentList(getChilds(0));
068: code
069: .invokevirtual(pool
070: .addMethodRef(
071: "anvil/script/compiler/NativeClass",
072: "newInstance",
073: "(Lanvil/script/Context;[Lanvil/core/Any;)Lanvil/core/Any;"));
074:
075: } else {
076: context.compileCall(_constructor, getChilds(0));
077:
078: }
079:
080: } else {
081: int classindex = _class.getTypeRef(pool);
082: boolean has_splices = hasSplices();
083: if (has_splices) {
084: code.getstatic(pool.addFieldRef(classindex, "m_"
085: + _constructor.getName(),
086: "Lanvil/script/Function;"));
087: code.aload_first();
088: }
089: code.anew(classindex);
090: code.dup();
091: ClassType[] clazz_parents = _class.getEnclosingClasses();
092: int n = clazz_parents.length;
093: for (int i = 0; i < n; i++) {
094: context.accessInstance(_context, clazz_parents[i]);
095: }
096: code.invokespecial(_class.getConstructorReference(pool));
097: if (has_splices) {
098: context.compileArgumentList(getChilds(0));
099: code
100: .invokeinterface(pool
101: .addInterfaceMethodRef(
102: "anvil/script/Function",
103: "execute",
104: "(Lanvil/script/Context;Lanvil/core/Any;[Lanvil/core/Any;)Lanvil/core/Any;"));
105: } else {
106: context.compileArgumentList(_constructor, getChilds(0));
107: code.invokevirtual(_constructor.getTypeRef(pool));
108: }
109: }
110: if (operation == GET_BOOLEAN) {
111: context.any2boolean();
112: }
113:
114: }
115:
116: }
|