OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

[/] [System09/] [trunk/] [Tools/] [as09/] [ifd.c] - Blame information for rev 108

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 83 davidgb
/* IfMachine() --- This function implements the IFD & IFND conditional
2
                assembly machine.
3
                version 1.0 made for release TER_2.0 cross assembler 27 Jun 89
4
*/
5
 
6
#define FALSE_BLOCK     0       /* values for state variable */
7
#define TRUE_BLOCK      1
8
#define POP_TEST        2
9
#define ELSE_TEST       3
10
#define FALSE           0
11
#define TRUE            1
12
 
13
void IfMachine(Token)
14
int Token;      /* input token from calling machine */
15
                /* See file as.h for definition (globals) */
16
{
17
  static int State = TRUE_BLOCK, StackPt = 0, IfStack[MAXIFD];
18
                /* State variable, pointer to "IF stack pointer" and "Stack" */
19
  int Hiatus;   /* flag to break out of FSM & resume normal processing */
20
 
21
  Hiatus=FALSE; /* infinite loop to operate machine
22
                                 until time to break out */
23
  do    /* test at end */
24
   {
25
 
26
#ifdef DEBUG3
27
  printf("IfMachine state=%u , token=%u\n",State,Token);
28
#endif
29
 
30
   if (State == TRUE_BLOCK)     /* a block of statements processed normally */
31
     switch(Token) {
32
        case IF_TRUE:
33
                IfStack[StackPt]=TRUE;
34
                if (++StackPt > MAXIFD) {       /* check for over flow */
35
                        StackPt = MAXIFD;
36
                        error("Error:IFD/IFND nested too deep");
37
                        }
38
                /* print_line() will be done in normal processing */
39
                Hiatus = TRUE;  /* resume normal line processing */
40
                break;
41
        case IF_FALSE:
42
                IfStack[StackPt]=TRUE;
43
                if (++StackPt > MAXIFD) {       /* check for over flow */
44
                        StackPt = MAXIFD;
45
                        error("Error:IFD/IFND nested too deep");
46
                        }
47
                if (Pass == 2 && Lflag && !N_page)      /* need to print here */
48
                        print_line(); /* cuz will not return to normal */
49
                Token = GetToken(); /* get next line & examine for IF */
50
                State = FALSE_BLOCK; /* change state */
51
                break;
52
        case IF_ELSE:
53
                if (StackPt == 0) /* bad IF nesting */
54
                        error("Error: ELSE without IF");
55
                if (Pass == 2 && Lflag && !N_page)
56
                        print_line();
57
                Token = GetToken(); /* get next line & examine for IF */
58
                State = FALSE_BLOCK;
59
                break;
60
        case IF_ENDIF:
61
                if (StackPt == 0)       /* bad IF nesting */
62
                        error("Error: ENDIF without IF");
63
                else
64
                        StackPt--; /* popped state must be TRUE */
65
                 Hiatus = TRUE;
66
                 break;
67
        /* case NORMAL is not implemented as it represents normal line
68
                processing. */
69
        case IF_END:    /* file ended with improperly nested IFD */
70
                        /* this code can't actually be reached at present
71
                           in a TRUE_BLOCK */
72
                fatal("Error: file ended before IFD/IFND/ELSE/ENDIF");
73
                break;
74
        default:        /* This code can't be reached at the present.
75
                           Logically would happen if EOF but handled
76
                           else where */
77
                fatal("Can't get here from there.");
78
                break;
79
      }
80
   else if (State == FALSE_BLOCK)       /* statements not processed */
81
     switch(Token) {
82
        case IF_TRUE:   /* doesn't make any diff. Just nest IFs */
83
        case IF_FALSE:
84
                IfStack[StackPt]=FALSE;
85
                if (++StackPt > MAXIFD) {
86
                        StackPt = MAXIFD;
87
                        error("Error:IFD/IFND nested too deep");
88
                        }
89
                if (Pass == 2 && Lflag && !N_page)
90
                        print_line();
91
                Token = GetToken();
92
                break;
93
        case IF_ELSE:
94
             /* if (Pass == 2 && Lflag && !N_page) */
95
             /*         print_line();              */
96
                State = ELSE_TEST;
97
                break;
98
        case IF_ENDIF:
99
                State = POP_TEST;
100
                break;
101
        case IF_END:    /* file ended with improperly nested IFD */
102
                fatal("Fatal Error: file ended before last ENDIF");
103
                        /* Fatal will exit assembler.  Things are too
104
                           messed up.  Include file handling is else where
105
                           and don't want to duplicate here. */
106
                break;
107
        case IF_NORMAL: /* normal line in a FALSE BLOCK */
108
                if (Pass == 2 && Lflag && !N_page)
109
                        print_line();
110
                Token = GetToken();
111
                break;
112
        default:
113
                fatal("Fatal Error: file ended before last ENDIF");
114
                        /* must be EOF or something else terrible */
115
                break;
116
     }
117
   else if (State == POP_TEST) {        /* pop up outside nest state */
118
     if (StackPt == 0) {        /* bad IF nesting */
119
        error("Error: ENDIF without IF");
120
        if (Pass == 2 && Lflag && !N_page)
121
                        print_line();
122
        State = TRUE;
123
        }
124
     else {
125
        StackPt--;      /* pop stack */
126
        if (IfStack[StackPt] == TRUE) { /* back to normal */
127
                /* had to come from FALSE block cuz TRUE block cannot
128
                        be inside FALSE block */
129
                if (Pass == 2 && Lflag && !N_page)
130
                        print_line();
131
                State = TRUE;
132
                Hiatus = TRUE;  /* sleep for normal line processing */
133
                }
134
        else {  /* gotta be that stack == FALSE, still inside FALSE nest */
135
                if (Pass == 2 && Lflag && !N_page)
136
                        print_line();
137
                State = FALSE;
138
                Token = GetToken();
139
                }
140
          }
141
     }
142
   else if (State == ELSE_TEST) {       /* change state */
143
        if (IfStack[StackPt-1] == TRUE) {
144
                State = TRUE_BLOCK;
145
                Hiatus = TRUE;
146
                }
147
        else
148
                State = FALSE_BLOCK;
149
      }
150
   }
151
while (Hiatus == FALSE);        /* loop if not exit */
152
}
153
 
