00001 #define DEBUG
00002 # include <stdio.h>
00003 # include "parm.h"
00004
00005 # include "stree/ststructs.mh"
00006
00007 # include "sigs.h"
00008 # include "../pass3/is_local.h"
00009
00010 boolean impure();
00011
00012 extern FILE * unparse_file;
00013
00014 extern int stplinks[];
00015 extern int stsigs[];
00016 extern int yynerrs;
00017 extern boolean Lflag;
00018 extern NODE * var_Void;
00019
00020 NODE * infunc = NIL;
00021
00022
00023
00024 NODE * insig = NIL;
00025
00026 static int Clevel = -1;
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 import(p, scope)
00037 NODE * p, * scope;
00038 {
00039 register int * q;
00040
00041 register int plinkv;
00042
00043
00044 register int sigv;
00045 NODE * old_infunc = infunc;
00046 NODE * old_insig = insig;
00047 int sig_kind;
00048 boolean is_expression;
00049 NODE * def;
00050
00051 if (p == NIL || p == ERR_SIG) return;
00052
00053 switch(p -> kind) {
00054 case BLOCKDENOTATION:
00055 case USELIST:
00056 case APPLICATION:
00057 case ENUMERATION:
00058 case EXTENSION:
00059 case PRODCONSTRUCTION:
00060 case RECORDCONSTRUCTION:
00061 case UNIONCONSTRUCTION:
00062 case MODPRIMARY:
00063 case WORDELSE:
00064 case GUARDEDLIST:
00065 case LOOPDENOTATION:
00066 case OPRID:
00067 case LETTERID:
00068 case QSTR:
00069 case UQSTR:
00070 case FUNCCONSTR:
00071 case REXTERNDEF:
00072 is_expression = TRUE;
00073 break;
00074
00075 default:
00076 is_expression = FALSE;
00077 break;
00078 }
00079
00080 if (is_expression && has_sig(p) ) {
00081 sig_kind = p -> signature -> kind;
00082 if (sig_kind == TYPESIGNATURE) {
00083 infunc = p;
00084 }
00085 if (p -> kind == FUNCCONSTR) {
00086 if (impure(p -> signature)) {
00087 infunc = NIL;
00088 } else {
00089 infunc = p;
00090 }
00091 }
00092 }
00093
00094 switch( p -> kind ) {
00095 case OPRID:
00096 case LETTERID:
00097 if ( p -> sel_type != NIL ) {
00098 import( p -> sel_type, scope);
00099 } else {
00100 if ((def = p -> id_last_definition) == NIL) {
00101 break;
00102 }
00103 if (scope != NIL
00104 && def -> kind == DECLARATION
00105 && ( !(def -> decl_sig_transp)
00106 && def -> decl_scope == scope
00107 || def -> decl_sig_transp
00108 && def -> decl_innermost_id != NIL
00109 && def -> decl_innermost_id -> decl_scope == scope)) {
00110 errmsg1(p,
00111 "Identifier %s contained in signature outside its scope",
00112 def -> decl_sig_transp?
00113 getname(def -> decl_innermost_id -> decl_id
00114 -> id_str_table_index)
00115 : getname(p -> id_str_table_index));
00116 }
00117 if (infunc != NIL) {
00118 if (insig == NIL && has_sig(p) &&
00119 sig_kind == VARSIGNATURE && !is_local(p, infunc)) {
00120 errmsg1(p,
00121 "Variable %s imported into function or type:",
00122 getname(p -> id_str_table_index)
00123 );
00124 fprintf(stderr, "\t");
00125 unparse_file = stderr;
00126 unparse(infunc);
00127 fprintf(stderr,"\n\tfunction or type signature:\n\t");
00128 unparse(infunc -> signature);
00129 fprintf(stderr, "\n");
00130 }
00131 }
00132 }
00133 break;
00134
00135 case FUNCCONSTR:
00136 Clevel++;
00137 p -> ar_static_level = Clevel;
00138
00139 import(p -> fc_body, scope);
00140 Clevel--;
00141 break;
00142
00143 case APPLICATION:
00144 import(p -> ap_operator, scope);
00145 import(p -> ap_args, scope);
00146 if (insig == NIL) {
00147
00148
00149 insig = p -> signature;
00150 import(p -> signature, scope);
00151 }
00152 break;
00153
00154 case BLOCKDENOTATION:
00155 import(p -> bld_declaration_list, scope);
00156 import(p -> bld_den_seq, scope);
00157 if (insig == NIL) {
00158
00159 insig = p -> signature;
00160 import(p -> signature, p);
00161 }
00162 break;
00163
00164 case DECLARATION:
00165 p -> level = Clevel;
00166 import(p -> decl_denotation, scope);
00167
00168
00169
00170
00171
00172 infunc = p -> decl_signature;
00173 import(p -> decl_signature, scope);
00174 break;
00175
00176 case MODPRIMARY:
00177 p -> level = Clevel;
00178 import(p -> mp_primary, scope);
00179 import(p -> mp_type_modifier, scope);
00180 break;
00181
00182 case QSTR:
00183 case UQSTR:
00184
00185 break;
00186
00187 default:
00188
00189 if (is_list(p)) {
00190 maplist(e, p, {
00191 import(e, scope);
00192 });
00193 } else {
00194 plinkv = stplinks[p -> kind];
00195 sigv = stsigs[p -> kind];
00196 q = (int *) p;
00197 while ( plinkv != 0 ) {
00198 if ( plinkv < 0 /* msb is set */ && sigv >= 0) {
00199 import(*q, scope);
00200 }
00201 q++;
00202 plinkv <<= 1;
00203 sigv <<= 1;
00204 }
00205 }
00206 }
00207 infunc = old_infunc;
00208 insig = old_insig;
00209 }
00210
00211
00212 boolean impure(p)
00213 NODE *p;
00214 {
00215 # ifdef DEBUG
00216 if (p -> kind != FUNCSIGNATURE) {
00217 dbgmsg("Bad call to impure\n");
00218 }
00219 # endif
00220 if (!Lflag) {
00221 return(FALSE);
00222 } else {
00223 NODE * plist = p -> fsig_param_list;
00224
00225 if (is_empty(plist)
00226 || comp_st(last(plist) -> par_signature,
00227 var_Void,
00228 NIL, NIL) != 0) {
00229 return(FALSE);
00230 } else {
00231 return(TRUE);
00232 }
00233 }
00234 }