summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-06-27 20:12:16 +0000
committerPaul Phillips <paulp@improving.org>2009-06-27 20:12:16 +0000
commit4fccc851b8796d092a2910f6b746e4767d057fc4 (patch)
tree7a2bd1684270406c759df32fba3289081e421d8f /src/compiler/scala/tools/nsc/ast/TreeDSL.scala
parentcfe07c80c3a4d9cacd870e91cb20c129821b2956 (diff)
downloadscala-4fccc851b8796d092a2910f6b746e4767d057fc4.tar.gz
scala-4fccc851b8796d092a2910f6b746e4767d057fc4.tar.bz2
scala-4fccc851b8796d092a2910f6b746e4767d057fc4.zip
Continued development of code generation DSL.
target file was the aptly named CleanUp.scala. Will continue polishing that file but checking in to keep this patch from getting out of hand.
Diffstat (limited to 'src/compiler/scala/tools/nsc/ast/TreeDSL.scala')
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeDSL.scala73
1 files changed, 61 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
index 98a6919f27..1ef0a1bc69 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
@@ -21,16 +21,20 @@ trait TreeDSL {
def LIT(x: Any) = Literal(Constant(x))
def TRUE = LIT(true)
def FALSE = LIT(false)
+ def NULL = LIT(null)
+ def UNIT = LIT(())
+ def ZERO = LIT(0)
def WILD = Ident(nme.WILDCARD)
+ case class ExpectApply(target: Tree) {
+ def apply(args: Tree*) = Apply(target, args.toList)
+ }
+
class TreeMethods(target: Tree) {
- private def binop(lhs: Tree, op: Name, rhs: Tree) = Apply(Select(lhs, op), List(rhs))
+ private def binop(lhs: Tree, op: Name, rhs: Tree) = Apply(Select(lhs, op), List(rhs))
+ private def binop(lhs: Tree, op: Symbol, rhs: Tree) = Apply(Select(lhs, op), List(rhs))
private def toAnyRef(x: Tree) = x setType AnyRefClass.tpe
- case class ExpectApply(target: Tree) {
- def apply(args: Tree*) = Apply(target, args.toList)
- }
-
/** logical/comparison ops **/
def OR(other: Tree) =
if (target == EmptyTree) other
@@ -42,8 +46,13 @@ trait TreeDSL {
else if (other == EmptyTree) target
else gen.mkAnd(target, other)
+ def BIT_AND(other: Tree) = binop(target, Int_And, other)
def EQREF(other: Tree) = binop(target, nme.eq, toAnyRef(other))
+ def NE_REF(other: Tree) = binop(target, nme.ne, other)
def EQEQ(other: Tree) = binop(target, nme.EQ, other)
+ def EQINT(other: Tree) = binop(target, Int_==, other)
+ def EQANY(other: Tree) = binop(target, Any_==, other)
+ def NOT_==(other: Tree) = binop(target, Object_ne, other)
/** Apply, Select, Match **/
def APPLY(params: List[Tree]) = Apply(target, params)
@@ -51,17 +60,45 @@ trait TreeDSL {
def DOT(member: Name) = ExpectApply(Select(target, member))
def DOT(sym: Symbol) = ExpectApply(Select(target, sym))
- /** Casting */
- def AS(tpe: Type) = TypeApply(Select(target, Any_asInstanceOf), List(TypeTree(tpe)))
- def TOSTRING() = Select(target, nme.toString_)
+ /** Assignment */
+ def ===(rhs: Tree) = Assign(target, rhs)
+
+ /** Casting & type tests -- working our way toward understanding exactly
+ * what differs between the different forms of IS and AS.
+ */
+ def AS(tpe: Type) = TypeApply(Select(target, Any_asInstanceOf), List(TypeTree(tpe)))
+ def AS_ATTR(tpe: Type) = gen.mkAttributedCast(target, tpe)
+
+ def IS(tpe: Type) = gen.mkIsInstanceOf(target, tpe, true)
+ def IS_OBJ(tpe: Type) = gen.mkIsInstanceOf(target, tpe, false)
+
+ def TOSTRING() = Apply(Select(target, nme.toString_), Nil)
+ def GETCLASS() = Apply(Select(target, Object_getClass), Nil)
}
class CaseStart(pat: Tree, guard: Tree) {
def IF(g: Tree): CaseStart = new CaseStart(pat, g)
- def ==>(body: Tree): CaseDef = CaseDef(pat, guard, body) // DSL for =>
+ def ==>(body: Tree): CaseDef = CaseDef(pat, guard, body)
+ }
+
+ abstract class ValOrDefStart(sym: Symbol) {
+ def ===(body: Tree): ValOrDefDef
+ }
+ class DefStart(sym: Symbol) extends ValOrDefStart(sym) {
+ def ===(body: Tree) = DefDef(sym, body)
+ }
+ class ValStart(sym: Symbol) extends ValOrDefStart(sym) {
+ def ===(body: Tree) = ValDef(sym, body)
+ }
+ class IfStart(cond: Tree, thenp: Tree) {
+ def THEN(x: Tree) = new IfStart(cond, x)
+ def ELSE(elsep: Tree) = If(cond, thenp, elsep)
+ def ENDIF = If(cond, thenp, EmptyTree)
}
- class DefStart(sym: Symbol) {
- def ===(body: Tree) = DefDef(sym, body) // DSL for =
+ class TryStart(body: Tree, catches: List[CaseDef], fin: Tree) {
+ def CATCH(xs: CaseDef*) = new TryStart(body, xs.toList, fin)
+ def FINALLY(x: Tree) = Try(body, catches, x)
+ def ENDTRY = Try(body, catches, fin)
}
def CASE(pat: Tree): CaseStart = new CaseStart(pat, EmptyTree)
@@ -73,6 +110,7 @@ trait TreeDSL {
class SymbolMethods(target: Symbol) {
def BIND(body: Tree) = Bind(target, body)
+ // def DOT(member: Symbol) = new TreeMethods(Ident(target)) DOT member
// name of nth indexed argument to a method (first parameter list), defaults to 1st
def ARG(idx: Int = 0) = Ident(target.paramss.head(idx))
@@ -81,12 +119,23 @@ trait TreeDSL {
}
/** Top level accessible. */
- def THROW(sym: Symbol, msg: Tree) = Throw(New(TypeTree(sym.tpe), List(List(msg.TOSTRING))))
+ def THROW(sym: Symbol, msg: Tree = null) = {
+ val arg = if (msg == null) Nil else List(msg.TOSTRING)
+ Throw(New(TypeTree(sym.tpe), List(arg)))
+ }
+ def NEW(tpe: Tree, args: Tree*) = New(tpe, List(args.toList))
+
+ def VAL(sym: Symbol) = new ValStart(sym)
def DEF(sym: Symbol) = new DefStart(sym)
def AND(guards: Tree*) =
if (guards.isEmpty) EmptyTree
else guards reduceLeft gen.mkAnd
+ def IF(tree: Tree) = new IfStart(tree, EmptyTree)
+ def TRY(tree: Tree) = new TryStart(tree, Nil, EmptyTree)
+ def REF(sym: Symbol) = gen.mkAttributedRef(sym)
+ def BLOCK(xs: Tree*) = Block(xs.init.toList, xs.last)
+
/** Implicits - some of these should probably disappear **/
implicit def mkTreeMethods(target: Tree): TreeMethods = new TreeMethods(target)
implicit def mkTreeMethodsFromSymbol(target: Symbol): TreeMethods = new TreeMethods(Ident(target))