001 package com.croftsoft.apps.compiler.mini.node; 002 003 import java.util.*; 004 005 /********************************************************************* 006 * Parse tree node for the Mini programming language. 007 * 008 * @see 009 * MiniNode 010 * 011 * @author 012 * <A HREF="http://www.alumni.caltech.edu/~croft/">David W. Croft</A> 013 * @version 014 * 1999-04-26 015 *********************************************************************/ 016 017 public class ProcedureCallStatementMiniNode extends AbstractMiniNode 018 implements StatementMiniNode 019 ////////////////////////////////////////////////////////////////////// 020 ////////////////////////////////////////////////////////////////////// 021 { 022 023 protected NameMiniNode nameMiniNode; 024 protected ExpressionSequenceMiniNode expressionSequenceMiniNode; 025 026 protected Boolean callsNested; 027 028 ////////////////////////////////////////////////////////////////////// 029 // Constructor methods 030 ////////////////////////////////////////////////////////////////////// 031 032 public ProcedureCallStatementMiniNode ( 033 NameMiniNode nameMiniNode, 034 ExpressionSequenceMiniNode expressionSequenceMiniNode ) 035 ////////////////////////////////////////////////////////////////////// 036 { 037 this.nameMiniNode = nameMiniNode; 038 this.expressionSequenceMiniNode = expressionSequenceMiniNode; 039 } 040 041 public ProcedureCallStatementMiniNode ( NameMiniNode nameMiniNode ) 042 ////////////////////////////////////////////////////////////////////// 043 { 044 this ( nameMiniNode, null ); 045 } 046 047 ////////////////////////////////////////////////////////////////////// 048 // Access methods 049 ////////////////////////////////////////////////////////////////////// 050 051 public NameMiniNode getNameMiniNode ( ) { return nameMiniNode; } 052 053 public ExpressionSequenceMiniNode getExpressionSequenceMiniNode ( ) 054 ////////////////////////////////////////////////////////////////////// 055 { 056 return expressionSequenceMiniNode; 057 } 058 059 public Boolean callsNested ( ) { return callsNested; } 060 061 ////////////////////////////////////////////////////////////////////// 062 // MiniNode interface methods 063 ////////////////////////////////////////////////////////////////////// 064 065 public void generate ( MiniNodeCodeVisitor miniNodeCodeVisitor ) 066 ////////////////////////////////////////////////////////////////////// 067 { 068 miniNodeCodeVisitor.generateProcedureCallStatement ( this ); 069 } 070 071 public void checkSemantics ( Stack parentMiniNodeStack ) 072 throws SemanticErrorException 073 ////////////////////////////////////////////////////////////////////// 074 { 075 parentMiniNodeStack.push ( this ); 076 077 if ( expressionSequenceMiniNode != null ) 078 { 079 expressionSequenceMiniNode.checkSemantics ( parentMiniNodeStack ); 080 } 081 082 int size = parentMiniNodeStack.size ( ); 083 084 boolean wasDeclared = false; 085 086 outerLoop: 087 for ( int i = size - 2; i >= 0; i-- ) 088 { 089 MiniNode miniNode = ( MiniNode ) parentMiniNodeStack.get ( i ); 090 091 if ( !( miniNode instanceof BlockMiniNode ) ) continue; 092 093 DeclarationSequenceMiniNode declarationSequenceMiniNode 094 = ( ( BlockMiniNode ) miniNode 095 ).getDeclarationSequenceMiniNode ( ); 096 097 if ( declarationSequenceMiniNode == null ) continue; 098 099 List declarationMiniNodeList 100 = declarationSequenceMiniNode.getDeclarationMiniNodeList ( ); 101 102 Iterator j = declarationMiniNodeList.iterator ( ); 103 104 while ( j.hasNext ( ) ) 105 { 106 DeclarationMiniNode declarationMiniNode 107 = ( DeclarationMiniNode ) j.next ( ); 108 109 if ( !( declarationMiniNode instanceof 110 ProcedureDeclarationMiniNode ) ) continue; 111 112 ProcedureDeclarationMiniNode procedureDeclarationMiniNode 113 = ( ProcedureDeclarationMiniNode ) declarationMiniNode; 114 115 ParameterSequenceMiniNode parameterSequenceMiniNode 116 = procedureDeclarationMiniNode.getParameterSequenceMiniNode ( 117 ); 118 119 if ( nameMiniNode.equals ( 120 procedureDeclarationMiniNode.getNameMiniNode ( ) ) 121 && ( expressionSequenceMiniNode.size ( ) 122 == parameterSequenceMiniNode.size ( ) ) ) 123 { 124 callsNested = procedureDeclarationMiniNode.containsNested ( ); 125 wasDeclared = true; 126 break outerLoop; 127 } 128 } 129 } 130 131 if ( !wasDeclared ) 132 { 133 throw new SemanticErrorException ( "procedure undeclared" ); 134 } 135 136 parentMiniNodeStack.pop ( ); 137 } 138 139 ////////////////////////////////////////////////////////////////////// 140 ////////////////////////////////////////////////////////////////////// 141 }