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 "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)
00089 if (--plint->flow.ctl.count)
00090 plint->flow.ctl.parm.retn = plint_stack.top->down->proc;
00091
00092 return !0;
00093 }
00094 void plint_return_start()
00095 {
00096
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 };