diff options
author | Martin Odersky <odersky@gmail.com> | 2011-11-28 11:01:12 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2011-11-28 11:01:12 +0000 |
commit | 311d813910a2ec590b11b84c28fac2ae6e086270 (patch) | |
tree | 4a35454e77a8d09d822a7b7c3126b10c7c3861bb /src/compiler/scala/tools/nsc/typechecker/Macros.scala | |
parent | 0bea2ab5f6b211a83bbf14ea46fe57b8163c6334 (diff) | |
download | scala-311d813910a2ec590b11b84c28fac2ae6e086270.tar.gz scala-311d813910a2ec590b11b84c28fac2ae6e086270.tar.bz2 scala-311d813910a2ec590b11b84c28fac2ae6e086270.zip |
Experimental version of macro definitions.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Macros.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Macros.scala | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala new file mode 100644 index 0000000000..05eadb03ae --- /dev/null +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -0,0 +1,68 @@ +package scala.tools.nsc +package typechecker + +import symtab.Flags._ + +trait Macros { self: Analyzer => + import global._ + import definitions._ + + def macroMethName(name: Name) = + newTermName((if (name.isTypeName) "type" else "def") + "macro$" + name) + + def macroMeth(mac: Symbol): Symbol = { + var owner = mac.owner + if (!owner.isModuleClass) owner = owner.companionModule.moduleClass + owner.info.decl(macroMethName(mac.name)) + } + + /** + * The definition of the method implementing a macro. Example: + * Say we have + * + * def macro foo[T](xs: List[T]): T = expr + * + * Then the following macro method is generated for `foo`: + * + * def foo(glob: scala.reflect.api.Universe) + * (_this: glob.Tree) + * (T: glob.Type) + * (xs: glob.Tree): glob.Tree = { + * implicit val $glob = glob + * expr + * } + */ + def macroMethDef(mdef: DefDef): Tree = { + def paramDef(name: Name, tpt: Tree) = ValDef(Modifiers(PARAM), name, tpt, EmptyTree) + val universeType = TypeTree(ReflectApiUniverse.tpe) + val globParam = paramDef("glob", universeType) + def globSelect(name: Name) = Select(Ident("glob"), name) + def globTree = globSelect(newTypeName("Tree")) + def globType = globSelect(newTypeName("Type")) + val thisParam = paramDef("_this", globTree) + def tparamInMacro(tdef: TypeDef) = paramDef(tdef.name.toTermName, globType) + def vparamInMacro(vdef: ValDef): ValDef = paramDef(vdef.name, globTree) + def wrapImplicit(tree: Tree) = atPos(tree.pos) { + Block(List(ValDef(Modifiers(IMPLICIT), "$glob", universeType, Ident("glob"))), tree) + } + + treeCopy.DefDef( + mdef, + mods = mdef.mods &~ MACRO, + name = mdef.name.toTermName, + tparams = List(), + vparamss = List(globParam) :: List(thisParam) :: (mdef.tparams map tparamInMacro) :: + (mdef.vparamss map (_ map vparamInMacro)), + tpt = globTree, + wrapImplicit(mdef.rhs)) + } + + def addMacroMethods(templ: Template, namer: Namer): Unit = { + for (ddef @ DefDef(mods, _, _, _, _, _) <- templ.body if mods hasFlag MACRO) { + namer.enterSyntheticSym(macroMethDef(ddef)) + } + } + + def macroExpand(tree: Tree): Tree = ??? + +}
\ No newline at end of file |