Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions compiler/lib/src/main/scala/analysis/Analysis.scala
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,9 @@ case class Analysis(
case a: Type.Array =>
val id = a.node._2.data.eltType.id
getElementReason(id)
case v: Type.Vector =>
val id = v.node._2.data.eltType.id
getElementReason(id)
case s: Type.Struct =>
val idOpt = s.node._2.data.members.map(_._2.data.typeName.id).find(
id => !this.typeMap(id).isDisplayable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ trait BasicUseAnalyzer extends TypeExpressionAnalyzer {
} yield a
}

override def defVectorAnnotatedNode(a: Analysis, node: Ast.Annotated[AstNode[Ast.DefVector]]) = {
// A vector whose size specifier omits a size-prefix type has an implied
// use of the framework type FwSizeStoreType (see ConstructImpliedUseMap).
val id = node._2.id
for {
a <- visitImpliedUses(a, id)
a <- super.defVectorAnnotatedNode(a, node)
} yield a
}

override def defTopologyAnnotatedNode(a: Analysis, node: Ast.Annotated[AstNode[Ast.DefTopology]]) = {
val id = node._2.id
for {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@ trait TypeExpressionAnalyzer
} yield a
}

override def defVectorAnnotatedNode(a: Analysis, node: Ast.Annotated[AstNode[Ast.DefVector]]) = {
val (_, node1, _) = node
val data = node1.data
for {
a <- exprNode(a, data.size)
a <- opt(typeNameNode)(a, data.sizePrefixType)
a <- typeNameNode(a, data.eltType)
a <- opt(exprNode)(a, data.default)
} yield a
}

override def defComponentInstanceAnnotatedNode(a: Analysis, node: Ast.Annotated[AstNode[Ast.DefComponentInstance]]) = {
val (_, node1, _) = node
val data = node1.data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ object CheckDictionaryDefs
override def defStructAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefStruct]]) =
checkTypeDef(a, Symbol.Struct(aNode))

override def defVectorAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefVector]]) =
checkTypeDef(a, Symbol.Vector(aNode))

override def defConstantAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefConstant]]) =
checkConstantDef(a, Symbol.Constant(aNode))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,25 @@ object CheckExprTypes extends UseAnalyzer {
} yield a
}

override def defVectorAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefVector]]) = {
val (_, node, _) = aNode
val data = node.data
for {
a <- super.defVectorAnnotatedNode(a, aNode)
_ <- convertNodeToNumeric(a, data.size)
_ <- data.default match {
case Some(defaultNode) =>
val vectorId = node.id
val vectorType = a.typeMap(vectorId)
val defaultId = defaultNode.id
val defaultType = a.typeMap(defaultId)
val loc = Locations.get(defaultId)
Analysis.convertTypes(loc, defaultType -> vectorType)
case None => Right(a)
}
} yield a
}

override def defConstantAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefConstant]]) = {
val (_, node,_) = aNode
if (!a.typeMap.contains(node.id)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ object CheckFrameworkDefs
override def defStructAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefStruct]]) =
analyzeType(a, Symbol.Struct(aNode))

override def defVectorAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefVector]]) =
analyzeType(a, Symbol.Vector(aNode))

private val constants = Map(
"FW_ASSERT_COUNT_MAX" -> requireIntegerConstant,
"FW_CMD_ARG_BUFFER_MAX_SIZE" -> requireIntegerConstant,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ object CheckSpecLocs
aNode: Ast.Annotated[AstNode[Ast.DefStruct]]
) = checkSpecLoc(a, Ast.SpecLoc.Type, Symbol.Struct(aNode))

override def defVectorAnnotatedNode(
a: Analysis,
aNode: Ast.Annotated[AstNode[Ast.DefVector]]
) = checkSpecLoc(a, Ast.SpecLoc.Type, Symbol.Vector(aNode))

