mirror of
https://github.com/nasa/fpp.git
synced 2025-12-15 04:05:00 -06:00
834 lines
31 KiB
Scala
834 lines
31 KiB
Scala
package fpp.compiler.util
|
|
|
|
import fpp.compiler.util.Location
|
|
import java.util.Locale
|
|
|
|
/** An exception for signaling internal compiler errors */
|
|
final case class InternalError(val msg: String) extends Exception {
|
|
override def toString = s"internal error: $msg"
|
|
}
|
|
|
|
/** A data type for handling compilation errors */
|
|
sealed trait Error {
|
|
|
|
/** Print the location of a port matching */
|
|
def printMatchingLoc(matchingLoc: Location): Unit = {
|
|
System.err.println("port matching is specified here:")
|
|
System.err.println(matchingLoc)
|
|
}
|
|
|
|
/** Print the location of a previous occurrence */
|
|
def printPrevLoc(prevLoc: Location): Unit = {
|
|
System.err.println("previous occurrence is here:")
|
|
System.err.println(prevLoc)
|
|
}
|
|
|
|
/** Print a note */
|
|
def printNote(note: String) = System.err.println(s"note: $note")
|
|
|
|
/*** Print the error */
|
|
def print: Unit = {
|
|
this match {
|
|
case SyntaxError(loc, msg) => Error.print (Some(loc)) (msg)
|
|
case CodeGenError.DuplicateCppFile(file, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate C++ file ${file}")
|
|
System.err.println("previous file would be generated here:")
|
|
System.err.println(prevLoc)
|
|
case CodeGenError.DuplicateJsonFile(file, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate JSON file ${file}")
|
|
System.err.println("previous file would be generated here:")
|
|
System.err.println(prevLoc)
|
|
case CodeGenError.DuplicateXmlFile(file, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate XML file ${file}")
|
|
System.err.println("previous file would be generated here:")
|
|
System.err.println(prevLoc)
|
|
case CodeGenError.EmptyStruct(loc) =>
|
|
Error.print (Some(loc)) (s"cannot write XML for an empty struct")
|
|
case IncludeError.Cycle(loc, msg) => Error.print (Some(loc)) (msg)
|
|
case FileError.CannotOpen(locOpt, name) =>
|
|
Error.print (locOpt) (s"cannot open file $name")
|
|
case FileError.CannotResolvePath(loc, name) =>
|
|
Error.print (Some(loc)) (s"cannot resolve path $name")
|
|
case MultiError(errors) =>
|
|
errors.foreach(_.print)
|
|
case SemanticError.ChannelNotInDictionary(loc, channelName, topologyName) =>
|
|
Error.print (Some(loc)) (s"channel $channelName is not in the dictionary for topology $topologyName")
|
|
case SemanticError.DivisionByZero(loc) =>
|
|
Error.print (Some(loc)) ("division by zero")
|
|
case SemanticError.DuplicateConnectionAtMatchedPort(loc, port, portNum, prevLoc, matchingLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate connection at matched port $port[$portNum]")
|
|
printPrevLoc(prevLoc)
|
|
printMatchingLoc(matchingLoc)
|
|
case SemanticError.DuplicateDictionaryName(kind, name, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate ${kind} name ${name}")
|
|
printPrevLoc(prevLoc)
|
|
case SemanticError.DuplicateEnumValue(value, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate enum value ${value}")
|
|
printPrevLoc(prevLoc)
|
|
case SemanticError.DuplicateIdValue(value, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate identifier value ${value}")
|
|
printPrevLoc(prevLoc)
|
|
case SemanticError.DuplicateInitSpecifier(phase, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate initialization for phase ${phase}")
|
|
printPrevLoc(prevLoc)
|
|
case SemanticError.DuplicateInstance(name, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate instance $name")
|
|
printPrevLoc(prevLoc)
|
|
case SemanticError.DuplicateLimit(loc, prevLoc) =>
|
|
Error.print (Some(loc)) ("duplicate limit")
|
|
printPrevLoc(prevLoc)
|
|
case SemanticError.DuplicateMatchedConnection(
|
|
loc,
|
|
prevLoc,
|
|
matchingLoc
|
|
) =>
|
|
Error.print (Some(loc)) ("duplicate connection between a matched port array and a single instance")
|
|
printPrevLoc(prevLoc)
|
|
printMatchingLoc(matchingLoc)
|
|
printNote("each port in a matched port array must be connected to a separate instance")
|
|
case SemanticError.DuplicateOpcodeValue(value, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate opcode value ${value}")
|
|
printPrevLoc(prevLoc)
|
|
case SemanticError.DuplicateOutputConnection(loc, portNum, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate connection at output port $portNum")
|
|
printPrevLoc(prevLoc)
|
|
case SemanticError.DuplicateParameter(name, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate parameter ${name}")
|
|
System.err.println("previous parameter is here:")
|
|
System.err.println(prevLoc)
|
|
case SemanticError.DuplicatePattern(kind, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate $kind pattern")
|
|
printPrevLoc(prevLoc)
|
|
case SemanticError.DuplicatePortInstance(name, loc, importLocs, prevLoc, prevImportLocs) =>
|
|
Error.print (Some(loc)) (s"duplicate port instance ${name}")
|
|
if (importLocs.nonEmpty) {
|
|
System.err.println(s"port imported from here")
|
|
importLocs.map(System.err.println)
|
|
}
|
|
System.err.println("previous instance is here:")
|
|
System.err.println(prevLoc)
|
|
if (prevImportLocs.nonEmpty) {
|
|
System.err.println(s"previous instance imported from here")
|
|
prevImportLocs.reverse.map(System.err.println)
|
|
}
|
|
case SemanticError.DuplicateStateMachineInstance(name, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate state machine instance name ${name}")
|
|
printPrevLoc(prevLoc)
|
|
case SemanticError.DuplicateStructMember(name, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate struct member ${name}")
|
|
System.err.println("previous member is here:")
|
|
System.err.println(prevLoc)
|
|
case SemanticError.DuplicateTlmPacketSet(name, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate telemetry packet set ${name}")
|
|
System.err.println("previous set is here:")
|
|
System.err.println(prevLoc)
|
|
case SemanticError.DuplicateTopology(name, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate topology ${name}")
|
|
printPrevLoc(prevLoc)
|
|
case SemanticError.DuplicateInterface(name, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate interface ${name}")
|
|
printPrevLoc(prevLoc)
|
|
case SemanticError.EmptyArray(loc) =>
|
|
Error.print (Some(loc)) ("array expression may not be empty")
|
|
case SemanticError.ImplicitDuplicateConnectionAtMatchedPort(
|
|
loc,
|
|
port,
|
|
portNum,
|
|
implyingLoc,
|
|
matchingLoc,
|
|
prevLoc
|
|
) =>
|
|
Error.print (Some(loc)) (s"implicit duplicate connection at matched port $port[$portNum]")
|
|
System.err.println("connection is implied here:")
|
|
System.err.println(implyingLoc)
|
|
System.err.println("because of matching specified here:")
|
|
System.err.println(matchingLoc)
|
|
System.err.println("conflicting connection is here:")
|
|
System.err.println(prevLoc)
|
|
case SemanticError.InconsistentDictionarySpecifier(loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"inconsistent location specifier")
|
|
printPrevLoc(prevLoc)
|
|
printNote("one specifies dictionary and one does not")
|
|
case SemanticError.InconsistentLocationPath(loc, path, prevLoc, prevPath) =>
|
|
Error.print (Some(loc)) (s"inconsistent location path ${path}")
|
|
printPrevLoc(prevLoc)
|
|
System.err.println(s"previous path is ${prevPath}")
|
|
case SemanticError.IncorrectDictionarySpecifier(loc, defLoc) =>
|
|
Error.print (Some(loc)) (s"incorrect location specifier")
|
|
System.err.println(s"actual definition is here:")
|
|
System.err.println(defLoc)
|
|
printNote("one specifies dictionary and one does not")
|
|
case SemanticError.IncorrectLocationPath(loc, specifiedPath, actualLoc) =>
|
|
Error.print (Some(loc)) (s"incorrect location path ${specifiedPath}")
|
|
System.err.println(s"actual location is ${actualLoc}")
|
|
case SemanticError.InvalidArraySize(loc, size) =>
|
|
Error.print (Some(loc)) (s"invalid array size $size")
|
|
printNote("size must be greater than zero")
|
|
case SemanticError.InvalidCommand(loc, msg) =>
|
|
Error.print (Some(loc)) (msg)
|
|
case SemanticError.InvalidComponentInstance(loc, instanceName, topName) =>
|
|
Error.print (Some(loc)) (s"instance $instanceName is not a member of topology $topName")
|
|
case SemanticError.InvalidConnection(loc, msg, fromLoc, toLoc, fromPortDefLoc, toPortDefLoc) =>
|
|
Error.print (Some(loc)) (msg)
|
|
System.err.println("from port is specified here:")
|
|
System.err.println(fromLoc)
|
|
System.err.println("to port is specified here:")
|
|
System.err.println(toLoc)
|
|
fromPortDefLoc match {
|
|
case Some(loc) =>
|
|
System.err.println("from port type is defined here:")
|
|
System.err.println(loc)
|
|
case _ => ()
|
|
}
|
|
toPortDefLoc match {
|
|
case Some(loc) =>
|
|
System.err.println("to port type is defined here:")
|
|
System.err.println(loc)
|
|
case _ => ()
|
|
}
|
|
case SemanticError.InvalidDataProducts(loc, msg) =>
|
|
Error.print (Some(loc)) (msg)
|
|
case SemanticError.InvalidDefComponentInstance(name, loc, msg) =>
|
|
Error.print (Some(loc)) (s"invalid component instance definition $name: $msg")
|
|
case SemanticError.InvalidEnumConstants(loc) =>
|
|
Error.print (Some(loc)) ("enum constants must be all explicit or all implied")
|
|
case SemanticError.InvalidEvent(loc, msg) =>
|
|
Error.print (Some(loc)) (msg)
|
|
case SemanticError.InvalidFormatString(loc, msg) =>
|
|
Error.print (Some(loc)) (s"invalid format string: $msg")
|
|
case SemanticError.InvalidIntValue(loc, v, msg) =>
|
|
Error.print (Some(loc)) (s"invalid integer value $v")
|
|
System.err.println(msg)
|
|
case SemanticError.InvalidInternalPort(loc, msg) =>
|
|
Error.print (Some(loc)) (msg)
|
|
case SemanticError.InvalidPattern(loc, msg) =>
|
|
Error.print (Some(loc)) (msg)
|
|
case SemanticError.InvalidPortInstance(loc, msg, defLoc) =>
|
|
Error.print (Some(loc)) (msg)
|
|
System.err.println(s"port definition is here:")
|
|
System.err.println(defLoc)
|
|
case SemanticError.InvalidPortInstanceId(loc, portName, componentName) =>
|
|
Error.print (Some(loc)) (s"$portName is not a port instance of component $componentName")
|
|
case SemanticError.InvalidPortKind(loc, msg, specLoc) =>
|
|
Error.print (Some(loc)) (msg)
|
|
System.err.println(s"port instance is specified here:")
|
|
System.err.println(specLoc)
|
|
case SemanticError.InvalidPortMatching(loc, msg) =>
|
|
Error.print (Some(loc)) (msg)
|
|
case SemanticError.InvalidPortNumber(loc, portNumber, port, arraySize, specLoc) =>
|
|
Error.print (Some(loc)) (s"invalid port number $portNumber for port $port (max is ${arraySize - 1})")
|
|
System.err.println(s"port instance is specified here:")
|
|
System.err.println(specLoc)
|
|
case SemanticError.InvalidPriority(loc) =>
|
|
Error.print (Some(loc)) ("only async input may have a priority")
|
|
case SemanticError.InvalidQueueFull(loc) =>
|
|
Error.print (Some(loc)) ("only async input may have queue full behavior")
|
|
case SemanticError.InvalidSpecialPort(loc, msg) =>
|
|
Error.print (Some(loc)) (msg)
|
|
case SemanticError.InvalidStringSize(loc, size) =>
|
|
Error.print (Some(loc)) (s"invalid string size $size")
|
|
case SemanticError.InvalidAnonStructMember(memberName, loc, defLoc) =>
|
|
Error.print (Some(loc)) (s"no member $memberName in anonymous struct value")
|
|
System.err.println("symbol is defined here:")
|
|
System.err.println(defLoc)
|
|
case SemanticError.InvalidStructMember(memberName, loc, structTypeName, defLoc) =>
|
|
Error.print (Some(loc)) (s"no member $memberName in struct type $structTypeName")
|
|
System.err.println("symbol is defined here:")
|
|
System.err.println(defLoc)
|
|
case SemanticError.InvalidTypeForMemberSelection(memberName, loc, typeName) =>
|
|
Error.print (Some(loc)) (s"no member $memberName in value of type $typeName")
|
|
case SemanticError.InvalidSymbol(name, loc, msg, defLoc) =>
|
|
Error.print (Some(loc)) (s"invalid symbol $name: $msg")
|
|
System.err.println("symbol is defined here:")
|
|
System.err.println(defLoc)
|
|
case SemanticError.InvalidTlmChannelName(loc, channelName, componentName) =>
|
|
Error.print (Some(loc)) (s"$channelName is not a telemetry channel of component $componentName")
|
|
case SemanticError.InvalidTlmPacketSet(loc, name, msg) =>
|
|
Error.print (Some(loc)) (s"invalid telemetry packet set $name")
|
|
System.err.println(msg)
|
|
case SemanticError.InvalidType(loc, msg) =>
|
|
Error.print (Some(loc)) (msg)
|
|
case SemanticError.InvalidToken(loc, msg) =>
|
|
Error.print (Some(loc)) (s"invalid token: $msg")
|
|
case SemanticError.MismatchedPortNumbers(
|
|
p1Loc: Location,
|
|
p1Number: Int,
|
|
p2Loc: Location,
|
|
p2Number: Int,
|
|
matchingLoc: Location
|
|
) =>
|
|
Error.print (Some(p1Loc)) (s"mismatched port numbers ($p1Number vs. $p2Number)")
|
|
System.err.println("conflicting port number is here:")
|
|
System.err.println(p2Loc)
|
|
printMatchingLoc(matchingLoc)
|
|
case SemanticError.MissingAsync(kind, loc) =>
|
|
Error.print (Some(loc)) (s"$kind component must have async input")
|
|
case SemanticError.MissingConnection(loc, matchingLoc) =>
|
|
Error.print (Some(loc)) ("no match for this connection")
|
|
printMatchingLoc(matchingLoc)
|
|
case SemanticError.MissingPortMatching(loc) =>
|
|
Error.print (Some(loc)) ("unmatched connection must go from or to a matched port")
|
|
case SemanticError.MissingPort(loc, specMsg, portMsg) =>
|
|
Error.print (Some(loc)) (s"component with $specMsg must have $portMsg")
|
|
case SemanticError.NoPortAvailableForMatchedNumbering(loc1, loc2, matchingLoc) =>
|
|
Error.print (None) (s"no port available for matched numbering")
|
|
System.err.println("matched connections are specified here:")
|
|
System.err.println(loc1)
|
|
System.err.println(loc2)
|
|
printMatchingLoc(matchingLoc)
|
|
printNote("to be available, a port number must be in bounds and unassigned at each of the matched ports")
|
|
case SemanticError.OverlappingIdRanges(
|
|
baseId1, name1, loc1, baseId2, maxId2, name2, loc2
|
|
) =>
|
|
Error.print (None) (
|
|
s"base ID $baseId1 for instance $name1 lies inside the ID range [$baseId2, $maxId2] for instance $name2"
|
|
)
|
|
System.err.println(s"$name1 is defined here")
|
|
System.err.println(loc1)
|
|
System.err.println(s"$name2 is defined here")
|
|
System.err.println(loc2)
|
|
case SemanticError.PassiveAsync(loc, importLocs) =>
|
|
Error.print (Some(loc)) ("passive component may not have async input")
|
|
if (importLocs.nonEmpty) {
|
|
System.err.println(s"port instance was imported from here")
|
|
importLocs.reverse.map(System.err.println)
|
|
}
|
|
case SemanticError.PassiveStateMachine(loc) =>
|
|
Error.print (Some(loc)) ("passive component may not have a state machine instance")
|
|
case SemanticError.RedefinedSymbol(name, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"redefinition of symbol ${name}")
|
|
System.err.println("previous definition is here:")
|
|
System.err.println(prevLoc)
|
|
case SemanticError.StateMachine.CallSiteTypeMismatch(
|
|
loc,
|
|
teKind,
|
|
teTy,
|
|
siteKind,
|
|
siteTy
|
|
) =>
|
|
Error.print (Some(loc)) (s"type mismatch at $teKind")
|
|
System.err.println(s"type of $teKind is $teTy")
|
|
System.err.println(s"type of $siteKind is $siteTy")
|
|
case SemanticError.StateMachine.DuplicateSignal(sigName, stateName, loc, prevLoc) =>
|
|
Error.print (Some(loc)) (s"duplicate use of signal $sigName in state $stateName")
|
|
System.err.println("previous use is here:")
|
|
System.err.println(prevLoc)
|
|
case SemanticError.StateMachine.InvalidInitialTransition(loc, msg, destLoc) =>
|
|
Error.print (Some(loc)) (msg)
|
|
destLoc.map(loc => {
|
|
System.err.println("target is defined here:")
|
|
System.err.println(loc)
|
|
})
|
|
case SemanticError.StateMachine.ChoiceCycle(loc, msg) =>
|
|
Error.print (Some(loc)) (msg)
|
|
case SemanticError.StateMachine.ChoiceTypeMismatch(
|
|
loc, toLoc1, to1, toLoc2, to2
|
|
) =>
|
|
Error.print (Some(loc)) (s"type mismatch at choice")
|
|
System.err.println(toLoc1)
|
|
System.err.println(s"type of transition is $to1")
|
|
System.err.println(toLoc2)
|
|
System.err.println(s"type of transition is $to2")
|
|
case SemanticError.StateMachine.UnreachableNode(name, loc) =>
|
|
Error.print (Some(loc)) (s"$name is unreachable")
|
|
case SemanticError.TooManyOutputPorts(loc, numPorts, arraySize, instanceLoc) =>
|
|
Error.print (Some(loc)) (s"too many ports connected here (found $numPorts, max is $arraySize)")
|
|
System.err.println("for this component instance:")
|
|
System.err.println(instanceLoc)
|
|
case SemanticError.TypeMismatch(loc, msg) => Error.print (Some(loc)) (msg)
|
|
case SemanticError.UndefinedSymbol(name, symbolKind, loc) =>
|
|
Error.print (Some(loc)) (s"symbol ${name} is not defined")
|
|
printNote(s"looking for a $symbolKind here")
|
|
case SemanticError.InterfaceImport(
|
|
importLoc,
|
|
err
|
|
) =>
|
|
Error.print (Some(importLoc)) (s"failed to import interface")
|
|
err.print
|
|
case SemanticError.UseDefCycle(loc, msg) => Error.print (Some(loc)) (msg)
|
|
case XmlError.ParseError(file, msg) => Error.printXml (file) (msg)
|
|
case XmlError.SemanticError(file, msg) => Error.printXml (file) (msg)
|
|
case AnnotatedError(error, note) =>
|
|
error.print
|
|
printNote(note)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/** An error with a note */
|
|
final case class AnnotatedError(error: Error, note: String) extends Error
|
|
/** A syntax error */
|
|
final case class SyntaxError(loc: Location, msg: String) extends Error
|
|
|
|
/** A code generation error */
|
|
object CodeGenError {
|
|
/** Duplicate C++ file path */
|
|
final case class DuplicateCppFile(file: String, loc: Location, prevLoc: Location) extends Error
|
|
/** Duplicate JSON file path */
|
|
final case class DuplicateJsonFile(file: String, loc: Location, prevLoc: Location) extends Error
|
|
/** Duplicate XML file path */
|
|
final case class DuplicateXmlFile(file: String, loc: Location, prevLoc: Location) extends Error
|
|
/** Empty struct */
|
|
final case class EmptyStruct(loc: Location) extends Error
|
|
}
|
|
|
|
/** An include error */
|
|
object IncludeError {
|
|
/** Include cycle */
|
|
final case class Cycle(loc: Location, msg: String) extends Error
|
|
}
|
|
|
|
/** A file error */
|
|
object FileError {
|
|
/** Cannot open file */
|
|
final case class CannotOpen(locOpt: Option[Location], name: String) extends Error
|
|
/** Cannot resolve path */
|
|
final case class CannotResolvePath(loc: Location, name: String) extends Error
|
|
}
|
|
|
|
/** An error representing several other errors */
|
|
final case class MultiError(errors: List[Error]) extends Error
|
|
|
|
/** A semantic error */
|
|
object SemanticError {
|
|
/** Empty array */
|
|
final case class EmptyArray(loc: Location) extends Error
|
|
/** Channel not in dictionary */
|
|
final case class ChannelNotInDictionary(
|
|
loc: Location,
|
|
channelName: String,
|
|
topologyName: String
|
|
) extends Error
|
|
/** Division by zero */
|
|
final case class DivisionByZero(loc: Location) extends Error
|
|
/** Duplicate connection at matched port */
|
|
final case class DuplicateConnectionAtMatchedPort(
|
|
loc: Location,
|
|
port: String,
|
|
portNum: Int,
|
|
prevLoc: Location,
|
|
matchingLoc: Location
|
|
) extends Error
|
|
/** Duplicate name in dictionary */
|
|
final case class DuplicateDictionaryName(
|
|
kind: String,
|
|
name: String,
|
|
loc: Location,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Duplicate enum value */
|
|
final case class DuplicateEnumValue(
|
|
value: String,
|
|
loc: Location,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Dupliate ID value */
|
|
final case class DuplicateIdValue(
|
|
value: String,
|
|
loc: Location,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Duplicate init specifier */
|
|
final case class DuplicateInitSpecifier(
|
|
phase: Int,
|
|
loc: Location,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Duplicate instance */
|
|
final case class DuplicateInstance(
|
|
name: String,
|
|
loc: Location,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Duplicate telemetry channel limit */
|
|
final case class DuplicateLimit(
|
|
loc: Location,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Duplicate matched connection */
|
|
final case class DuplicateMatchedConnection(
|
|
loc: Location,
|
|
prevLoc: Location,
|
|
matchingLoc: Location
|
|
) extends Error
|
|
/** Duplicate opcode value */
|
|
final case class DuplicateOpcodeValue(
|
|
value: String,
|
|
loc: Location,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Duplicate output port */
|
|
final case class DuplicateOutputConnection(
|
|
loc: Location,
|
|
portNum: Int,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Duplicate parameter */
|
|
final case class DuplicateParameter(
|
|
name: String,
|
|
loc: Location,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Duplicate pattern */
|
|
final case class DuplicatePattern(
|
|
kind: String,
|
|
loc: Location,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Duplicate port instance */
|
|
final case class DuplicatePortInstance(
|
|
name: String,
|
|
loc: Location,
|
|
importLocs: List[Location],
|
|
prevLoc: Location,
|
|
prevImportLocs: List[Location]
|
|
) extends Error
|
|
/** Duplicate state machine instance */
|
|
final case class DuplicateStateMachineInstance(
|
|
name: String,
|
|
loc: Location,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Duplicate struct member */
|
|
final case class DuplicateStructMember(
|
|
name: String,
|
|
loc: Location,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Duplicate telemetry packet set */
|
|
final case class DuplicateTlmPacketSet(
|
|
name: String,
|
|
loc: Location,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Duplicate topology */
|
|
final case class DuplicateTopology(
|
|
name: String,
|
|
loc: Location,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Duplicate interface */
|
|
final case class DuplicateInterface(
|
|
name: String,
|
|
loc: Location,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Implicit duplicate connection at matched port */
|
|
final case class ImplicitDuplicateConnectionAtMatchedPort(
|
|
loc: Location,
|
|
port: String,
|
|
portNum: Int,
|
|
implyingLoc: Location,
|
|
matchingLoc: Location,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Inconsistent dictionary specifiers in location specifiers */
|
|
final case class InconsistentDictionarySpecifier(
|
|
loc: Location,
|
|
prevLoc: Location,
|
|
) extends Error
|
|
/** Inconsistent location specifiers */
|
|
final case class InconsistentLocationPath(
|
|
loc: Location,
|
|
path: String,
|
|
prevLoc: Location,
|
|
prevPath: String
|
|
) extends Error
|
|
/** Incorrect dictionary specifier in location specifier */
|
|
final case class IncorrectDictionarySpecifier(
|
|
loc: Location,
|
|
defLoc: Location
|
|
) extends Error
|
|
/** Incorrect location specifiers */
|
|
final case class IncorrectLocationPath(
|
|
loc: Location,
|
|
specifiedPath: String,
|
|
actualLoc: Location
|
|
) extends Error
|
|
/** Invalid array size */
|
|
final case class InvalidArraySize(loc: Location, size: BigInt) extends Error
|
|
/** Invalid command */
|
|
final case class InvalidCommand(loc: Location, msg: String) extends Error
|
|
/** Invalid component instance */
|
|
final case class InvalidComponentInstance(
|
|
loc: Location,
|
|
instanceName: String,
|
|
topName: String
|
|
) extends Error
|
|
/** Invalid connection */
|
|
final case class InvalidConnection(
|
|
loc: Location,
|
|
msg: String,
|
|
fromLoc: Location,
|
|
toLoc: Location,
|
|
fromPortDefLoc: Option[Location] = None,
|
|
toPortDefLoc: Option[Location] = None
|
|
) extends Error
|
|
/** Invalid data products */
|
|
final case class InvalidDataProducts(
|
|
loc: Location,
|
|
msg: String
|
|
) extends Error
|
|
/** Invalid component instance definition */
|
|
final case class InvalidDefComponentInstance(
|
|
name: String,
|
|
loc: Location,
|
|
msg: String
|
|
) extends Error
|
|
/** Invalid enum constants */
|
|
final case class InvalidEnumConstants(loc: Location) extends Error
|
|
/** Invalid event */
|
|
final case class InvalidEvent(loc: Location, msg: String) extends Error
|
|
/** Invalid format string */
|
|
final case class InvalidFormatString(loc: Location, msg: String) extends Error
|
|
/** Invalid integer value */
|
|
final case class InvalidIntValue(
|
|
loc: Location,
|
|
v: BigInt,
|
|
msg: String
|
|
) extends Error
|
|
/** Invalid internal port */
|
|
final case class InvalidInternalPort(loc: Location, msg: String) extends Error
|
|
/** Invalid connection pattern */
|
|
final case class InvalidPattern(
|
|
loc: Location,
|
|
msg: String
|
|
) extends Error
|
|
/** Invalid port instance */
|
|
final case class InvalidPortInstance(
|
|
loc: Location,
|
|
msg: String,
|
|
defLoc: Location
|
|
) extends Error
|
|
/** Invalid port instance identifier */
|
|
final case class InvalidPortInstanceId(
|
|
loc: Location,
|
|
portName: String,
|
|
componentName: String
|
|
) extends Error
|
|
/** Invalid port kind */
|
|
final case class InvalidPortKind(
|
|
loc: Location,
|
|
msg: String,
|
|
specLoc: Location
|
|
) extends Error
|
|
/** Invalid port matching */
|
|
final case class InvalidPortMatching(loc: Location, msg: String) extends Error
|
|
/** Invalid port number */
|
|
final case class InvalidPortNumber(
|
|
loc: Location,
|
|
portNumber: Int,
|
|
port: String,
|
|
size: Int,
|
|
specLoc: Location
|
|
) extends Error
|
|
/** Invalid priority specifier */
|
|
final case class InvalidPriority(loc: Location) extends Error
|
|
/** Invalid queue full specifier */
|
|
final case class InvalidQueueFull(loc: Location) extends Error
|
|
/** Invalid special port */
|
|
final case class InvalidSpecialPort(loc: Location, msg: String) extends Error
|
|
/** Invalid string size */
|
|
final case class InvalidStringSize(loc: Location, size: BigInt) extends Error
|
|
/** No member in struct type */
|
|
final case class InvalidStructMember(
|
|
memberName: String,
|
|
loc: Location,
|
|
structTypeName: String,
|
|
defLoc: Location
|
|
) extends Error
|
|
/** No member in anonymous struct type */
|
|
final case class InvalidAnonStructMember(
|
|
memberName: String,
|
|
loc: Location,
|
|
defLoc: Location
|
|
) extends Error
|
|
/** No member in anonymous struct type */
|
|
final case class InvalidTypeForMemberSelection(
|
|
memberName: String,
|
|
loc: Location,
|
|
typeName: String,
|
|
) extends Error
|
|
/** Invalid symbol */
|
|
final case class InvalidSymbol(
|
|
name: String,
|
|
loc: Location,
|
|
msg: String,
|
|
defLoc: Location
|
|
) extends Error
|
|
/** Invalid telemetry channel identifier name */
|
|
final case class InvalidTlmChannelName(
|
|
loc: Location,
|
|
channelName: String,
|
|
componentName: String
|
|
) extends Error
|
|
/** Invalid telemetry packet */
|
|
final case class InvalidTlmPacketSet(
|
|
loc: Location,
|
|
name: String,
|
|
msg: String
|
|
) extends Error
|
|
/** Invalid type */
|
|
final case class InvalidType(loc: Location, msg: String) extends Error
|
|
/** Mismatched port numbers */
|
|
final case class MismatchedPortNumbers(
|
|
p1Loc: Location,
|
|
p1Number: Int,
|
|
p2Loc: Location,
|
|
p2Number: Int,
|
|
matchingLoc: Location
|
|
) extends Error
|
|
/** Missing async input */
|
|
final case class MissingAsync(kind: String, loc: Location) extends Error
|
|
/** Missing connection */
|
|
final case class MissingConnection(
|
|
loc: Location,
|
|
matchingLoc: Location
|
|
) extends Error
|
|
/** Missing port */
|
|
final case class MissingPort(
|
|
loc: Location,
|
|
specMsg: String,
|
|
portmsg: String
|
|
) extends Error
|
|
final case class MissingPortMatching(
|
|
loc: Location
|
|
) extends Error
|
|
/** Matched port numbering could not find a valid port number */
|
|
final case class NoPortAvailableForMatchedNumbering(
|
|
loc1: Location,
|
|
loc2: Location,
|
|
matchingLoc: Location
|
|
) extends Error
|
|
/** Overlapping ID ranges */
|
|
final case class OverlappingIdRanges(
|
|
baseId1: BigInt,
|
|
name1: String,
|
|
loc1: Location,
|
|
baseId2: BigInt,
|
|
maxId2: BigInt,
|
|
name2: String,
|
|
loc2: Location
|
|
) extends Error
|
|
/** Error while importing an interface */
|
|
final case class InterfaceImport(
|
|
importLoc: Location,
|
|
err: Error
|
|
) extends Error
|
|
/** Passive async input */
|
|
final case class PassiveAsync(loc: Location, importLocs: List[Location]) extends Error
|
|
final case class PassiveStateMachine(loc: Location) extends Error
|
|
/** Redefined symbol */
|
|
final case class RedefinedSymbol(
|
|
name: String,
|
|
loc: Location,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Lexer Error */
|
|
final case class InvalidToken(
|
|
loc: Location,
|
|
msg: String,
|
|
) extends Error
|
|
/** State machine semantic errors */
|
|
object StateMachine {
|
|
/** Call site type mismatch */
|
|
final case class CallSiteTypeMismatch(
|
|
loc: Location,
|
|
teKind: String,
|
|
teTy: String,
|
|
siteKind: String,
|
|
siteTy: String
|
|
) extends Error
|
|
/** Duplicate signal */
|
|
final case class DuplicateSignal(
|
|
sigName: String,
|
|
stateName: String,
|
|
loc: Location,
|
|
prevLoc: Location
|
|
) extends Error
|
|
/** Invalid initial transition specifier */
|
|
final case class InvalidInitialTransition(
|
|
loc: Location,
|
|
msg: String,
|
|
destLoc: Option[Location] = None
|
|
) extends Error
|
|
/** Choice cycle */
|
|
final case class ChoiceCycle(
|
|
loc: Location,
|
|
msg: String
|
|
) extends Error
|
|
/** Choice type mismatch */
|
|
final case class ChoiceTypeMismatch(
|
|
loc: Location,
|
|
toLoc1: Location,
|
|
to1: String,
|
|
tLoc2: Location,
|
|
to2: String
|
|
) extends Error
|
|
/** Unreachable node in the transition graph */
|
|
final case class UnreachableNode(
|
|
name: String,
|
|
loc: Location
|
|
) extends Error
|
|
}
|
|
/** Too many output ports */
|
|
final case class TooManyOutputPorts(
|
|
loc: Location,
|
|
numPorts: Int,
|
|
arraySize: Int,
|
|
instanceLoc: Location
|
|
) extends Error
|
|
/** Type mismatch */
|
|
final case class TypeMismatch(loc: Location, msg: String) extends Error
|
|
/** Undefined symbol */
|
|
final case class UndefinedSymbol(name: String, symbolKind: String, loc: Location) extends Error
|
|
/** Use-def cycle */
|
|
final case class UseDefCycle(loc: Location, msg: String) extends Error
|
|
}
|
|
|
|
/** An F Prime XML error */
|
|
object XmlError {
|
|
/** A parse error */
|
|
final case class ParseError(file: String, msg: String) extends Error
|
|
/** A semantic error */
|
|
final case class SemanticError(file: String, msg: String) extends Error
|
|
}
|
|
|
|
object Error {
|
|
|
|
/** The tool in use, if there is one */
|
|
private var toolOpt: Option[Tool] = None
|
|
|
|
/** Set the tool */
|
|
def setTool(t: Tool): Unit = { toolOpt = Some(t) }
|
|
|
|
/** Print an optional value */
|
|
def printOpt[T](opt: T): Unit = {
|
|
opt match {
|
|
case Some(t) => System.err.println(t.toString)
|
|
case _ => ()
|
|
}
|
|
}
|
|
|
|
/** Print the tool */
|
|
def printTool: Unit = printOpt(toolOpt)
|
|
|
|
/** Print an optional location and a message */
|
|
def print (locOpt: Option[Location]) (msg: String): Unit = {
|
|
printTool
|
|
printOpt(locOpt)
|
|
System.err.print("error: ")
|
|
System.err.println(msg)
|
|
}
|
|
|
|
/** Print an XML file and a message */
|
|
def printXml (file: String) (msg: String): Unit = {
|
|
printTool
|
|
System.err.println(s"file: $file")
|
|
System.err.print("error: ")
|
|
System.err.println(msg)
|
|
}
|
|
|
|
}
|