home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
prgramer
/
adaptor
/
src
/
controlf.c
< prev
next >
Wrap
Text File
|
1994-01-02
|
14KB
|
631 lines
# include "ControlF.h"
# include "yyCFlow.w"
# include <stdio.h>
# if defined __STDC__ | defined __cplusplus
# include <stdlib.h>
# else
extern void exit ();
# endif
# include "Tree.h"
# ifndef NULL
# define NULL 0L
# endif
# ifndef false
# define false 0
# endif
# ifndef true
# define true 1
# endif
# ifdef yyInline
# define yyALLOC(tree, free, max, alloc, nodesize, make, ptr, kind) \
if ((ptr = (tree) free) >= (tree) max) ptr = alloc (); \
free += nodesize [kind]; \
ptr->yyHead.yyMark = 0; \
ptr->Kind = kind;
# else
# define yyALLOC(tree, free, max, alloc, nodesize, make, ptr, kind) ptr = make (kind);
# endif
# define yyWrite(s) (void) fputs (s, yyf)
# define yyWriteNl (void) fputc ('\n', yyf)
# line 21 "ControlFlow.puma"
# include "Idents.h"
# include "StringMe.h"
# include "protocol.h"
# include "Types.h"
# include "Transfor.h" /* ReplaceACF */
/*********************************************************************
* *
* Global Data for Control Flow Analysis *
* *
*********************************************************************/
int MaxLabel;
int NoReturns;
void SetMaxLabel (label)
int label;
{ if (label > MaxLabel) MaxLabel = label;
} /* SetMaxLabel */
static FILE * yyf = stdout;
static void yyAbort
# ifdef __cplusplus
(char * yyFunction)
# else
(yyFunction) char * yyFunction;
# endif
{
(void) fprintf (stderr, "Error: module ControlFlow, routine %s failed\n", yyFunction);
exit (1);
}
void ControlFlow ARGS((tTree t));
static void CheckUpLabels ARGS((tTree t));
static tTree RemoveLastReturn ARGS((tTree t));
static tTree AppendEndLabel ARGS((tTree t, int label));
static void ReplaceReturn ARGS((tTree t, int gotolabel));
void ControlFlow
# if defined __STDC__ | defined __cplusplus
(register tTree t)
# else
(t)
register tTree t;
# endif
{
if (t == NoTree) return;
switch (t->Kind) {
case kCOMP_UNIT:
# line 54 "ControlFlow.puma"
{
# line 55 "ControlFlow.puma"
open_protocol ("adaptor.cf");
# line 56 "ControlFlow.puma"
ControlFlow (t->COMP_UNIT.COMP_ELEMENTS);
# line 57 "ControlFlow.puma"
close_protocol ();
}
return;
case kDECL_EMPTY:
# line 62 "ControlFlow.puma"
return;
case kDECL_LIST:
# line 65 "ControlFlow.puma"
{
# line 66 "ControlFlow.puma"
ControlFlow (t->DECL_LIST.Elem);
# line 67 "ControlFlow.puma"
ControlFlow (t->DECL_LIST.Next);
}
return;
case kPROGRAM_DECL:
# line 77 "ControlFlow.puma"
{
# line 78 "ControlFlow.puma"
set_protocol_unit (t);
# line 79 "ControlFlow.puma"
ControlFlow (t->PROGRAM_DECL.PROGRAM_BODY);
}
return;
case kPROC_DECL:
# line 82 "ControlFlow.puma"
{
# line 83 "ControlFlow.puma"
set_protocol_unit (t);
# line 84 "ControlFlow.puma"
ControlFlow (t->PROC_DECL.PROC_BODY);
}
return;
case kFUNC_DECL:
# line 87 "ControlFlow.puma"
{
# line 88 "ControlFlow.puma"
set_protocol_unit (t);
# line 89 "ControlFlow.puma"
ControlFlow (t->FUNC_DECL.FUNC_BODY);
}
return;
case kMODULE_DECL:
# line 92 "ControlFlow.puma"
{
# line 93 "ControlFlow.puma"
set_protocol_unit (t);
# line 94 "ControlFlow.puma"
ControlFlow (t->MODULE_DECL.MODULE_BODY);
}
return;
case kBLOCK_DATA_DECL:
# line 97 "ControlFlow.puma"
{
# line 98 "ControlFlow.puma"
set_protocol_unit (t);
# line 99 "ControlFlow.puma"
ControlFlow (t->BLOCK_DATA_DECL.DATA_BODY);
}
return;
case kBODY_NODE:
# line 112 "ControlFlow.puma"
{
# line 116 "ControlFlow.puma"
MaxLabel = 0;
# line 117 "ControlFlow.puma"
NoReturns = 0;
# line 121 "ControlFlow.puma"
CheckUpLabels (t->BODY_NODE.STATS);
# line 124 "ControlFlow.puma"
if (NoReturns > 0)
t->BODY_NODE.STATS = RemoveLastReturn (t->BODY_NODE.STATS);
# line 129 "ControlFlow.puma"
if (NoReturns > 0)
{ t->BODY_NODE.STATS = AppendEndLabel (t->BODY_NODE.STATS, MaxLabel + 1);
ReplaceReturn (t->BODY_NODE.STATS, MaxLabel+1); }
# line 136 "ControlFlow.puma"
if (NoReturns > 0)
simple_error_protocol ("not all returns removed");
}
return;
}
;
}
static void CheckUpLabels
# if defined __STDC__ | defined __cplusplus
(register tTree t)
# else
(t)
register tTree t;
# endif
{
if (t == NoTree) return;
switch (t->Kind) {
case kACF_LIST:
# line 152 "ControlFlow.puma"
{
# line 153 "ControlFlow.puma"
set_protocol_stmt (t->ACF_LIST.Elem);
# line 154 "ControlFlow.puma"
CheckUpLabels (t->ACF_LIST.Elem);
# line 155 "ControlFlow.puma"
CheckUpLabels (t->ACF_LIST.Next);
}
return;
case kACF_EMPTY:
# line 158 "ControlFlow.puma"
return;
case kACF_DUMMY:
# line 161 "ControlFlow.puma"
{
# line 162 "ControlFlow.puma"
SetMaxLabel (t->ACF_DUMMY.Label);
}
return;
case kACF_BASIC:
if (t->ACF_BASIC.BASIC_STMT->Kind == kRETURN_STMT) {
if (t->ACF_BASIC.BASIC_STMT->RETURN_STMT.RETURN_EXP->Kind == kDUMMY_EXP) {
# line 165 "ControlFlow.puma"
{
# line 166 "ControlFlow.puma"
SetMaxLabel (t->ACF_BASIC.Label);
# line 167 "ControlFlow.puma"
NoReturns = NoReturns + 1;
}
return;
}
# line 170 "ControlFlow.puma"
{
# line 171 "ControlFlow.puma"
SetMaxLabel (t->ACF_BASIC.Label);
# line 172 "ControlFlow.puma"
error_protocol ("Alternative return is rejected\n");
}
return;
}
# line 175 "ControlFlow.puma"
{
# line 176 "ControlFlow.puma"
SetMaxLabel (t->ACF_BASIC.Label);
}
return;
case kACF_IF:
# line 179 "ControlFlow.puma"
{
# line 180 "ControlFlow.puma"
SetMaxLabel (t->ACF_IF.Label);
# line 181 "ControlFlow.puma"
CheckUpLabels (t->ACF_IF.THEN_PART);
# line 182 "ControlFlow.puma"
CheckUpLabels (t->ACF_IF.ELSE_PART);
}
return;
case kACF_WHERE:
# line 185 "ControlFlow.puma"
{
# line 186 "ControlFlow.puma"
SetMaxLabel (t->ACF_WHERE.Label);
# line 187 "ControlFlow.puma"
CheckUpLabels (t->ACF_WHERE.TRUE_PART);
# line 188 "ControlFlow.puma"
CheckUpLabels (t->ACF_WHERE.FALSE_PART);
}
return;
case kACF_CASE:
# line 191 "ControlFlow.puma"
{
# line 192 "ControlFlow.puma"
SetMaxLabel (t->ACF_CASE.Label);
# line 193 "ControlFlow.puma"
CheckUpLabels (t->ACF_CASE.CASE_ALTS);
# line 194 "ControlFlow.puma"
CheckUpLabels (t->ACF_CASE.CASE_OTHERWISE);
}
return;
case kSELECTED_ACF_LIST:
# line 197 "ControlFlow.puma"
{
# line 198 "ControlFlow.puma"
CheckUpLabels (t->SELECTED_ACF_LIST.Elem);
# line 199 "ControlFlow.puma"
CheckUpLabels (t->SELECTED_ACF_LIST.Next);
}
return;
case kSELECTED_ACF_EMPTY:
# line 202 "ControlFlow.puma"
return;
case kSELECTED_ACF_NODE:
# line 205 "ControlFlow.puma"
{
# line 206 "ControlFlow.puma"
CheckUpLabels (t->SELECTED_ACF_NODE.SELECT_ACFS);
}
return;
case kACF_WHILE:
# line 209 "ControlFlow.puma"
{
# line 210 "ControlFlow.puma"
SetMaxLabel (t->ACF_WHILE.Label);
# line 211 "ControlFlow.puma"
CheckUpLabels (t->ACF_WHILE.WHILE_BODY);
}
return;
case kACF_DOLOCAL:
# line 214 "ControlFlow.puma"
{
# line 215 "ControlFlow.puma"
SetMaxLabel (t->ACF_DOLOCAL.Label);
# line 216 "ControlFlow.puma"
CheckUpLabels (t->ACF_DOLOCAL.DOLOCAL_BODY);
}
return;
case kACF_DOALL:
# line 219 "ControlFlow.puma"
{
# line 220 "ControlFlow.puma"
SetMaxLabel (t->ACF_DOALL.Label);
# line 221 "ControlFlow.puma"
CheckUpLabels (t->ACF_DOALL.DOALL_BODY);
}
return;
case kACF_FORALL:
# line 224 "ControlFlow.puma"
{
# line 225 "ControlFlow.puma"
SetMaxLabel (t->ACF_FORALL.Label);
# line 226 "ControlFlow.puma"
CheckUpLabels (t->ACF_FORALL.FORALL_BODY);
}
return;
case kACF_DO:
# line 229 "ControlFlow.puma"
{
# line 230 "ControlFlow.puma"
SetMaxLabel (t->ACF_DO.Label);
# line 231 "ControlFlow.puma"
CheckUpLabels (t->ACF_DO.DO_BODY);
}
return;
case kACF_ENTRY:
# line 234 "ControlFlow.puma"
{
# line 235 "ControlFlow.puma"
SetMaxLabel (t->ACF_ENTRY.Label);
}
return;
}
# line 238 "ControlFlow.puma"
{
# line 239 "ControlFlow.puma"
printf ("Unknown Tree in ControlFlow: CheckUpLabels\n");
# line 240 "ControlFlow.puma"
WriteTree (stdout, t);
# line 241 "ControlFlow.puma"
kill_in_protocol ();
}
return;
;
}
static tTree RemoveLastReturn
# if defined __STDC__ | defined __cplusplus
(register tTree t)
# else
(t)
register tTree t;
# endif
{
if (t->Kind == kACF_LIST) {
if (t->ACF_LIST.Elem->Kind == kACF_BASIC) {
if (t->ACF_LIST.Elem->ACF_BASIC.BASIC_STMT->Kind == kRETURN_STMT) {
if (t->ACF_LIST.Elem->ACF_BASIC.BASIC_STMT->RETURN_STMT.RETURN_EXP->Kind == kDUMMY_EXP) {
if (t->ACF_LIST.Next->Kind == kACF_EMPTY) {
# line 255 "ControlFlow.puma"
{
# line 257 "ControlFlow.puma"
NoReturns = NoReturns - 1;
}
return ReplaceACF (t, NoTree, t->ACF_LIST.Next);
}
}
}
}
# line 262 "ControlFlow.puma"
{
# line 263 "ControlFlow.puma"
t->ACF_LIST.Next = RemoveLastReturn (t->ACF_LIST.Next);
}
return t;
}
if (t->Kind == kACF_EMPTY) {
# line 267 "ControlFlow.puma"
return t;
}
yyAbort ("RemoveLastReturn");
}
static tTree AppendEndLabel
# if defined __STDC__ | defined __cplusplus
(register tTree t, register int label)
# else
(t, label)
register tTree t;
register int label;
# endif
{
# line 283 "ControlFlow.puma"
tTree new;
if (t->Kind == kACF_EMPTY) {
# line 287 "ControlFlow.puma"
{
# line 288 "ControlFlow.puma"
new = mACF_DUMMY ();
new->ACF_NODE.Label = label;
new->ACF_NODE.Line = 0;
new = mACF_LIST (new, t);
}
return new;
}
if (t->Kind == kACF_LIST) {
# line 296 "ControlFlow.puma"
{
# line 297 "ControlFlow.puma"
t->ACF_LIST.Next = AppendEndLabel (t->ACF_LIST.Next, label);
}
return t;
}
yyAbort ("AppendEndLabel");
}
static void ReplaceReturn
# if defined __STDC__ | defined __cplusplus
(register tTree t, register int gotolabel)
# else
(t, gotolabel)
register tTree t;
register int gotolabel;
# endif
{
if (t == NoTree) return;
switch (t->Kind) {
case kACF_LIST:
# line 315 "ControlFlow.puma"
{
# line 316 "ControlFlow.puma"
ReplaceReturn (t->ACF_LIST.Elem, gotolabel);
# line 317 "ControlFlow.puma"
ReplaceReturn (t->ACF_LIST.Next, gotolabel);
}
return;
case kACF_EMPTY:
# line 320 "ControlFlow.puma"
return;
case kACF_DUMMY:
# line 323 "ControlFlow.puma"
return;
case kACF_BASIC:
if (t->ACF_BASIC.BASIC_STMT->Kind == kRETURN_STMT) {
if (t->ACF_BASIC.BASIC_STMT->RETURN_STMT.RETURN_EXP->Kind == kDUMMY_EXP) {
# line 326 "ControlFlow.puma"
{
# line 327 "ControlFlow.puma"
t->ACF_BASIC.BASIC_STMT = mGOTO_STMT (gotolabel);
# line 328 "ControlFlow.puma"
NoReturns = NoReturns - 1;
}
return;
}
# line 331 "ControlFlow.puma"
return;
}
# line 335 "ControlFlow.puma"
return;
case kACF_IF:
# line 338 "ControlFlow.puma"
{
# line 339 "ControlFlow.puma"
ReplaceReturn (t->ACF_IF.THEN_PART, gotolabel);
# line 340 "ControlFlow.puma"
ReplaceReturn (t->ACF_IF.ELSE_PART, gotolabel);
}
return;
case kACF_WHERE:
# line 343 "ControlFlow.puma"
{
# line 344 "ControlFlow.puma"
ReplaceReturn (t->ACF_WHERE.TRUE_PART, gotolabel);
# line 345 "ControlFlow.puma"
ReplaceReturn (t->ACF_WHERE.FALSE_PART, gotolabel);
}
return;
case kACF_CASE:
# line 348 "ControlFlow.puma"
{
# line 349 "ControlFlow.puma"
ReplaceReturn (t->ACF_CASE.CASE_ALTS, gotolabel);
# line 350 "ControlFlow.puma"
ReplaceReturn (t->ACF_CASE.CASE_OTHERWISE, gotolabel);
}
return;
case kSELECTED_ACF_LIST:
# line 353 "ControlFlow.puma"
{
# line 354 "ControlFlow.puma"
ReplaceReturn (t->SELECTED_ACF_LIST.Elem, gotolabel);
# line 355 "ControlFlow.puma"
ReplaceReturn (t->SELECTED_ACF_LIST.Next, gotolabel);
}
return;
case kSELECTED_ACF_EMPTY:
# line 358 "ControlFlow.puma"
return;
case kSELECTED_ACF_NODE:
# line 361 "ControlFlow.puma"
{
# line 362 "ControlFlow.puma"
ReplaceReturn (t->SELECTED_ACF_NODE.SELECT_ACFS, gotolabel);
}
return;
case kACF_WHILE:
# line 365 "ControlFlow.puma"
{
# line 366 "ControlFlow.puma"
ReplaceReturn (t->ACF_WHILE.WHILE_BODY, gotolabel);
}
return;
case kACF_DOLOCAL:
# line 369 "ControlFlow.puma"
{
# line 370 "ControlFlow.puma"
ReplaceReturn (t->ACF_DOLOCAL.DOLOCAL_BODY, gotolabel);
}
return;
case kACF_FORALL:
# line 373 "ControlFlow.puma"
{
# line 374 "ControlFlow.puma"
ReplaceReturn (t->ACF_FORALL.FORALL_BODY, gotolabel);
}
return;
case kACF_DO:
# line 377 "ControlFlow.puma"
{
# line 378 "ControlFlow.puma"
ReplaceReturn (t->ACF_DO.DO_BODY, gotolabel);
}
return;
case kACF_ENTRY:
# line 381 "ControlFlow.puma"
return;
}
# line 384 "ControlFlow.puma"
{
# line 385 "ControlFlow.puma"
printf ("Unknown Tree in ControlFlow: ReplaceReturn\n");
# line 386 "ControlFlow.puma"
WriteTree (stdout, t);
# line 387 "ControlFlow.puma"
kill_in_protocol ();
}
return;
;
}
void BeginControlFlow ()
{
}
void CloseControlFlow ()
{
}