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
Это синоним к варианте PExpr для использования в параметрах макросов. Почему не работает полное имя — я не знаю, надо дождаться Влада, возможно это просто баг.
Здравствуйте, 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. Этот алиас нужнен например для случая с неопределенным количеством аргументов:
J>имеем ошибку компиляции: J>Error 2 complex types are not supported for macro parameters: Nemerle.Compiler.Parsetree.PExpr
J>Это бага или тут потаенный смысл имеется??
Чтобы понять что происходит для начала имеет смысл прочесть раздел Параметры макроса
[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 и т.п.).
По уму там нужно переписать анализ типов, так чтобы он производил полноценную типизацию.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.