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 }