override def defSystemAnnotatedNode(
a: Analysis,
aNode: Ast.Annotated[AstNode[Ast.DefSystem]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,41 @@ object CheckTypeUses extends UseAnalyzer {
visitIfNeeded(visitor)(a, aNode)
}

override def defVectorAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefVector]]) = {
def visitor(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefVector]]) =
for {
a <- super.defVectorAnnotatedNode(a, aNode)
// Resolve and check the size-prefix type, if present.
// Its underlying type must be an unsigned primitive integer type.
sizePrefixType <- {
val data = aNode._2.data
data.sizePrefixType match {
case Some(typeName) =>
val t = a.typeMap(typeName.id)
val loc = Locations.get(typeName.id)
t.getUnderlyingType match {
case pi : Type.PrimitiveInt
if pi.signedness == Type.PrimitiveInt.Unsigned => Right(Some(t))
case _ => Left(SemanticError.InvalidType(
loc,
"vector size-prefix type must be an unsigned primitive integer type"
))
}
case None => Right(None)
}
}
}
yield {
val (_, node, _) = aNode
val data = node.data
val eltType = a.typeMap(data.eltType.id)
val anonVector = Type.AnonVector(None, eltType)
val t = Type.Vector(aNode, anonVector, sizePrefixType)
a.assignType(node -> t)
}
visitIfNeeded(visitor)(a, aNode)
}

override def exprNode(a: Analysis, node: AstNode[Ast.Expr]) = matchExprNode(a, node)

override def typeNameBoolNode(a: Analysis, node: AstNode[Ast.TypeName]) =
Expand Down Expand Up @@ -154,6 +189,7 @@ object CheckTypeUses extends UseAnalyzer {
case Symbol.Array(node) => defArrayAnnotatedNode(a, node)
case Symbol.Enum(node) => defEnumAnnotatedNode(a, node)
case Symbol.Struct(node) => defStructAnnotatedNode(a, node)
case Symbol.Vector(node) => defVectorAnnotatedNode(a, node)
case _ => Right(a)
}
t <- a.typeMap.get(symbol.getNodeId) match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ object CheckUseDefCycles extends UseAnalyzer {
visitDefPost(a, symbol, node, super.defStructAnnotatedNode)
}

override def defVectorAnnotatedNode(a: Analysis, node: Ast.Annotated[AstNode[Ast.DefVector]]) = {
val symbol = Symbol.Vector(node)
visitDefPost(a, symbol, node, super.defVectorAnnotatedNode)
}

