home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 5
/
DATAFILE_PDCD5.iso
/
utilities
/
m
/
motorola
/
!AsRef
/
Sources
/
c
/
ifd
< prev
next >
Wrap
Text File
|
1993-07-18
|
13KB
|
277 lines
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "mselect.h" /*external selection of microprocessor symbol table*/
#include "proto.h"
#include "as.h"
#include "extvars.h"
#include "structs.h"
/*
* IfMachine() --- This function implements the IFD & IFND conditional
* assembly machine. version 1.0 made for release TER_2.0 cross assembler 27
* Jun 89
*/
#define FALSE_BLOCK 0 /* values for state variable */
#define TRUE_BLOCK 1
#define POP_TEST 2
#define ELSE_TEST 3
#define FALSE 0
#define TRUE 1
void
IfMachine(int Token)
/* input token from calling machine */
/* See file as.h for definition (globals) */
{
static int State = TRUE_BLOCK, StackPt = 0, IfStack[MAXIFD];
/* State variable, pointer to "IF stack pointer" and "Stack" */
int Hiatus; /* flag to break out of FSM & resume normal
* processing */
Hiatus = FALSE; /* infinite loop to operate machine until
* time to break out */
do { /* test at end */
#ifdef DEBUG3
printf("IfMachine state=%u , token=%u\n", State, Token);
#endif
if (State == TRUE_BLOCK) /* a block of statements
* processed normally */
switch (Token) {
case IF_TRUE:
IfStack[StackPt] = TRUE;
if (++StackPt > MAXIFD) { /* check for over flow */
StackPt = MAXIFD;
error("Error:IFD/IFND nested too deep");
}
/*
* print_line() will be done in normal
* processing
*/
Hiatus = TRUE; /* resume normal line
* processing */
break;
case IF_FALSE:
IfStack[StackPt] = TRUE;
if (++StackPt > MAXIFD) { /* check for over flow */
StackPt = MAXIFD;
error("Error:IFD/IFND nested too deep");
}
if (Pass == 2 && Lflag && !N_page) /* need to print here */
print_line(); /* cuz will not return
* to normal */
Token = GetToken(); /* get next line &
* examine for IF */
State = FALSE_BLOCK; /* change state */
break;
case IF_ELSE:
if (StackPt == 0) /* bad IF nesting */
error("Error: ELSE without IF");
if (Pass == 2 && Lflag && !N_page)
print_line();
Token = GetToken(); /* get next line &
* examine for IF */
State = FALSE_BLOCK;
break;
case IF_ENDIF:
if (StackPt == 0) /* bad IF nesting */
error("Error: ENDIF without IF");
else
StackPt--; /* popped state must be
* TRUE */
Hiatus = TRUE;
break;
/*
* case NORMAL is not implemented as it
* represents normal line processing.
*/
case IF_END: /* file ended with improperly nested
* IFD */
/*
* this code can't actually be reached at
* present in a TRUE_BLOCK
*/
fatal("Error: file ended before IFD/IFND/ELSE/ENDIF");
break;
default: /* This code can't be reached at the
* present. Logically would happen if
* EOF but handled else where */
fatal("Can't get here from there.");
break;
}
else if (State == FALSE_BLOCK) /* statements not processed */
switch (Token) {
case IF_TRUE: /* doesn't make any diff. Just nest
* IFs */
case IF_FALSE:
IfStack[StackPt] = FALSE;
if (++StackPt > MAXIFD) {
StackPt = MAXIFD;
error("Error:IFD/IFND nested too deep");
}
if (Pass == 2 && Lflag && !N_page)
print_line();
Token = GetToken();
break;
case IF_ELSE:
if (Pass == 2 && Lflag && !N_page)
print_line();
State = ELSE_TEST;
break;
case IF_ENDIF:
State = POP_TEST;
break;
case IF_END: /* file ended with improperly nested
* IFD */
fatal("Fatal Error: file ended before last ENDIF");
/*
* Fatal will exit assembler. Things are too
* messed up. Include file handling is else
* where and don't want to duplicate here.
*/
break;
case IF_NORMAL: /* normal line in a FALSE
* BLOCK */
if (Pass == 2 && Lflag && !N_page)
print_line();
Token = GetToken();
break;
default:
fatal("Fatal Error: file ended before last ENDIF");
/* must be EOF or something else terrible */
break;
}
else if (State == POP_TEST) { /* pop up outside nest state */
if (StackPt == 0) { /* bad IF nesting */
error("Error: ENDIF without IF");
if (Pass == 2 && Lflag && !N_page)
print_line();
State = TRUE;
} else {
StackPt--; /* pop stack */
if (IfStack[StackPt] == TRUE) { /* back to normal */
/*
* had to come from FALSE block cuz
* TRUE block cannot be inside FALSE
* block