2012-07-09 14 views
12

Podczas korzystania z toolchainu SBT w Scali, możliwe jest napisanie zadania, które odczyta specjalną część źródła projektu, aby wygenerować kod scala w czasie kompilacji.Generowanie kodu za pomocą Scala

Wszelkie pomysły, a nawet artykuły/samouczki na ten temat? Szukam czegoś podobnego do szablonu Haskell.

+0

Tak, jest to możliwe. Jestem prawie pewien, że istnieją wtyczki, które to robią. Czy przejrzałeś listę istniejących wtyczek? –

Odpowiedz

13

treehugger.scala jest biblioteką przeznaczony do generowania kodu.

import treehugger.forest._ 
import definitions._ 
import treehuggerDSL._ 

val tree: Tree = Predef_println APPLY LIT("Hello, world!") 

println(tree) 
println(treeToString(tree)) 

Powyższy kod drukuje dwie linie:

Apply(Ident(println),List(Literal(Constant(Hello, world!)))) 
println("Hello, world!") 

treehugger generuje AST, ale niezgodnych AST scalac'S.

+5

Aby wyjaśnić: treehugger = generowanie kodu źródłowego; makra = generowanie AST. Ten pierwszy jest niższy technicznie, co w rzeczywistości może być zaletą :) – retronym

+0

@EugeneYokota, czy planowane jest pobliskie wydanie dla Scala 2.10? – jeslg

7

Scala 2.10 ma eksperymentalne wsparcie dla makr, które podobnie jak wyrafinowane generowanie kodu kompilacji. Aby uzyskać więcej informacji, patrz here.

Istnieje kilka przykładów zabawy na macrocosm git repozytorium Jason Zaugg, a biblioteka SLICK który jest ewolucja DSL ScalaQuery SQL umożliwiającej typu bezpieczne bazy danych (i kolekcji) zapytań być wyrażone w LINQ-jak sposób.

I ten przykład, z biblioteki expecty twierdzenie:

import org.expecty.Expecty 

case class Person(name: String = "Fred", age: Int = 42) { 
    def say(words: String*) = words.mkString(" ") 
} 

val person = Person() 
val expect = new Expecty() 

... 
val word1 = "ping" 
val word2 = "pong" 

expect { 
    person.say(word1, word2) == "pong pong" 
} 

Uzyskano

java.lang.AssertionError: 

person.say(word1, word2) == "pong pong" 
|  | |  |  | 
|  | ping pong false 
|  ping pong 
Person(Fred,42) 
+0

Kiedy należy spodziewać się pełnej funkcji? – Lanbo

+1

Wierzę, że zespół programistów kompilatora testuje je w wersji 2.10, aby zobaczyć, jak użyteczna jest dla nich społeczność. Obecne myślenie (od kiedy ostatnio czytałem listę mailingową internals, kilka tygodni temu) jest to, że wciąż pozostawiają otwartą możliwość posiadania ich tylko jako eksperymentalnych. Ale jeśli wsparcie społeczności jest bardzo pozytywne, wyobrażam sobie, że zostaną adoptowani. Są inni na tej stronie, którzy mogą być w stanie dać ci bardziej ostateczną odpowiedź. –

+1

Wyglądają bardzo podobnie do szablonu Haskella i jest to powszechnie stosowane. Chociaż w wielu przypadkach Scala może dobrze służyć bez tego (jak automatyczne rozszerzenie dla złożonych klas). Ale dla mojego celu, wstępne przetwarzanie zasobów podczas kompilacji jest właściwe. – Lanbo