/* * Russell compiler -- Passes 1 through 5 * * Pass 1 : * initial syntax analysis * * Pass 2 : * symbol table generation * * Pass 3 : * minor tree massaging * * Pass 4: * signature deduction and checking * * Pass 5c: * Vax code generation * * Pass5d: * Intermediate code generation (run instead of pass5c) * * Input: * ifile: preprocessor output * stdin is reopened as ifile * * Output : * ofile: VAX assembly code or intermediate code. * sigfile: contains signature of program (-c flag only) * optfile: contains the concatenation of optimization info from * files mentioned in "extern" expressions * * Diagnostics : * written to stderr * * Compiler control messages : * written to stderr * * * Calling Sequence: * Rc [-BDSidaMcLPTGfVxXhOOOfF] actual_ifile ifile ofile [sigfile] [optfile] * sigfile should appear only with -c * optfile should appear only with -OO * actual_ifile is the name of the original input file. * It is never opened, but is used to build function names * * Flags: * B - Debugging flag. Turn on bad allocation debug. * D - Debugging flag. Turn on yydebug. * S - Debugging. Catch signals and flush buffers before aborting. * i - Just build the syntax tree, and write out the final core image * on rc.x . rc.x is in a.out format. The parse tree produced by * rc.x for any RUSSELL program will then be inserted * in place of the denotation represented by in the * first program. Compilation then proceeds as normal. This allows * building initialized RUSSELL compilers which know about a * certain standard prologue. * Boolean and Integer should be defined in the standard Prologue. * Boolean must be defined as a parameter. The initial occurrence * of the identifier Boolean must be as the first identifier in a * list of parameters having the same signature. (Generally it will * be the only element of such a list. ) * This is of course both machine and operating system dependent. * It is intended to work only with * Berkeley VAX UNIX. (Which form is used depends on macros de- * fined in parm.h.) An old style a.out file is produced on the VAX. * d - Same as i except produces a demand loadable file on the VAX. * This requires that the old version of Rc also be demand * loadable. * a - Generate abstract syntax rather than VAX code. * (obsolete, no longer implemented.) * M - allocate all variables in memory. (Opposite of R) * c - Generate code only for the user supplied (not initial env.) * code. Set things up so that it can be called from another * Russell program. Write signature information onto sigfile. * p - infile is preprocessor output. * L - Allow functions with trailing var Void argument to violate * import rule. * P - Generate code to count function calls * T - Generate trace code * G - Generate general intermediate code * V - Verbose - print call graph info on stdout * N - No use of Callcc * f - It is not possible to update the stack pointer SP * HINT ONS is however assumed to be understood by the code * generator. * F - Same as f, but in addition BSF functions can't access GF * and GAR instructions must precede first nested procedure call. * HINT ONS is not assumed to be understood. * R - use registers for identifier bindings * O - optimize at the expense of compilation time and possibly * execution space * OO - also prepare to run intermediate code optimizer * OOO - unroll loops once * X - compile an externally callable type. * x - Generate code for Xerox Portable Common Runtime. * h - heap allocate variables and activation records, unless the * variables would otherwise be in registers. */ import java.io.*; public class Russell { public static String copyright1 = new String("Copyright 1986-1989 Hans-Juergen Boehm, Alan J. Demers, Kumar Srikantan, Vernon Lee, and Lucy Hederman.\n"); public static String copyright2 = new String("Copyright (c) 1990-1993 by Xerox Corporation. All rights reserved.\n"); public static String copyright3 = new String("This material is provided as is, with no warranty expressed or implied. Any use is at your own risk.\n"); // public static Node stxtree; // public static Node insrtptr; static Lexer yylexer = new Lexer(); static Parser yyparser = new Parser(); static boolean parse_init_r = true; private static int argn; public static RIC_instr ric_instr = new RIC_instr(); public static void main(String args[]) { Mine.open_my_files(); if ( Globals.VERBOSE ) { System.out.println("Hello Russell."); } // if (!Globals.insrtptr.russell_initialized) { /* Not a pre-initialized compiler */ // Globals.gc_dont_gc = true; // GC_init(); // } /* Initialize flags */ Globals.dloadflag = false; Globals.initflag = false; Globals.bADflag = 0; Globals.aflag = false; Globals.yydebug = 0; /* Initialize file name pointers. */ Globals.ifname = Globals.ofname = Globals.sigfname = Globals.optfname = Globals.actual_ifname = "NULL"; for (argn = 1; argn < args.length; argn++) { if (args[argn].startsWith("-")) { switch ( args[argn].charAt(1) ) { case 'B': Globals.bADflag++; break; case 'D': Globals.yydebug++; break; // case 'S': // catchsigs(); // break; case 'i': Globals.initflag = true; break; case 'd': Globals.initflag = true; Globals.dloadflag = true; break; case 'a': Globals.aflag = true; break; case 'M': Globals.Mflag = true; break; case 'c': Globals.cflag = true; break; case 'p': Globals.pflag = true; break; case 'L': Globals.Lflag = true; break; case 'P': Globals.Pflag = true; break; case 'T': Globals.Tflag = true; break; case 'G': Globals.Gflag = true; break; case 'V': Globals.Vflag = true; break; case 'N': Globals.Nflag = true; break; case 'f': Globals.fflag = true; break; case 'F': Globals.fflag = true; Globals.Fflag = true; break; case 'R': Globals.Rflag = true; break; case 'O': if (Globals.OOflag) { Globals.OOOflag = true; } else if (Globals.Oflag) { Globals.OOflag = true; } else { Globals.Oflag = true; } break; case 'X': Globals.Xflag = true; break; case 'x': Globals.xflag = true; break; case 'h': Globals.hflag = true; break; default: System.err.printf("Russell: illegal flag option: %c\n", args[argn].charAt(1)); System.exit(1); } } else { if ( Globals.actual_ifname.compareTo("NULL") == 0) { Globals.actual_ifname = args[argn]; } else if ( Globals.ifname.compareTo("NULL") == 0) { Globals.ifname = args[argn]; } else if (Globals.ofname.compareTo("NULL") == 0) { Globals.ofname = args[argn]; } else if ((Globals.sigfname.compareTo("NULL") == 0) && Globals.cflag) { Globals.sigfname = args[argn]; } else if ((Globals.optfname.compareTo("NULL") == 0) && Globals.OOflag) { Globals.optfname = args[argn]; } else { System.err.println("Russell: Too many args."); System.exit(1); } } } if (Globals.ofname.compareTo("NULL") == 0) { System.err.println("Russell: Too few arguments"); System.exit(1); } if (Globals.cflag && Globals.sigfname.compareTo("NULL") == 0) { System.err.println("Rc: Missing file name for signature info"); System.exit(1); } if (Globals.OOflag && Globals.optfname.compareTo("NULL") == 0) { System.err.println("Rc: Missing file name for optimization info"); System.exit(1); } System.out.println("ifname = |" + Globals.ifname + "|"); System.out.println("actual_ifname = |" + Globals.actual_ifname + "|"); System.out.println("ofname = |" + Globals.ofname + "|"); System.out.println("sigfname = |" + Globals.sigfname + "|"); System.out.println("optfname = |" + Globals.optfname + "|"); /* Initialize */ if (Globals.initflag) // if (! Globals.insrtptr.russell_initialized) /* no previous initialization has taken place */ { Initids.initids(); if (Globals.Gflag) { ric_instr.init_RIC_table(); } if (parse_init_r) { if (!Globals.pflag) { Globals.yyinfnm = Stt.stt_enter("init.r"); Globals.yyline = 0; // addposition(yyinfnm, yyline); } /* open init file */ try { Globals.ifile = new BufferedReader(new FileReader("init.r")); } catch (IOException e) { System.err.printf("Can't open %s\n", "init.r"); } if (Globals.initflag) // Build syntax tree (pass 1). if (Globals.VERBOSE) { Mine.russinfo("Calling yyparser.parse"); } // Parse init.r yyparser.yyparse(); // close init.r try { Globals.ifile.close(); } catch (IOException e) { System.err.printf("Can't close %s\n", "init.r"); } } // START INFILE /* open input file */ try { Globals.ifile = new BufferedReader(new FileReader(Globals.ifname)); } catch (IOException e) { System.err.printf("Can't open %s\n", Globals.ifname); } if (Globals.initflag) // Build syntax tree (pass 1). if (Globals.VERBOSE) { Mine.russinfo("Calling yyparser.parse"); } yyparser.yyparse(); } try { Globals.ifile.close(); } catch (IOException e) { System.err.printf("Can't close %s\n", Globals.ifname); } Mine.close_my_files(); System.out.println("Bye Russell."); } }