diff options
| author | Richard Lin | 2016-06-08 17:12:42 -0700 |
|---|---|---|
| committer | Richard Lin | 2016-06-08 17:12:42 -0700 |
| commit | 07fa5622ccc995f925d6d967d2a386540c9064cc (patch) | |
| tree | fab4d62dba2ffb78e673ee54939d9088739a79f1 /chiselFrontend/src/main/scala/chisel/internal/Error.scala | |
| parent | 53813f61b7dfe246d214ab966739d01c65c8ecb0 (diff) | |
| parent | 68447044e8eba5c8f525639130f1a347677ff543 (diff) | |
Merge pull request #197 from ucb-bar/lowercaseChisel
Rename package Chisel to chisel, add Chisel package for compatibility
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel/internal/Error.scala')
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel/internal/Error.scala | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/chiselFrontend/src/main/scala/chisel/internal/Error.scala b/chiselFrontend/src/main/scala/chisel/internal/Error.scala new file mode 100644 index 00000000..f0481dc4 --- /dev/null +++ b/chiselFrontend/src/main/scala/chisel/internal/Error.scala @@ -0,0 +1,91 @@ +// See LICENSE for license details. + +package chisel.internal + +import scala.collection.mutable.ArrayBuffer + +import chisel.core._ + +class ChiselException(message: String, cause: Throwable) extends Exception(message, cause) + +private[chisel] object throwException { + def apply(s: String, t: Throwable = null): Nothing = + throw new ChiselException(s, t) +} + +/** Records and reports runtime errors and warnings. */ +private[chisel] class ErrorLog { + def hasErrors: Boolean = errors.exists(_.isFatal) + + /** Log an error message */ + def error(m: => String): Unit = + errors += new Error(m, getUserLineNumber) + + /** Log a warning message */ + def warning(m: => String): Unit = + errors += new Warning(m, getUserLineNumber) + + /** Emit an informational message */ + def info(m: String): Unit = + println(new Info("[%2.3f] %s".format(elapsedTime/1e3, m), None)) // scalastyle:ignore regex + + /** Prints error messages generated by Chisel at runtime. */ + def report(): Unit = errors foreach println // scalastyle:ignore regex + + /** Throw an exception if any errors have yet occurred. */ + def checkpoint(): Unit = if(hasErrors) { + import Console._ + throwException(errors.map(_ + "\n").reduce(_ + _) + + UNDERLINED + "CODE HAS " + errors.filter(_.isFatal).length + RESET + + UNDERLINED + " " + RED + "ERRORS" + RESET + + UNDERLINED + " and " + errors.filterNot(_.isFatal).length + RESET + + UNDERLINED + " " + YELLOW + "WARNINGS" + RESET) + } + + private def findFirstUserFrame(stack: Array[StackTraceElement]): Option[StackTraceElement] = { + def isUserCode(ste: StackTraceElement): Boolean = { + def isUserModule(c: Class[_]): Boolean = + c != null && (c == classOf[Module] || isUserModule(c.getSuperclass)) + isUserModule(Class.forName(ste.getClassName)) + } + + stack.indexWhere(isUserCode) match { + case x if x < 0 => None + case x => Some(stack(x)) + } + } + + private def getUserLineNumber = + findFirstUserFrame(Thread.currentThread().getStackTrace) + + private val errors = ArrayBuffer[LogEntry]() + + private val startTime = System.currentTimeMillis + private def elapsedTime: Long = System.currentTimeMillis - startTime +} + +private abstract class LogEntry(msg: => String, line: Option[StackTraceElement]) { + def isFatal: Boolean = false + def format: String + + override def toString: String = line match { + case Some(l) => s"${format} ${l.getFileName}:${l.getLineNumber}: ${msg} in class ${l.getClassName}" + case None => s"${format} ${msg}" + } + + protected def tag(name: String, color: String): String = + s"[${color}${name}${Console.RESET}]" +} + +private class Error(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) { + override def isFatal: Boolean = true + def format: String = tag("error", Console.RED) +} + +private class Warning(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) { + def format: String = tag("warn", Console.YELLOW) +} + +private class Info(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) { + def format: String = tag("info", Console.MAGENTA) +} |
