logo
class

compiler::Main

sys::Obj
  compiler::Main
   1  //
   2  // Copyright (c) 2006, Brian Frank and Andy Frank
   3  // Licensed under the Academic Free License version 3.0
   4  //
   5  // History:
   6  //   15 Sep 05  Brian Frank  Creation
   7  //    3 Jun 06  Brian Frank  Ported from Java to Fan - Megan's b-day
   8  //
   9  
  10  **
  11  ** Main is the main entry point for the Fan compiler.  It handles
  12  ** all the argument processing and misc commands like help, version,
  13  **
  14  class Main
  15  {
  16  
  17  //////////////////////////////////////////////////////////////////////////
  18  // Run
  19  //////////////////////////////////////////////////////////////////////////
  20  
  21    **
  22    ** Main entry point for compiler.
  23    **
  24    Int run(Str[] args)
  25    {
  26      t1 := Duration.now
  27      success := true
  28  
  29      // process args
  30      if (!parseArgs(args)) return 0
  31  
  32      // process each directory specified
  33      try
  34      {
  35        compile
  36      }
  37      catch (CompilerErr err)
  38      {
  39        // all errors should already be logged by Compiler
  40        success = false;
  41      }
  42      catch (Err err)
  43      {
  44        log.compilerErr(CompilerErr.make("Internal compiler error"null, err));
  45        err.trace
  46        success = false;
  47      }
  48  
  49      t2 := Duration.now
  50      if (success)
  51      {
  52        println("SUCCESS (" + (t2-t1).toMillis + "ms)")
  53        return 0
  54      }
  55      else
  56      {
  57        println("FAILED (" + (t2-t1).toMillis + "ms)")
  58        return -1
  59      }
  60    }
  61  
  62    **
  63    ** Process command line args and return false if we should exit.
  64    **
  65    Bool parseArgs(Str[] args)
  66    {
  67      if (args.isEmpty)
  68      {
  69        help
  70        return false
  71      }
  72  
  73      for (i:=0; i<args.size; ++i)
  74      {
  75        a := args[i]
  76        if (a.isEmpty) continue
  77        if (a == "-help" || a == "-h" || a == "-?")
  78        {
  79          help
  80          return false
  81        }
  82        else if (a == "-version")
  83        {
  84          version
  85          return false
  86        }
  87        else if (a == "-d")
  88        {
  89          if (i+1 >= args.size)
  90          {
  91            println("ERROR: must specified dir with -d option")
  92            return false
  93          }
  94          outDir = File.make(args[++i].toUri).normalize
  95        }
  96        else if (a == "-src")
  97        {
  98          includeSrc = true
  99        }
 100        else if (a == "-doc")
 101        {
 102          includeDoc = true
 103        }
 104        else if (a == "-v")
 105        {
 106          log.level = LogLevel.verbose
 107        }
 108        else if (a == "-silent")
 109        {
 110          log.level = LogLevel.silent
 111        }
 112        else if (a[0] == '-')
 113        {
 114          println("WARNING: Unknown option " + a)
 115        }
 116        else
 117        {
 118          if (podName == null)
 119            podName = a
 120          else
 121            srcDirs.add(File.make(a.toUri))
 122        }
 123      }
 124  
 125      // if no dirs were specified, assume current dir
 126      if (podName == null || srcDirs.isEmpty)
 127      {
 128        println("ERROR: not enough arguments")
 129        help
 130        return false
 131      }
 132  
 133      return true
 134    }
 135  
 136    **
 137    ** Dump help usage.
 138    **
 139    Void help()
 140    {
 141      println("Fan Compiler (the one written in Fan itself)")
 142      println("Usage:")
 143      println("  ffanc [options] <podName> <srcDir>*")
 144      println("Options:")
 145      println("  -help, -h, -?  print usage help")
 146      println("  -version       print version information")
 147      println("  -d <dir>       output directory for pod file")
 148      println("  -doc           include fandoc in pod")
 149      println("  -src           include source code in pod")
 150      println("  -v             verbose mode (more logging)")
 151      println("  -silent        silent mode (no logging)")
 152    }
 153  
 154    **
 155    ** Dump version.
 156    **
 157    Void version()
 158    {
 159      println("Fan Compiler - Version ${type.pod.version}")
 160      println("Copyright (c) 2006, Brian Frank and Andy Frank")
 161      println("Licensed under the Academic Free License version 3.0")
 162    }
 163  
 164    **
 165    ** Compile using current configuration
 166    **
 167    Void compile()
 168    {
 169      input := CompilerInput.make
 170      input.podName    = podName
 171      input.log        = log
 172      input.mode       = CompilerInputMode.file
 173      input.homeDir    = srcDirs.first.parent
 174      input.srcDirs    = srcDirs
 175      input.includeDoc = includeDoc
 176      input.includeSrc = includeSrc
 177      input.output     = CompilerOutputMode.podFile
 178      if (outDir != null) input.outDir = outDir
 179  
 180      Compiler.make(input).compile
 181    }
 182  
 183    **
 184    ** Compile the script file into a transient pod
 185    **
 186    static Pod compileScript(File file)
 187    {
 188      input := CompilerInput.make
 189      input.log.level      = LogLevel.error
 190      input.podName        = "script_$file.basename"
 191      input.isScript       = true
 192      input.srcStr         = file.readAllStr
 193      input.srcStrLocation = Location.makeFile(file)
 194      input.mode           = CompilerInputMode.str
 195      input.output         = CompilerOutputMode.transientPod
 196      return Compiler.make(input).compile.transientPod
 197    }
 198  
 199  //////////////////////////////////////////////////////////////////////////
 200  // Utils
 201  //////////////////////////////////////////////////////////////////////////
 202  
 203    Void println(Obj s)
 204    {
 205      log.printLine(s)
 206    }
 207  
 208  //////////////////////////////////////////////////////////////////////////
 209  // Main
 210  //////////////////////////////////////////////////////////////////////////
 211  
 212    static Void main()
 213    {
 214      Sys.exit(make.run(Sys.args))
 215    }
 216  
 217  //////////////////////////////////////////////////////////////////////////
 218  // Fields
 219  //////////////////////////////////////////////////////////////////////////
 220  
 221    Str podName
 222    File[] srcDirs := File[,]    // directories to build
 223    File outDir := null          // -d output directory
 224    CompilerLog log := CompilerLog.make  // logging, -v verbose output
 225    Bool includeDoc := false     // include fandoc in output pod
 226    Bool includeSrc := false     // include source code in output pod
 227  
 228  }