Abstract function declarations are written using DEF(...)
or PROC(...)
. Optionally, parameter lists can be specified using withParams(PARAM(...), ...)
and type parameters can be specified using withTypeParams(TYPEVAR(...), ...)
:
scala> import treehugger.forest._, definitions._, treehuggerDSL._
import treehugger.forest._
import definitions._
import treehuggerDSL._
scala> val tree = DEF("get", IntClass).tree
[1m[34mtree[0m: [1m[32mtreehugger.forest.DefDef[0m = DefDef(Modifiers(, , Map()),get,List(),List(),TypeTree(),EmptyTree)
scala> val tree2 = (DEF("sideEffect", UnitClass) withParams()).tree
[1m[34mtree2[0m: [1m[32mtreehugger.forest.DefDef[0m = DefDef(Modifiers(, , Map()),sideEffect,List(),List(List()),TypeTree(),EmptyTree)
scala> val tree3 = (PROC("put") withParams(PARAM("x", IntClass))).tree
[1m[34mtree3[0m: [1m[32mtreehugger.forest.ProcDef[0m = ProcDef(Modifiers(, , Map()),put,List(),List(List(ValDef(Modifiers(<param>, , Map()),Typed(Ident(x),TypeTree()),EmptyTree))),EmptyTree)
scala> object sym {
val A = RootClass.newAliasType("A")
val B = RootClass.newAliasType("B")
}
defined object sym
scala> val tree4 = (DEF("compare", BooleanClass)
withTypeParams(TYPEVAR(sym.A))
withParams(PARAM("a", sym.A) := LIT(0))
withParams(PARAM("b", sym.A) := LIT(0)): Tree)
[1m[34mtree4[0m: [1m[32mtreehugger.forest.Tree[0m = DefDef(Modifiers(, , Map()),compare,List(TypeDef(Modifiers(, , Map()),A,List(),EmptyTree)),List(List(ValDef(Modifiers(<param>, , Map()),Typed(Ident(a),TypeTree()),Literal(Constant(0)))), List(ValDef(Modifiers(<param>, , Map()),Typed(Ident(b),TypeTree()),Literal(Constant(0))))),TypeTree(),EmptyTree)
The above examples print as:
scala> treeToString(tree)
[1m[34mres0[0m: [1m[32mString[0m = def get: Int
scala> treeToString(tree2)
[1m[34mres1[0m: [1m[32mString[0m = def sideEffect(): Unit
scala> treeToString(tree3)
[1m[34mres2[0m: [1m[32mString[0m = def put(x: Int)
scala> treeToString(tree4)
[1m[34mres3[0m: [1m[32mString[0m = def compare[A](a: A = 0)(b: A = 0): Boolean
In genral, for functions with return type:
(DEF("get"|sym, typ)
[withParams(PARAM("x"|sym, typ|"C")[ := arg], ...)]*
[withTypeParams(TYPEVAR(...), ...)]).tree
For procedures:
(PROC("get"|sym)
[withParams(PARAM("x"|sym, typ|"C")[ := arg], ...)]*
[withTypeParams(TYPEVAR(...), ...)]).tree
Function definitions are written by appending right-hand side tree after :=
as follows:
scala> val tree5 = DEF("get", IntClass) := LIT(0)
[1m[34mtree5[0m: [1m[32mtreehugger.forest.DefDef[0m = DefDef(Modifiers(, , Map()),get,List(),List(),TypeTree(),Literal(Constant(0)))
scala> treeToString(tree5)
[1m[34mres4[0m: [1m[32mString[0m = def get: Int = 0
The result type can be omitted using DEF(...)
as follows:
scala> val tree6 = DEF("get") := LIT(0)
[1m[34mtree6[0m: [1m[32mtreehugger.forest.DefDef[0m = DefDef(Modifiers(, , Map()),get,List(),List(),TypeTree(),Literal(Constant(0)))
scala> treeToString(tree6)
[1m[34mres5[0m: [1m[32mString[0m = def get = 0
When rhs is a BLOCK(tree, ...)
you need to use DEFINFER(...)
to differentiate from procedures (PROC
was added in 0.4.0).
scala> val tree7 = DEFINFER("get") := BLOCK(LIT(0))
[1m[34mtree7[0m: [1m[32mtreehugger.forest.DefDef[0m = DefDef(Modifiers(, , Map()),get,List(),List(),TypeTree(),Block(List(),Literal(Constant(0))))
scala> treeToString(tree7)
[1m[34mres6[0m: [1m[32mString[0m =
def get = {
0
}
Procedure definitions are written using PROC(...)
with BLOCK(tree, ...)
for the rhs:
scala> val tree8 = PROC("write") withParams(PARAM("str", StringClass)) := BLOCK(
LIT(0)
)
[1m[34mtree8[0m: [1m[32mtreehugger.forest.ProcDef[0m = ProcDef(Modifiers(, , Map()),write,List(),List(List(ValDef(Modifiers(<param>, , Map()),Typed(Ident(str),TypeTree()),EmptyTree))),Block(List(),Literal(Constant(0))))
scala> treeToString(tree8)
[1m[34mres7[0m: [1m[32mString[0m =
def write(str: String) {
0
}
Note withParams(...)
clause may be added multiple times, each forming a parameter list:
scala> val tree9 = (DEF("compare")
withTypeParams(TYPEVAR(sym.A))
withParams(PARAM("a", sym.A))
withParams(PARAM("b", sym.A))) := FALSE
[1m[34mtree9[0m: [1m[32mtreehugger.forest.DefDef[0m = DefDef(Modifiers(, , Map()),compare,List(TypeDef(Modifiers(, , Map()),A,List(),EmptyTree)),List(List(ValDef(Modifiers(<param>, , Map()),Typed(Ident(a),TypeTree()),EmptyTree)), List(ValDef(Modifiers(<param>, , Map()),Typed(Ident(b),TypeTree()),EmptyTree))),TypeTree(),Literal(Constant(false)))
scala> treeToString(tree9)
[1m[34mres8[0m: [1m[32mString[0m = def compare[A](a: A)(b: A) = false
Similar to VAL(...)
, PARAM(...)
can be followed by :=
and rhs to specify the default argument:
scala> val tree10 = (DEF("compare")
withTypeParams(TYPEVAR(sym.A))
withParams(PARAM("a", sym.A) := LIT(0))
withParams(PARAM("b", sym.A) := LIT(0))) := FALSE
[1m[34mtree10[0m: [1m[32mtreehugger.forest.DefDef[0m = DefDef(Modifiers(, , Map()),compare,List(TypeDef(Modifiers(, , Map()),A,List(),EmptyTree)),List(List(ValDef(Modifiers(<param>, , Map()),Typed(Ident(a),TypeTree()),Literal(Constant(0)))), List(ValDef(Modifiers(<param>, , Map()),Typed(Ident(b),TypeTree()),Literal(Constant(0))))),TypeTree(),Literal(Constant(false)))
scala> treeToString(tree10)
[1m[34mres9[0m: [1m[32mString[0m = def compare[A](a: A = 0)(b: A = 0) = false
By-name parameters are written using TYPE_BYNAME(typ)
as follows:
scala> val tree11 = (PROC("whileLoop")
withParams(PARAM("cond", TYPE_BYNAME(BooleanClass)))
withParams(PARAM("stat", TYPE_BYNAME(UnitClass))): Tree)
[1m[34mtree11[0m: [1m[32mtreehugger.forest.Tree[0m = ProcDef(Modifiers(, , Map()),whileLoop,List(),List(List(ValDef(Modifiers(<param>, , Map()),Typed(Ident(cond),TypeTree()),EmptyTree)), List(ValDef(Modifiers(<param>, , Map()),Typed(Ident(stat),TypeTree()),EmptyTree))),EmptyTree)
scala> treeToString(tree11)
[1m[34mres10[0m: [1m[32mString[0m = def whileLoop(cond: => Boolean)(stat: => Unit)
Repeated parameters are written using TYPE_*(typ)
as follows:
scala> val tree12 = (DEF("sum", IntClass)
withParams(PARAM("args", TYPE_*(IntClass))): Tree)
[1m[34mtree12[0m: [1m[32mtreehugger.forest.Tree[0m = DefDef(Modifiers(, , Map()),sum,List(),List(List(ValDef(Modifiers(<param>, , Map()),Typed(Ident(args),TypeTree()),EmptyTree))),TypeTree(),EmptyTree)
scala> treeToString(tree12)
[1m[34mres11[0m: [1m[32mString[0m = def sum(args: Int*): Int