2013-09-10 25 views
5

Bir makro için bir parametrenin orijinal giriş dizesi almaya çalışıyorum, ancak döndürülen konum biraz uzakta görünüyor. örneğin, bu makro düşünün:Scala makrolarında ne var?

object M { 
    import scala.reflect.macros.Context 
    import language.experimental.macros 
    def f[T](v: => T) = macro fImpl[T] 
    def fImpl[T : c.WeakTypeTag](c: Context)(v: c.Expr[T]): c.Expr[Unit] = { 
    import c.universe._ 
    val pos = v.tree.pos 
    println(pos.lineContent) 
    println(" " * pos.column + "^") 
    println(" " * pos.point + "^") 
    c.literalUnit 
    } 
} 

bu dosya ile çalıştığınızda:

object N extends App { 
    val x = 1 
    val y = 2 
    println(M.f(x + y)) 
} 

bu çıktıyı almak:

println(M.f(x + y)) 
       ^
                   ^

bana mantıklı olmadığı. x'a işaret etmesini beklerim ya da bir defalık olsun. Ne var ne yok?

+0

. + (Y))) 'nokta y üzerinde bir noktaya kaydırır ve println (Mf (if (doğru) {x + y})) ile f'de işaret eder. Ağacın tepesine bakmaya çalıştığını sanıyorum, isterse isterse isterse başka bir soru olsa da olmasa da, + ya da onun ifadesi. En az bir tane birebir hata da olabilir. Bu bana bir hata raporu için uygun görünüyor. – wingedsubmariner

+0

Soru okunduğunda daha eğlenceli olur, Makrolardaki konumunuz nedir? –

cevap

3

Position.column ve Position.line'un 1 temelli olduğu birebir hata.

Onların API belgelemek için rahatsız ama belirtmeyi uğraşmadı anlamda bir dokümantasyon böcek.

Sen -Yrangepos ile derlemek ve edebilirsiniz:

val n = pos.column - (pos.point - pos.startOrPoint) - 1 
println(" " * n + "^") 

veya benzeri ağaçta en erken konumunu belirtmek için.

println(M.f(x + y)) 
      ^

Güncelleme:

makro Return sonra bu verilen ifadeyi izin verme ve -Xprint:typer -Yshow-trees ile derleme, ağaç + konumlandırılır iç Apply düğüm vardır:

 Apply(// def println(x: Any): Unit in object Predef, tree.tpe=Unit 
     scala.this."Predef"."println" // def println(x: Any): Unit in object Predef, tree.tpe=(x: Any)Unit 
     Apply(// def +(x: Int): Int in class Int, tree.tpe=Int 
      "x"."$plus" // def +(x: Int): Int in class Int, tree.tpe=(x: Int)Int 
      "y" // val y: Int, tree.tpe=Int 
     ) 
    ) 

ile bir "aralık" pozisyonu, ağacın üst kısmının konumu, altındaki her şeyi içerir. point süre Yani + olduğu, bir dizi pozisyon start yani aralık pozisyonu, çevrelediği her şeyin en erken pozisyon, ağaçta alt herşeyi. Bu durumda, sol yaprak x'dur.

Yani fark point - start yedeklemek için ne kadar anlatır.

(ı kabul ne kaynak dosyasının içine uzaklıklar nedeniyle karakter kodlaması farklılıklar sütun uzaklıklar farklı olması durumunda.)

Eğer println (Mf (x `bunu değiştirirseniz
+0

Ama _what_ 'sütunu 'işaret ediyor? Ve pos.point - pos.startOrPoint' (her ikisi de benim için anlamsızdı) anlamı nedir? –

+0

@ DanielC.Sobral IDE kişilerin düzeltmek zorunda olduğu bir hatayı bir araya getirecek şekilde sadece aralık pozisyonları hakkında yeterli bilgiye sahibim. En azından bir hatayı tamir ediyordum, bu yüzden bir yıkaydı. Ayrıca, -Yrangepos'un varsayılan haline geleceğini düşündüm? Sınırlı bilgilerimle güncellendi. https://github.com/scala/scala/pull/2936 –

+0

@ DanielC.Sobral var geliştirilir yorumlar (ve kod) Ah, nihayet sapmalarına o 'point',' start' ve 'Sonu 'noktasını fark dosyaya değil, dosyaya. –