Can scala macros be used to construct types?

I know it is possible to create types inside the generated function, but is it possible to return them outside?

I need a macro that generates Parser [T] - where both the parser and the T are built from an external grammar written in a simplified grammar description language for library users. T is parsed by AST, which contains mutually nested case classes. These case classes must be generated and visible from the outside.

Grammar:

RootType {
  member1: {
    member11: TypeB
    member12: String
    member13: TypeB
  }
  member2: String
  TypeB {
     member3: String
  }
}

      

Using:

//Somewhere in my library:
trait ASTNode
def parser: Parser[ASTNode] = macro ... //interpret types from grammar-file

//On the client side:
val input = ... //reads unparsed string from some script-file
val parsed = parse(parser, input)
parsed.member1.member11.member3 //so ASTNode should be replaced  with RootType 
//case class TypeB and synthetic case class for member1 should be also generated 

      

I am thinking about solutions:

  • black box macro (how to determine the type that can be used outside of the generated function?)
  • Workaround: macro annotated types with elements generated from my grammar (I don't know how many types I have, so I need to subclass by annotation, is this possible?)
  • write a compiler plugin or a separate sbt-task or watch a macroparad
  • generating a class at runtime is not an option because I need to check types
+3


source to share


1 answer


Yes it is possible. You can generate AST including ClassDef

, ModuleDef

etc. No problem, and if you use macros (from macro paradise) they will be visible to external code (in a normal macro def

such as parser

in your desired code they are local). See "Public Type Providers" at http://docs.scala-lang.org/overviews/macros/typeproviders.html and https://github.com/travisbrown/type-provider-examples . The library code will look slightly different:



@Grammar("path/to/file") trait ASTNode // reads grammar, and generates subclasses, parser, etc.

      

+2


source







All Articles