Skip to content

Commit

Permalink
Merge pull request #369 from Duhemm/wip/nir-parser
Browse files Browse the repository at this point in the history
NIR parser
  • Loading branch information
densh committed Nov 3, 2016
2 parents 473cac1 + b703f09 commit 27c8207
Show file tree
Hide file tree
Showing 44 changed files with 1,511 additions and 39 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,4 @@ before_script:
script:
- java -version
- bin/scalafmt --version 0.4.7 --test
- sbt 'cleanCache' 'cleanLocal' 'nscplugin/publishLocal' 'nativelib/publishLocal' 'publishLocal' 'sandbox/run' 'demoNative/run' 'tests/run' 'scripted' 'publishSnapshot'
- sbt 'cleanCache' 'cleanLocal' 'nscplugin/publishLocal' 'nativelib/publishLocal' 'publishLocal' 'sandbox/run' 'demoNative/run' 'tests/run' 'tools/test' 'scripted' 'publishSnapshot'
8 changes: 8 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,14 @@ lazy val tools =
.in(file("tools"))
.settings(toolSettings)
.settings(publishSettings)
.settings(
libraryDependencies ++= Seq(
"com.lihaoyi" %% "fastparse" % "0.4.2",
"com.lihaoyi" %% "scalaparse" % "0.4.2",
compilerPlugin(
"org.scalamacros" % "paradise" % "2.0.1" cross CrossVersion.full),
"org.scalatest" %% "scalatest" % "3.0.0" % "test"
))
.dependsOn(nir, util)

