00001 #include <stdio.h>
00002 #include "parm.h"
00003
00004 #include "stree/ststructs.mh"
00005
00006 #include "sigs.h"
00007
00008 # define SIZE_SIZE 8
00009 # define DUMMY -2
00010 # define is_dummy(id) ((id) -> id_str_table_index == DUMMY)
00011
00012 extern FILE * unparse_file;
00013
00014 extern int next_pre;
00015
00016 extern int yynerrs;
00017
00018 boolean replace_arg();
00019 NODE * mknode();
00020
00021 extern unsigned indx_subscr;
00022
00023 extern NODE * var_Void;
00024
00025 extern NODE * diff_p, * diff_q;
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 NODE *
00048 infer_args(initial_args, params, void_decl, oper)
00049 NODE * initial_args;
00050 NODE * params;
00051 NODE * void_decl;
00052 NODE * oper;
00053 {
00054 int n_params = length(params);
00055 int n_args = length(initial_args);
00056 NODE * new_args;
00057 NODE * Void_id;
00058 int i;
00059 NODE * s_params;
00060 boolean failed = FALSE;
00061 boolean is_decimal_point;
00062
00063 # ifdef DEBUG
00064 if (nargs() != 4) {
00065 dbgmsg("infer_args: wrong number of arguments\n");
00066 }
00067 # endif
00068 if (n_args == n_params) return(initial_args);
00069 new_args = lock(copylist(initial_args));
00070
00071 is_decimal_point = n_params >= 3 && n_args == 2 &&
00072 oper -> kind == OPRID &&
00073 oper -> id_str_table_index == indx_subscr;
00074 if (is_decimal_point) {
00075 int i = 0;
00076 extern boolean Gflag;
00077 extern NODE * val_Integer;
00078
00079 maplist(s, new_args, {
00080 if (s -> kind != UQSTR) {
00081 is_decimal_point = FALSE;
00082 } else if (!Gflag && strlen(s -> str_string) > MAXINTLEN
00083 || Gflag && strlen(s -> str_string) > GMAXINTLEN) {
00084 if (comp_st(s -> signature,
00085 val_Integer, NIL, NIL) == 0) {
00086 fprintf(stderr, "Warning: possible floating pt const too long\n");
00087 }
00088 }
00089 });
00090 maplist (s, params, {
00091 i++;
00092 if (i <= 3 && s -> par_signature -> kind != VALSIGNATURE) {
00093 is_decimal_point = FALSE;
00094 }
00095 });
00096 }
00097 if (is_decimal_point) {
00098
00099 char * new_str_string = (char *) malloc(SIZE_SIZE);
00100 NODE * new_str;
00101 sprintf(new_str_string, "%d",
00102 strlen(last(new_args) -> str_string));
00103 new_str = mknode(UQSTR, new_str_string);
00104 new_str -> vlineno = oper -> vlineno;
00105 new_str -> str_use_list = first(new_args) -> str_use_list;
00106 if (findsig(new_str,FALSE) != SUCCESS) {
00107 errmsg0(oper, "Can`t find signature for length arg of \".\" ");
00108 new_str -> signature = ERR_SIG;
00109 new_str -> sig_done = SIG_DONE;
00110 return(NIL);
00111 }
00112 addright(new_args, new_str);
00113 n_args++;
00114 }
00115
00116
00117 i = 1;
00118 maplist(s, params, {
00119 if (i > n_args) {
00120
00121 NODE * dummy_id;
00122 dummy_id = mknode(LETTERID, DUMMY);
00123 dummy_id -> id_last_definition = s;
00124 dummy_id -> id_def_found = TRUE;
00125 dummy_id -> signature = NIL;
00126 addright(new_args, dummy_id);
00127 }
00128 i++;
00129 });
00130
00131 if (void_decl != NIL) {
00132 Void_id = lock(mknode(LETTERID, 0));
00133
00134 # ifdef DEBUG
00135 if (void_decl -> kind != PARAMETER) {
00136 dbgmsg("infer_args: funny Void variable declaration: 0x%X, %s\n",
00137 void_decl, kindname(void_decl -> kind));
00138 abort();
00139 }
00140 # endif
00141 Void_id -> id_last_definition = void_decl;
00142 Void_id -> id_def_found = TRUE;
00143 Void_id -> vlineno = oper -> vlineno;
00144 initfld(&(Void_id -> signature), var_Void);
00145 Void_id -> sig_done = SIG_DONE;
00146 maplist(s, params, {
00147 if (comp_st(s -> par_signature, var_Void, NIL, NIL) == 0) {
00148 boolean success = replace_arg(new_args, s, Void_id);
00149 if (success ) {
00150 n_args++;
00151 }
00152 }
00153 });
00154 vfree(unlock(Void_id));
00155 }
00156
00157 while (!failed && n_args < n_params) {
00158 s_params = subst(params, params, new_args);
00159 begin_map2lists(s, s_params, r, new_args) {
00160 if ((r -> kind == LETTERID || r -> kind == OPRID) && is_dummy(r)) {
00161
00162 failed = TRUE;
00163 break;
00164 }
00165
00166 if (s -> par_signature -> kind != TYPESIGNATURE
00167 && r -> signature != ERR_SIG) {
00168 NODE * par_to_unify = s -> par_signature;
00169 NODE * arg_to_unify = r -> signature;
00170
00171
00172 if (par_to_unify -> kind == VALSIGNATURE) {
00173 if (arg_to_unify -> kind == VARSIGNATURE) {
00174 arg_to_unify = arg_to_unify -> var_denotation;
00175 par_to_unify = par_to_unify -> val_denotation;
00176 } else if (arg_to_unify -> kind == FUNCSIGNATURE
00177 && is_empty(arg_to_unify -> fsig_param_list)) {
00178 arg_to_unify = arg_to_unify -> fsig_result_sig;
00179 }
00180 }
00181
00182
00183 if (comp_st(par_to_unify,
00184 arg_to_unify, NIL, NIL) != 0) {
00185 NODE * sav_diff_p = diff_p;
00186 NODE * sav_diff_q = diff_q;
00187
00188 if(sav_diff_p != NIL && is_dummy(sav_diff_p) &&
00189 findsig(sav_diff_q, FALSE) == SUCCESS &&
00190 replace_arg(new_args, sav_diff_p -> id_last_definition,
00191 unshare(sav_diff_q))) {
00192
00193 n_args++;
00194 break;
00195 } else {
00196 failed = TRUE;
00197 }
00198 }
00199 }
00200 } end_map2lists;
00201 }
00202 unlock(new_args);
00203 if (n_args != n_params) {
00204 vfree(new_args);
00205 return(NIL);
00206 } else {
00207 return(new_args);
00208 }
00209 }
00210
00211
00212
00213
00214
00215
00216 boolean replace_arg(args, old, new)
00217 NODE * args, * old, * new;
00218 {
00219 int i = 1;
00220 int j;
00221 boolean found_it = FALSE;
00222
00223 mapinslist(s, args, {
00224 if (s != NIL &&
00225 s -> kind == LETTERID && is_dummy(s) &&
00226 is_declared_by(s, old)) {
00227 found_it = TRUE;
00228 DELETE;
00229 break;
00230 }
00231 i++;
00232 });
00233 if (!found_it) return(FALSE);
00234
00235
00236
00237
00238 j = 1;
00239 mapinslist(s, args, {
00240 if (j == i) {
00241 INSERT(new);
00242 }
00243 j++;
00244 });
00245 return(TRUE);
00246 }