PL/M to C converter Part 02/03
Bob Ankeney
bob at reed.UUCP
Wed Apr 10 03:01:59 AEST 1991
#!/bin/sh
# this is part 2 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file io.c continued
#
CurArch=2
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
exit 1; fi
( read Scheck
if test "$Scheck" != $CurArch
then echo "Please unpack part $Scheck next!"
exit 1;
else exit 0; fi
) < s2_seq_.tmp || exit 1
sed 's/^X//' << 'SHAR_EOF' >> io.c
X}
X
X/*
X * Print all white space up first new-line (if any).
X * Move white_space_start to point past first new-line.
X */
Xout_pre_line(token)
XTOKEN *token;
X{
X while ((token->white_space_start < token->white_space_end) &&
X (*token->white_space_start != '\n')) {
X out_char(*token->white_space_start);
X token->white_space_start++;
X }
X}
X
X/*
X * Print all white space up to but not including last new-line.
X * Move white_space_start to point to last new-line.
X */
Xout_pre_white(token)
XTOKEN *token;
X{
X char *ptr;
X int length;
X
X for (ptr = token->white_space_end;
X (ptr > token->white_space_start) && (*(ptr - 1) != '\n') ; )
X ptr--;
X
X if (ptr == token->white_space_start)
X return;
X
X /* Compute length of white space */
X length = ptr - token->white_space_start - 1;
X
X if (length)
X out_data(token->white_space_start, length);
X
X token->white_space_start = ptr - 1;
X}
X
X/*
X * Output token name
X */
Xout_token_name(token)
XTOKEN *token;
X{
X if (is_a_type(token))
X out_type(token->token_type);
X else
X out_data(token->token_name, strlen(token->token_name));
X}
X
X/*
X * Output white space and token name
X */
Xout_token(token)
XTOKEN *token;
X{
X out_white_space(token);
X out_token_name(token);
X}
X
X/*
X * Output guaranteed white space and token name
X */
Xout_must_token(token)
XTOKEN *token;
X{
X out_must_white(token);
X out_token_name(token);
X}
X
X/*
X * Output case converted token name
X */
Xout_cvt_name(token)
XTOKEN *token;
X{
X char *ptr;
X
X for (ptr = token->token_name; *ptr; ptr++) {
X if (is_a_lc_char(*ptr))
X out_char(*ptr - 32);
X else
X if (is_a_uc_char(*ptr))
X out_char(*ptr + 32);
X else
X out_char(*ptr);
X }
X}
X
X/*
X * Output string
X */
Xout_str(string)
Xchar *string;
X{
X out_data(string, strlen(string));
X}
X
X/*
X * Output character
X */
Xout_char(ch)
Xchar ch;
X{
X out_data(&ch, 1);
X}
X
X/*
X * Output new-line if not at start of line
X */
Xout_to_start()
X{
X if (last_out_ch != LF)
X out_char(LF);
X}
X
X/*
X * Output type
X */
Xout_type(type)
Xint type;
X{
X switch (type) {
X
X case BYTE :
X#ifdef CONVERT_TYPES
X out_str(TYPE_BYTE);
X#else
X out_str("BYTE");
X#endif
X break;
X
X case WORD :
X#ifdef CONVERT_TYPES
X out_str(TYPE_WORD);
X#else
X out_str("WORD");
X#endif
X break;
X
X case DWORD :
X#ifdef CONVERT_TYPES
X out_str(TYPE_DWORD);
X#else
X out_str("DWORD");
X#endif
X break;
X
X case INTEGER :
X#ifdef CONVERT_TYPES
X out_str(TYPE_INTEGER);
X#else
X out_str("INTEGER");
X#endif
X break;
X
X case REAL :
X#ifdef CONVERT_TYPES
X out_str(TYPE_REAL);
X#else
X out_str("REAL");
X#endif
X break;
X
X case POINTER :
X out_str(TYPE_POINTER);
X break;
X
X default :
X parse_error("Unknown type");
X }
X}
X
X/*
X * Initialize variables for I/O.
X */
Xout_init()
X{
X out_string = NULL;
X last_out_ch = '\0';
X parsing_literal = FALSE;
X}
X
X/*
X * Output string constant of form 'WXYZ' in form:
X * 'W' << 24 | 'X' << 16 | 'Y' << 8 | Z
X * where len specifies the number of bytes in the string to output.
X */
Xout_str_const(str_ptr, len)
Xchar *str_ptr;
Xint len;
X{
X while (len-- && *str_ptr) {
X out_char('\'');
X if (*str_ptr == '\'')
X out_char('\\');
X out_char(*str_ptr++);
X out_char('\'');
X
X if (len) {
X out_str(" << ");
X out_str(str_shifts[len]);
X if (*str_ptr)
X out_str(" | ");
X }
X }
X}
X
X/*
X * Convert NUMERIC constant to octal constant
X */
Xcvt_octal(token, octal_string)
XTOKEN *token;
Xchar octal_string[];
X{
X int octal;
X char ch, *ptr;
X
X octal = 0;
X octal_string[0] = '\\';
X octal_string[4] = '\0';
X
X ch = *(token->token_start + token->token_length - 1);
X
X /* Determine base of numeric */
X if (ch == 'H') {
X /* Hex */
X for (ptr = token->token_name + 2; *ptr; ptr++) {
X octal *= 16;
X if ((*ptr >= '0') && (*ptr <= '9'))
X octal += *ptr - '0';
X else
X if ((*ptr >= 'A') && (*ptr <= 'Z'))
X octal += *ptr - 'A' + 10;
X else
X if ((*ptr >= 'a') && (*ptr <= 'z'))
X octal += *ptr - 'a' + 10;
X else {
X parse_error("Illegal hex character");
X return;
X }
X }
X } else
X
X if ((ch == 'O') || (ch == 'Q')) {
X /* Octal constant */
X for (ptr = token->token_name + 1; *ptr; ptr++) {
X octal *= 8;
X if ((*ptr >= '0') && (*ptr <= '7'))
X octal += *ptr - '0';
X else {
X parse_error("Illegal decimal character");
X return;
X }
X }
X } else {
X
X /* Decimal constant */
X for (ptr = token->token_name + 1; *ptr; ptr++) {
X octal *= 10;
X if ((*ptr >= '0') && (*ptr <= '9'))
X octal += *ptr - '0';
X else {
X parse_error("Illegal decimal character");
X return;
X }
X }
X }
X
X
X /* Generate octal constant */
X octal_string[1] = ((octal >> 6) & 3) + '0';
X octal_string[2] = ((octal >> 3) & 7) + '0';
X octal_string[3] = (octal & 7) + '0';
X}
SHAR_EOF
chmod 0660 io.c || echo "restore of io.c fails"
sed 's/^X//' << 'SHAR_EOF' > lit.c &&
X /*********************************************************************
X *********************************************************************
X ** **
X ** **
X ** LITERALS **
X ** **
X ** **
X ** Revision History: SCO #23 (12/11/84) **
X ** SCO #31 (02/12/86) {SCO31.DOC} **
X ** SCO #33 (06/03/86) {SCO33.DOC} **
X ** SCO #34 (10/28/86) {SCO34.DOC} **
X ** SCO #36 (07/16/86) {SCO36.DOC} **
X ** SCO #48 (03/21/87) {SCO48.DOC} **
X ** **
X *********************************************************************
X *********************************************************************/
X
X
X
X
X
X#define POWER_FAIL_SENSE_LATCH 0x0080
X#define INTERRUPT_CONTROLLER_PORT_1 0x00C0
X#define INTERRUPT_CONTROLLER_PORT_2 0x00C2
X#define INSTRUCTION_WORD_1 0x13
X#define INSTRUCTION_WORD_2 0x20
X#define INSTRUCTION_WORD_3 0x01
X#define END_OF_PARITY_INTERRUPT 0x60
X#define END_OF_EXCEPTION_INTERRUPT 0x61
X#define END_OF_REFRESH_INTERRUPT 0x62
X#define END_OF_CYCLE_INTERRUPT 0x63
X#define END_OF_SHORT_INTERRUPT 0x67
X#define INTERRUPT_CONTROLLER_MASK_0 0x0F0
X#define INTERRUPT_CONTROLLER_MASK_1 0x0FC
X#define INTERRUPT_CONTROLLER_MASK_2 0x0F8
X#define INTERRUPT_CONTROLLER_MASK_3 0x0F4
X#define INTERVAL_TIMER_PORT_1 0x0D2
X#define INTERVAL_TIMER_PORT_2 0x0D6
X#define CONTROL_WORD 0x74
X#define DATA_WORD_1 0x12
X#define DATA_WORD_2 0x7A
X#define CONTROL_WORD_87 0x033C
X#define DPM_CONTROL_WORD_87 0x0F3C
X#define BIT_CONTROL_WORD_87 0x0F3C
X#define INTERFACE_1_START_CODE 0x01
X#define INTERFACE_2_START_CODE 0x01
X#define HCP_NORMAL 0x00
X#define HCP_TEST_MODE 0x01
X#define HCP_ADVANCE 0x02
X#define HCP_RESET 0x03
X#define HCP_ALTITUDE_HOLD_RESET 0x04
X#define HCP_FAIL 0x07
X
X#define IS =
X#define VALID 0x55
X#define NO_COMPUTED_DATA 0x66
X#define FUNCTIONAL_TEST 0x99
X#define TEST_MODE 0x0AA /*{SCO36.DOC}*/
X#define FLIGHT_MODE 0x55 /*{SCO36.DOC}*/
X#define POSITIVE_BIAS 0 /*{SCO31.DOC}*/
X#define NEGATIVE_BIAS 1 /*{SCO31.DOC}*/
X#define RESET 0x0AA
X#define PASS 0x55
X#define ON 0x55
X#define TO_VOR 0x55
X#define FROM_VOR 0x99
X#define ILS 0x55 /*{SCO48.DOC}*/
X#define VOR 0x0AA /*{SCO48.DOC}*/
X#define INVALID 0x0AA
X#define OFF 0x0AA
X#define PUSHED 0x55
X#define SET 0x55
X#define FAIL 0x0AA
X#define FAILED 0x0FF
X#define VMC 4
X#define IMC 5
X#define CRZ 6
X#define TOGA 7
X#define BLANK 10
X#define NEGATIVE_SIGN 11
X
X#define ERROR_DISPLAY 0x5554
X#define PFM_KEY_COUNTER 0x5555
X#define PFM_TIMER 0x5556
X#define COMPUTER_FAULT 0x5557
X#define KEY1 5
X#define KEY2 4
X#define KEY3 3
X#define KEY4 2
X#define KEY5 1
X#define KEY6 0
X#define DISPLAY_GENERATOR_PORT 0x0C000
X#define DISPLAY_GENERATOR_HALT_CODE 3
X#define DISPLAY_GENERATOR_START_CODE 4
X#define DISPLAY_HALT_ENABLE_CODE 0
X#define DG_HALT 0x0005
X#define LOAD_ROTATION_ANGLE 0x0007
X#define LOAD_PRESENT_POSITION 0x0008
X#define DRAW_VECTOR 0x0009
X#define LOAD_BORDERS 0x000D
X#define ZERO_DEGREE_ANGLE 0
X#define NINETY_DEGREE_ANGLE 0x4000
X#define NEG_NINETY_DEGREE_ANGLE 0x0C000
X#define ONE_EIGHTY_DEGREE_ANGLE 0x8000
X#define FIRST_HALF_OF_BUFFER 0
X#define SECOND_HALF_OF_BUFFER 750
X#define WINDOW_COMPARATOR_FAIL 0
X#define WINDOW_COMPARATOR_PASS 7
X#define TWENTY_CYCLES 20
X#define FORTY_CYCLES 40
X
X#define IOS1_CODE_CHECKSUM_ERROR 0x11 /*{SCO31.DOC}*/
X#define IOS1_RAM_ERROR 0x12 /*{SCO31.DOC}*/
X#define IOS1_80186_ERROR 0x13 /*{SCO31.DOC}*/
X#define IOS1_8087_ERROR 0x14 /*{SCO31.DOC}*/
X#define IOS1_CONVERTOR_ERROR 0x15 /*{SCO31.DOC}*/
X#define IOS1_HUD_POWER_SUPPLY_ERROR 0x16 /*{SCO31.DOC}*/
X#define IOS2_CODE_CHECKSUM_ERROR 0x21 /*{SCO31.DOC}*/
X#define IOS2_RAM_ERROR 0x22 /*{SCO31.DOC}*/
X#define IOS2_80186_ERROR 0x23 /*{SCO31.DOC}*/
X#define IOS2_8087_ERROR 0x24 /*{SCO31.DOC}*/
X#define IOS2_CONVERTOR_ERROR 0x25 /*{SCO31.DOC}*/
X#define CLP_CODE_CHECKSUM_ERROR 0x31 /*{SCO31.DOC}*/
X#define CLP_RAM_ERROR 0x32 /*{SCO31.DOC}*/
X#define CLP_8086_ERROR 0x33 /*{SCO31.DOC}*/
X#define CLP_8087_ERROR 0x34 /*{SCO31.DOC}*/
X#define SM_CODE_CHECKSUM_ERROR 0x41 /*{SCO31.DOC}*/
X#define SM_RAM_ERROR 0x42 /*{SCO31.DOC}*/
X#define SM_8086_ERROR 0x43 /*{SCO31.DOC}*/
X#define SM_8087_ERROR 0x44 /*{SCO31.DOC}*/
X#define SYSTEM_MONITOR_INACTIVE 0x45 /*{SCO31.DOC}*/
X#define DISPLAY_GENERATOR_ERROR 0x51 /*{SCO31.DOC}*/
X#define SYMBOL_MISPOSITIONED_1 0x52 /*{SCO31.DOC}*/
X#define OHU_VIDEO_FAIL 0x63 /*{SCO31.DOC}*/
X#define OHU_HVPS_FAIL 0x64 /*{SCO31.DOC}*/
X#define OHU_95_OR_30_VOLT_SUPPLY_FAIL 0x65 /*{SCO31.DOC}*/
X#define SYMBOL_MISPOSITIONED_2 0x71 /*{SCO31.DOC}*/
X#define WINDOW_COMPARATOR_ERROR 0x77 /*{SCO31.DOC}*/
X#define DEU_VERTICAL_DEFLECTION_FAIL 0x7A /*{SCO31.DOC}*/
X#define DEU_HORIZONTAL_DEFLECTION_FAIL 0x7B /*{SCO31.DOC}*/
X#define DEU_DC_SUPPLY_FAIL 0x7C /*{SCO31.DOC}*/
X#define DEU_BOOST_SUPPLY_FAIL 0x7D /*{SCO31.DOC}*/
X#define DEU_DEFLECTION_SUPPLY_FAIL 0x7E /*{SCO31.DOC}*/
X#define TEST_ERROR_DISPLAY 0x88
X#define DISPLAY_GENERATOR_TEST 0x89
X#define HCP_FAILURE 0x91 /*{SCO31.DOC}*/
X#define RSU_FAILURE 0x0A1 /*{SCO34.DOC}*/
X#define COMBINER_NOT_LOCKED 0x0B1 /*{SCO33.DOC}*/
X#define EIGHTH_SECOND 3
X#define ONE_SIXTH_SECOND 3
X#define QUARTER_SECOND 5
X#define ONE_THIRD_SECOND 6
X#define HALF_SECOND 10
X#define ONE_SECOND 20
X#define ONE_POINT_FIVE_SECONDS 30
X#define TWO_SECONDS 40
X#define FIVE_SECONDS 100
X
X#define HALF_PI 1.57079633F
X#define PI 3.14159265F
X#define TWO_PI 6.28318531F
X#define TEN_KNOTS 16.9F
X#define TEN_DEGREES 0.1745F
X#define FIFTEEN_DEGREES 0.2618F
X#define MAXIMUM_NUMBER 99999.9F
X
X#define FOREVER while (1)
X
SHAR_EOF
chmod 0660 lit.c || echo "restore of lit.c fails"
sed 's/^X//' << 'SHAR_EOF' > main.c &&
X#include <stdio.h>
X#ifdef IBMPC
X#include <stdlib.h>
X#include <sys\stat.h>
X#else
X#include <sys/types.h>
X#include <sys/stat.h>
X#endif
X#include <fcntl.h>
X#include "misc.h"
X#include "defs.h"
X#include "cvt.h"
X#include "struct.h"
X#include "tokens.h"
X#include "tkn_defs.h"
X
Xchar *text_buffer, *text_ptr;
Xint line_count;
Xchar *line_ptr;
Xchar current_file_name[128];
Xchar out_file_name[128];
Xint at_decl_count;
Xchar at_decl_list[MAX_AT_DECLS][MAX_TOKEN_LENGTH];
XFILE *ofd;
X
Xint file_depth;
X
XFILE *fopen();
X
X/*
X * Get list of AT declaration variables for EXTERNAL declaration checks
X */
Xget_at_decl()
X{
X int i, fd;
X char ch;
X
X at_decl_count = 0;
X if ((fd = open("at_decl.cvt", O_RDONLY)) == -1)
X /* Not found */
X return;
X
X while (read(fd, &ch, 1) == 1) {
X i = 0;
X if (!is_a_char(ch)) {
X fprintf(stderr, "Illegal identifier in line %d at_decl.cvt\n",
X at_decl_count + 1);
X exit(1);
X }
X do {
X#ifdef CONVERT_CASE
X if (is_a_uc_char(ch))
X /* Convert to lower case */
X ch += 32;
X else
X if (is_a_lc_char(ch))
X /* Convert to upper case */
X ch -= 32;
X#endif
X at_decl_list[at_decl_count][i++] = ch;
X if (read(fd, &ch, 1) != 1) {
X fprintf(stderr, "Unexpected EOF in at_decl.cvt\n");
X exit(1);
X }
X } while ((ch != '\n') && (ch != ' '));
X
X at_decl_list[at_decl_count++][i] = '\0';
X }
X}
X
X/*
X * Open specified file, init options, and parse.
X */
Xcvt_file(file_name)
Xchar *file_name;
X{
X int fd, nr;
X struct stat file_stat;
X TOKEN token, fname_token, token_module, token_do;
X int token_class;
X char *tmp_text_buffer, *tmp_text_ptr, *tmp_line_ptr;
X char *tmp_ptr;
X int tmp_line_count;
X char tmp_file_name[128];
X
X char *get_mem();
X
X /* Is this the first file? */
X if (file_depth) {
X /* No - save old text pointers */
X tmp_text_buffer = text_buffer;
X tmp_text_ptr = text_ptr;
X tmp_line_ptr = line_ptr;
X tmp_line_count = line_count;
X (void) strcpy(tmp_file_name, current_file_name);
X }
X
X /* Save file name */
X (void) strcpy(current_file_name, file_name);
X
X /* Open file */
X if ((fd = open(file_name, O_RDONLY)) == -1) {
X (void) fprintf(stderr, "Cannot open input file %s", file_name);
X perror("");
X exit(1);
X }
X
X /* Get length */
X if (fstat(fd, &file_stat)) {
X perror("Cannot stat input file");
X exit(1);
X }
X
X /* Allocate that much RAM */
X text_buffer = get_mem((unsigned int) file_stat.st_size + 1);
X
X /* Read file */
X if ((nr = read(fd, text_buffer, (int) file_stat.st_size)) == -1) {
X perror("Cannot read input file");
X exit(1);
X }
X
X /* Insert End-of-file Mark */
X text_buffer[nr] = '\0';
X (void) close(fd);
X
X /* Init pointers */
X text_ptr = text_buffer;
X line_ptr = text_ptr;
X line_count = 1;
X
X /* Init I/O */
X out_init();
X
X /* Start with initial context using file name */
X (void) strcpy(fname_token.token_name, file_name);
X fname_token.token_class = IDENTIFIER;
X new_context(MODULE, &fname_token);
X
X /* Is this the first file? */
X if (file_depth++ == 0) {
X /* Yes - open output file */
X if ((ofd = fopen(out_file_name, "w")) == NULL) {
X (void) fprintf(stderr, "Cannot create output file %s",
X out_file_name);
X exit(1);
X }
X
X /* Check for module name */
X token_class = get_token(&token_module);
X out_pre_white(&token_module);
X tmp_ptr = token_module.token_start;
X if ((token_class == IDENTIFIER) &&
X /* Maybe got module name - Check for : */
X (get_token(&token) == LABEL) &&
X /* Check for DO; */
X ((get_token(&token_do) == RESERVED) &&
X (token_do.token_type == DO)) &&
X (get_token(&token) == END_OF_LINE)) {
X
X /* Got module header */
X out_pre_white(&token_do);
X
X /* Parse to END [<module name>] */
X parse_till_end(&token);
X out_white_space(&token);
X
X token_class = get_token(&token);
X if (token_class == IDENTIFIER) {
X out_pre_white(&token);
X token_class = get_token(&token);
X }
X
X /* Should be at end of line */
X if (token_class != END_OF_LINE) {
X parse_error("';' expected");
X }
X
X /* Should be at end of file */
X if (get_token(&token) != END_OF_FILE) {
X parse_error("End of file expected");
X }
X out_white_space(&token);
X } else {
X out_pre_white(&token_do);
X parse_warning("Module name expected");
X text_ptr = tmp_ptr;
X parse_file();
X }
X } else
X parse_file();
X
X free(text_buffer);
X
X /* Was this the first file? */
X if (--file_depth) {
X /* No - restore old text pointers */
X text_buffer = tmp_text_buffer;
X text_ptr = tmp_text_ptr;
X line_ptr = tmp_line_ptr;
X line_count = tmp_line_count;
X (void) strcpy(current_file_name, tmp_file_name);
X } else
X exit(0);
X}
X
X/*
X * Open file and init options
X */
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X int i;
X char ch;
X
X if (argc != 2) {
X (void) fprintf(stderr, "usage: %s filename\n", argv[0]);
X exit(1);
X }
X
X /* Search for a '.' in filename */
X for (i = strlen(argv[1]) - 1; i; i--) {
X ch = argv[1][i];
X if ((ch == '.') || (ch == '/') || (ch == '\\'))
X break;
X }
X
X if (ch != '.')
X i = strlen(argv[1]);
X
X /* Append a '.c' */
X (void) strncpy(out_file_name, argv[1], i);
X out_file_name[i] = '\0';
X (void) strcat(out_file_name, ".c");
X (void) printf("Output to: %s\n", out_file_name);
X
X /* Get AT declaration list */
X get_at_decl();
X
X /* Init context */
X init_context();
X
X file_depth = 0;
X
X /* Parse main file */
X cvt_file(argv[1]);
X}
SHAR_EOF
chmod 0660 main.c || echo "restore of main.c fails"
sed 's/^X//' << 'SHAR_EOF' > makefile &&
X# Makefile for Unix
X
XSRCS = convert.c \
X parse.c \
X declare.c \
X decl_out.c \
X control.c \
X io.c \
X token.c \
X context.c \
X mem.c \
X error.c \
X version.c \
X main.c
X
XOBJS = convert.o \
X parse.o \
X declare.o \
X decl_out.o \
X control.o \
X io.o \
X token.o \
X context.o \
X mem.o \
X error.o \
X version.o \
X main.o
X
XLNKS = convert parse declare decl_out control io token context mem error version main
X
XTOKEN_HDRS = misc.h defs.h struct.h cvt.h cvt_id.h tokens.h
XHDRS = $(TOKEN_HDRS) tkn_defs.h tkn_ext.h
X
XOPTS = -c -O
X
Xplm2c: $(OBJS)
X $(CC) -o plm2c $(OBJS)
X
Xconvert.o: convert.c $(TOKEN_HDRS)
X $(CC) $(OPTS) convert.c
X
Xparse.o: parse.c $(TOKEN_HDRS) cvt_id.h
X $(CC) $(OPTS) parse.c
X
Xdeclare.o: declare.c $(TOKEN_HDRS)
X $(CC) $(OPTS) declare.c
X
Xcontrol.o: control.c $(TOKEN_HDRS) tkn_ext.h
X $(CC) $(OPTS) control.c
X
Xdecl_out.o: decl_out.c $(TOKEN_HDRS)
X $(CC) $(OPTS) decl_out.c
X
Xio.o: io.c $(TOKEN_HDRS) tkn_ext.h
X $(CC) $(OPTS) io.c
X
Xtoken.o: token.c $(TOKEN_HDRS) tkn_ext.h
X $(CC) $(OPTS) token.c
X
Xcontext.o: context.c $(TOKEN_HDRS)
X $(CC) $(OPTS) context.c
X
Xmem.o: mem.c $(TOKEN_HDRS)
X $(CC) $(OPTS) mem.c
X
Xerror.o: error.c $(TOKEN_HDRS)
X $(CC) $(OPTS) error.c
X
Xversion.o: version.c
X $(CC) $(OPTS) version.c
X
Xmain.o: main.c $(TOKEN_HDRS) tkn_defs.h
X $(CC) $(OPTS) main.c
X
Xbackup:
X cp $(HDRS) Makefile bak
X cp $(SRCS) bak
X
Xlint:
X lint $(SRCS)
X
Xclean:
X rm -f $(OBJS)
SHAR_EOF
chmod 0660 makefile || echo "restore of makefile fails"
sed 's/^X//' << 'SHAR_EOF' > makefile.ibm &&
X# Makefile for IBM-PC MSDOS
X
XSRCS = convert.c \
X parse.c \
X declare.c \
X decl_out.c \
X control.c \
X io.c \
X token.c \
X context.c \
X mem.c \
X error.c \
X version.c \
X main.c
X
XOBJS = convert.obj \
X parse.obj \
X declare.obj \
X decl_out.obj \
X control.obj \
X io.obj \
X token.obj \
X context.obj \
X mem.obj \
X error.obj \
X version.obj \
X main.obj
X
XLNKS = convert parse declare decl_out control io token context mem error version main
X
XTOKEN_HDRS = misc.h defs.h struct.h cvt.h cvt_id.h tokens.h
XHDRS = $(TOKEN_HDRS) tkn_defs.h tkn_ext.h
X
XMDL = m
XOPTS = -c -N -v -DIBMPC -m$(MDL)
X
Xplm2c: $(OBJS)
X tlink /c /v c:\tc\lib\c0$(MDL) $(LNKS), plm2c, plm2c, c:\tc\lib\c$(MDL)
X
Xconvert.obj: convert.c $(TOKEN_HDRS)
X tcc $(OPTS) convert
X
Xparse.obj: parse.c $(TOKEN_HDRS) cvt_id.h
X tcc $(OPTS) parse
X
Xdeclare.obj: declare.c $(TOKEN_HDRS)
X tcc $(OPTS) declare
X
Xcontrol.obj: control.c $(TOKEN_HDRS) tkn_ext.h
X tcc $(OPTS) control
X
Xdecl_out.obj: decl_out.c $(TOKEN_HDRS)
X tcc $(OPTS) decl_out
X
Xio.obj: io.c $(TOKEN_HDRS) tkn_ext.h
X tcc $(OPTS) io
X
Xtoken.obj: token.c $(TOKEN_HDRS) tkn_ext.h
X tcc $(OPTS) token
X
Xcontext.obj: context.c $(TOKEN_HDRS)
X tcc $(OPTS) context
X
Xmem.obj: mem.c $(TOKEN_HDRS)
X tcc $(OPTS) mem
X
Xerror.obj: error.c $(TOKEN_HDRS)
X tcc $(OPTS) error
X
Xversion.obj: version.c
X tcc $(OPTS) version
X
Xmain.obj: main.c $(TOKEN_HDRS) tkn_defs.h
X tcc $(OPTS) main
X
Xbackup:
X cp $(HDRS) Makefile bak
X cp $(SRCS) bak
X
Xfloppy:
X cp $(HDRS) makefile a:
X cp $(SRCS) a:
X
Xlint:
X lint $(SRCS)
X
SHAR_EOF
chmod 0660 makefile.ibm || echo "restore of makefile.ibm fails"
sed 's/^X//' << 'SHAR_EOF' > mem.c &&
X#ifdef IBMPC
X#include <alloc.h>
X#endif
X#include "misc.h"
X#include "defs.h"
X#include "cvt.h"
X#include "struct.h"
X
X/*
X * Memory allocation and deallocation routines.
X */
X
X/*
X * Allocate memory
X */
Xchar *get_mem(size)
Xunsigned int size;
X{
X char *malloc_ptr;
X void *malloc();
X
X if ((malloc_ptr = (char *)malloc(size)) == NULL) {
X parse_error("Out of memory");
X exit(1);
X }
X return malloc_ptr;
X}
X
X/*
X * Generate a new context.
X */
Xget_context_ptr(context)
XCONTEXT **context;
X{
X *context = (CONTEXT *) get_mem(sizeof(CONTEXT));
X (*context)->decl_head = NULL;
X (*context)->next_context = NULL;
X}
X
X/*
X * Malloc memory for a TOKEN.
X */
Xget_token_ptr(token)
XTOKEN **token;
X{
X *token = (TOKEN *) get_mem(sizeof(TOKEN));
X}
X
X/*
X * Malloc memory for a DECL_ID.
X */
Xget_var_ptr(var)
XDECL_ID **var;
X{
X *var = (DECL_ID *) get_mem(sizeof(DECL_ID));
X (*var)->name = NULL;
X (*var)->based_name = NULL;
X (*var)->next_var = NULL;
X (*var)->is_ext_at = FALSE;
X}
X
X/*
X * Free a linked list of variables.
X */
Xfree_var_list(list_ptr)
XDECL_ID *list_ptr;
X{
X DECL_ID *next_ptr;
X
X while (list_ptr) {
X if (list_ptr->name)
X free( (char *) list_ptr->name);
X if (list_ptr->based_name)
X free( (char *) list_ptr->based_name);
X next_ptr = list_ptr->next_var;
X free((char *) list_ptr);
X list_ptr = next_ptr;
X }
X}
X
X/*
X * Malloc space for a DECL_MEMBER structure and return pointer.
X */
Xget_element_ptr(element)
XDECL_MEMBER **element;
X{
X DECL_MEMBER *el_ptr;
X
X /* Malloc space for element */
X el_ptr = (DECL_MEMBER *) get_mem(sizeof(DECL_MEMBER));
X
X /* Init pointers */
X el_ptr->name_list = NULL;
X el_ptr->literal = NULL;
X#ifdef PARSE_LITERALS
X el_ptr->literal_token = NULL;
X#endif
X el_ptr->array_bound = NULL;
X el_ptr->type = NULL;
X el_ptr->struct_list = NULL;
X el_ptr->at_ptr = NULL;
X el_ptr->init_ptr = NULL;
X el_ptr->next_member = NULL;
X
X el_ptr->attributes = NONE;
X el_ptr->initialization = NONE;
X
X *element = el_ptr;
X}
X
X/*
X * Free a DECL_MEMBER list.
X */
Xfree_decl_list(element)
XDECL_MEMBER *element;
X{
X DECL_MEMBER *el_ptr;
X
X while (element) {
X if (element->name_list)
X free_var_list(element->name_list);
X if (element->literal)
X free((char *) element->literal);
X if (element->array_bound)
X free((char *) element->array_bound);
X if (element->type)
X free((char *) element->type);
X if (element->struct_list)
X free_decl_list(element->struct_list);
X if (element->at_ptr)
X free(element->at_ptr);
X
X el_ptr = element->next_member;
X free((char *) element);
X element = el_ptr;
X }
X}
X
X/*
X * Malloc space for a procedure parameter
X */
Xget_param_ptr(param)
XPARAM_LIST **param;
X{
X *param = (PARAM_LIST *) get_mem(sizeof(PARAM_LIST));
X (*param)->next_param = NULL;
X}
X
X/*
X * Free parameter list
X */
Xfree_param_list(param_list)
XPARAM_LIST *param_list;
X{
X PARAM_LIST *param_ptr;
X
X while (param_list) {
X param_ptr = param_list->next_param;
X free((char *) param_list);
X param_list = param_ptr;
X }
X}
X
X/*
X * Malloc space for a DECLARE statement
X */
Xget_decl_ptr(decl)
XDECL **decl;
X{
X *decl = (DECL *) get_mem(sizeof(DECL));
X (*decl)->decl_list = NULL;
X (*decl)->next_decl = NULL;
X}
X
X/*
X * Free DECL list
X */
Xfree_decl(decl_list)
XDECL *decl_list;
X{
X DECL *decl_ptr;
X
X while (decl_list) {
X decl_ptr = decl_list->next_decl;
X#ifdef FREE_DECL_TOKEN
X if (decl_list->decl_token)
X free((char *) decl_list->decl_token);
X#endif
X if (decl_list->decl_list)
X free_decl_list(decl_list->decl_list);
X free((char *) decl_list);
X decl_list = decl_ptr;
X }
X}
X
X
SHAR_EOF
chmod 0660 mem.c || echo "restore of mem.c fails"
sed 's/^X//' << 'SHAR_EOF' > misc.h &&
X/*
X * Miscellaneous defines
X */
Xtypedef unsigned char BYTE;
Xtypedef unsigned char BOOLEAN;
X
X
X#ifndef TRUE
X#define TRUE 1
X#endif
X
X#ifndef FALSE
X#define FALSE 0
X#endif
X
X#ifndef NULL
X#define NULL 0
X#endif
X
X/*
X * White space characters
X */
X#define SPACE ' '
X#define TAB 9
X#define CR 13
X#define LF 10
X
X/*
X * Useful defines
X */
X#define is_a_uc_char(char) ((char >= 'A') && (char <= 'Z'))
X#define is_a_lc_char(char) ((char >= 'a') && (char <= 'z'))
X#define is_a_char(char) (((char & 0x5F) >= 'A') && ((char & 0x5F) <= 'Z'))
X#define is_a_digit(char) ((char >= '0') && (char <= '9'))
X
X#define is_a_type(token) ((token->token_class == RESERVED) && \
X (token->token_type >= BYTE) && (token->token_type <= REAL))
X
X#define is_white(ch) ((ch == ' ') || (ch == TAB))
X
X#define NONE 0
X
Xchar *strcat(), *strncat(), *strcpy(), *strncpy();
X#ifdef IBMPC
Xint sprintf();
X#endif
SHAR_EOF
chmod 0660 misc.h || echo "restore of misc.h fails"
sed 's/^X//' << 'SHAR_EOF' > parse.c &&
X#include <stdio.h>
X#ifdef IBMPC
X#include <stdlib.h>
X#endif
X#include "misc.h"
X#include "defs.h"
X#include "cvt.h"
X#include "struct.h"
X#include "cvt_id.h"
X#include "tokens.h"
X
Xextern char *text_buffer, *text_ptr;
Xextern int line_count;
Xextern char *out_string;
X
X/*
X * Parse a procedure parameter list.
X * Return head of linked list of parameters.
X */
Xget_param_list(param_head)
XPARAM_LIST **param_head;
X{
X PARAM_LIST *list_ptr, *param_ptr;
X int token_class;
X TOKEN sep_token;
X
X *param_head = NULL;
X list_ptr = NULL;
X
X do {
X get_param_ptr(¶m_ptr);
X if (*param_head == NULL)
X *param_head = param_ptr;
X if (list_ptr)
X list_ptr->next_param = param_ptr;
X list_ptr = param_ptr;
X token_class = get_token(¶m_ptr->param);
X if (token_class != IDENTIFIER) {
X parse_error("Identifier expected");
X free_param_list(*param_head);
X }
X /* Get ',' or ')' */
X token_class = get_token(&sep_token);
X } while (token_class == COMMA);
X
X if (token_class != RIGHT_PAREN) {
X parse_error("')' expected");
X free_param_list(*param_head);
X }
X}
X
X/*
X * Parse parameter list.
X * Parse DECLARE statements until all parameters in param_list
X * have been found. Split declare statements into those used in
X * param_list and those not. Return pointers to head of both
X * DECL_MEMBER lists.
X */
Xparse_param_list(param_list, decl_list, extra_decl_list)
XPARAM_LIST *param_list;
XDECL **decl_list, **extra_decl_list;
X{
X DECL *extra_decl, *extra_decl_ptr;
X DECL *list, *list_ptr;
X DECL_MEMBER *extra_list_ptr;
X DECL_MEMBER *el_ptr, *last_el_ptr, *next_el_ptr;
X DECL_MEMBER *extra_el_ptr;
X int token_class;
X TOKEN *decl_token;
X DECL_ID *var_ptr, *last_var_ptr, *next_var_ptr;
X DECL_ID *extra_last_var_ptr;
X PARAM_LIST *param_ptr, *last_param;
X
X *decl_list = NULL;
X *extra_decl_list = NULL;
X /* Pointer to next DECL_MEMBER in decl_ptr */
X list_ptr = NULL;
X /* Pointer to next DECL in extra_decl_list */
X extra_decl_ptr = NULL;
X
X while (param_list) {
X /* Get declaration */
X get_token_ptr(&decl_token);
X token_class = get_token(decl_token);
X if ((token_class != RESERVED) ||
X (decl_token->token_type != DECLARE)) {
X parse_error("DECLARE expected");
X free((char *) decl_token);
X return;
X }
X /* Get declaration list */
X get_decl_ptr(&list);
X get_decl_list(list);
X list->decl_token = decl_token;
X
X /* Points to start of extra declaration list */
X extra_list_ptr = NULL;
X
X /* Pointer to previous el_ptr */
X last_el_ptr = NULL;
X
X /* Check each element of the DECLARE statement */
X el_ptr = list->decl_list;
X while (el_ptr) {
X
X /* Point to next member */
X next_el_ptr = el_ptr->next_member;
X
X /* Pointer to next DECL_MEMBER in extra_decl_ptr */
X extra_el_ptr = NULL;
X
X /* Points to last variable in variable list */
X last_var_ptr = NULL;
X /* Contains not found variables in name_list */
X extra_last_var_ptr = NULL;
X
X /* Check each variable in name list */
X for (var_ptr = el_ptr->name_list; var_ptr; ) {
X /* Point to following var_ptr */
X next_var_ptr = var_ptr->next_var;
X
X /* Is this variable in param list? */
X last_param = NULL;
X for (param_ptr = param_list; param_ptr;
X param_ptr = param_ptr->next_param) {
X if (!strcmp(param_ptr->param.token_name,
X var_ptr->name->token_name))
X break;
X else
X last_param = param_ptr;
X }
X
X if (param_ptr) {
X
X /* Variable found */
X /* Remove from parameter list */
X if (last_param)
X last_param->next_param = param_ptr->next_param;
X else
X param_list = param_ptr->next_param;
X
X free((char *) param_ptr);
X last_var_ptr = var_ptr;
X } else {
X/*
X * Variable not found - Add to extra variable list
X */
X if (extra_el_ptr == NULL) {
X/*
X * Create new element and copy DECLARE info
X */
X get_element_ptr(&extra_el_ptr);
X element_copy(el_ptr, extra_el_ptr);
X extra_last_var_ptr = NULL;
X/*
X * Link new extra element into extra_list_ptr
X */
X if (extra_list_ptr) {
X extra_list_ptr->next_member = extra_el_ptr;
X } else {
X/*
X * Create new extra declaration
X */
X get_decl_ptr(&extra_decl);
X
X /* Point to DECLARE token */
X extra_decl->decl_token =
X list->decl_token;
X extra_decl->decl_list = extra_el_ptr;
X/*
X * Link new extra declaration into extra_decl_list
X */
X if (extra_decl_ptr)
X extra_decl_ptr->next_decl = extra_decl;
X else
X *extra_decl_list = extra_decl;
X
X extra_decl_ptr = extra_decl;
X }
X extra_list_ptr = extra_el_ptr;
X }
X
X /* Add var_ptr to extra list */
X if (extra_last_var_ptr)
X extra_last_var_ptr->next_var = var_ptr;
X else
X extra_list_ptr->name_list = var_ptr;
X
X extra_last_var_ptr = var_ptr;
X
X /* Remove from DECLARE list */
X if (last_var_ptr)
X last_var_ptr->next_var = next_var_ptr;
X else
X el_ptr->name_list = next_var_ptr;
X
X var_ptr->next_var = NULL;
X }
X
X var_ptr = next_var_ptr;
X }
X
X/*
X * Check for empty name list
X */
X if (el_ptr->name_list == NULL) {
X/*
X * Empty name list - unlink and discard element from declaration list
X */
X if (last_el_ptr)
X last_el_ptr->next_member = next_el_ptr;
X else
X list->decl_list = next_el_ptr;
X
X el_ptr->next_member = NULL;
X free((char *) el_ptr);
X } else
X last_el_ptr = el_ptr;
X
X el_ptr = next_el_ptr;
X }
X
X /* Save found items in decl_list */
X if (list->decl_list->name_list) {
X if (*decl_list)
X list_ptr->next_decl = list;
X else
X *decl_list = list;
X list_ptr = list;
X } else
X free((char *) list);
X
X }
X}
X
X/*
X * Parse until desired token type appears
X */
Xparse_till(type, token)
Xint type;
XTOKEN *token;
X{
X while (get_token(token) != type)
X out_token(token);
X}
X
X/*
X * Parse until END statement
X */
Xparse_till_end(token)
XTOKEN *token;
X{
X int token_class;
X
X while (1) {
X token_class = get_token(token);
X
X if (token_class == END_OF_FILE) {
X parse_error("Premature end-of-file");
X exit(1);
X }
X
X if ((token_class == RESERVED) && (token->token_type == END))
X return;
X
X parse_statement(token);
X }
X}
X
X/*
X * Parse through END statement
X */
Xparse_to_end()
X{
X TOKEN token;
X
X parse_till_end(&token);
X parse_statement(&token);
X}
X
X/*
X * Check for end of line (';')
X */
Xcheck_eol()
X{
X TOKEN token;
X
X if (get_token(&token) != END_OF_LINE)
X parse_error("';' expected");
X else
X out_token(&token);
X}
X
X/*
X * Parse simple variable and return variable token and following token.
X * Passed with initial identifier in token.
X * Returns with next_token terminating variable.
X * Handles [ .<identifier> ] ...
X */
Xparse_simple_variable(token, next_token)
XTOKEN *token, *next_token;
X{
X int token_class;
X
X while (1) {
X token_class = get_token(next_token);
X if (token_class != PERIOD)
X return token_class;
X
X /* Process .<identifier> */
X token_class = get_token(next_token);
X if (token_class != IDENTIFIER) {
X parse_error("Illegal identifier");
X return ERROR;
X }
X /* Add .<identifier> to original token name */
X (void) strcat(token->token_name, ".");
X (void) strcat(token->token_name, next_token->token_name);
X /* Parse for additional member */
X return parse_simple_variable(token, next_token);
X }
X}
X
X/*
X * Parse variable identifier. If pointer, output (*ident) else
X * If variable has BASED attribute, output (*based_name).
X * Otherwise, output ident.
X */
Xout_ident(ident, decl, decl_id)
XTOKEN *ident;
XDECL_MEMBER *decl;
XDECL_ID *decl_id;
X{
X if (decl->at_ptr || decl_id->is_ext_at) {
X out_white_space(ident);
X out_str("(*");
X out_token_name(ident);
X out_char(')');
X } else
X
X if (decl_id->based_name) {
X out_white_space(ident);
X out_str("(**");
X out_token_name(decl_id->name);
X out_char(')');
X } else
X out_token(ident);
X}
X
X/*
X * Parse variable name or structure element and output appropriate tokens.
X * Passed with identifier in token, and declaration for token in decl.
X * Returns with token terminating variable.
X * Handles <member> { [ ( <expression> ) ] [ .<identifier> ] }
X */
Xparse_member(token, decl, decl_id)
XTOKEN *token;
XDECL_MEMBER *decl;
XDECL_ID *decl_id;
X{
X int token_class;
X TOKEN member;
X DECL_MEMBER *var_decl;
X DECL_ID *var_decl_id;
X
X /* Check for literal */
X if (decl->literal) {
X /* Yes - output case converted literal */
X out_white_space(token);
X out_cvt_name(token);
X /* Return next token */
X token_class = get_token(token);
X return token_class;
X }
X
X token_copy(token, &member);
X
X token_class = get_token(token);
X
X /* Check for array subscript */
X if (decl->array_bound) {
X out_ident(&member, decl, decl_id);
X
X if (token_class == LEFT_PAREN) {
X /* Convert to open square bracket */
X token->token_name[0] = '[';
X out_token(token);
X
X /* Parse expression to right parenthesis */
X token_class = parse_expression(token);
X if (token_class != RIGHT_PAREN) {
X parse_error("')' expected");
X return ERROR;
X }
X
X /* Convert to close square bracket */
X token->token_name[0] = ']';
X out_token(token);
X
X token_class = get_token(token);
X }
X }
X
X /* Check for .<identifier> */
X if ((decl->type->token_type == STRUCTURE) && (token_class == PERIOD)) {
X
X if (decl->array_bound)
X /* Already printed identifier */
X out_token(token);
X else {
X if (decl->at_ptr || decl_id->based_name) {
X/*
X * --- Note: Does not handle BASED AT variables!
X */
X /* Print 'member->' */
X out_token(&member);
X out_str("->");
X } else {
X /* Print 'member.' */
X out_ident(&member, decl, decl_id);
X out_token(token);
X }
X }
X
X token_class = get_token(token);
X if (token_class != IDENTIFIER) {
X parse_error("Illegal structure member");
X return ERROR;
X }
X
X /* Find variable in list */
X if (!find_list_symbol(token, decl->struct_list,
X &var_decl, &var_decl_id)) {
X parse_error("Undefined structure member");
X return ERROR;
X }
X
X /* Parse this member now */
X token_class = parse_member(token, var_decl, var_decl_id);
X } else
X if (decl->array_bound == NULL)
X out_ident(&member, decl, decl_id);
X
X return token_class;
X}
X
X/*
X * Parse variable and output appropriate tokens.
X * Passed with initial identifier in token.
X * Returns with token terminating variable.
X * Handles { [ ( <expression> ) ] [ .<identifier> ] } ...
X */
Xparse_variable(token, var_decl, var_decl_id)
XTOKEN *token;
XDECL_MEMBER **var_decl;
XDECL_ID **var_decl_id;
X{
X if (!find_symbol(token, var_decl, var_decl_id)) {
X parse_error("Undefined variable");
X return ERROR;
X }
X
X return parse_member(token, *var_decl, *var_decl_id);
X}
X
X/*
X * See if token is in cvt_list.
X * If found, return pointer to conversion string.
X */
Xcheck_cvt_id(token, cvt_id, cvt_string)
XTOKEN *token;
XCVT_ID *cvt_id;
Xchar **cvt_string;
X{
X /* Check each string in cvt_id */
X while (*(cvt_id->id_name)) {
X if (!strcmp(token->token_name, cvt_id->id_name)) {
X /* Found match - return new string */
X *cvt_string = cvt_id->new_id;
X return TRUE;
X }
X
X cvt_id++;
X }
X
X return FALSE;
X}
X
X/*
X * Parse function call
X */
Xparse_function(token)
XTOKEN *token;
X{
X int token_class;
X BOOLEAN left_shift, right_shift;
X char *new_func;
X DECL_MEMBER *decl_ptr;
X DECL_ID *decl_id;
X
X /* Function call - check for SHL or SHR */
X out_white_space(token);
X left_shift = !strcmp(token->token_name, "shl") ||
X !strcmp(token->token_name, "SHL");
X right_shift = !strcmp(token->token_name, "shr") ||
X !strcmp(token->token_name, "SHR");
X if (left_shift || right_shift) {
X /* SHL(expr, expr) or SHR(expr, expr) */
X /* Check for '(' */
X token_class = get_token(token);
X if (token_class != LEFT_PAREN) {
X parse_error("'(' expected");
X return ERROR;
X }
X out_token(token);
X
X /* Output first expression */
X out_char('(');
X token_class = parse_expression(token);
X if (token_class != COMMA) {
X parse_error("',' expected");
X return ERROR;
X }
X
X out_str(left_shift ? ") << (" : ") >> (");
X
X /* Output second expression */
X token_class = parse_expression(token);
X if (token_class != RIGHT_PAREN) {
X parse_error("Missing ')'");
X return ERROR;
X }
X out_char(')');
X out_token(token);
X } else {
X
X /* Check for a type cast function */
X if (check_cvt_id(token, &cast_functions[0], &new_func)) {
X /* Convert to a cast */
X out_char('(');
X out_str(new_func);
X out_str(") ");
X } else
X
X /* Check for a function conversion */
X if (check_cvt_id(token, &cvt_functions[0], &new_func)) {
X /* Convert to desired function */
X out_str(new_func);
X } else {
X
X /* Output function name */
X out_token_name(token);
X
X /* Check for parameter list */
X if (find_symbol(token, &decl_ptr, &decl_id)) {
X if (decl_ptr->type->token_type != PROCEDURE) {
X parse_error("Illegal function call");
X return ERROR;
X }
X if (decl_ptr->initialization != DATA) {
X /* No param list */
X token_class = get_token(token);
X return token_class;
X }
X }
X }
X
X /* Check for parameter list */
X token_class = get_token(token);
X if (token_class != LEFT_PAREN) {
X parse_warning("Parameter list expected");
X return token_class;
X }
X out_token(token);
X
X /* Parse to closing right paren */
X do {
X token_class = parse_expression(token);
X out_token(token);
X } while (token_class == COMMA);
X
X if (token_class != RIGHT_PAREN) {
X parse_error("Missing ')'");
X return ERROR;
X }
X }
X /* Return token following function */
X token_class = get_token(token);
X return token_class;
X}
X
X/*
X * Parse expression and output appropriate tokens.
X * Return token at end of expression.
X */
Xparse_expression(token)
XTOKEN *token;
X{
X int token_class;
X int i, last_class, temp_class;
X DECL_MEMBER *id_type;
X DECL_ID *id_id;
X char *new_id;
X char string_const[MAX_TOKEN_LENGTH], octal_const[5];
X
X last_class = OPERATOR;
X
X token_class = get_token(token);
X
X while (1) {
X
X switch (token_class) {
X
X case LEFT_PAREN :
X if (last_class != OPERATOR) {
X parse_error("Missing operator");
X return ERROR;
X }
X
X /* Sub-expression */
X out_token(token);
X /* Parse to closing right paren */
X token_class = parse_expression(token);
X if (token_class != RIGHT_PAREN) {
X parse_error("Missing ')'");
X return ERROR;
X }
X
X out_token(token);
X break;
X
X case RIGHT_PAREN :
X return token_class;
X
X case OPERATOR :
X out_white_space(token);
X if (token->token_type == EQUAL)
X /* Make it a '==' */
X out_str("==");
X else
X
X /* Check for address operator '@' or '.' */
X if ((token->token_type == AT_OP) ||
X (token->token_type == PERIOD)) {
X token_class = get_token(token);
X if (token_class == IDENTIFIER) {
X /* Make it a '&' */
X out_char('&');
X
X /* See if it's a function reference */
X if (find_symbol(token, &id_type, &id_id) &&
X (id_type->type->token_type != PROCEDURE)) {
X /* Variable - parse it */
X temp_class = parse_member(token, id_type, id_id);
X } else {
X
X /* Function call - Check for */
X /* a function conversion */
X if (check_cvt_id(token, &cvt_functions[0], &new_id))
X /* Convert to desired function */
X out_str(new_id);
X else
X /* Function call - output name */
X out_token_name(token);
X
X temp_class = get_token(token);
X }
X } else
X
X if (token_class == LEFT_PAREN) {
X /* Constant list - convert to string */
X out_char('"');
X string_const[0] = '\0';
X
X do {
X token_class = get_token(token);
X if (token_class == STRING)
X (void) strcat(string_const, token->token_name);
X else
X if (token_class == NUMERIC) {
X cvt_octal(token, octal_const);
X (void) strcat(string_const, octal_const);
X } else {
X parse_error("Illegal constant");
X return ERROR;
X }
X
X token_class = get_token(token);
X } while (token_class == COMMA);
X
X if (token_class != RIGHT_PAREN) {
X parse_error("')' expected");
X return ERROR;
X }
X
X i = strlen(string_const);
X if ((i >= 4) &&
X (!strcmp(string_const + i - 4, "\\000")))
X /* Discard trailing null */
X string_const[i - 4] = '\0';
X out_str(string_const);
X out_char('"');
X } else {
X parse_error("Illegal operator");
X return ERROR;
X }
X } else
X
X out_token_name(token);
X break;
X
X case IDENTIFIER :
X /* Check for identifier conversion */
X if (check_cvt_id(token, &cvt_identifiers[0], &new_id)) {
X out_white_space(token);
X out_str(new_id);
X temp_class = get_token(token);
X } else
X
X /* See if variable in context */
X if (find_symbol(token, &id_type, &id_id) &&
X (id_type->type->token_type != PROCEDURE)) {
X /* Variable - parse it */
X temp_class = parse_member(token, id_type, id_id);
X } else
X
X /* Function call - parse it */
X temp_class = parse_function(token);
X break;
X
X case NUMERIC :
X out_token(token);
X break;
X
X case STRING :
X out_white_space(token);
X /* Convert to a numeric constant */
X if (token->token_length > 4) {
X parse_error("Illegal string constant");
X return ERROR;
X }
X
X if (token->token_length > 1)
X out_char('(');
X
X out_str_const(token->token_name, token->token_length);
X
X if (token->token_length > 1)
X out_char(')');
X break;
X
X default :
X /* Must not be part of an expression! */
X return token_class;
X }
X
X last_class = token_class;
X
X token_class = (last_class == IDENTIFIER) ?
X temp_class : get_token(token);
X }
X}
X
X/*
X * DO statement
X * Handles DO;, DO CASE, DO WHILE, and iterative DO
X */
Xparse_do(first_token)
XTOKEN *first_token;
X{
X TOKEN token;
X int token_class;
X int case_line;
X char case_statement[MAX_TOKEN_LENGTH];
X char case_output[MAX_CASE_STATEMENT_SIZE];
X char var_string[MAX_TOKEN_LENGTH];
X char *temp_out_string, *temp_out_string1;
X DECL_MEMBER *var_decl;
X DECL_ID *var_decl_id;
X
X /* Create new context */
X new_context(DO, (TOKEN *) NULL);
X
X out_white_space(first_token);
X
X /* Determine what kind of DO statement */
X token_class = get_token(&token);
X
X switch (token_class) {
X
X case END_OF_LINE :
X /* DO; */
X out_white_space(&token);
X out_char('{'); /* } for dumb vi */
X parse_to_end();
X break;
X
X case IDENTIFIER :
X /* DO counter = start TO limit BY step */
X out_str("for");
X out_must_white(&token);
X out_char('(');
X
X /* Put full variable in var_string */
X var_string[0] = '\0';
X temp_out_string = out_string;
X out_string = var_string;
X token_class = parse_variable(&token, &var_decl, &var_decl_id);
SHAR_EOF
echo "End of part 2, continue with part 3"
echo "3" > s2_seq_.tmp
exit 0
More information about the Alt.sources
mailing list