lazy val nscplugin =
Expand Down
8 changes: 4 additions & 4 deletions nir/src/main/scala/scala/scalanative/nir/Ops.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ sealed abstract class Op {
case Op.Select(_, v, _) => v.ty

case Op.Classalloc(n) => Type.Class(n)
case Op.Field(ty, _, _) => Type.Ptr
case Op.Method(ty, _, _) => Type.Ptr
case Op.Field(_, _) => Type.Ptr
case Op.Method(_, _) => Type.Ptr
case Op.Module(n) => Type.Module(n)
case Op.As(ty, _) => ty
case Op.Is(_, _) => Type.Bool
Expand Down Expand Up @@ -48,8 +48,8 @@ object Op {

// high-level
final case class Classalloc(name: Global) extends Op
final case class Field(ty: Type, obj: Val, name: Global) extends Op
final case class Method(ty: Type, obj: Val, name: Global) extends Op
final case class Field(obj: Val, name: Global) extends Op
final case class Method(obj: Val, name: Global) extends Op
final case class Module(name: Global) extends Op
final case class As(ty: Type, obj: Val) extends Op
final case class Is(ty: Type, obj: Val) extends Op
Expand Down
28 changes: 21 additions & 7 deletions nir/src/main/scala/scala/scalanative/nir/Shows.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package scala.scalanative
package nir

import scala.util.matching.Regex

import util.{unreachable, sh, Show}
import Show.{
Sequence => s,
Expand Down Expand Up @@ -120,10 +122,10 @@ object Shows {

case Op.Classalloc(name) =>
sh"classalloc $name"
case Op.Field(ty, value, name) =>
sh"field[$ty] $value, $name"
case Op.Method(ty, value, name) =>
sh"method[$ty] $value, $name"
case Op.Field(value, name) =>
sh"field $value, $name"
case Op.Method(value, name) =>
sh"method $value, $name"
case Op.Module(name) =>
sh"module $name"
case Op.As(ty, value) =>
Expand Down Expand Up @@ -209,13 +211,13 @@ object Shows {
case Val.Struct(Global.None, values) => sh"struct {${r(values, ", ")}}"
case Val.Struct(n, values) => sh"struct $n {${r(values, ", ")}}"
case Val.Array(ty, values) => sh"array $ty {${r(values, ", ")}}"
case Val.Chars(v) => s("c\"", v, "\"")
case Val.Chars(v) => s("c\"", escapeNewLine(escapeQuotes(v)), "\"")
case Val.Local(name, ty) => sh"$name: $ty"
case Val.Global(name, ty) => sh"$name"
case Val.Global(name, ty) => sh"$name[$ty]"

case Val.Unit => "unit"
case Val.Const(v) => sh"const $v"
case Val.String(v) => "\"" + v + "\""
case Val.String(v) => "\"" + escapeNewLine(escapeQuotes(v)) + "\""
}

implicit val showDefns: Show[Seq[Defn]] = Show { defns =>
Expand Down Expand Up @@ -303,4 +305,16 @@ object Shows {
implicit val showLocal: Show[Local] = Show {
case Local(scope, id) => sh"%$scope.$id"
}

def escapeNewLine(s: String): String =
"""([^\\]|^)\n""".r.replaceAllIn(s, _.matched.toSeq match {
case Seq(sngl) => s"""\\\\n"""
case Seq(fst, snd) => s"""${fst}\\\\n"""
})

private def escapeQuotes(s: String): String =
"""([^\\]|^)"""".r.replaceAllIn(s, _.matched.toSeq match {
case Seq(sngl) => s"\\\\$sngl"
case Seq(fst, snd) => s"$fst\\\\$snd"
})
}
4 changes: 2 additions & 2 deletions nir/src/main/scala/scala/scalanative/nir/Versions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ object Versions {
* when 1.3-based release happens all of the code needs to recompiled with
* new version of the toolchain.
*/
final val compat: Int = 6
final val revision: Int = 7
final val compat: Int = 7
final val revision: Int = 8

/* Current public release version of Scala Native. */
final val current: String = "0.1-SNAPSHOT"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,8 @@ final class BinaryDeserializer(_buffer: => ByteBuffer) {
case T.SelectOp => Op.Select(getVal, getVal, getVal)

case T.ClassallocOp => Op.Classalloc(getGlobal)
case T.FieldOp => Op.Field(getType, getVal, getGlobal)
case T.MethodOp => Op.Method(getType, getVal, getGlobal)
case T.FieldOp => Op.Field(getVal, getGlobal)
case T.MethodOp => Op.Method(getVal, getGlobal)
case T.ModuleOp => Op.Module(getGlobal)
case T.AsOp => Op.As(getType, getVal)
case T.IsOp => Op.Is(getType, getVal)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,15 +335,13 @@ final class BinarySerializer(buffer: ByteBuffer) {
putInt(T.ClassallocOp)
putGlobal(n)

case Op.Field(ty, v, name) =>
case Op.Field(v, name) =>
putInt(T.FieldOp)
putType(ty)
putVal(v)
putGlobal(name)

case Op.Method(ty, v, name) =>
case Op.Method(v, name) =>
putInt(T.MethodOp)
putType(ty)
putVal(v)
putGlobal(name)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ abstract class NirCodeGen
val elem =
if (isExternModule(sym.owner))
qual withValue Val.Global(name, Type.Ptr)
else qual withOp Op.Field(ty, qual.value, name)
else qual withOp Op.Field(qual.value, name)
elem withOp Op.Load(ty, elem.value)
}

Expand Down Expand Up @@ -558,7 +558,7 @@ abstract class NirCodeGen
if (isExternModule(sel.symbol.owner)) {
rhs withValue Val.Global(name, Type.Ptr)
} else {
rhs withOp Op.Field(ty, qual.value, name)
rhs withOp Op.Field(qual.value, name)
}
elem withOp Op.Store(ty, elem.value, rhs.value)

Expand Down Expand Up @@ -754,7 +754,7 @@ abstract class NirCodeGen
else {
val ty = genType(sym.tpe)
val module = focus withOp Op.Module(genTypeName(sym.owner))
val elem = module withOp Op.Field(ty, module.value, genFieldName(sym))
val elem = module withOp Op.Field(module.value, genFieldName(sym))

elem withOp Op.Load(ty, elem.value)
}
Expand Down Expand Up @@ -1730,7 +1730,7 @@ abstract class NirCodeGen
val method =
if (statically || isStruct(owner) || isExternModule(owner))
last withValue Val.Global(name, nir.Type.Ptr)
else last withOp Op.Method(sig, self, name)
else last withOp Op.Method(self, name)
val values =
if (isExternModule(owner) || owner.isImplClass) args
else self +: args
Expand Down
7 changes: 7 additions & 0 deletions project/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ unmanagedSourceDirectories in Compile ++= {

libraryDependencies += "org.eclipse.jgit" % "org.eclipse.jgit.pgm" % "3.2.0.201312181205-r"

libraryDependencies += "com.lihaoyi" %% "fastparse" % "0.4.2"

libraryDependencies += "com.lihaoyi" %% "scalaparse" % "0.4.2"

libraryDependencies += compilerPlugin(
"org.scalamacros" % "paradise" % "2.0.1" cross CrossVersion.full)

addSbtPlugin("com.eed3si9n" % "sbt-dirty-money" % "0.1.0")

libraryDependencies <+= (sbtVersion) { sv =>
Expand Down
8 changes: 4 additions & 4 deletions tools/src/main/scala/scala/scalanative/compiler/Pass.scala
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,10 @@ trait Pass extends (Seq[Defn] => Seq[Defn]) {

case Op.Classalloc(n) =>
Op.Classalloc(n)
case Op.Field(ty, v, n) =>
Op.Field(txType(ty), txVal(v), n)
case Op.Method(ty, v, n) =>
Op.Method(txType(ty), txVal(v), n)
case Op.Field(v, n) =>
Op.Field(txVal(v), n)
case Op.Method(v, n) =>
Op.Method(txVal(v), n)
case Op.Module(n) =>
Op.Module(n)
case Op.As(ty, v) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class ClassLowering(implicit top: Top, fresh: Fresh) extends Pass {
}

override def preInst = {
case Let(n, Op.Field(ty, obj, FieldRef(cls: Class, fld))) =>
case Let(n, Op.Field(obj, FieldRef(cls: Class, fld))) =>
val classty = cls.classStruct

Seq(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,11 @@ object GlobalValueNumbering extends PassCompanion {
Select(condB, thenvB, elsevB)) =>
eqVals(Seq(condA, thenvA, elsevA), Seq(condB, thenvB, elsevB))

case (Field(tyA, objA, nameA), Field(tyB, objB, nameB)) =>
eqType(tyA, tyB) && eqVal(objA, objB) && eqGlobal(nameA, nameB)
case (Field(objA, nameA), Field(objB, nameB)) =>
eqVal(objA, objB) && eqGlobal(nameA, nameB)

case (Method(tyA, objA, nameA), Method(tyB, objB, nameB)) =>
eqType(tyA, tyB) && eqVal(objA, objB) && eqGlobal(nameA, nameB)
case (Method(objA, nameA), Method(objB, nameB)) =>
eqVal(objA, objB) && eqGlobal(nameA, nameB)

case (Module(nameA), Module(nameB)) =>
eqGlobal(nameA, nameB)
Expand Down Expand Up @@ -287,8 +287,8 @@ object GlobalValueNumbering extends PassCompanion {
case Conv(conv, ty, value) => Seq("Conv", ty, value)
case Select(cond, thenv, elsev) => Seq("Select", cond, thenv, elsev)

case Field(ty, obj, name) => Seq("Field", obj, name)
case Method(ty, obj, name) => Seq("Method", ty, obj, name)
case Field(obj, name) => Seq("Field", obj, name)
case Method(obj, name) => Seq("Method", obj, name)
case As(ty, obj) => Seq("As", ty, obj)
case Is(ty, obj) => Seq("Is", ty, obj)
case Copy(value) => Seq("Copy", value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import nir._, Inst.Let
*/
class MethodLowering(implicit fresh: Fresh, top: Top) extends Pass {
override def preInst = {
case Let(n, Op.Method(sig, obj, MethodRef(cls: Class, meth)))
case Let(n, Op.Method(obj, MethodRef(cls: Class, meth)))
if meth.isVirtual =>
val typeptr = Val.Local(fresh(), Type.Ptr)
val methptrptr = Val.Local(fresh(), Type.Ptr)
Expand All @@ -28,13 +28,12 @@ class MethodLowering(implicit fresh: Fresh, top: Top) extends Pass {
Let(n, Op.Load(Type.Ptr, methptrptr))
)

case Let(n, Op.Method(sig, obj, MethodRef(_: Class, meth)))
if meth.isStatic =>
case Let(n, Op.Method(obj, MethodRef(_: Class, meth))) if meth.isStatic =>
Seq(
Let(n, Op.Copy(Val.Global(meth.name, Type.Ptr)))
)

case Let(n, Op.Method(sig, obj, MethodRef(trt: Trait, meth))) =>
case Let(n, Op.Method(obj, MethodRef(trt: Trait, meth))) =>
val typeptr = Val.Local(fresh(), Type.Ptr)
val idptr = Val.Local(fresh(), Type.Ptr)
val id = Val.Local(fresh(), Type.I32)
Expand Down
14 changes: 14 additions & 0 deletions tools/src/main/scala/scala/scalanative/nir/parser/Arg.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package scala.scalanative
package nir
package parser

import fastparse.all._

object Arg extends Base[nir.Arg] {

override val parser: P[nir.Arg] =
P(PassConv.parser.? ~ Type.parser map {
case (pc, ty) => nir.Arg(ty, pc)
})

}
30 changes: 30 additions & 0 deletions tools/src/main/scala/scala/scalanative/nir/parser/Attr.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package scala.scalanative
package nir
package parser

import fastparse.all._

object Attr extends Base[nir.Attr] {

import Base._
import IgnoreWhitespace._

val MayInline = P("mayinline".! map (_ => nir.Attr.MayInline))
val InlineHint = P("inlinehint".! map (_ => nir.Attr.InlineHint))
val NoInline = P("noinline".! map (_ => nir.Attr.NoInline))
val AlwaysInline = P("alwaysinline".! map (_ => nir.Attr.AlwaysInline))
val Pure = P("pure".! map (_ => nir.Attr.Pure))
val Extern = P("extern".! map (_ => nir.Attr.Extern))
val Override =
P("override(" ~ Global.parser ~ ")" map (nir.Attr.Override(_)))
val Link = P("link(" ~ qualifiedId ~ ")" map (nir.Attr.Link(_)))
val PinAlways = P("pin(" ~ Global.parser ~ ")" map (nir.Attr.PinAlways(_)))
val PinIf =
P("pin-if(" ~ Global.parser ~ "," ~ Global.parser ~ ")" map {
case (name, cond) => nir.Attr.PinIf(name, cond)
})

override val parser: P[nir.Attr] =
MayInline | InlineHint | NoInline | AlwaysInline | Pure | Extern | Override | Link | PinAlways | PinIf

}
13 changes: 13 additions & 0 deletions tools/src/main/scala/scala/scalanative/nir/parser/Attrs.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package scala.scalanative
package nir
package parser

import fastparse.all._

object Attrs extends Base[nir.Attrs] {

import Base.IgnoreWhitespace._

override val parser: P[nir.Attrs] =
P(Attr.parser.rep map (nir.Attrs.fromSeq(_)))
}

0 comments on commit 27c8207

Please sign in to comment.