package node.exprNode.methodNameNode; import node.*; import node.declNode.*; import node.exprNode.*; import env.*; import type.*; import template.*; import runEnv.*; import text.*; public class IdentMethodNameNode extends MethodNameNode { private String ident; private Env env; public IdentMethodNameNode( String ident ) { this.ident = ident; } public String toString() { return ident; } public void genEnv( Env env ) { this.env = env; } public MethodType checkType( TypeList typeList ) { decl = env.searchEnv( ident, new InvocationTemplate( typeList ), Decl.PRIVATE ); if ( decl == null ) error( "Undeclared method " + ident ); switch ( decl.section() ) { case Decl.SECT_INSTANCE: case Decl.SECT_GLOBAL: case Decl.SECT_STATIC: break; default: error( ident + " must be method" ); } type = ( MethodType ) decl.type(); return type; } public MethodValue eval( RunEnv runEnv ) { // Return a MethodValue representing the code and runtime environment for the method // In the case of a constructor, creates and initialises the instance. InstanceValue instanceValue; switch ( decl.section() ) { case Decl.SECT_INSTANCE: instanceValue = runEnv.currentInstance(); return new MethodValue( instanceValue.methodTable().elementAt( decl.offset() ), instanceValue ); case Decl.SECT_GLOBAL: case Decl.SECT_STATIC: return new MethodValue( decl, null ); default: error( "Invalid section" ); return null; } } public int calcWeight() { weight = 1; return weight; } public void regCode( int freeReg, int freeTemp ) { // Loads $nip and $pv with appropriate values. switch ( decl.section() ) { case Decl.SECT_INSTANCE: move( "$ip", "$nip" ); load( "$at", displacement( "INST.methods", "$nip" ) ); load( "$pv", displacement( decl.absoluteName(), "$at" ) ); break; case Decl.SECT_GLOBAL: case Decl.SECT_STATIC: move( "$zero", "$nip" ); Node.loadIQ( "$pv", decl.absoluteName() + ".enter" ); break; default: error( "Invalid section of " + Decl.sectionText( decl.section() ) ); } } }