Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -3505,6 +3505,10 @@
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$321",
"fields":[{"name":"0bitmap$297"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$322",
"fields":[{"name":"0bitmap$296"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$324",
"fields":[{"name":"0bitmap$337"}]
Expand Down Expand Up @@ -3713,26 +3717,150 @@
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$46",
"fields":[{"name":"0bitmap$86"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$47",
"fields":[{"name":"0bitmap$85"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$48",
"fields":[{"name":"0bitmap$84"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$49",
"fields":[{"name":"0bitmap$83"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$5",
"fields":[{"name":"0bitmap$2"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$50",
"fields":[{"name":"0bitmap$80"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$51",
"fields":[{"name":"0bitmap$79"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$52",
"fields":[{"name":"0bitmap$54"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$53",
"fields":[{"name":"0bitmap$48"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$54",
"fields":[{"name":"0bitmap$44"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$55",
"fields":[{"name":"0bitmap$45"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$56",
"fields":[{"name":"0bitmap$46"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$57",
"fields":[{"name":"0bitmap$47"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$59",
"fields":[{"name":"0bitmap$53"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$6",
"fields":[{"name":"0bitmap$3"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$64",
"fields":[{"name":"0bitmap$78"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$65",
"fields":[{"name":"0bitmap$58"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$7",
"fields":[{"name":"0bitmap$4"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$70",
"fields":[{"name":"0bitmap$72"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$71",
"fields":[{"name":"0bitmap$59"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$72",
"fields":[{"name":"0bitmap$60"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$73",
"fields":[{"name":"0bitmap$61"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$74",
"fields":[{"name":"0bitmap$62"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$75",
"fields":[{"name":"0bitmap$63"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$76",
"fields":[{"name":"0bitmap$64"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$77",
"fields":[{"name":"0bitmap$65"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$78",
"fields":[{"name":"0bitmap$66"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$79",
"fields":[{"name":"0bitmap$67"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$8",
"fields":[{"name":"0bitmap$5"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$80",
"fields":[{"name":"0bitmap$68"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$81",
"fields":[{"name":"0bitmap$69"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$82",
"fields":[{"name":"0bitmap$70"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$83",
"fields":[{"name":"0bitmap$71"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$85",
"fields":[{"name":"0bitmap$77"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$9",
"fields":[{"name":"0bitmap$8"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$90",
"fields":[{"name":"0bitmap$82"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$91",
"fields":[{"name":"0bitmap$81"}]
},
{
"name":"fpp.compiler.codegen.AstJsonEncoder$$anon$93",
"fields":[{"name":"0bitmap$88"}]
Expand Down
26 changes: 26 additions & 0 deletions compiler/lib/src/main/scala/analysis/Analysis.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package fpp.compiler.analysis
import fpp.compiler.ast._
import fpp.compiler.util._

import scala.annotation.tailrec

/** The analysis data structure */
case class Analysis(
/** The set of files presented to the analyzer */
Expand Down Expand Up @@ -59,6 +61,10 @@ case class Analysis(
componentInstanceMap: Map[Symbol.ComponentInstance, ComponentInstance] = Map(),
/** The component instance under construction */
componentInstance: Option[ComponentInstance] = None,
/** The map from interface symbols to interfaces */
interfaceMap: Map[Symbol.Interface, Interface] = Map(),
/** The interface under construction */
interface: Option[Interface] = None,
/** The map from topology symbols to topologies */
topologyMap: Map[Symbol.Topology, Topology] = Map(),
/** The topology under construction */
Expand Down Expand Up @@ -118,6 +124,7 @@ case class Analysis(

/** Compute the common type for a list of node Ids */
def commonType(nodes: List[AstNode.Id], emptyListError: Error): Result.Result[Type] = {
@tailrec
def helper(prevNodeId: AstNode.Id, prevType: Type, nextNodes: List[AstNode.Id]): Result.Result[Type] = {
nextNodes match {
case Nil => Right(prevType)
Expand Down Expand Up @@ -236,6 +243,25 @@ case class Analysis(
for (cis <- getComponentInstanceSymbol(id))
yield this.componentInstanceMap(cis)

/** Gets an interface symbol from use-def map */
def getInterfaceSymbol(id: AstNode.Id): Result.Result[Symbol.Interface] =
this.useDefMap(id) match {
case ts: Symbol.Interface => Right(ts)
case s => Left(
SemanticError.InvalidSymbol(
s.getUnqualifiedName,
Locations.get(id),
"not a interface symbol",
s.getLoc
)
)
}

/** Gets an interface from the interface definition map */
def getInterface(id: AstNode.Id): Result.Result[Interface] =
for (cis <- getInterfaceSymbol(id))
yield this.interfaceMap(cis)

/** Gets a topology symbol from use-def map */
def getTopologySymbol(id: AstNode.Id): Result.Result[Symbol.Topology] =
this.useDefMap(id) match {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package fpp.compiler.analysis

import fpp.compiler.ast.*
import fpp.compiler.util.*

/** Analyze interface members */
trait InterfaceAnalyzer extends Analyzer {

override def defInterfaceAnnotatedNode(
a: Analysis,
node: Ast.Annotated[AstNode[Ast.DefInterface]]
) = {
val (_, node1, _) = node
val Ast.DefInterface(name, members) = node1.data
for { a2 <- visitList(a, members, matchInterfaceMember) }
yield a2
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import fpp.compiler.ast._
import fpp.compiler.util._

/** Analyze types and expressions */
trait TypeExpressionAnalyzer
extends Analyzer
trait TypeExpressionAnalyzer
extends Analyzer
with ComponentAnalyzer
with InterfaceAnalyzer
with ModuleAnalyzer
with StateMachineAnalyzer
with TlmPacketSetAnalyzer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ trait UseAnalyzer extends TypeExpressionAnalyzer {
/** A use of a topology definition */
def topologyUse(a: Analysis, node: AstNode[Ast.QualIdent], use: Name.Qualified): Result = default(a)

/** A use of an interface definition */
def interfaceUse(a: Analysis, node: AstNode[Ast.QualIdent], use: Name.Qualified): Result = default(a)

/** A use of a type definition */
def typeUse(a: Analysis, node: AstNode[Ast.TypeName], use: Name.Qualified): Result = default(a)

Expand Down Expand Up @@ -155,6 +158,12 @@ trait UseAnalyzer extends TypeExpressionAnalyzer {
qualIdentNode(topologyUse)(a, data.sym)
}

override def specInterfaceImportAnnotatedNode(a: Analysis, node: Ast.Annotated[AstNode[Ast.SpecImport]]) = {
val (_, node1, _) = node
val data = node1.data
qualIdentNode(interfaceUse)(a, data.sym)
}

override def typeNameQualIdentNode(a: Analysis, node: AstNode[Ast.TypeName], tn: Ast.TypeNameQualIdent) = {
val use = Name.Qualified.fromQualIdent(tn.name.data)
typeUse(a, node, use)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import fpp.compiler.util._

/** Check component definitions */
object CheckComponentDefs
extends Analyzer
extends Analyzer
with ComponentAnalyzer
with ModuleAnalyzer
{
Expand Down Expand Up @@ -104,6 +104,23 @@ object CheckComponentDefs
yield a.copy(component = Some(component))
}

override def specInterfaceImportAnnotatedNode(
a: Analysis,
aNode: Ast.Annotated[AstNode[Ast.SpecImport]]
) = {
val node = aNode._2
val ifaceNode = node.data.sym
val component = a.component.get
for {
iface <- a.getInterface(ifaceNode.id)
c2 <- component.addImportedInterface(
iface,
node.id,
)
}
yield a.copy(component = Some(c2))
}

override def specPortMatchingAnnotatedNode(
a: Analysis,
aNode: Ast.Annotated[AstNode[Ast.SpecPortMatching]]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package fpp.compiler.analysis

import fpp.compiler.ast.*
import fpp.compiler.util.*

/** Check component definitions */
object CheckInterfaceDefs
extends Analyzer
with InterfaceAnalyzer
with ModuleAnalyzer
{

override def defInterfaceAnnotatedNode(
a: Analysis,
aNode: Ast.Annotated[AstNode[Ast.DefInterface]]
) = {
val a1 = a.copy(interface = Some(Interface(aNode)))
for {
a <- super.defInterfaceAnnotatedNode(a1, aNode)
}
yield {
val symbol = Symbol.Interface(aNode)
a.copy(interfaceMap = a.interfaceMap + (symbol -> a.interface.get))
}
}

override def specPortInstanceAnnotatedNode(
a: Analysis,
aNode: Ast.Annotated[AstNode[Ast.SpecPortInstance]]
) = {
for {
instance <- PortInstance.fromSpecPortInstance(a, aNode)
interface <- a.interface.get.addPortInstance(instance)
}
yield a.copy(interface = Some(interface))
}

override def specInterfaceImportAnnotatedNode(
a: Analysis,
aNode: Ast.Annotated[AstNode[Ast.SpecImport]]
) = {
val node = aNode._2
val ifaceNode = node.data.sym
for {
iface <- a.getInterface(ifaceNode.id)
i <- a.interface.get.addImportedInterface(
iface,
node.id,
)
} yield a.copy(interface = Some(i))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ object CheckSemantics {
a <- EvalConstantExprs.visitList(a, tul, EvalConstantExprs.transUnit)
a <- FinalizeTypeDefs.visitList(a, tul, FinalizeTypeDefs.transUnit)
a <- CheckPortDefs.visitList(a, tul, CheckPortDefs.transUnit)
a <- CheckInterfaceDefs.visitList(a, tul, CheckInterfaceDefs.transUnit)
a <- CheckComponentDefs.visitList(a, tul, CheckComponentDefs.transUnit)
a <- CheckComponentInstanceDefs.visitList(a, tul, CheckComponentInstanceDefs.transUnit)
_ <- CheckComponentInstanceDefs.checkIdRanges(a)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import fpp.compiler.util._
/** Check location specifiers */
object CheckSpecLocs
extends Analyzer
with ModuleAnalyzer
with ModuleAnalyzer
{

override def defAbsTypeAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefAbsType]]) = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ object CheckUseDefCycles extends UseAnalyzer {
visitDefPost(a, symbol, node, super.defTopologyAnnotatedNode)
}

override def defInterfaceAnnotatedNode(a: Analysis, node: Ast.Annotated[AstNode[Ast.DefInterface]]) = {
val symbol = Symbol.Interface(node)
visitDefPost(a, symbol, node, super.defInterfaceAnnotatedNode)
}

override def topologyUse(a: Analysis, node: AstNode[Ast.QualIdent], use: Name.Qualified) =
visitUse(a, node, use)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ object CheckUses extends UseAnalyzer {
override def topologyUse(a: Analysis, node: AstNode[Ast.QualIdent], use: Name.Qualified) =
helpers.visitQualIdentNode (NameGroup.Topology) (a, node)

override def interfaceUse(a: Analysis, node: AstNode[Ast.QualIdent], use: Name.Qualified) =
helpers.visitQualIdentNode (NameGroup.Interface) (a, node)

override def typeUse(a: Analysis, node: AstNode[Ast.TypeName], use: Name.Qualified) = {
val data = node.data
data match {
Expand Down
Loading