-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial check-in of Scala Hammer IR library
- Loading branch information
1 parent
ae17833
commit 14f70a1
Showing
14 changed files
with
398 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
out/ | ||
*.jar | ||
amm | ||
mill | ||
test/tmp_* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
Hammer IR Scala library | ||
======================= | ||
|
||
This API is experimental and subject to change at any time. | ||
|
||
To get a JAR, run `./build.sh`. | ||
You can find the output JAR in `out/hammer_ir/assembly/dest/out.jar`. | ||
|
||
TODO(edwardw): write documentation for what this is and how to use it. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import mill._, scalalib._ | ||
|
||
object hammer_ir extends SbtModule { | ||
def scalaVersion = "2.12.6" | ||
|
||
// Unrooted submodule | ||
override def millSourcePath = super.millSourcePath / ammonite.ops.up | ||
|
||
def ivyDeps = Agg( | ||
ivy"com.typesafe.play::play-json:2.6.10" | ||
) | ||
|
||
object test extends Tests { | ||
def ivyDeps = Agg(ivy"org.scalatest::scalatest:3.0.4") | ||
def testFrameworks = Seq("org.scalatest.tools.Framework") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#!/bin/sh | ||
if [ ! -f "./mill" ]; then | ||
./get_mill.sh | ||
fi | ||
./mill hammer_ir.assembly | ||
cp out/hammer_ir/assembly/dest/out.jar hammer_ir.jar |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#!/bin/sh | ||
set -ex | ||
wget -nv https://github.com/lihaoyi/Ammonite/releases/download/1.6.6/2.12-1.6.6 -O amm | ||
chmod +x ./amm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#!/bin/sh | ||
set -ex | ||
wget -nv https://github.com/lihaoyi/mill/releases/download/0.3.6/0.3.6 -O mill | ||
chmod +x ./mill |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#!/bin/sh | ||
./mill hammer_ir.test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// See LICENSE for licence details. | ||
|
||
package hammer_ir | ||
|
||
import scala.reflect.ClassTag | ||
|
||
import play.api.libs.json.{Json, JsObject, JsValue} | ||
|
||
/** | ||
* All Hammer IR types that can be converted to a JsValue. | ||
*/ | ||
trait JSONConvertible { | ||
/** | ||
* Turn this object into a Play JSON object. | ||
*/ | ||
private[hammer_ir] def toJSON: JsValue | ||
} | ||
|
||
/** | ||
* All Hammer IR objects implement this trait which allows them to be | ||
* serialized to/deserialized from JSON. | ||
*/ | ||
trait HammerObject { | ||
/** | ||
* Turn this object into a Play JSON object. | ||
*/ | ||
private[hammer_ir] def toJSON: JsObject | ||
|
||
/** | ||
* Turn this object into a JSON string. | ||
*/ | ||
override def toString = Json.prettyPrint(toJSON) | ||
|
||
/** | ||
* Write this object as a JSON string into the given file. | ||
*/ | ||
def toFile(filename: String) = reflect.io.File(filename).writeAll(toString) | ||
} | ||
|
||
/** | ||
* Abstract class mixed into companion classes of Hammer IR objects. | ||
*/ | ||
abstract class HammerObjectCompanion[T <: HammerObject : ClassTag] { | ||
/** | ||
* Create this object from a Play JSON object. | ||
*/ | ||
private[hammer_ir] def fromJSON(json: JsObject): T | ||
|
||
/** | ||
* Create this object from a JSON string. | ||
*/ | ||
def fromString(json: String): T = fromJSON(Json.parse(json).as[JsObject]) | ||
|
||
/** | ||
* Create this object from a JSON file. | ||
*/ | ||
def fromFile(filename: String): T = { | ||
val source = scala.io.Source.fromFile(filename) | ||
val lines = try source.mkString finally source.close() | ||
fromString(lines) | ||
} | ||
} |
136 changes: 136 additions & 0 deletions
136
hammer_ir/scalalib/src/main/scala/PlacementConstraint.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
// See LICENSE for licence details. | ||
|
||
package hammer_ir | ||
|
||
import play.api.libs.json.{JsNumber, JsObject, JsString} | ||
|
||
sealed abstract class PlacementConstraintType extends JSONConvertible { | ||
override def toJSON = JsString(stringVal) | ||
// Force objects to implement this since toString is defined by | ||
// default. | ||
def stringVal: String | ||
override def toString = stringVal | ||
} | ||
object PlacementConstraintType { | ||
def fromString(input: String): PlacementConstraintType = { | ||
values.foreach { i => | ||
if (i.stringVal == input) return i | ||
} | ||
throw new IllegalArgumentException(s"Illegal PlacementConstraintType $input") | ||
} | ||
|
||
case object Dummy extends PlacementConstraintType { | ||
override def stringVal = "dummy" | ||
} | ||
case object Placement extends PlacementConstraintType { | ||
override def stringVal = "placement" | ||
} | ||
case object TopLevel extends PlacementConstraintType { | ||
override def stringVal = "toplevel" | ||
} | ||
case object HardMacro extends PlacementConstraintType { | ||
override def stringVal = "hardmacro" | ||
} | ||
case object Hierarchical extends PlacementConstraintType { | ||
override def stringVal = "hierarchical" | ||
} | ||
case object Obstruction extends PlacementConstraintType { | ||
override def stringVal = "obstruction" | ||
} | ||
|
||
def values = Seq( | ||
Dummy, Placement, TopLevel, HardMacro, Hierarchical, Obstruction | ||
) | ||
} | ||
|
||
sealed abstract class ObstructionType | ||
object ObstructionType { | ||
case object Place extends ObstructionType | ||
case object Route extends ObstructionType | ||
case object Power extends ObstructionType | ||
} | ||
|
||
case class Margins( | ||
left: Double, | ||
bottom: Double, | ||
right: Double, | ||
top: Double | ||
) | ||
|
||
case class PlacementConstraint( | ||
path: String, | ||
`type`: PlacementConstraintType, | ||
x: Double, | ||
y: Double, | ||
width: Double, | ||
height: Double, | ||
orientation: Option[String], | ||
margins: Option[Margins], | ||
top_layer: Option[String], | ||
layers: Option[Seq[String]], | ||
obs_types: Option[Seq[ObstructionType]] | ||
) extends HammerObject { | ||
override def toJSON = { | ||
JsObject(Seq( | ||
"path" -> JsString(path), | ||
"type" -> `type`.toJSON, | ||
"x" -> JsNumber(x), | ||
"y" -> JsNumber(y), | ||
"width" -> JsNumber(width), | ||
"height" -> JsNumber(height) | ||
// TODO(edwardw): FIXME | ||
)) | ||
} | ||
} | ||
|
||
object PlacementConstraint extends HammerObjectCompanion[PlacementConstraint] { | ||
def apply( | ||
path: String, | ||
`type`: PlacementConstraintType, | ||
x: Double, | ||
y: Double, | ||
width: Double, | ||
height: Double | ||
): PlacementConstraint = { | ||
new PlacementConstraint( | ||
path, | ||
`type`, | ||
x, | ||
y, | ||
width, | ||
height, | ||
None, // TODO(edwardw): FIXME | ||
None, | ||
None, | ||
None, | ||
None | ||
) | ||
} | ||
|
||
/* Helper function used to convert strings to Double | ||
* for forwards-compatibility with Decimal type. */ | ||
def doubleOrString(value: play.api.libs.json.JsLookupResult): Double = { | ||
try { | ||
value.as[Double] | ||
} catch { | ||
case _: play.api.libs.json.JsResultException => | ||
value.as[String].toDouble | ||
} | ||
} | ||
|
||
override def fromJSON(json: JsObject): PlacementConstraint = { | ||
new PlacementConstraint( | ||
(json \ "path").as[String], | ||
PlacementConstraintType.fromString((json \ "type").as[String]), | ||
doubleOrString(json \ "x"), | ||
doubleOrString(json \ "y"), | ||
doubleOrString(json \ "width"), | ||
doubleOrString(json \ "height"), | ||
None, // TODO(edwardw): FIXME | ||
None, | ||
None, | ||
None, | ||
None | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// See LICENSE for licence details. | ||
|
||
package hammer_ir.test | ||
|
||
import org.scalatest.{FlatSpec, Matchers} | ||
import play.api.libs.json.{JsObject, JsString} | ||
|
||
import hammer_ir._ | ||
|
||
class HammerObjectSpec extends FlatSpec with Matchers { | ||
behavior of "HammerObject" | ||
|
||
case class Test(foobar: String) extends HammerObject { | ||
override def toJSON = JsObject(Seq( | ||
"foobar" -> JsString(foobar) | ||
)) | ||
} | ||
object Test extends HammerObjectCompanion[Test] { | ||
override def fromJSON(json: JsObject): Test = { | ||
new Test( | ||
(json \ "foobar").as[String] | ||
) | ||
} | ||
} | ||
|
||
it should "serialize and deserialize correctly" in { | ||
val t = Test("helloworld") | ||
// Need these replaces to be robust to spacing variations | ||
assert(t.toString | ||
.replaceAll("\n", "").replaceAll(" ", "") | ||
=== """{"foobar":"helloworld"}""") | ||
assert(Test.fromJSON(t.toJSON) == t) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// See LICENSE for licence details. | ||
|
||
import $cp.`hammer_ir.jar` | ||
|
||
import hammer_ir._ | ||
|
||
// Read and write back | ||
val p = PlacementConstraint.fromFile("c1.json") | ||
|
||
p.`type` match { | ||
case PlacementConstraintType.Placement => println("Am placement") | ||
case _ => println("Am not placement") | ||
} | ||
|
||
p.toFile("c1-out.json") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#!/bin/bash | ||
# Test preparation script. | ||
# Ensures that ammonite and the Hammer IR JAR are built. | ||
|
||
set -e | ||
set -euo pipefail | ||
|
||
script_dir=$(dirname $0) | ||
cd $script_dir | ||
|
||
# Build Hammer IR | ||
pushd .. | ||
./build.sh | ||
|
||
# Ensure ammonite exists | ||
if [ ! -f "amm" ]; then | ||
./get_ammonite.sh | ||
fi | ||
|
||
popd | ||
|
||
# Create ammonite wrapper to import hammer_ir JAR. | ||
echo "../amm --predef-code 'import ammonite.ops._; interp.load.cp(pwd/os.up/\"hammer_ir.jar\")' \$1" > amm | ||
chmod +x amm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#!/bin/sh | ||
set -ex | ||
cd $(dirname $0) | ||
./test_* |
Oops, something went wrong.