home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Language / Compiler / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-16  |  8.9 KB  |  349 lines

  1. /*
  2.  * @(#)main.c    1.8  2/23/90
  3.  */
  4. #include <stdio.h>
  5. #include "assert.h"
  6. #include "nodes.h"
  7. #include "scan.h"
  8. #include "semantics.h"
  9. #include "builtins.h"
  10. #include "environment.h"
  11. #include "trace.h"
  12. #include "option.h"
  13.  
  14. void yyparse();
  15.  
  16. NodePtr Root;
  17. #include "tokenNames.c"
  18.  
  19. char *Usage = "Usage:\tec <flags> <filename>\n\
  20. \tflags:\n\
  21. \t\t[-why] [-v] [-c] [-C[-]n] [-z] [-h] [-g[dtm]] [-i] [-Z]\n\
  22. \t\t[-T<tracename>[=level]] [-O<optionname>[=value]]\n\
  23. \t\t[-R <rootpath>] [-[Mm] <machinename>]\n\
  24. \tmaintenance flags:\n\
  25. \t\t[-b] [-t] [-d <oid>]\n";
  26.  
  27. Boolean bflag = FALSE,
  28.     tflag = FALSE,
  29.     vflag = FALSE,
  30.     dflag = FALSE,
  31.     oflag = FALSE,
  32.     cflag = FALSE,
  33.     Cflag = FALSE,
  34.     Dflag = FALSE,
  35.     hflag = FALSE,
  36.     zflag = FALSE,
  37.     gdflag= FALSE,
  38.     gtflag= FALSE,
  39.     gmflag= FALSE,
  40.     iflag = FALSE,
  41.     Zflag = FALSE,
  42.     mflag = FALSE;
  43.     
  44. char *dstring = NULL;
  45. char *mdata = NULL;
  46. int Cvalue = -1;
  47.  
  48. #ifndef EMDIR
  49. #define EMDIR "/scratch/eric/emerald/"
  50. #endif
  51.  
  52. char *emDirectory = EMDIR;
  53. char *emdbDirectory = NULL;
  54.  
  55. /*VARARGS1*/
  56. static void usagePanic(s, a)
  57. char *s;
  58. char *a;
  59. {
  60.   if (s != NULL) {
  61.     fprintf(stderr, s, a);
  62.     putc('\n', stderr);
  63.   }
  64.   fprintf(stderr, Usage);
  65.   exit(1);
  66. }
  67.  
  68. parseFlags(argc, argv)
  69. int argc;
  70. char **argv;
  71. {
  72.   register int i;
  73.   char cwd[1024];
  74.  
  75.   for (i = 1; i < argc; i++) {
  76.     if (argv[i][0] == '-') {
  77.       switch (argv[i][1]) {
  78.     case 'b':
  79.       bflag = TRUE;
  80.       break;
  81.     case 'h':
  82.       hflag = TRUE;
  83.       break;
  84.     case 'w':
  85.       if (strcmp(&argv[i][1], "why")) {
  86.         usagePanic("Unknown flag: %s", argv[i]);
  87.       } else {
  88.         if (traceconformfailure == 0) traceconformfailure = 1;
  89.       }
  90.       break;
  91.     case 'v':
  92.       vflag = TRUE;
  93.       if (tracepasses == 0) tracepasses = 1;
  94.       break;
  95.     case 'T':
  96.       if (! parseTraceFlag(argv[i])) usagePanic(NULL);
  97.       break;
  98.     case 'O':
  99.       if (! parseOptionFlag(argv[i])) usagePanic(NULL);
  100.       break;
  101.     case 'o':
  102.       oflag = 1;
  103.       break;
  104.     case 'g':
  105.       switch (argv[i][2]) {
  106.         case 'd':
  107.           gdflag = 1;
  108.           break;
  109.         case 't':
  110.           gtflag = 1;
  111.           break;
  112.         case 'm':
  113.           gmflag = 1;
  114.           break;
  115.         default:
  116.           usagePanic("Unknown flag: %s", argv[i]);
  117.           break;
  118.       }
  119.       break;
  120.     case 't':
  121.       tflag = TRUE;
  122.       break;
  123.     case 'i':
  124.       iflag = TRUE;
  125.       break;
  126.     case 'D':
  127.       if (argv[i][2] == '\0') Dflag = TRUE;
  128.       else Dflag = atoi(&argv[i][2]);
  129.       break;
  130.     case 'd':
  131.       dflag = TRUE;
  132.       dstring = &argv[i][2];
  133.       break;
  134.     case 'c':
  135.       cflag = TRUE;
  136.       break;
  137.     case 'z':
  138.       zflag = TRUE;
  139.       break;
  140.     case 'Z':
  141.       Zflag = TRUE;
  142.       break;
  143.     case 'C':
  144.       Cflag = TRUE;
  145.       if (argv[i][2] != '\0') Cvalue = atoi(&argv[i][2]);
  146.       else Cvalue = -1;
  147.       break;
  148.     case 'm':
  149.     case 'M':
  150.       if (argv[i][2] == '\0') {
  151.         i++;
  152.         if (i < argc) {
  153.           mdata = argv[i];
  154.         } else {
  155.           usagePanic("-M must be followed by machine name", 0);
  156.         }
  157.       } else {
  158.         mdata = &argv[i][2];
  159.       }
  160.       break;
  161.     case 'R':
  162.       if (argv[i][2] == '\0') {
  163.         i++;
  164.         if (i < argc) {
  165.           emDirectory = argv[i];
  166.         } else {
  167.           usagePanic("-R must be followed by directory name", 0);
  168.         }
  169.       } else {
  170.         emDirectory = &argv[i][2];
  171.       }
  172.       break;
  173.     default:
  174.       usagePanic("Unknown flag %s", argv[i]);
  175.       break;
  176.       }
  177.     } else if (currentFileName == NULL) {
  178.       currentFileName = argv[i];
  179.     } else {
  180.       fprintf(stderr, "ec can only compile a single source file\n");
  181.       fprintf(stderr, "\tFirst: \"%s\"\n\tSecond: \"%s\"\n", 
  182.     currentFileName, argv[i]);
  183.       usagePanic(NULL);
  184.     }
  185.   }
  186.   if (currentFileName == NULL) {
  187.     inputFile = stdin;
  188.     currentFileName = "<stdin>";
  189.   } else {
  190.     inputFile = fopen(currentFileName, "r");
  191.     if (inputFile == NULL) {
  192.       fprintf(stderr, "Can't find \"%s\".\n", currentFileName);
  193.       exit(1);
  194.     }
  195.     if (getwd(cwd) <= 0) {
  196.       fprintf(stderr, "Can't get current directory: %s\n", cwd);
  197.       exit(1);
  198.     }
  199.     strcat(cwd, "/");
  200.     strcat(cwd, currentFileName);
  201.     currentFileName = (char *)malloc(strlen(cwd)+1);
  202.     strcpy(currentFileName, cwd);
  203.   }
  204.   IFOPTION(debugstack, 1) gdflag = 1;
  205. }  
  206.  
  207. void checkEnvironmentVariables()
  208. {
  209.   if ((emdbDirectory = (char *)getenv("EMDBDIRECTORY")) == NULL) {
  210.     emdbDirectory = (char *)malloc((unsigned)strlen(emDirectory) + 5);
  211.     sprintf(emdbDirectory, "%s/EC/", emDirectory);
  212.   }
  213. }
  214.  
  215. extern void initialize(), Finalize();
  216. extern void DisplayTree();
  217. extern NodePtr readTree();
  218.  
  219. static OID getIDFromString(s)
  220. char *s;
  221. {
  222.   OID id;
  223.   if (sscanf(s, "%*[^D]D%x", &id) != 1) assert(FALSE);
  224.   return(id);
  225. }
  226.  
  227. main(argc, argv)
  228. int argc;
  229. char **argv;
  230. {
  231.   umask(0000);
  232.   parseFlags(argc, argv);
  233.   checkEnvironmentVariables();
  234.   if (hflag) {
  235.     printf("%s\n", Usage);
  236.     printf("The Emerald Compiler compiles a single Emerald source program and \n");
  237.     printf("executes it on the local Emerald kernel.  The flag arguments are:\n");
  238.     printf("    -why        Tell me why conforms checking fails.\n");
  239.     printf("    -v          Be verbose about the various compiler passes\n");
  240.     printf("    -c          Stop after type checking (except when doing a builtin \n");
  241.     printf("                where it means stop after doing exports)\n");
  242.     printf("    -C[n]       Stop after n passes (N >= 0), or with n passes to go\n");
  243.     printf("                (n < 0) -C-2 means stop after generating code, -C-1 means\n");
  244.     printf("                stop before invoking the Emerald kernel to run the program\n");
  245.     printf("    -z          Leave the temporary files in the current directory\n");
  246.     printf("    -h          Prints this list.\n");
  247.     printf("    -gd         Compile code to assist in debugging.\n");
  248.     printf("    -gt         Compile code to enable line number tracing.\n");
  249.     printf("    -gm         Compile code to gather statistics.\n");
  250.     printf("    -i          Interactive - the compiler's stdin/out is passed to the\n");
  251.     printf("                created object.\n");
  252.     printf("    -Z          Create mutable objects at compile time.\n");
  253.     printf("    -T<traces>  Turn on tracing.  The traces argument is parsed as a comma \n");
  254.     printf("                separated string of trace names and optional trace values\n");
  255.     printf("                with an = between the name and value.  A legal string is:\n");
  256.     printf("                    -Tassign,environment=5\n");
  257.     printf("                Use -Thelp to see the available traces.\n");
  258.     printf("    -O<options> Turn on various options.  The options argument is parsed\n");
  259.     printf("                as a comma separated string of option names and optional\n");
  260.     printf("                option values with an = between the name and value.\n");
  261.     printf("                A legal string is:\n");
  262.     printf("                    -Oinvokequeue,comment=5\n");
  263.     printf("                Use -Thelp to see the available options.\n");
  264.     printf("    -M <name>   Run the compiled program on machine named \"name\".\n");
  265.     printf("    -R <path>   Use path instead of /usr/em as the root of the Emerald\n");
  266.     printf("                Unix subtree.\n");
  267.     printf("Maintainance flags:\n");
  268.     printf("    -b          Compile the description of a builtin type\n");
  269.     printf("    -t          Write the intermediate tree file at interesting \n");
  270.     printf("                stages (currently undergoing change)\n");
  271.     printf("    -d<oid>     Read the intermediate tree file (internal format)\n");
  272.     printf("                and display it\n");
  273.     exit(0);
  274.   }
  275.   Root = F_NewNode(T_NONE, 0);
  276.   assert(NodeSize(Root) == BODYSIZE);
  277.   assert(sizeof(STEntry) == 28);
  278.   assert(&((NodePtr)0)->b.oblit.name == &((NodePtr)0)->b.atlit.name);
  279.  
  280.   FreeNode(Root);
  281.   TRACE0(passes, 1, "Initializing.");
  282.   initialize();
  283.   TRACE0(passes, 1, "Loading builtins.");
  284.   loadBuiltins();
  285.   if (loadedDummyBuiltins && !bflag) {
  286.     fprintf(stdout, "Warning: Dummy builtins loaded\n");
  287.   }
  288.   if (dflag) {
  289.     Root = loadObject(getIDFromString(dstring));
  290.     if (!oflag) {
  291.       doInput();
  292.       if (Root->tag == P_OBLIT &&
  293.       (Root->b.oblit.id & 0xff000000) == (OID)0xff000000 &&
  294.       Root->b.oblit.id <= (OID)0xff000100) {
  295.     Root->b.oblit.id = 0xff123000 + (Root->b.oblit.id & 0xff);
  296.       }
  297.       DisplayTree(stdout, Root, vflag ? 1 : 0, 9999);
  298.     } else {
  299.       DisplayGlobalRefs(Root);
  300.     }
  301.   } else {
  302.     TRACE0(passes, 1, "Parsing.");
  303.     yyparse();
  304.     DoneParsing(Root);
  305.   }
  306.   Finalize();
  307. }
  308.  
  309. static Map displayMap;
  310.  
  311. dgr(t)
  312. register NodePtr t;
  313. {
  314.   register Symbol st;
  315.   register int i;
  316.   if ((int)t < 0x200) return;
  317.   if (Map_Lookup(displayMap, (int)t) != NIL) return;
  318.   Map_Insert(displayMap, (int)t, 1);
  319.   switch (t->tag) {
  320.     case P_GLOBALREF:
  321.       fprintf(stdout, "0x%8x\n", t->b.globalref.id);
  322.       break;
  323.     case P_SYMREF:
  324.     case P_SYMDEF:
  325.     case P_SYMBOL:
  326.       if (t->tag == P_SYMBOL) {
  327.     st = (Symbol) t;
  328.       } else {
  329.     st = t->b.symref.symbol;
  330.       }
  331.       dgr(st->value.ATinfo);
  332.       dgr(st->value.CTinfo);
  333.       dgr(st->value.value);
  334.       break;
  335.   }
  336.   if (t->tag == P_SYMBOL) return;
  337.   for (i = t->firstChild; i < t->nChildren; i++) {
  338.     dgr(t->b.children[i]);
  339.   }
  340. }
  341.  
  342. DisplayGlobalRefs(p)
  343. NodePtr p;
  344. {
  345.   displayMap = Map_Create();
  346.   dgr(p);
  347.   Map_Destroy(displayMap);
  348. }
  349.