00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #pragma GCC dependency "Makefile" maybe some command line defines have changed
00026
00027 #include "plint.h"
00028 #include "error.h"
00029 #include "share.h"
00030
00031 #include "data.h"
00032 #include "proc.h"
00033 #include "stack.h"
00034
00035
00036
00037 static void save_prnt(plint_tree_t p)
00038 {
00039 plint_insprnt_t x;
00040 NEW(x);
00041
00042 x->insp = p;
00043 x->prnt = p->prnt;
00044 x->next = plint_ins.prnt;
00045 plint_ins.prnt = x;
00046 }
00047
00048 static plint_tree_t proc_chlds(plint_tree_t r)
00049 {
00050 int i;
00051 plint_tree_t p;
00052 static plint_tree_t q;
00053 for (i = r->nchlds; i; )
00054 {
00055 p = r->chlds[--i];
00056 if (PROC_SIG_EQU(plint_proc.lup.sig, p->proc))
00057 {
00058 if (!PLINT_TREE_ISPRC(plint_proc.lup.ptr))
00059 plint_proc.lup.ptr = plint_tree_host(plint_proc.lup.ptr);
00060 return p;
00061 }
00062 else if (PLINT_TREE_ISINS(p) && (q = proc_chlds(p)))
00063 {
00064 save_prnt(p);
00065 p->prnt = r;
00066 p->host.d = plint_proc.lup.ptr;
00067 return q;
00068 }
00069 }
00070
00071 return 0;
00072 }
00073
00074 void *plint_proc_miss(hashindex_t hi, plint_proc_t *pproc)
00075 {
00076 plint_tree_t r = plint_stack.top->block.src, p;
00077 plint_proc.lup.sig = *pproc;
00078
00079 while (r)
00080 if ((p = proc_chlds(plint_proc.lup.ptr = r)))
00081 {
00082 r = p;
00083 break;
00084 }
00085 else
00086 r = r->prnt;
00087
00088 if (!r)
00089 {
00090 r = plint_code.root;
00091 if (!PROC_SIG_EQU(plint_proc.lup.sig, r->proc))
00092 r = 0;
00093 }
00094
00095 return r;
00096 }
00097
00098 plint_tree_t plint_proc_lookup(hashindex_t hi)
00099 {
00100 plint_tree_t ret = 0;
00101
00102 if (!HASH_INDEX_ISBAD(hi))
00103 {
00104 plint_proc_t proc;
00105
00106 proc.name = hi;
00107 proc.arrity = plint_tab_n(plint->reg.tab);
00108
00109 for (;;)
00110 if (!(ret = cache_lookup(plint_cache.proc, proc.name, &proc)) ||
00111 ret->proc.arrity == proc.arrity)
00112 break;
00113 else
00114 {
00115 plint_cache_invparm_t cip = { mode: 0, data: &proc };
00116 ret = 0;
00117 if (cache_invalidate(plint_cache.proc, (void*)&cip))
00118
00119 break;
00120 }
00121 }
00122
00123 return ret;
00124 }
00125
00126 void plint_proc_call()
00127 {
00128 plint_tree_t r;
00129 (r = 0)
00130 || (r = plint_proc_lookup(hash_getindex(plint_hash.id, plint_str_sn(plint->reg.str))))
00131 || (r = plint_map_proc[PLINT_PROC_LOOKUP][plint_stack.top->block.src->blk](PLINT_PROC_LOOKUP,
00132 plint_stack.top->block.src, plint->reg.str));
00133
00134 if (!r)
00135 PLINT_ERROR(PLINT_ERR_PROC_CALL, plint_str_s(plint->reg.str), &plint_tab_n(plint->reg.tab));
00136
00137 r->flag = 4;
00138
00139 if (plint->reg.var && r->frm != PLINT_FRM_METH)
00140 PLINT_ERROR(PLINT_ERR_METH_NON);
00141 else if (!plint->reg.var && r->frm == PLINT_FRM_METH)
00142 PLINT_ERROR(PLINT_ERR_METH_OBJ);
00143
00144 plint_stack_push(r);
00145
00146 plint_free_str();
00147 }
00148
00149 int plint_proc_invalidate(hashindex_t *hi, void **data, void *parm)
00150 {
00151 if (!HASH_INDEX_ISBAD(*hi))
00152 {
00153 switch (((plint_cache_invparm_t *)parm)->mode)
00154 {
00155 case -1:
00156 {
00157 return plint_proc_lup_ptr((plint_tree_t)*data);
00158 }
00159
00160 case +1:
00161 {
00162
00163 plint_tree_t p;
00164 plint_proc.lup.sig.name = *hi;
00165 plint_proc.lup.sig.arrity = ((plint_tree_t)*data)->proc.arrity;
00166 p = plint_proc_lup_sig(plint_proc.lup.ptr);
00167 if (p)
00168 {
00169 *hi = p->proc.name;
00170 *data = p;
00171 }
00172 return 0;
00173 }
00174
00175 case 0:
00176 {
00177 plint_proc_t *pproc = ((plint_cache_invparm_t *)parm)->data;
00178 if (HASH_INDEX_EQU(*hi, pproc->name))
00179 {
00180 plint_tree_t t = plint_proc_miss(*hi, pproc);
00181 if (!t)
00182
00183 return !0;
00184 *data = t;
00185 }
00186 return 0;
00187 }
00188 }
00189 }
00190 return ((int)parm) == 0;
00191 }