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

Subversion Repositories System09

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

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

Line No. Rev Author Line
1 74 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
struct nlist *lookup();
173
 
174
#ifndef IBM
175
  if (FGETS(Line,MAXBUF-1,Fd) == (char *)NULL)
176
#else
177
  if (fgets(Line,MAXBUF,Fd) == (char *)NULL)
178
#endif
179
        return(IF_EOF); /* banged into eof */
180
  Line_num++;
181
  P_force=0;
182
  N_page=0;
183
  if (!parse_line())
184
        return(IF_NORMAL);      /* comment line */
185
  if (*Op==EOS)                 /* skipping over label, probably. */
186
        return(IF_NORMAL);      /* strcmp() returns 0 if arg1 is NULL string */
187
 
188
  if (strcmp(Op,"ifd")==0)
189
        return(eval_ifd());
190
  else if (strcmp(Op,"ifnd")==0)
191
        return(eval_ifnd());
192
  else if (strcmp(Op,"else")==0)
193
        return(IF_ELSE);
194
  else if (strcmp(Op,"endif")==0)
195
        return(IF_ENDIF);
196
  else if (strcmp(Op,"end")==0)
197
        return(IF_END);
198
  else
199
        return(IF_NORMAL);      /* or might be garbage...but who cares?
200
                                   This is FALSE BLOCK */
201
}
202
 
203
 
204
/*
205
*  eval_ifd() --- evaluate an if define statement for TRUE or FALSE
206
*/
207
 
208
int
209
eval_ifd()
210
         {
211
  struct nlist *np;     /* symbol structure */
212
 
213
        if (*Operand==EOS) {
214
                warn("No symbol for IFD");
215
                return(IF_FALSE);       /* nothing to check */
216
                }
217
        if ((np=lookup(Operand)) == NULL)
218
                return(IF_FALSE);       /* not defined at all...yet */
219
        else
220
                if(np->def2 == Pass)
221
                        return(IF_TRUE); /* defined for this pass */
222
 
223
        return(IF_FALSE);       /* not defined this pass */
224
        }
225
 
226
/*
227
*  eval_ifnd() --- evaluate an if not define statement for TRUE or FALSE
228
*/
229
 
230
int
231
eval_ifnd()
232
 {
233
  struct nlist *np;     /* symbol structure */
234
 
235
        if (*Operand==EOS) {
236
                warn("No symbol for IFND");
237
                return(IF_TRUE);        /* nothing to check */
238
                }
239
        if ((np=lookup(Operand)) == NULL)
240
                return(IF_TRUE);        /* not defined at all...yet */
241
        else
242
                if(np->def2 == Pass)
243
                        return(IF_FALSE); /* defined for this pass */
244
 
245
        return(IF_TRUE);        /* not defined this pass */
246
 }

powered by: WebSVN 2.1.0

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