This page is no longer maintained — Please continue to the home page at www.scala-lang.org

help with very simple compiler transformation

5 replies
Nicholas Tung
Joined: 2009-05-19,
User offline. Last seen 42 years 45 weeks ago.

Dear all,

I'm trying to write a very simple compiler transformation, which
will create temporary variables, for the sake of maintaining type
annotations through compilation (since they will not be erased from
symbols). I want to rewrite [for example] "(fcn() : Int @ Range(-31 to
31)) + 2" into "{ val tmp = fcn() : Int @ Range(-31 to 31); tmp; } +
2". I think I'm getting farther and farther from what I want...

The current code goes something like this,

class CreateTmpvarsForTyped() extends Transformer {
def createBlockForTyped(expr:Tree, tpt:Tree) = {
val name = newTermName("__skalch_internal_typed_tmp")
val sym = expr.tpe.typeSymbol.newValue(NoPosition,
name).setInfo(expr.tpe)
val vd = ValDef(Modifiers(LOCAL), name, tpt, expr)
vd.symbol = sym
val ident = Ident(name)
ident.symbol = sym
Block(List(vd), ident)
}

override def transform(tree : Tree) = tree match {
case Typed(expr, tpt) =>
createBlockForTyped(expr, tpt)
case _ => super.transform(tree)
}
}

It's throwing a null pointer exception in a later stage,

Exception in thread "main" java.lang.NullPointerException
at scala.tools.nsc.transform.UnCurry.scala$tools$nsc$transform$UnCurry$$expandAlias(UnCurry.scala:50)
at scala.tools.nsc.transform.UnCurry$$anon$3.apply(UnCurry.scala:59)
at scala.tools.nsc.transform.UnCurry$$anon$3.apply(UnCurry.scala:57)

Any help would be much appreciated.

Thanks very much,
Nicholas — ntung at ntung — https://ntung.com — CS major @ UC Berkeley

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: help with very simple compiler transformation

