package node.exprNode.methodNameNode; import node.*; import node.declNode.*; import node.exprNode.*; import env.*; import type.*; import type.basicType.*; import runEnv.*; import code.*; import text.*; public class IdentMethodNameNode extends MethodNameNode { private String ident; public IdentMethodNameNode( String ident ) { this.ident = ident; } public String toString() { return ident; } public Type checkType() { decl = env().searchEnv( ident ); if ( decl == null ) throw new Error( "Undeclared method " + ident ); switch ( decl.section() ) { case Decl.DECL_METHOD: type = ( MethodType ) decl.type(); return type; default: throw new Error( ident + " must be a method" ); } } public ObjectMethodPair eval( RunEnv runEnv ) { // Return an ObjectMethodPair representing // the instance and code for the method switch ( decl.env().envKind() ) { case Env.ENV_CLASS: { PtrValue instanceValue = runEnv.instance(); DeclList methodTable = instanceValue.getValue().methodTable(); return new ObjectMethodPair( instanceValue, methodTable.elementAt( decl.offset().interp() ) ); } case Env.ENV_GLOBAL: { return new ObjectMethodPair( null, decl ); } default: throw new Error( "Invalid section of " + Decl.sectionText( decl.section() ) ); } } public Register saveReg( int dataType, Usage usage ) { return null; } public void evalCode( Node sibling ) { setSibling( sibling ); // Loads $nip and $pv with appropriate values. switch ( decl.env().envKind() ) { case Env.ENV_CLASS: Code.move( SpecialReg.instPtr, SpecialReg.newInstPtr ); Code.load( IntType.type, SpecialReg.assemTemp, new Displacement( decl.env().absoluteName() + ".field.methodTablePtr", SpecialReg.newInstPtr ) ); Code.load( IntType.type, SpecialReg.procValue, new Displacement( decl.absoluteName(), SpecialReg.assemTemp ) ); break; case Env.ENV_GLOBAL: Code.move( SpecialReg.zero, SpecialReg.newInstPtr ); Code.loadImm( IntType.type, SpecialReg.procValue, decl.absoluteName() + ".enter" ); break; default: throw new Error( "Invalid section of " + Decl.sectionText( decl.section() ) ); } } }