home *** CD-ROM | disk | FTP | other *** search
- /*
- TEST PROGRAM
-
- source: bigline.pp
- started: February 1, 1986
- version: see below
-
- Copyright (C) 1985, 1986 by Edward K. Ream
- */
-
- #include "pl68k.h"
- #define SIGNON "CPP v3: February 1, 1986"
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- char *in, *out, *arg;
-
-
- /* Do rest of initializing AFTER getting the arguments. */
-
- #ifdef BUG
- bug_init(); /* Do this FIRST. */
- mm_init(); /* And SECOND. */
- ops_init(); /* And THIRD. */
- sysinit(&argc, &argv); /* And FOURTH. */
- TICK("main");
- if (argc < 3) {
- printf("usage: cpp in out <optional tracing names>\n");
- exit();
- }
-
- in = NULL;
- out = NULL;
-
- /* Extra command-line arguments enable tracing. */
- argv++;
- while (--argc) {
- arg = *argv++;
- if (*arg == '+') {
- printf("enabling trace of <%s>\n", arg+1);
- BEGIN_TRACE(arg+1);
- }
- else if (*arg == '-') {
- printf("disabling trace of <%s>\n", arg+1);
- END_TRACE(arg+1);
- }
- else if (in == NULL) {
- in = arg;
- }
- else if (out == NULL) {
- out = arg;
- }
- else {
- printf("extra argument <%s> ignored\n", arg+1);
- }
- }
- if (in == NULL) {
- printf("missing input, output file\n");
- exit();
- }
- if (out == NULL) {
- printf("missing output file name\n");
- exit();
- }
-
- #else
- mm_init(); /* Do this FIRST. */
- ops_init(); /* And SECOND. */
- sysinit(&argc, &argv); /* And THIRD. */
- if (argc != 3) {
- printf("usage: cpp in out\n");
- exit();
- }
-
- argv++;
- in = *argv++;
- out = *argv++;
- #endif
-
- /* Put out the sign on message. */
- printf("%s\n", SIGNON);
-
- /* Initialize AFTER getting the args so we can trace. */
- t_init();
- mst_init();
-
- /* Open the input file. */
- sysopen(in);
- if (Z) {
- printf("can not open %s\n", in);
- exit();
- }
-
- /* Open the output file. */
- syscreat(out);
- if (Z) {
- printf("can not open %s\n", out);
- exit();
- }
-
- /* Copy the file completely. */
- get_token();
-
- /* Close the output file. */
- sysoclose();
-
- TRACE("bug_dump", mm_stat());
- TRACE("bug_dump", bug_dump());
-
- sysend();
- }
-
-
- /*
- Get ready for execution.
- */
-
- t_init()
- {
- TICK("t_init");
-
- BAD124;
- nest_flag = TRUE;
- t_iflevel = 0;
- t_errcount = 0;
- }
-
-
- /*
- Copy the input to the output.
- */
-
- get_token()
- {
- int delim;
- register struct mst_node * p;
- struct mst_node * mst_lookup();
-
- TICK("get_token");
-
- rescan: switch (ch) {
-
- TICK("get_token1");
-
- case '\r':
- case ' ':
- case '\t':
- TICK("get_token_ws");
-
- syscput(ch);
- sysnext();
- goto rescan;
-
- case '\n':
- TICK("get_token_nl");
-
- sysnext();
- do_nl();
- begin_line(TRUE);
- goto rescan;
-
- case '#':
- sysnext();
- do_pp();
- goto rescan;
-
- case '\'':
- case '"':
- delim = ch;
- syscput(delim);
- t_string(t_symbol);
- syssput(t_symbol);
- syscput(delim);
- goto rescan;
-
- case 'A': case 'B': case 'C': case 'D':
- case 'E': case 'F': case 'G': case 'H':
- case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P':
- case 'Q': case 'R': case 'S': case 'T':
- case 'U': case 'V': case 'W': case 'X':
- case 'Y': case 'Z':
- case 'a': case 'b': case 'c': case 'd':
- case 'e': case 'f': case 'g': case 'h':
- case 'i': case 'j': case 'k': case 'l':
- case 'm': case 'n': case 'o': case 'p':
- case 'q': case 'r': case 's': case 't':
- case 'u': case 'v': case 'w': case 'x':
- case 'y': case 'z':
- case '_':
-
- /*
- The t_id() routine puts the identifier into t_symbol[].
- */
-
- TICK("get_token_id");
-
- t_id(t_symbol);
- p = mst_lookup(t_symbol);
- if (p == NULL) {
- syssput(t_symbol);
- }
- else {
- /* Push back the replacement text. */
- pp_expand(p -> mst_nargs, p -> mst_text);
- }
- goto rescan;
-
- case END_FILE:
-
- /* Switch input streams. */
- sysiclose();
- if (t_inlevel == -1) {
- return;
- }
- else {
- goto rescan;
- }
-
- /* Ignore C style comments. */
- case '/':
- sysnext();
- if (ch == '*') {
- sysnext();
- t_comment();
- }
- else {
- syscput('/');
- }
- goto rescan;
-
- default:
- syscput(ch);
- sysnext();
- goto rescan;
- }
- }
-
-
- /*
- Return the next token in a constant expression.
- Return NULL on end of expression.
- Return ERROR on mal-formed expression.
- */
-
- int
- con_token()
- {
- register struct mst_node * p;
- struct mst_node * mst_lookup();
-
- TICK("con_token");
-
- /*
- If you do not wish macros to be legal in #if statements,
- just replace the following with:
-
- if (isid1(ch)) return ERROR;
- */
-
- rescan:
- if (isid1(ch)) {
- t_id(t_symbol);
- p = mst_lookup(t_symbol);
- if (p == NULL) {
- return ID_TOK;
- }
- else {
- pp_expand(p -> mst_nargs, p -> mst_text);
- goto rescan;
- }
- }
-
- switch(ch) {
-
- case '\n':
- case END_FILE:
- case '#':
-
- /* Terminate the expression immediately. */
- return NULL;
-
-
- case ' ':
- case '\t':
- case '\r':
-
- /* Ignore white space except for comments. */
- sysnext();
- goto rescan;
-
-
- case '\\':
-
- /* Allow continuation lines. */
- sysnext();
- if (ch == '\n') {
- sysnext();
- goto rescan;
- }
- else {
- return ERROR;
- }
-
-
- case '/':
-
- /* Do not allow comments. */
- sysnext();
- return (ch == '*') ? ERROR : DIV_TOK;
-
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
-
- t_number();
- return INT_TOK; /* 1/10/86 */
-
-
- case '\'':
-
- t_string();
- t_value = char_val(t_symbol);
- return CHAR_TOK;
-
-
- case '=': /* == */
-
- sysnext();
- if (ch == '=') {
- sysnext();
- return EQUAL_TOK;
- }
- else {
- return ERROR;
- }
-
-
- case '!': /* != */
-
- sysnext();
- if (ch == '=') {
- sysnext();
- return NE_TOK;
- }
- else {
- return ERROR;
- }
-
-
- case '>': /* > or >= or >> */
-
- sysnext();
- if (ch == '>') {
- sysnext();
- return RSHIFT_TOK;
- }
- else if (ch == '=') {
- sysnext();
- return GE_TOK;
- }
- else {
- return GT_TOK;
- }
-
-
- case '<': /* < or <= or << */
-
- sysnext();
- if (ch == '<') {
- sysnext();
- return LSHIFT_TOK;
- }
- else if (ch == '=') {
- sysnext();
- return LE_TOK;
- }
- else {
- return LT_TOK;
- }
-
-
- case '+': sysnext(); return PLUS_TOK;
- case '-': sysnext(); return MINUS_TOK;
- case '*': sysnext(); return STAR_TOK;
- case '%': sysnext(); return MOD_TOK;
- case '|': sysnext(); return OR_TOK;
- case '&': sysnext(); return AND_TOK;
- case '~': sysnext(); return TILDE_TOK;
- case '?': sysnext(); return QUESTION_TOK;
- case ':': sysnext(); return COLON_TOK;
- case '^': sysnext(); return XOR_TOK;
-
- default: return ERROR;
- }
- }
-
-
- /*
- Do beginning of line processing.
- In PL/68K and CPP the flag is not used, but in MACRO
- the flag would be used to determine if preprocessor directives
- should be processed.
- */
-
- begin_line(flag)
- int flag;
- {
- TICK("begin_line");
- TRACE("begin_line", printf("begin_line: t_inlevel %d, ch = %x\n",
- t_inlevel, ch));
-
- /*
- At this point, ch contains the character AFTER the '\n'
- so that we can look ahead to determine what the level of
- the NEXT line will be.
- */
- if (ch == END_FILE) {
- if (t_inlevel > 1) {
- syscput(1);
- }
- return;
- }
- if (t_inlevel > 0 || sysinmac()==TRUE) {
- syscput(1);
- }
- if (ch == '.') {
- skip_1line();
- }
- }
-
-
- /*
- Do end of line processing.
- */
-
- do_nl()
- {
- TICK("do_nl");
-
- BAD442;
- sysnlput();
- if (sysinmac()==FALSE) {
- t_line++;
- }
- }
-