override def defTopologyAnnotatedNode(a: Analysis, node: Ast.Annotated[AstNode[Ast.DefTopology]]) = {
val symbol = Symbol.Topology(node)
visitDefPost(a, symbol, node, super.defTopologyAnnotatedNode)
Expand Down Expand Up @@ -77,6 +82,7 @@ object CheckUseDefCycles extends UseAnalyzer {
case Symbol.Interface(node) => defInterfaceAnnotatedNode(a, node)
case Symbol.Struct(node) => defStructAnnotatedNode(a, node)
case Symbol.Topology(node) => defTopologyAnnotatedNode(a, node)
case Symbol.Vector(node) => defVectorAnnotatedNode(a, node)
case _ => Right(a)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,34 @@ object ConstructImpliedUseMap extends TypeExpressionAnalyzer {
Right(a)
}

override def defVectorAnnotatedNode(
a: Analysis,
aNode: Ast.Annotated[AstNode[Ast.DefVector]]
) = {
val node = aNode._2
val id = node.id
val a1 = node.data.sizePrefixType match {
// An explicit size-prefix type is an ordinary type use, handled by the
// superclass recursion. No implied use.
case Some(_) => a
// When the size-prefix type is omitted, the size specifier represents an
// implied use of the framework type FwSizeStoreType.
case None =>
val identList = List("FwSizeStoreType")
val id1 = ImpliedUse.replicateId(id)
val impliedUse = ImpliedUse.fromIdentListAndId(
identList,
id1,
List("use of a vector type without a size-prefix type requires this definition")
)
val map = Map(ImpliedUse.Kind.Type -> Set(impliedUse))
a.copy(impliedUseMap = a.impliedUseMap + (id -> map))
}
super.defVectorAnnotatedNode(a1, aNode)
}

override def typeNameStringNode(
a: Analysis,
a: Analysis,
node: AstNode[Ast.TypeName],
tn: Ast.TypeNameString
) = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,19 @@ object EnterSymbols
yield updateMap(a, symbol).copy(nestedScope = nestedScope)
}

override def defVectorAnnotatedNode(
a: Analysis,
aNode: Ast.Annotated[AstNode[Ast.DefVector]]
) = {
val (_, node, _) = aNode
val data = node.data
val name = data.name
val symbol = Symbol.Vector(aNode)
val nestedScope = a.nestedScope
for (nestedScope <- nestedScope.put(NameGroup.Type)(name, symbol))
yield updateMap(a, symbol).copy(nestedScope = nestedScope)
}

private def updateMap(a: Analysis, s: Symbol): Analysis = {
val parentSymbolMap = a.parentSymbol.fold (a.parentSymbolMap) (ps =>
a.parentSymbolMap + (s -> ps)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,13 @@ object EvalConstantExprs extends UseAnalyzer {
a <- FinalizeTypeDefs.defStructAnnotatedNode(a, t.node)
} yield a

override def vector(a: Analysis, t: Type.Vector) =
for {
a <- defVectorAnnotatedNode(a, t.node)
a <- finalizeIfNeeded(a, t.anonVector.eltType)
a <- FinalizeTypeDefs.defVectorAnnotatedNode(a, t.node)
} yield a

// Query whether a type is finalized
// A type is finalized if (1) it has a definition symbol S
// and S is in the visited symbol set; or (2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,60 @@ object FinalizeTypeDefs
visitIfNeeded(symbol, visitor)(a, aNode)
}

override def defVectorAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefVector]]) = {
val symbol = Symbol.Vector(aNode)
def visitor(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefVector]]) = {
val node = aNode._2
val data = node.data
// Get the type of this node as a vector type V
val vectorType @ Type.Vector(_, _, _, _, _) = a.typeMap(node.id)
for {
// Visit the element type of V, to update its members
eltType <- TypeVisitor.ty(a, vectorType.anonVector.eltType)
// Visit the size-prefix type of V, if present, to resolve aliases
sizePrefixType <- vectorType.sizePrefixType match {
case Some(t) => for (t1 <- TypeVisitor.ty(a, t)) yield Some(t1)
case None => Right(None)
}
// Update the maximum size, element type, and size-prefix type in V
size <- a.getArraySize(data.size.id)
vectorType <- {
val anonVector = Type.AnonVector(Some(size.toInt), eltType)
Right(vectorType.copy(anonVector = anonVector, sizePrefixType = sizePrefixType))
}
// Compute the default value
default <- data.default match {
case Some(defaultNode) => {
val id = defaultNode.id
val v = a.valueMap(id)
val loc = Locations.get(id)
for (_ <- Analysis.convertTypes(loc, v.getType -> vectorType))
yield {
val vector @ Value.Vector(_, _) = Analysis.convertValueToType(v, vectorType)
vector
}
}
case None => {
// The default value is the empty vector, i.e., the value of length zero
Right(Value.Vector(Value.AnonArray(Nil), vectorType))
}
}
// Compute the format
format <- Result.mapOpt(
data.format,
Analysis.computeFormat(_, List(eltType))
)
}
yield {
// Update the default value and format in V
val vectorType1 = vectorType.copy(default = Some(default), format = format)
// Update V in the type map
a.assignType(node -> vectorType1)
}
}
visitIfNeeded(symbol, visitor)(a, aNode)
}

override def transUnit(a: Analysis, tu: Ast.TransUnit) =
super.transUnit(a.copy(visitedSymbolSet = Set()), tu)

Expand Down Expand Up @@ -232,6 +286,14 @@ object FinalizeTypeDefs
for (a <- defStructAnnotatedNode(a, t.node))
yield a.typeMap(t.node._2.id)

override def vector(a: Analysis, t: Type.Vector) =
for (a <- defVectorAnnotatedNode(a, t.node))
yield a.typeMap(t.node._2.id)

override def anonVector(a: Analysis, t: Type.AnonVector) =
for (eltType <- ty(a, t.eltType))
yield Type.AnonVector(t.maxSize, eltType)

override def anonStruct(a: Analysis, t: Type.AnonStruct) = {
def visitor(member: Type.Struct.Member): Result.Result[Type.Struct.Member] =
for (memberType <- ty(a, member._2)) yield member._1 -> memberType
Expand Down
5 changes: 5 additions & 0 deletions compiler/lib/src/main/scala/analysis/Semantics/Symbol.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ object Symbol {
override def getNodeId = node._2.id
override def getUnqualifiedName = node._2.data.name
}
final case class Vector(node: Ast.Annotated[AstNode[Ast.DefVector]]) extends TypeSymbol {
override def isDictionaryDef = node._2.data.isDictionaryDef
override def getNodeId = node._2.id
override def getUnqualifiedName = node._2.data.name
}
final case class Topology(node: Ast.Annotated[AstNode[Ast.DefTopology]]) extends InterfaceInstanceSymbol {
override def getNodeId = node._2.id
override def getUnqualifiedName = node._2.data.name
Expand Down
Loading