<commit_before>package org.mozartoz.bootcompiler

import java.io.{ Console => _, _ }

import scala.collection.immutable.PagedSeq
import scala.util.parsing.combinator._
import scala.util.parsing.input._
import scala.util.parsing.json._

import parser._
import ast._
import transform._
import symtab._
import util._

case class Config(
    fileName: String = "",
    outputStream: PrintStream = Console.out,
    moduleDefs: List[String] = Nil
)

object Main {
  def main(args: Array[String]) {
    // Define command-line options
    val optParser = new scopt.immutable.OptionParser[Config]("scopt", "2.x") {
      def options = Seq(
        opt("o", "output", "output file") {
          (v: String, c: Config) => c.copy(outputStream = new PrintStream(v))
        },
        opt("m", "module", "module definition file") {
          (v: String, c: Config) => c.copy(moduleDefs = v :: c.moduleDefs)
        },
        arg("<file>", "input file") {
          (v: String, c: Config) => c.copy(fileName = v)
        }
      )
    }

    // Parse the options
    optParser.parse(args, Config()) map { config =>
      // OK, we're good to go
      import config._

      val reader = new PagedSeqReader(PagedSeq.fromReader(
          new BufferedReader(new FileReader(fileName))))
      val parser = new OzParser()

      parser.parse(reader) match {
        case parser.Success(rawCode, _) =>
          produce(rawCode, outputStream, moduleDefs)
        case parser.NoSuccess(msg, _) =>
          Console.err.println(msg)
      }
    } getOrElse {
      // Bad command-line arguments
      optParser.showUsage
    }
  }

  def produce(rawCode: Statement, outputStream: PrintStream,
      moduleDefs: List[String]) {
    val prog = new Program(rawCode)
    loadModuleDefs(prog, moduleDefs)
    loadBaseEnvironment(prog)
    applyTransforms(prog)

    prog.produceCC(new Output(outputStream))
  }

  private def loadModuleDefs(prog: Program, moduleDefs: List[String]) {
    JSON.globalNumberParser = (_.toInt)

    for (moduleDef <- moduleDefs) {
      val file = new File(moduleDef)

      if (file.isFile())
        loadModuleDef(prog, file)
      else {
        val pattern = """.*-builtin\.json$""".r
        for {
          f <- file.listFiles()
          if (pattern.findFirstIn(f.getName).isDefined)
        } {
          loadModuleDef(prog, f)
        }
      }
    }
  }

  private def loadModuleDef(prog: Program, moduleDef: File) {
    class CC[T] {
      def unapply(a: Any): Option[T] = Some(a.asInstanceOf[T])
    }

    object M extends CC[Map[String, Any]]
    object L extends CC[List[Any]]
    object S extends CC[String]<commit_msg>Better integration with build tools on failure.<commit_after>package org.mozartoz.bootcompiler

import java.io.{ Console => _, _ }

import scala.collection.immutable.PagedSeq
import scala.util.parsing.combinator._
import scala.util.parsing.input._
import scala.util.parsing.json._

import parser._
import ast._
import transform._
import symtab._
import util._

case class Config(
    fileName: String = "",
    outputStream: () => PrintStream = () => Console.out,
    moduleDefs: List[String] = Nil
)

object Main {
  def main(args: Array[String]) {
    // Define command-line options
    val optParser = new scopt.immutable.OptionParser[Config]("scopt", "2.x") {
      def options = Seq(
        opt("o", "output", "output file") {
          (v: String, c: Config) => c.copy(
              outputStream = () => new PrintStream(v))
        },
        opt("m", "module", "module definition file") {
          (v: String, c: Config) => c.copy(moduleDefs = v :: c.moduleDefs)
        },
        arg("<file>", "input file") {
          (v: String, c: Config) => c.copy(fileName = v)
        }
      )
    }

    // Parse the options
    optParser.parse(args, Config()) map { config =>
      // OK, we're good to go
      import config._

      try {
        val reader = new PagedSeqReader(PagedSeq.fromReader(
            new BufferedReader(new FileReader(fileName))))
        val parser = new OzParser()

        parser.parse(reader) match {
          case parser.Success(rawCode, _) =>
            produce(rawCode, outputStream, moduleDefs)
          case parser.NoSuccess(msg, _) =>
            Console.err.println(msg)
            sys.exit(2)
        }
      } catch {
        case th: Throwable =>
          th.printStackTrace()
          sys.exit(2)
      }
    } getOrElse {
      // Bad command-line arguments
      optParser.showUsage
      sys.exit(1)
    }
  }

  def produce(rawCode: Statement, outputStream: () => PrintStream,
      moduleDefs: List[String]) {
    val prog = new Program(rawCode)
    loadModuleDefs(prog, moduleDefs)
    loadBaseEnvironment(prog)
    applyTransforms(prog)

    prog.produceCC(new Output(outputStream()))
  }

  private def loadModuleDefs(prog: Program, moduleDefs: List[String]) {
    JSON.globalNumberParser = (_.toInt)

    for (moduleDef <- moduleDefs) {
      val file = new File(moduleDef)

      if (file.isFile())
        loadModuleDef(prog, file)
      else {
        val pattern = """.*-builtin\.json$""".r
        for {
          f <- file.listFiles()
          if (pattern.findFirstIn(f.getName).isDefined)
        } {
          loadModuleDef(prog, f)
        }
      }
    }
  }

  private def loadModuleDef(prog: Program, moduleDef: File) {
    class CC[T] {
      def unapply(a: Any): Option[T] = Some(a.asInstanceOf[T])
    }

    object M extends CC[Map[String, Any]]
    object L extends CC[List[Any]]
    object S extends CC[String]
{'fraction_non_alphanumeric': 0.12865919768702566, 'fraction_numerical': 0.0009035056017347307, 'mean_word_length': 2.4314941103533787, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2560441', 'n_tokens_mistral': 1763, 'n_tokens_neox': 1725, 'n_words': 405}