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

flow.c

00001  /*
00002   * plint/prog/flow.c : program flow handling
00003   * 
00004   * Time-stamp: <2002-12-21 14:41:27 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 "flow.h"
00033 #include "block.h"
00034 #include "stack.h"
00035 
00036 #include "parse/mylex.h"
00037 
00038 
00039 
00040 inline void plint_block_push(plint_tree_t t)
00041 {
00042   plint_stack_push(t);
00043 }
00044 
00045 inline void plint_block_pop()
00046 {
00047   plint_stack_pop();
00048 }
00049 
00050 
00051 static int block_exit()
00052 {
00053   return !0;
00054 }
00055 void plint_exit_start()
00056 {
00057   plint->flow.ctl.type = PLINT_CTL_EXIT;
00058   plint->flow.ctl.count = -1;
00059 
00060   PLINT_LEX_EOF;
00061 }
00062 
00063 
00064 static int block_escape()
00065 {
00066   if (plint->flow.ctl.parm.escp == plint_stack.top->block.src)
00067     if (--plint->flow.ctl.count)
00068       plint->flow.ctl.parm.escp = plint_tree_non_ins(plint_stack.top->proc->block.src->prnt);
00069 
00070   return !!plint->flow.ctl.count;
00071 }
00072 void plint_escape_start()
00073 {
00074   plint->flow.ctl.parm.escp = plint_tree_non_ins(plint_stack.top->proc->block.src->prnt);
00075 
00076   plint->flow.ctl.type = PLINT_CTL_ESCP;
00077   if (plint->flow.ctl.count == -1)
00078     plint->flow.ctl.count = 0;
00079 
00080   ++plint->flow.ctl.count;
00081 
00082   PLINT_LEX_EOF;
00083 }
00084 
00085 
00086 static int block_return()
00087 {
00088   if (plint->flow.ctl.parm.retn == plint_stack.top) /* current top block is a procedure */
00089     if (--plint->flow.ctl.count)
00090       plint->flow.ctl.parm.retn = plint_stack.top->down->proc; /* who's the calling procedure ? */
00091 
00092   return !0;
00093 }
00094 void plint_return_start()
00095 {
00096   /* first, let's see who's the on top */
00097   plint->flow.ctl.parm.retn = plint_stack.top->proc;
00098 
00099   plint->flow.ctl.type= PLINT_CTL_RETN;
00100   if (plint->flow.ctl.count == -1)
00101     plint->flow.ctl.count = 0;
00102 
00103   ++plint->flow.ctl.count;
00104 
00105   block_return();
00106 
00107   PLINT_LEX_EOF;
00108 }
00109 
00110 
00111 static int block_ctrl()
00112 {
00113   --plint->flow.ctl.count;
00114   return !0;
00115 }
00116 void plint_ctrl_start(plint_ectl_t ctl)
00117 {
00118   plint->flow.ctl.type = ctl;
00119 
00120   if (plint->flow.ctl.count == -1)
00121     plint->flow.ctl.count = 1;
00122 
00123   PLINT_LEX_EOF;
00124 }
00125 
00126 
00127 static int block_extension()
00128 {
00129   return PLINT_MAP_BLOCK(CONTROL, plint_stack.top->block.src->blk, &plint_stack.top->block);
00130 }
00131 void plint_flow_start(int count, int type, void * data)
00132 {
00133   plint->flow.ctl.type= PLINT_CTL_EXTN;
00134   plint->flow.ctl.count = count;
00135   slot_setdata(plint->flow.ext, plint->flow.ctl.parm.extn = type, data);
00136 
00137   PLINT_LEX_EOF;
00138 }
00139 
00140 int plint_flow_register(freefunc_t f)
00141 {
00142   return slot_register(plint->flow.ext, 0, f);
00143 }
00144 
00145 void plint_flow_unregister(int type)
00146 {
00147   slot_unregister(plint->flow.ext, type);
00148 }
00149 
00150 int (* const plint_map_ctl[_PLINT_CTL_NO])() =
00151 {
00152   [PLINT_CTL_EXIT] = block_exit,
00153   [PLINT_CTL_RETN] = block_return,
00154   [PLINT_CTL_ESCP] = block_escape,
00155   [PLINT_CTL_BREK] = block_ctrl,
00156   [PLINT_CTL_CONT] = block_ctrl,
00157   [PLINT_CTL_LOOP] = block_ctrl,
00158   [PLINT_CTL_EXTN] = block_extension,
00159 };

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