154
 
155
/* GetToken() --- get another line from within False Block and extract token
156
                as would be done in pseudo.c.  Returns token id:
157
                        IF_TRUE         IFD/IFND evaluated to TRUE
158
                        IF_FALSE        IFD/IFND evaluated to FALSE
159
                        IF_ELSE         ELSE pseudo op
160
                        IF_ENDIF        ENDIF pseudo op
161
                        IF_END          END pseudo op
162
                        IF_NORMAL       none of the above, perhaps assy code
163
                        IF_EOF          encountered end of file
164
                This function exists because conditional assembly was added
165
                as pseudo op rather than with key character ("%") and did
166
                not want to disturb original software topology */
167
 
168
int GetToken()  /* get another line and find token in it */
169
{               /* similar to make_pass() except one line at a time */
170
                /* most variables & constants are global */
171
 
172
#ifndef IBM
173
  if (FGETS(Line,MAXBUF-1,Fd) == (char *)NULL)
174
#else
175
  if (fgets(Line,MAXBUF,Fd) == (char *)NULL)
176
#endif
177
        return(IF_EOF); /* banged into eof */
178
  Line_num++;
179
  P_force=0;
180
  N_page=0;
181
  if (!parse_line())
182
        return(IF_NORMAL);      /* comment line */
183
  if (*Op==EOS)                 /* skipping over label, probably. */
184
        return(IF_NORMAL);      /* strcmp() returns 0 if arg1 is NULL string */
185
 
186
  if (strcmp(Op,"ifd")==0)
187
        return(eval_ifd());
188
  else if (strcmp(Op,"ifnd")==0)
189
        return(eval_ifnd());
190
  else if (strcmp(Op,"else")==0)
191
        return(IF_ELSE);
192
  else if (strcmp(Op,"endif")==0)
193
        return(IF_ENDIF);
194
  else if (strcmp(Op,"end")==0)
195
        return(IF_END);
196
  else
197
        return(IF_NORMAL);      /* or might be garbage...but who cares?
198
                                   This is FALSE BLOCK */
199
}
200
 
201
 
202
/*
203
*  eval_ifd() --- evaluate an if define statement for TRUE or FALSE
204
*/
205
 
206
int
207
eval_ifd()
208
         {
209
  struct nlist *np;     /* symbol structure */
210
 
211
        if (*Operand==EOS) {
212
                warn("No symbol for IFD");
213
                return(IF_FALSE);       /* nothing to check */
214
                }
215
        if ((np=lookup(Operand)) == NULL)
216
                return(IF_FALSE);       /* not defined at all...yet */
217
        else
218
                if(np->def2 == Pass)
219
                        return(IF_TRUE); /* defined for this pass */
220
 
221
        return(IF_FALSE);       /* not defined this pass */
222
        }
223
 
224
/*
225
*  eval_ifnd() --- evaluate an if not define statement for TRUE or FALSE
226
*/
227
 
228
int
229
eval_ifnd()
230
 {
231
  struct nlist *np;     /* symbol structure */
232
 
233
        if (*Operand==EOS) {
234
                warn("No symbol for IFND");
235
                return(IF_TRUE);        /* nothing to check */
236
                }
237
        if ((np=lookup(Operand)) == NULL)
238
                return(IF_TRUE);        /* not defined at all...yet */
239
        else
240
                if(np->def2 == Pass)
241
                        return(IF_FALSE); /* defined for this pass */
242
 
243
        return(IF_TRUE);        /* not defined this pass */
244
 }

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.