Beispiel #1
0
  /**
   * compile the project passed as parameter to the constructor. The basic packages of Cyan, stored
   * in project <code>cyanLangPackageProject</code>, are added to the project. Currently there is
   * only one basic package of the language: "cyan.lang". This should be included in every
   * compilation.
   *
   * @return <code>false</code> in error
   */
  public boolean compile(HashSet<saci.CompilationInstruction> compInstSet) {

    Compiler compiler;

    try {

      // list of non-generic prototypes of the programc
      nonGenericCompilationUnitList = new ArrayList<CompilationUnit>();
      // list of generic prototypes of the program
      ArrayList<CompilationUnit> genericCompilationUnitList = new ArrayList<CompilationUnit>();

      /* separates the compilation units (source files) that have generic prototypes from
         those that don´t.
         A prototype whose file has a digit after '(' is a generic prototype. For example,
            Proto(1)(1).cyan has a generic prototype Proto<T><R>. And file
         MyData<main.Person><Int> is put in file MyData(main.Person)(Int).cyan.
      */

      for (CompilationUnit compilationUnit : program.getCompilationUnitList()) {

        /*
        // if the file name has a '(' character followed by a digit, then it is a
        // generic prototype. Note that "Stack(Int).cyan" contains prototype "Stack<Int>"
        // which is not considered generic
        	 *
        	 */
        String filename = compilationUnit.getFilename();
        boolean foundDigit = false;
        int ifn = 0;
        int sizeFilename = filename.length();
        while (ifn < sizeFilename) {
          if (filename.charAt(ifn) == '(' && Character.isDigit(filename.charAt(ifn + 1))) {
            foundDigit = true;
            break;
          }
          ++ifn;
        }
        if (foundDigit) {
          compilationUnit.setHasGenericPrototype(true);
          genericCompilationUnitList.add(compilationUnit);
        } else nonGenericCompilationUnitList.add(compilationUnit);
        /*
        if ( indexOfLeftPar > 0 && Character.isDigit(compilationUnit.getFilename().charAt(indexOfLeftPar + 1))  )
        	genericCompilationUnitList.add(compilationUnit);
        else
        	nonGenericCompilationUnitList.add(compilationUnit);
        */
      }

      /**
       * delete all files from "tmp" directories. If a generic prototype is in a directory "D", the
       * Compiler creates the generic instantiations in "D\tmp". For example, if "Stack<T>" is in
       * directory "util", the Compiler creates prototypes "Stack<Int>" and "Stack<Person>"
       * (assuming the program uses "Stack<Int>" and "Stack<Person>") in directory "util\tmp".
       */
      Set<String> pathCompilationUnitTable = new HashSet<String>();
      for (CompilationUnit c : genericCompilationUnitList) {
        pathCompilationUnitTable.add(c.getPackageCanonicalPath());

        c.getCyanPackage().setHasGenericPrototype(true);
      }
      for (String path : pathCompilationUnitTable) {
        File dir = new File(path + NameServer.temporaryDirName);
        if (dir.exists()) for (File file : dir.listFiles()) file.delete();
      }

      String dotExtension = "." + NameServer.cyanSourceFileExtension;

      boolean hasCompilationError = false;

      /**
       * first of all, parse all generic prototypes. This is not allowed in step 7 of the
       * compilation because all generic prototype instantiation should have been created before
       * that.
       */
      if (this.compilationStep.compareTo(CompilationStep.step_7) < 0) {
        for (CompilationUnit compilationUnit : genericCompilationUnitList) {
          compiler = new Compiler(compilationUnit, compInstSet, compilationStep, project, null);
          compiler.parse();
          /**
           * print the errors found in the generic prototypes and apply all actions to them. An
           * action is a small refactoring like insert a ";"
           */
          if (compilationUnit.hasCompilationError()) {
            // compilationUnit.printErrorList(printWriter);
            hasCompilationError = true;
          }
          if (compilationUnit.getActionList().size() > 0) compilationUnit.doActionList(printWriter);
        }
      }

      /* if ( hasCompilationError )
      	return false;
      */

      /*
       * in the first step of this while statement, all non-generic prototypes are compiled.
       *
       * In the second step of the while statement, the real prototypes created in the previous step
       * are compiled. They may instantiate new generic prototypes. For example, Stack<Int> may
       * declare a variable of type "Array<Int>". This new Cyan prototype should be created and
       * compiled. The process continues till no new prototypes should be created.
       */
      CompilationUnit compilationUnit;
      int numCompilationUnitsAlreadyCompiled = 0;
      int sizeNonGenericCompilationUnitList;
      while (numCompilationUnitsAlreadyCompiled < nonGenericCompilationUnitList.size()) {

        sizeNonGenericCompilationUnitList = nonGenericCompilationUnitList.size();
        boolean thereWasErrors = false;

        // parse of all source files that were not yet parsed. That may include some
        // generic prototypes that were instantiated in the previous round of the above
        // while statement.
        for (int i = numCompilationUnitsAlreadyCompiled;
            i < sizeNonGenericCompilationUnitList;
            i++) {
          compilationUnit = nonGenericCompilationUnitList.get(i);

          // System.out.println("cc: " + compilationUnit.getFilename());
          compiler = new Compiler(compilationUnit, compInstSet, compilationStep, project, null);
          compiler.parse();
          // if ( ! compilationUnit.hasCompilationError() ) {
          // }
          if (compilationUnit.hasCompilationError()) {
            thereWasErrors = true;
            // compilationUnit.printErrorList(printWriter);
          } else if (compInstSet.contains(CompilationInstruction.createPrototypesForInterfaces)
              && compilationUnit.getPrototypeIsNotGeneric()
              && compilationUnit.getPublicPrototype() instanceof InterfaceDec) {
            // if public program unit is an interface, create ProtoInterface
            CompilationUnit newCompilationUnit = compilationUnit.createProtoInterface();
            if (newCompilationUnit == null) {
              if (compilationUnit.hasCompilationError()) {
                thereWasErrors = true;
                compilationUnit.printErrorList(printWriter);
              }
            } else {
              CyanPackage thisCyanPackage = compilationUnit.getCyanPackage();

              thisCyanPackage.addCompilationUnit(newCompilationUnit);
              newCompilationUnit.setCyanPackage(thisCyanPackage);
              nonGenericCompilationUnitList.add(newCompilationUnit);

              String name = newCompilationUnit.getFilename();
              int indexDotCyan = name.indexOf(dotExtension);
              if (indexDotCyan > 0) name = name.substring(0, indexDotCyan);

              program.addCompilationUnit(newCompilationUnit);

              if (nameSet.contains(newCompilationUnit.getFilename()))
                System.out.println("error: " + newCompilationUnit.getFilename());
              else nameSet.add(newCompilationUnit.getFilename());
            }
          }
          // if there was not any errors and there is a list of actions ...
          /*if ( compilationUnit.getActionList().size() > 0 )
          	compilationUnit.doActionList(printWriter);
          compilationUnit.clearErrorsActions(); */
        }

        if (thereWasErrors) {
          return false;
        }
        numCompilationUnitsAlreadyCompiled = sizeNonGenericCompilationUnitList;
      }

    } catch (Exception e) {
      System.out.println(
          "Internal error at CompilerManager::compile(). e = " + e.getClass().getName());
      e.printStackTrace();
      return false;
    }

    project.printErrorList(printWriter);
    return true;
  }