On Sat, May 29, 2010 at 08:59:37PM -0700, Nicholas Tung wrote:
> def createBlockForTyped(expr:Tree, tpt:Tree) = {
...
> Block(List(vd), ident)

That's an untyped tree.

> override def transform(tree : Tree) = tree match {
> case Typed(expr, tpt) =>

That's a typed tree.

> createBlockForTyped(expr, tpt)

That's you replacing a typed tree with an untyped tree.

> Exception in thread "main" java.lang.NullPointerException
> at scala.tools.nsc.transform.UnCurry.scala$tools$nsc$transform$UnCurry$$expandAlias(UnCurry.scala:50)

That's the compiler dereferencing the null pointer where it expects the
tpe to be.

Nicholas Tung
Joined: 2009-05-19,
User offline. Last seen 42 years 45 weeks ago.
Re: help with very simple compiler transformation

On Sat, May 29, 2010 at 9:06 PM, Paul Phillips wrote:
>
> On Sat, May 29, 2010 at 08:59:37PM -0700, Nicholas Tung wrote:
> >                 def createBlockForTyped(expr:Tree, tpt:Tree) = {
> ...
> >                     Block(List(vd), ident)
>
> That's an untyped tree.
>
> >                 override def transform(tree : Tree) = tree match {
> >                     case Typed(expr, tpt) =>
>
> That's a typed tree.
>
> >                         createBlockForTyped(expr, tpt)
>
> That's you replacing a typed tree with an untyped tree.
>
> > Exception in thread "main" java.lang.NullPointerException
> >         at scala.tools.nsc.transform.UnCurry.scala$tools$nsc$transform$UnCurry$$expandAlias(UnCurry.scala:50)
>
> That's the compiler dereferencing the null pointer where it expects the
> tpe to be.
>
> --
> Paul Phillips      | It's better to have gloved and tossed than never to
> Apatheist          | have played baseball.
> Empiricist         |
> up hill, pi pals!  |----------* http://www.improving.org/paulp/ *----------

Thanks very much. I have another question -- how can I follow a
TypeRef to get an annotation? Here's some example code:
type Int5 = Int @ Range(-32 to 31)
val x = (fcn() : Int5)

I want the "Range" annotation, so I can map "x -> Range(-32 to 31)",
since the compiler destroys this info later on.

If there is more documentation than the videos listed here, I'd
appreciate a reference.
http://www.scala-lang.org/node/598

Thanks,
Nicholas — ntung at ntung — https://ntung.com — CS major @ UC Berkeley

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: help with very simple compiler transformation

On Mon, May 31, 2010 at 03:23:52PM -0700, Nicholas Tung wrote:
> Thanks very much. I have another question -- how can I follow a
> TypeRef to get an annotation? Here's some example code:
> type Int5 = Int @ Range(-32 to 31)
> val x = (fcn() : Int5)

Do you have reason to believe this can work? I'll be surprised. It'd be
neat if so. I don't think type aliases are sufficiently first class
that you can annotate them and distinguish between the annotated alias
and the underlying type.

Here's a little repl session in my current repl, which I can't resist to
demo the stuff I've been adding. Not sure what if anything this will
tell you -- I know little about the annotations implementation. But it
seems to support my suspicion since I only see the annotation at all if
I normalize.

scala> class Range(x: scala.Range) extends scala.StaticAnnotation
defined class Range

scala> type Int5 = Int @ Range(-32 to 31)
defined type alias Int5

scala> :type Int5
tpe7: global.Type = Int5

scala> tpe7.normalize
res10: global.Type = Int

scala> repl.allPhases( tpe7.normalize.annotations)
parser -> List(Range(scala.this.Predef.intWrapper(-32).to(31)))
namer -> " " "
packageobjects -> " " "
typer -> " " "
superaccessors -> " " "
pickler -> " " "
refchecks -> " " "
selectiveanf -> " " "
liftcode -> " " "
selectivecps -> " " "
uncurry -> " " "
tailcalls -> " " "
specialize -> " " "
explicitouter -> " " "
erasure -> " " "
lazyvals -> List()
lambdalift -> " " "
constructors -> " " "
flatten -> " " "
mixin -> " " "
cleanup -> " " "
icode -> " " "
inliner -> " " "
closelim -> " " "
dce -> " " "
jvm -> " " "
terminal -> " " "

scala> repl.allPhases( tpe7.annotations)
parser -> List()
namer -> " " "
packageobjects -> " " "
typer -> " " "
superaccessors -> " " "
pickler -> " " "
refchecks -> " " "
selectiveanf -> " " "
liftcode -> " " "
selectivecps -> " " "
uncurry -> " " "
tailcalls -> " " "
specialize -> " " "
explicitouter -> " " "
erasure -> " " "
lazyvals -> " " "
lambdalift -> " " "
constructors -> " " "
flatten -> " " "
mixin -> " " "
cleanup -> " " "
icode -> " " "
inliner -> " " "
closelim -> " " "
dce -> " " "
jvm -> " " "
terminal -> " " "

Nicholas Tung
Joined: 2009-05-19,
User offline. Last seen 42 years 45 weeks ago.
Re: help with very simple compiler transformation

Thanks so much, normalize works great!!!

I'm not sure why the annotations are not showing up for you... I see them
after the typer. I'm running Scala 2.8.0 RC2 from Maven; the primary files
in my project are here (plugin, file, and library defining @Range):

http://github.com/gatoatigrado/skalch/blob/564b7e6b97305e62faeee69a321cd...

http://github.com/gatoatigrado/skalch/blob/564b7e6b97305e62faeee69a321cd...

http://github.com/gatoatigrado/skalch/blob/564b7e6b97305e62faeee69a321cd...

regards,
Nicholas — ntung at ntung — https://ntung.com — CS major @ UC Berkeley

On Mon, May 31, 2010 at 5:39 PM, Paul Phillips wrote:
> On Mon, May 31, 2010 at 03:23:52PM -0700, Nicholas Tung wrote:
>> Thanks very much. I have another question -- how can I follow a
>> TypeRef to get an annotation? Here's some example code:
>> type Int5 = Int @ Range(-32 to 31)
>> val x = (fcn() : Int5)
>
> Do you have reason to believe this can work? I'll be surprised.  It'd be
> neat if so.  I don't think type aliases are sufficiently first class
> that you can annotate them and distinguish between the annotated alias
> and the underlying type.
>
> Here's a little repl session in my current repl, which I can't resist to
> demo the stuff I've been adding.  Not sure what if anything this will
> tell you -- I know little about the annotations implementation.  But it
> seems to support my suspicion since I only see the annotation at all if
> I normalize.
>
> scala> class Range(x: scala.Range) extends scala.StaticAnnotation
> defined class Range
>
> scala> type Int5 = Int @ Range(-32 to 31)
> defined type alias Int5
>
> scala> :type Int5
> tpe7: global.Type = Int5
>
> scala> tpe7.normalize
> res10: global.Type = Int
>
> scala> repl.allPhases( tpe7.normalize.annotations)
>         parser -> List(Range(scala.this.Predef.intWrapper(-32).to(31)))
>          namer -> " " "
>  packageobjects -> " " "
>          typer -> " " "
>  superaccessors -> " " "
>        pickler -> " " "
>      refchecks -> " " "
>   selectiveanf -> " " "
>       liftcode -> " " "
>   selectivecps -> " " "
>        uncurry -> " " "
>      tailcalls -> " " "
>     specialize -> " " "
>  explicitouter -> " " "
>        erasure -> " " "
>       lazyvals -> List()
>     lambdalift -> " " "
>   constructors -> " " "
>        flatten -> " " "
>          mixin -> " " "
>        cleanup -> " " "
>          icode -> " " "
>        inliner -> " " "
>       closelim -> " " "
>            dce -> " " "
>            jvm -> " " "
>       terminal -> " " "
>
> scala> repl.allPhases( tpe7.annotations)
>         parser -> List()
>          namer -> " " "
>  packageobjects -> " " "
>          typer -> " " "
>  superaccessors -> " " "
>        pickler -> " " "
>      refchecks -> " " "
>   selectiveanf -> " " "
>       liftcode -> " " "
>   selectivecps -> " " "
>        uncurry -> " " "
>      tailcalls -> " " "
>     specialize -> " " "
>  explicitouter -> " " "
>        erasure -> " " "
>       lazyvals -> " " "
>     lambdalift -> " " "
>   constructors -> " " "
>        flatten -> " " "
>          mixin -> " " "
>        cleanup -> " " "
>          icode -> " " "
>        inliner -> " " "
>       closelim -> " " "
>            dce -> " " "
>            jvm -> " " "
>       terminal -> " " "
>
> --
> Paul Phillips      | On two occasions, I have been asked, 'Mr. Babbage, if you
> Caged Spirit       | put into the machine wrong figures, will the right answers
> Empiricist         | come out?' I am not able to rightly apprehend the kind of
> i'll ship a pulp   | confusion of ideas that could provoke such a question.
>

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: help with very simple compiler transformation

On Mon, May 31, 2010 at 07:00:37PM -0700, Nicholas Tung wrote:
> I'm not sure why the annotations are not showing up for you... I see
> them after the typer. I'm running Scala 2.8.0 RC2 from Maven; the
> primary files in my project are here (plugin, file, and library
> defining @Range):

I'm going to guess it's because I defined the annotation in the repl.
I've recently found myself unable to recover the scala sig annotation in
repl defined classes so maybe this is serendipitously pointing me in the
right general direction for fixing that.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland