Тип параметра в макро-атрибутах..
От: Jack128  
Дата: 09.04.10 22:22
Оценка:
Имеем макроатрибут:
    [MacroUsage(MacroPhase.BeforeTypedMembers, 
        MacroTargets.Class, Inherited = true)]
    macro MyFirstMetaattribute(tb : TypeBuilder, s)
    {
        Message.Hint(s.GetType().ToString());
    }

хинт выдает:
Message 1 Nemerle.Compiler.Parsetree.PExpr+Literal

Но если явно указать тип параметра s
    [MacroUsage(MacroPhase.BeforeTypedMembers, 
        MacroTargets.Class, Inherited = true)]
    macro MyFirstMetaattribute(tb : TypeBuilder, s : Nemerle.Compiler.Parsetree.PExpr)
    {
        Message.Hint(s.GetType().ToString());
    }

имеем ошибку компиляции:
Error 2 complex types are not supported for macro parameters: Nemerle.Compiler.Parsetree.PExpr

Это бага или тут потаенный смысл имеется??
Re: Тип параметра в макро-атрибутах..
От: evilbeaver  
Дата: 10.04.10 05:30
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Имеем макроатрибут:

J>
J>    [MacroUsage(MacroPhase.BeforeTypedMembers, 
J>        MacroTargets.Class, Inherited = true)]
J>    macro MyFirstMetaattribute(tb : TypeBuilder, s)
J>    {
J>        Message.Hint(s.GetType().ToString());
J>    }
J>

J>хинт выдает:
J>Message 1 Nemerle.Compiler.Parsetree.PExpr+Literal

J>Но если явно указать тип параметра s

J>
J>    [MacroUsage(MacroPhase.BeforeTypedMembers, 
J>        MacroTargets.Class, Inherited = true)]
J>    macro MyFirstMetaattribute(tb : TypeBuilder, s : Nemerle.Compiler.Parsetree.PExpr)
J>    {
J>        Message.Hint(s.GetType().ToString());
J>    }
J>

J>имеем ошибку компиляции:
J>Error 2 complex types are not supported for macro parameters: Nemerle.Compiler.Parsetree.PExpr

J>Это бага или тут потаенный смысл имеется??


Я конечно могу ошибаться, но
Nemerle.Compiler.Parsetree.PExpr+Literal

то есть в классе PExpr есть еще иннер класс Literal, Вы же указываете сам класс PExpr
Re[2]: Тип параметра в макро-атрибутах..
От: Jack128  
Дата: 10.04.10 06:17
Оценка:
Здравствуйте, evilbeaver, Вы писали:

E>Я конечно могу ошибаться, но

E>
E>Nemerle.Compiler.Parsetree.PExpr+Literal
E>

E>то есть в классе PExpr есть еще иннер класс Literal, Вы же указываете сам класс PExpr

литерал я тоже побывал подставлять — та же ошибка.
Re[3]: Тип параметра в макро-атрибутах..
От: hardcase Пират http://nemerle.org
Дата: 10.04.10 15:40
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Здравствуйте, evilbeaver, Вы писали:


E>>Я конечно могу ошибаться, но

E>>
E>>Nemerle.Compiler.Parsetree.PExpr+Literal
E>>

E>>то есть в классе PExpr есть еще иннер класс Literal, Вы же указываете сам класс PExpr

J>литерал я тоже побывал подставлять — та же ошибка.


    [MacroUsage(MacroPhase.BeforeTypedMembers, 
        MacroTargets.Class, Inherited = true)]
    macro MyFirstMetaattribute(tb : TypeBuilder, s : expr)
    {
        Message.Hint(s.GetType().ToString());
    }
/* иЗвиНите зА неРовнЫй поЧерК */
Re[4]: Тип параметра в макро-атрибутах..
От: Jack128  
Дата: 10.04.10 17:02
Оценка:
Здравствуйте, hardcase, Вы писали:

H>
H>    [MacroUsage(MacroPhase.BeforeTypedMembers, 
H>        MacroTargets.Class, Inherited = true)]
H>    macro MyFirstMetaattribute(tb : TypeBuilder, s : expr)
H>    {
H>        Message.Hint(s.GetType().ToString());
H>    }
H>


