/* M A I N P R O G R A M */ #include #include #include "parameters.h" #include "debug.h" #include #include #include #include #include "print.h" #include "LLlex.h" #include "Lpars.h" #include "class.h" #include "const.h" #include "def.h" #include "f_info.h" #include "idf.h" #include "input.h" #include "main.h" #include "node.h" #include "required.h" #include "tokenname.h" #include "type.h" #include "scope.h" #include "cstoper.h" #include "stab.h" #include "options.h" #include "error.h" char options[128]; char *ProgName; char *input = "input"; char *output = "output"; label data_label; label text_label; struct def *program; extern int fp_used; /* set if floating point used */ extern void LLparse(void); int Compile(char *src, char *dst); void AddRequired(void); #ifdef DEBUG void LexScan(void); void Info(void); #endif int main(int argc, register char **argv) { register int Nargc = 1; register char **Nargv = &argv[0]; ProgName = *argv++; while( --argc > 0 ) { if( **argv == '-' ) DoOption((*argv++) + 1); else Nargv[Nargc++] = *argv++; } Nargv[Nargc] = 0; /* terminate the arg vector */ if( Nargc < 2 ) { fprint(STDERR, "%s: Use a file argument\n", ProgName); return EXIT_FAILURE; } if(!Compile(Nargv[1], Nargv[2])) return EXIT_FAILURE; return EXIT_SUCCESS; } int Compile(char *src, char *dst) { extern struct tokenname tkidf[]; extern struct tokenname tkstandard[]; int tk; if( !InsertFile(src, (char **) 0, &src) ) { fprint(STDERR, "%s: cannot open %s\n", ProgName, src); return 0; } LineNumber = 1; FileName = src; init_idf(); InitCst(); reserve(tkidf); reserve(tkstandard); CheckForLineDirective(); tk = LLlex(); /* Read the first token and put */ aside = dot; /* it aside. In this way, options */ asidetype = toktype; /* inside comments will be seen */ dot.tk_symb = tk; /* before the program starts. */ tokenseen = 1; InitScope(); InitTypes(); if( options['c'] ) tkclass['"'] = STSTR; if( options['u'] || options['U'] ) { class('_') = STIDF; inidf['_'] = 1; } if( tk == '"' || tk == '_' ) { PushBack(); ASIDE = 0; } #ifdef DEBUG if( options['l'] ) { LexScan(); return 0; /* running the optimizer is not very useful */ } #endif /* DEBUG */ C_init(word_size, pointer_size); if( !C_open(dst) ) fatal("couldn't open output file"); C_magic(); C_ms_emx(word_size, pointer_size); #ifdef DBSYMTAB if (options['g']) { C_ms_std(FileName, N_SO, 0); } #endif /* DBSYMTAB */ AddRequired(); C_df_dlb(++data_label); C_rom_scon(FileName,(arith) strlen(FileName) + 1); LLparse(); C_ms_src((int)LineNumber - 1, FileName); if( fp_used ) C_ms_flt(); C_close(); #ifdef DEBUG if( options['I'] ) Info(); #endif /* DEBUG */ return !err_occurred; } #ifdef DEBUG void LexScan(void) { register struct token *tkp = ˙ while( LLlex() > 0 ) { print(">>> %s ", symbol2str(tkp->tk_symb)); switch( tkp->tk_symb ) { case IDENT: print("%s\n", tkp->TOK_IDF->id_text); break; case INTEGER: print("%ld\n", tkp->TOK_INT); break; case REAL: print("%s\n", tkp->TOK_REL); break; case STRING: print("'%s'\n", tkp->TOK_STR); break; default: print("\n"); } } } #endif void AddRequired(void) { register struct def *df; extern struct def *Enter(); static struct node maxintnode = { 0, 0, Value, 0, { INTEGER, 0 } }; /* PROCEDURES */ /* File handling procedures, Read(ln) & Write(ln) are handled * in the grammar */ df = Enter("false", D_ENUM, bool_type, 0); df->enm_val = 0; df->df_flags |= D_SET; bool_type->enm_enums = df; df->enm_next = Enter("true", D_ENUM, bool_type, 0); df->enm_next->enm_val = 1; df->df_flags |= D_SET; df->enm_next->enm_next = NULLDEF; (void) Enter("rewrite", D_PROCEDURE, std_type, R_REWRITE); (void) Enter("put", D_PROCEDURE, std_type, R_PUT); (void) Enter("reset", D_PROCEDURE, std_type, R_RESET); (void) Enter("get", D_PROCEDURE, std_type, R_GET); (void) Enter("page", D_PROCEDURE, std_type, R_PAGE); /* DYNAMIC ALLOCATION PROCEDURES */ (void) Enter("new", D_PROCEDURE, std_type, R_NEW); (void) Enter("dispose", D_PROCEDURE, std_type, R_DISPOSE); /* MISCELLANEOUS PROCEDURE(S) */ if( !options['s'] ) (void) Enter("halt", D_PROCEDURE, std_type, R_HALT); /* TRANSFER PROCEDURES */ (void) Enter("pack", D_PROCEDURE, std_type, R_PACK); (void) Enter("unpack", D_PROCEDURE, std_type, R_UNPACK); /* FUNCTIONS */ /* ARITHMETIC FUNCTIONS */ (void) Enter("abs", D_FUNCTION, std_type, R_ABS); (void) Enter("sqr", D_FUNCTION, std_type, R_SQR); (void) Enter("sin", D_FUNCTION, std_type, R_SIN); (void) Enter("cos", D_FUNCTION, std_type, R_COS); (void) Enter("exp", D_FUNCTION, std_type, R_EXP); (void) Enter("ln", D_FUNCTION, std_type, R_LN); (void) Enter("sqrt", D_FUNCTION, std_type, R_SQRT); (void) Enter("arctan", D_FUNCTION, std_type, R_ARCTAN); /* TRANSFER FUNCTIONS */ (void) Enter("trunc", D_FUNCTION, std_type, R_TRUNC); (void) Enter("round", D_FUNCTION, std_type, R_ROUND); /* ORDINAL FUNCTIONS */ (void) Enter("ord", D_FUNCTION, std_type, R_ORD); (void) Enter("chr", D_FUNCTION, std_type, R_CHR); (void) Enter("succ", D_FUNCTION, std_type, R_SUCC); (void) Enter("pred", D_FUNCTION, std_type, R_PRED); /* BOOLEAN FUNCTIONS */ (void) Enter("odd", D_FUNCTION, std_type, R_ODD); (void) Enter("eof", D_FUNCTION, std_type, R_EOF); (void) Enter("eoln", D_FUNCTION, std_type, R_EOLN); /* TYPES */ (void) Enter("char", D_TYPE, char_type, 0); (void) Enter("integer", D_TYPE, int_type, 0); (void) Enter("real", D_TYPE, real_type, 0); (void) Enter("boolean", D_TYPE, bool_type, 0); (void) Enter("text", D_TYPE, text_type, 0); (void) Enter("(void)", D_TYPE, void_type, 0); if( options['d'] ) (void) Enter("long", D_TYPE, long_type, 0); if( options['c'] ) (void) Enter("string", D_TYPE, string_type, 0); /* DIRECTIVES */ (void) Enter("forward", D_FORWARD, error_type, 0); (void) Enter("extern", D_EXTERN, error_type, 0); /* CONSTANTS */ /* nil is TOKEN and thus part of the grammar */ maxintnode.nd_type = int_type; maxintnode.nd_INT = max_int; /* defined in cstoper.c */ df = define(str2idf("maxint", 0), CurrentScope, D_CONST); df->df_type = int_type; df->con_const = &maxintnode; df->df_flags |= D_SET; #ifdef DBSYMTAB if (options['g']) stb_string(df, D_CONST); #endif /* DBSYMTAB */ } #ifdef DEBUG int cntlines; void Info(void) { extern int cnt_def, cnt_node, cnt_paramlist, cnt_type, cnt_scope, cnt_scopelist, cnt_tmpvar, cnt_withdesig, cnt_case_hdr, cnt_case_entry; print("\ %6d def\n%6d node\n%6d paramlist\n%6d type\n%6d scope\n%6d scopelist\n\ %6d lab\n%6d tmpvar\n%6d withdesig\n%6d casehdr\n%6d caseentry\n", cnt_def, cnt_node, cnt_paramlist, cnt_type, cnt_scope, cnt_scopelist, cnt_lab, cnt_tmpvar, cnt_withdesig, cnt_case_hdr, cnt_case_entry); print("\nNumber of lines read: %d\n", cntlines); } #endif