Skip to content

Commit

Permalink
Add foreach as alternative to map (#952)
Browse files Browse the repository at this point in the history
* Added Foreachers

* Changed CheckTypes to use foreach

* Check widths now uses foreach

* Finished merge, added foreachers to added stmts

* Address reviewer feedback
  • Loading branch information
azidar authored Nov 27, 2018
1 parent 82f62e0 commit 17d1d2d
Show file tree
Hide file tree
Showing 8 changed files with 370 additions and 65 deletions.
9 changes: 9 additions & 0 deletions src/main/scala/firrtl/AddDescriptionNodes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ private case class DescribedStmt(description: Description, stmt: Statement) exte
def mapType(f: Type => Type): Statement = this.copy(stmt = stmt.mapType(f))
def mapString(f: String => String): Statement = this.copy(stmt = stmt.mapString(f))
def mapInfo(f: Info => Info): Statement = this.copy(stmt = stmt.mapInfo(f))
def foreachStmt(f: Statement => Unit): Unit = f(stmt)
def foreachExpr(f: Expression => Unit): Unit = stmt.foreachExpr(f)
def foreachType(f: Type => Unit): Unit = stmt.foreachType(f)
def foreachString(f: String => Unit): Unit = stmt.foreachString(f)
def foreachInfo(f: Info => Unit): Unit = stmt.foreachInfo(f)
}