а что что такое expr?? Полное имя типа можно?
Re[5]: Тип параметра в макро-атрибутах..
От: hardcase Пират http://nemerle.org
Дата: 10.04.10 17:30
Оценка:
Здравствуйте, Jack128, Вы писали:


J>а что что такое expr?? Полное имя типа можно?


Это синоним к варианте PExpr для использования в параметрах макросов. Почему не работает полное имя — я не знаю, надо дождаться Влада, возможно это просто баг.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: Тип параметра в макро-атрибутах..
От: hardcase Пират http://nemerle.org
Дата: 10.04.10 22:34
Оценка: +1
Здравствуйте, evilbeaver, Вы писали:

E>Я конечно могу ошибаться, но

E>
E>Nemerle.Compiler.Parsetree.PExpr+Literal
E>

E>то есть в классе PExpr есть еще иннер класс Literal, Вы же указываете сам класс PExpr

PExpr является вариантными типом (алгебраический тип) и фактический тип переданного s — это варианта PExpr.Literal, видимо Jack128 подставил в вызов макроса строку или число, если бы он туда передал что-то вроде f(x) то фактический тип стал бы PExpr.Call (вызов функции).
Метаатрибут может принимать на вход помимо обязательных параметров вроде TypeBuilder-а еще и набор выражений типы аргументов при этом не указываются, или указывается алиас к PExpr — expr. Этот алиас нужнен например для случая с неопределенным количеством аргументов:
    [MacroUsage(MacroPhase.BeforeTypedMembers, 
        MacroTargets.Class, Inherited = true)]
    macro MyFirstMetaattribute(tb : TypeBuilder, params args : array[expr])
    {
        def args = NList.ToList(args);
        Message.Hint(args.ToString());
    }
/* иЗвиНите зА неРовнЫй поЧерК */
Re: Тип параметра в макро-атрибутах..
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.04.10 14:43
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Имеем макроатрибут:

