Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals  

proc.c

00001  /*
00002   * plint/prog/proc.c : named blocks handling
00003   * 
00004   * Time-stamp: <2002-10-06 03:02:14 gseba>
00005   * 
00006   * Copyright (C) Sebastian Glita, email: gseba@users.sourceforge.net
00007   * 
00008   * This file is part of plint.
00009   * 
00010   * plint is free software; you can  redistribute it and/or modify it under the
00011   * terms of the  GNU General Public License as published  by the Free Software
00012   * Foundation; either version 2, or (at your option) any later version.
00013   *
00014   * plint  is distributed  in the  hope  that it  will be  useful, but  WITHOUT
00015   * ANY  WARRANTY; without  even  the implied  warranty  of MERCHANTABILITY  or
00016   * FITNESS FOR A  PARTICULAR PURPOSE.  See the GNU  General Public License for
00017   * more details.
00018   * 
00019   * You should  have received a  copy of the  GNU General Public  License along
00020   * with  plint; see  the file  COPYING.  If  not, write  to the  Free Software
00021   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA USA.
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               /* it invalidated <=> it didn't replace <=> it didn't find */
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; /* it was called, mark it */
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             /* this mode never invalidates */
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                   /* this mode invalidates on a miss on the looked-up proc */
00183                   return !0;
00184                 *data = t;
00185               }
00186             return 0;
00187           }
00188         }
00189     }
00190   return ((int)parm) == 0;
00191 }

Generated on Thu Jan 9 19:02:38 2003 for plint by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002