private case class DescribedMod(description: Description,
Expand All @@ -49,6 +54,10 @@ private case class DescribedMod(description: Description,
def mapPort(f: Port => Port): DefModule = this.copy(mod = mod.mapPort(f))
def mapString(f: String => String): DefModule = this.copy(mod = mod.mapString(f))
def mapInfo(f: Info => Info): DefModule = this.copy(mod = mod.mapInfo(f))
def foreachStmt(f: Statement => Unit): Unit = mod.foreachStmt(f)
def foreachPort(f: Port => Unit): Unit = mod.foreachPort(f)
def foreachString(f: String => Unit): Unit = mod.foreachString(f)
def foreachInfo(f: Info => Unit): Unit = mod.foreachInfo(f)
}

/** Wraps modules or statements with their respective described nodes.
Expand Down
3 changes: 3 additions & 0 deletions src/main/scala/firrtl/Emitter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ case class VRandom(width: BigInt) extends Expression {
def mapExpr(f: Expression => Expression): Expression = this
def mapType(f: Type => Type): Expression = this
def mapWidth(f: Width => Width): Expression = this
def foreachExpr(f: Expression => Unit): Unit = Unit
def foreachType(f: Type => Unit): Unit = Unit
def foreachWidth(f: Width => Unit): Unit = Unit
}

class VerilogEmitter extends SeqTransform with Emitter {
Expand Down
41 changes: 41 additions & 0 deletions src/main/scala/firrtl/WIR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ case class WRef(name: String, tpe: Type, kind: Kind, gender: Gender) extends Exp
def mapExpr(f: Expression => Expression): Expression = this
def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
def mapWidth(f: Width => Width): Expression = this
def foreachExpr(f: Expression => Unit): Unit = Unit
def foreachType(f: Type => Unit): Unit = f(tpe)
def foreachWidth(f: Width => Unit): Unit = Unit
}
object WRef {
/** Creates a WRef from a Wire */
Expand All @@ -44,6 +47,9 @@ case class WSubField(expr: Expression, name: String, tpe: Type, gender: Gender)
def mapExpr(f: Expression => Expression): Expression = this.copy(expr = f(expr))
def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
def mapWidth(f: Width => Width): Expression = this
def foreachExpr(f: Expression => Unit): Unit = f(expr)
def foreachType(f: Type => Unit): Unit = f(tpe)
def foreachWidth(f: Width => Unit): Unit = Unit
}
object WSubField {
def apply(expr: Expression, n: String): WSubField = new WSubField(expr, n, field_type(expr.tpe, n), UNKNOWNGENDER)
Expand All @@ -54,26 +60,38 @@ case class WSubIndex(expr: Expression, value: Int, tpe: Type, gender: Gender) ex
def mapExpr(f: Expression => Expression): Expression = this.copy(expr = f(expr))
def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
def mapWidth(f: Width => Width): Expression = this
def foreachExpr(f: Expression => Unit): Unit = f(expr)
def foreachType(f: Type => Unit): Unit = f(tpe)
def foreachWidth(f: Width => Unit): Unit = Unit
}
case class WSubAccess(expr: Expression, index: Expression, tpe: Type, gender: Gender) extends Expression {
def serialize: String = s"${expr.serialize}[${index.serialize}]"
def mapExpr(f: Expression => Expression): Expression = this.copy(expr = f(expr), index = f(index))
def mapType(f: Type => Type): Expression = this.copy(tpe = f(tpe))
def mapWidth(f: Width => Width): Expression = this
def foreachExpr(f: Expression => Unit): Unit = { f(expr); f(index) }
def foreachType(f: Type => Unit): Unit = f(tpe)
def foreachWidth(f: Width => Unit): Unit = Unit
}
case object WVoid extends Expression {
def tpe = UnknownType
def serialize: String = "VOID"
def mapExpr(f: Expression => Expression): Expression = this
def mapType(f: Type => Type): Expression = this
def mapWidth(f: Width => Width): Expression = this
def foreachExpr(f: Expression => Unit): Unit = Unit
def foreachType(f: Type => Unit): Unit = Unit
def foreachWidth(f: Width => Unit): Unit = Unit
}
case object WInvalid extends Expression {
def tpe = UnknownType
def serialize: String = "INVALID"
def mapExpr(f: Expression => Expression): Expression = this
def mapType(f: Type => Type): Expression = this
def mapWidth(f: Width => Width): Expression = this
def foreachExpr(f: Expression => Unit): Unit = Unit
def foreachType(f: Type => Unit): Unit = Unit
def foreachWidth(f: Width => Unit): Unit = Unit
}
// Useful for splitting then remerging references
case object EmptyExpression extends Expression {
Expand All @@ -82,6 +100,9 @@ case object EmptyExpression extends Expression {
def mapExpr(f: Expression => Expression): Expression = this
def mapType(f: Type => Type): Expression = this
def mapWidth(f: Width => Width): Expression = this
def foreachExpr(f: Expression => Unit): Unit = Unit
def foreachType(f: Type => Unit): Unit = Unit
def foreachWidth(f: Width => Unit): Unit = Unit
}
case class WDefInstance(info: Info, name: String, module: String, tpe: Type) extends Statement with IsDeclaration {
def serialize: String = s"inst $name of $module" + info.serialize
Expand All @@ -90,6 +111,11 @@ case class WDefInstance(info: Info, name: String, module: String, tpe: Type) ext
def mapType(f: Type => Type): Statement = this.copy(tpe = f(tpe))
def mapString(f: String => String): Statement = this.copy(name = f(name))
def mapInfo(f: Info => Info): Statement = this.copy(f(info))
def foreachStmt(f: Statement => Unit): Unit = Unit
def foreachExpr(f: Expression => Unit): Unit = Unit
def foreachType(f: Type => Unit): Unit = f(tpe)
def foreachString(f: String => Unit): Unit = f(name)
def foreachInfo(f: Info => Unit): Unit = f(info)
}
object WDefInstance {
def apply(name: String, module: String): WDefInstance = new WDefInstance(NoInfo, name, module, UnknownType)
Expand All @@ -108,6 +134,11 @@ case class WDefInstanceConnector(
def mapType(f: Type => Type): Statement = this.copy(tpe = f(tpe))
def mapString(f: String => String): Statement = this.copy(name = f(name))
def mapInfo(f: Info => Info): Statement = this.copy(f(info))
def foreachStmt(f: Statement => Unit): Unit = Unit
def foreachExpr(f: Expression => Unit): Unit = portCons foreach { case (e1, e2) => (f(e1), f(e2)) }
def foreachType(f: Type => Unit): Unit = f(tpe)
def foreachString(f: String => Unit): Unit = f(name)
def foreachInfo(f: Info => Unit): Unit = f(info)
}

// Resultant width is the same as the maximum input width
Expand Down Expand Up @@ -285,6 +316,11 @@ case class CDefMemory(
def mapType(f: Type => Type): Statement = this.copy(tpe = f(tpe))
def mapString(f: String => String): Statement = this.copy(name = f(name))
def mapInfo(f: Info => Info): Statement = this.copy(f(info))
def foreachStmt(f: Statement => Unit): Unit = Unit
def foreachExpr(f: Expression => Unit): Unit = Unit
def foreachType(f: Type => Unit): Unit = f(tpe)
def foreachString(f: String => Unit): Unit = f(name)
def foreachInfo(f: Info => Unit): Unit = f(info)
}
case class CDefMPort(info: Info,
name: String,
Expand All @@ -301,5 +337,10 @@ case class CDefMPort(info: Info,
def mapType(f: Type => Type): Statement = this.copy(tpe = f(tpe))
def mapString(f: String => String): Statement = this.copy(name = f(name))
def mapInfo(f: Info => Info): Statement = this.copy(f(info))
def foreachStmt(f: Statement => Unit): Unit = Unit
def foreachExpr(f: Expression => Unit): Unit = exps.foreach(f)
def foreachType(f: Type => Unit): Unit = f(tpe)
def foreachString(f: String => Unit): Unit = f(name)
def foreachInfo(f: Info => Unit): Unit = f(info)
}

Loading

0 comments on commit 17d1d2d

Please sign in to comment.