J>
J>    macro MyFirstMetaattribute(tb : TypeBuilder, s)
J>    {
J>        Message.Hint(s.GetType().ToString());
J>

J>хинт выдает:
J>Message 1 Nemerle.Compiler.Parsetree.PExpr+Literal

J>Но если явно указать тип параметра s

J>
J>    macro MyFirstMetaattribute(tb : TypeBuilder, s : Nemerle.Compiler.Parsetree.PExpr)
J>    {
J>        Message.Hint(s.GetType().ToString());
J>

J>имеем ошибку компиляции:
J>Error 2 complex types are not supported for macro parameters: Nemerle.Compiler.Parsetree.PExpr

J>Это бага или тут потаенный смысл имеется??


Чтобы понять что происходит для начала имеет смысл прочесть раздел Параметры макроса
Автор(ы): Чистяков Владислав Юрьевич
Дата: 18.08.2011
Во второй части статьи о макросах Nemerle речь пойдет о макросах уровня выражения, о макросах, изменяющих синтаксис языка, а также о контексте компиляции, доступном в макросах, и тех возможностях, которые он предоставляет (типизации выражений, получении доступа к описанию типов проекта, информации о методах и т.п.).
из "Макросы Nemerle – расширенный курс Часть 2".

PExpr+Literal — это дотнетное представление типа PExpr.Literal который является вхождением вариантного типа PExpr:
http://code.google.com/p/nemerle/source/browse/nemerle/trunk/ncc/parsing/ParseTree.n#607
  [Record]
  public variant PExpr : Located 
  {
    | Wildcard        // `_' used mainly in patterns, but also in `_ = ignored'
    | Void            // `void' used only in types
    | As              { pat : PExpr; name : Splicable; }
    | Is              { pat : PExpr; ty : PExpr; }
    | Where           { name : PExpr; fields : PExpr; }
    | Match           { expr : PExpr; cases : list [MatchCase]; mutable expr_loc : Location;
                        this(loc : Location, expr : PExpr, cases : list [MatchCase]) { this(loc, expr, cases, Location.Default); }
                        this(expr : PExpr, cases : list [MatchCase]) { this(expr, cases, Location.Default); }
                      }

    | Ref             { name : Name; }
    | Member          { obj : PExpr; member : Splicable; }
    | Call            { func : PExpr; parms : list [PExpr]; }
    | GenericSpecifier { func : PExpr; generic_parms : list [PExpr]; }
    | ListLiteral     { elements : list [PExpr]; }
    | Assign          { target : PExpr; source : PExpr; }
    | DefMutable      { name : PExpr; val : PExpr; }
    | Define          { pattern : PExpr; val : PExpr; }
    | DefFunctions    { funs : list [Function_decl]; }
    | Lambda          { decl : Function_decl; }
    | Throw           { exn : PExpr; }
    | Try             { body : PExpr; cases : list [TryCase]; }
    | TryFinally      { body : PExpr; handler : PExpr; }
    | Literal         { val : Nemerle.Compiler.Literal; }
    | This
    | Base
    | Typeof          { ty : PExpr; }
    | TypeConversion  { expr : PExpr; ty : PExpr; }  // (expr :> ty)
    | TypeEnforcement { expr : PExpr; ty : PExpr; } // (expr : ty)
    | Sequence        { body : list [PExpr]; }
    | Tuple           { args : list [PExpr]; 
                        [RecordIgnore] public mutable argsCount : int;
                        
                        public static Create(loc : Location, args : list[PExpr]) : PExpr.Tuple
                        {
                          PExpr.Tuple(loc, args, args.Length);
                        }
                        public static Create(args : list[PExpr]) : PExpr.Tuple
                        {
                          PExpr.Tuple(args.EnclosingLocation(), args, args.Length);
                        }
                        public this(args : list[PExpr], argsCount : int)
                        { this(args); this.argsCount = argsCount; }
                        
                        public this(loc : Location, args : list[PExpr], argsCount : int)
                        { this(loc, args); this.argsCount = argsCount; }
                      }
    | Array           { rank : PExpr; args : PExpr; }
    | EmptyArray      { sizes : list [PExpr]; }
    | Indexer         { obj : PExpr; args : list [PExpr]; }
    | ParmByRef       { parm : PExpr; }
    | ParmOut         { parm : PExpr; }

    | Error // placeholder of missing tree (where some errors occured)

    // macros stuff    
    | MacroCall       { name : Name; ns : NamespaceTree.Node;
                        parms : list [SyntaxElement]; }
    | Quoted          { body : SyntaxElement; }
    | Spliced         { body : PExpr; }
    | ToComplete      { body : Name; }
    | Ellipsis        { body : PExpr; }
    | Typed           { body : Typedtree.TExpr; }
    | TypedPattern    { body : Typedtree.Pattern; }  
    | TypedType       { body : TypeVar; }

    [RecordIgnore] public TypedObject : object { get; internal set; }

    public override ToString () : string { PrettyPrint.SprintExpr (None (), this); }

    // transforms dot-separated identifier to the parse-tree expression 
    public static FromQualifiedIdentifier (manager : ManagerClass, qid : string) : PExpr 
    {
      if (string.IsNullOrEmpty (qid)) null
      else {
        def split = qid.Split ('.');
        mutable expr = <[ $(Name (split [0], manager.MacroColors.UseColor, manager.MacroColors.UseContext) : name) ]>;
        for (mutable i = 1; i < split.Length; i++)
          expr = <[ $expr . $(Name (split [i], manager.MacroColors.UseColor, manager.MacroColors.UseContext) : name) ]>;
        expr
      }
    }
  }

Квази-цитаты без префиксов — это синтаксический сахар для описания PExpr.

Так вот "expr" — это локальный для макросов псевдоним для PExpr. По глупости и лени при разборе типов параметров маросов не производится полноценная типизация. Вместо этого полагается, что тип параметров макросов либо не будет описываться вовсе, либо при описании типов будут использоваться встроенные типы (такие как int, string и т.п.).

По уму там нужно переписать анализ типов, так чтобы он производил полноценную типизацию.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.