src/Pure/System/build.scala
changeset 48337 9c7f8e5805b4
parent 48336 3c55bfad22eb
child 48339 62570361e608
equal deleted inserted replaced
48336:3c55bfad22eb 48337:9c7f8e5805b4
     6 
     6 
     7 package isabelle
     7 package isabelle
     8 
     8 
     9 
     9 
    10 import java.io.File
    10 import java.io.File
       
    11 
       
    12 import scala.collection.mutable
    11 
    13 
    12 
    14 
    13 object Build
    15 object Build
    14 {
    16 {
    15   /* command line entry point */
    17   /* command line entry point */
    62 
    64 
    63     0
    65     0
    64   }
    66   }
    65 
    67 
    66 
    68 
    67   /* session information */
    69   /** session information **/
    68 
       
    69   val ROOT_NAME = "ROOT"
       
    70 
    70 
    71   type Options = List[(String, Option[String])]
    71   type Options = List[(String, Option[String])]
    72 
    72 
    73   case class Session_Info(
    73   case class Session_Info(
    74     dir: Path,
    74     dir: Path,
    75     name: String,
    75     name: String,
    76     reset_name: Boolean,
       
    77     parent: String,
    76     parent: String,
    78     description: String,
    77     description: String,
    79     options: Options,
    78     options: Options,
    80     theories: List[(Options, String)],
    79     theories: List[(Options, String)],
       
    80     files: List[String])
       
    81 
       
    82   private val pure_info =
       
    83     Session_Info(Path.current, "Pure", "", "", Nil, List((Nil, "Pure")), Nil)
       
    84 
       
    85 
       
    86   /* parsing */
       
    87 
       
    88   val ROOT_NAME = "ROOT"
       
    89 
       
    90   private case class Session_Entry(
       
    91     name: String,
       
    92     reset: Boolean,
       
    93     path: Option[String],
       
    94     parent: String,
       
    95     description: String,
       
    96     options: Options,
       
    97     theories: List[(Options, List[String])],
    81     files: List[String])
    98     files: List[String])
    82 
    99 
    83   private object Parser extends Parse.Parser
   100   private object Parser extends Parse.Parser
    84   {
   101   {
    85     val SESSION = "session"
   102     val SESSION = "session"
    91 
   108 
    92     val syntax =
   109     val syntax =
    93       Outer_Syntax.empty + "!" + "(" + ")" + "+" + "," + "=" + "[" + "]" +
   110       Outer_Syntax.empty + "!" + "(" + ")" + "+" + "," + "=" + "[" + "]" +
    94         SESSION + IN + DESCRIPTION + OPTIONS + THEORIES + FILES
   111         SESSION + IN + DESCRIPTION + OPTIONS + THEORIES + FILES
    95 
   112 
    96     def session_info(dir: Path): Parser[Session_Info] =
   113     val session_entry: Parser[Session_Entry] =
    97     {
   114     {
    98       val session_name = atom("session name", _.is_name)
   115       val session_name = atom("session name", _.is_name)
    99       val theory_name = atom("theory name", _.is_name)
   116       val theory_name = atom("theory name", _.is_name)
   100 
   117 
   101       val option =
   118       val option =
   102         name ~ opt(keyword("=") ~! name ^^ { case _ ~ x => x }) ^^ { case x ~ y => (x, y) }
   119         name ~ opt(keyword("=") ~! name ^^ { case _ ~ x => x }) ^^ { case x ~ y => (x, y) }
   103       val options: Parser[Options] =
   120       val options = keyword("[") ~> repsep(option, keyword(",")) <~ keyword("]")
   104         keyword("[") ~> repsep(option, keyword(",")) <~ keyword("]")
       
   105 
   121 
   106       val theories =
   122       val theories =
   107         keyword(THEORIES) ~! ((options | success(Nil)) ~ rep1(theory_name)) ^^
   123         keyword(THEORIES) ~! ((options | success(Nil)) ~ rep1(theory_name)) ^^
   108           { case _ ~ (x ~ y) => (x, y) }
   124           { case _ ~ (x ~ y) => (x, y) }
   109 
   125 
   110       ((keyword(SESSION) ~! session_name) ^^ { case _ ~ x => x }) ~
   126       ((keyword(SESSION) ~! session_name) ^^ { case _ ~ x => x }) ~
   111         (keyword("!") ^^^ true | success(false)) ~
   127         (keyword("!") ^^^ true | success(false)) ~
   112         (opt(keyword(IN) ~! string ^^ { case _ ~ x => Path.explode(x) })) ~
   128         (opt(keyword(IN) ~! string ^^ { case _ ~ x => x })) ~
   113         (keyword("=") ~> session_name <~ keyword("+")) ~
   129         (keyword("=") ~> session_name <~ keyword("+")) ~
   114         (keyword(DESCRIPTION) ~! text ^^ { case _ ~ x => x } | success("")) ~
   130         (keyword(DESCRIPTION) ~! text ^^ { case _ ~ x => x } | success("")) ~
   115         (keyword(OPTIONS) ~! options ^^ { case _ ~ x => x } | success(Nil)) ~
   131         (keyword(OPTIONS) ~! options ^^ { case _ ~ x => x } | success(Nil)) ~
   116         rep(theories) ~
   132         rep1(theories) ~
   117         (keyword(FILES) ~! rep1(path) ^^ { case _ ~ x => x } | success(Nil)) ^^
   133         (keyword(FILES) ~! rep1(path) ^^ { case _ ~ x => x } | success(Nil)) ^^
   118           { case a ~ b ~ c ~ d ~ e ~ f ~ g ~ h =>
   134           { case a ~ b ~ c ~ d ~ e ~ f ~ g ~ h => Session_Entry(a, b, c, d, e, f, g, h) }
   119               val dir1 = dir + c.getOrElse(Path.basic(a))
       
   120               val thys = g.map({ case (x, ys) => ys.map(y => (x, y)) }).flatten
       
   121               Session_Info(dir1, a, b, d, e, f, thys, h) }
       
   122     }
   135     }
   123 
   136 
   124     def parse_entries(dir: Path, root: File): List[Session_Info] =
   137     def parse_entries(root: File): List[Session_Entry] =
   125     {
   138     {
   126       val toks = syntax.scan(Standard_System.read_file(root))
   139       val toks = syntax.scan(Standard_System.read_file(root))
   127       parse_all(rep(session_info(dir)), Token.reader(toks, root.toString)) match {
   140       parse_all(rep(session_entry), Token.reader(toks, root.toString)) match {
   128         case Success(result, _) => result
   141         case Success(result, _) => result
   129         case bad => error(bad.toString)
   142         case bad => error(bad.toString)
   130       }
   143       }
   131     }
   144     }
   132   }
   145   }
   133 
   146 
   134   def find_sessions(): List[Session_Info] =
   147 
       
   148   /* find session */
       
   149 
       
   150   def find_sessions(more_dirs: List[Path] = Nil): List[Session_Info] =
   135   {
   151   {
       
   152     val infos = new mutable.ListBuffer[Session_Info]
       
   153     infos += pure_info
       
   154 
   136     for {
   155     for {
   137       dir <- Isabelle_System.components()
   156       dir <- Isabelle_System.components() ++ more_dirs
   138       root = Isabelle_System.platform_file(dir + Path.basic(ROOT_NAME))
   157       root = Isabelle_System.platform_file(dir + Path.basic(ROOT_NAME))
   139       if root.isFile
   158       if root.isFile
   140       entry <- Parser.parse_entries(dir, root)
   159       entry <- Parser.parse_entries(root)
   141     } yield entry
   160     }
       
   161     {
       
   162       try {
       
   163         val parent =
       
   164           infos.find(_.name == entry.parent) getOrElse
       
   165            error("Unknown parent session: " + quote(entry.parent))
       
   166         val full_name =
       
   167           if (entry.reset) entry.name
       
   168           else parent.name + "-" + entry.name
       
   169         val path =
       
   170           entry.path match {
       
   171             case Some(p) => Path.explode(p)
       
   172             case None => Path.basic(entry.name)
       
   173           }
       
   174         val thys = entry.theories.map({ case (x, ys) => ys.map(y => (x, y)) }).flatten
       
   175         val info =
       
   176           Session_Info(dir + path, full_name, entry.parent, entry.description,
       
   177             entry.options, thys, entry.files)
       
   178         infos += info
       
   179       }
       
   180       catch {
       
   181         case ERROR(msg) =>
       
   182           error(msg + "\nThe error(s) above occurred in session entry " +
       
   183             quote(entry.name) + " (file " + quote(root.toString) + ")")
       
   184       }
       
   185     }
       
   186     infos.toList
   142   }
   187   }
   143 }
   188 }
   144 
   189