Beispiel #2
0
  public void run(String[] args) {

    File file;
    if (args.length < 1 || args.length > 2) {
      System.out.println("Usage:\n   comp input");
      System.out.println("input is the file or directory to be compiled");
      System.out.println("the output file will be created in the current directory");
    } else {

      numSourceFilesWithErros = 0;
      int numSourceFiles = 0;
      shouldButWereNotList = new ArrayList<>();
      wereButShouldNotList = new ArrayList<>();
      wereButWrongLineList = new ArrayList<>();
      correctList = new ArrayList<>();

      PrintWriter outError;
      outError = new PrintWriter(System.out);

      PrintWriter report;
      FileOutputStream reportStream = null;
      try {
        reportStream = new FileOutputStream("report.txt");
      } catch (FileNotFoundException e) {
        outError.println("Could not create 'report.txt'");
        return;
      }
      report = new PrintWriter(reportStream);

      file = new File(args[0]);
      if (!file.exists() || !file.canRead()) {
        String msg = "Either the file " + args[0] + " does not exist or it cannot be read";
        System.out.println(msg);
        outError.println("-1 : " + msg);
        outError.close();
        report.close();
        return;
      }
      if (file.isDirectory()) {
        // compile all files in this directory
        File fileList[] = file.listFiles();
        for (File f : fileList) {
          String filename = f.getName();
          int lastIndexDot = filename.lastIndexOf('.');
          String ext = filename.substring(lastIndexDot + 1);
          if (ext.equalsIgnoreCase("kra")) {
            numSourceFiles++;
            compileProgram(f, filename, outError);
          }
        }
        printReport(numSourceFiles, report);

      } else {
        compileProgram(file, args[0], outError);
        printReport(1, report);
      }

      report.close();
      System.out.println("Krakatoa compiler finished");
    }
  }