2013-08-29 3 views
1

не копаться в деталях DSL, я мог бы написать (based on that example):Как получить тип в Scala AST для подчеркнутого параметра функции лямбда?

def InputLine = rule { Number ~ zeroOrMore("+" ~ Number ~> ((x: Int, y: Int) => x + y)) ~ EOI } 

Мне нужно вызвать функцию лямбда из макроса. Scala AST представление состоит в следующем:

List(
    ValDef(Modifiers(PARAM), newTermName("x"), TypeTree().setOriginal(Select(Ident(scala), scala.Int)), EmptyTree), 
    ValDef(Modifiers(PARAM), newTermName("y"), TypeTree().setOriginal(Select(Ident(scala), scala.Int)), EmptyTree)) 

Важно отметить, что оба х и у имеет типы в AST. Это прекрасно работает.

Следующий шаг заключается в использовании логического вывода типа, а также упростить лямбда следующим образом:

def InputLine = rule { Number ~ zeroOrMore("+" ~ Number ~> ((_:Int) + _)) ~ EOI } 

Scala AST для этого лямбда:

List(
    ValDef(Modifiers(PARAM | SYNTHETIC), newTermName("x$1"), TypeTree().setOriginal(Select(Ident(scala), scala.Int)), EmptyTree), 
    ValDef(Modifiers(PARAM | SYNTHETIC), newTermName("x$2"), TypeTree(), EmptyTree)) 

Обратите внимание, что х $ 2 парам не имеет никакого явного типа. Мне нужно, чтобы вызвать функцию. Где я должен его получить? Решение «просто передать параметр типа Любое функции« не удовлетворяет scalac по мере необходимости Int.

Этот вопрос логически следует за that one.

Код доступен по адресу [email protected].

+0

Я не уверен, что я точно понимаю, что вы просите, но попробовали ли вы проверить тип дерева (или только его часть) с помощью 'c.typeCheck'? –

+0

@TravisBrown Я попробовал. Я не уверен, правильно ли я использую его. Если просто 'c.typeCheck (tree))' где 'tree' является Scala AST, который содержит подчеркнутую lambda, тогда это не поможет. 'println (s" $ {showRaw (c.typeCheck (tree))} ")' не показывает мне тип 'x $ 2'. Могу ли я каким-либо образом получить от 'macros.Context' какие аргументы типов конкретной функции? –

+0

I.e. имеет значение 'val function = Function (List (ValDef (модификаторы (PARAM | SYNTHETIC), newTermName (« x $ 1 »), TypeTree(). setOriginal (Select (Ident (scala), scala.Int)), EmptyTree), ValDef (Модификаторы (PARAM | SYNTHETIC), newTermName («x $ 2»), TypeTree(), EmptyTree)), Apply (Select (Typed (Ident (newTermName («x $ 1»)), TypeTree(). SetOriginal (Select (Ident (идентификатор (newTermName («x $ 2»))))) вызов 'c.inferTypes (function)', который преобразует ' x $ 2' в 'ValDef (модификаторы (PARAM | SYNTHETIC), newTermName (« x $ 2 »), TypeTree(). setOriginal (Select (Ident (scala), scala.Int)), EmptyTree)' –

ответ

1
Number ~> ((_:Int) + _) 

превращается в что-то вроде этого

pimpActionOp[...](rule).~>.apply[...](function) 

классов типовых pimpActionOp и apply содержит всю информацию, необходимую для восстановления типов.

 Смежные вопросы

  • Нет связанных вопросов^_^