баги вариантов в квазицитатах
От: CodingUnit Россия  
Дата: 20.07.11 10:57
Оценка:
Наткнулся не непонятности с вариантами, все дело в том что понадобилось создать вариант в макросе уровня класса, добавить вариант можно так обычным способом
<[ variant Test {} ]>

, но нужно добавлять динамически VariantOption пытался сделать квазицитатой:
<[decl: | $(name : usesite) {} ]>

, но он распознает это как EnumOption, вопрос первый как создать цитату VariantOption ?

Далее пытался создать обходными путями например так:
создать пустышку
def td= <[
  variant Dummy 
  {
    | $(name : usesite) {}
  } ]>;
def opt = td.td.GetMembers().Head;

def opts = // .. собираем множество options
def decl=<[ variant Test 
{
  ..$opts
} ]>;


но после когда запускаем ty.DefineNested(decl).Compile();
Выдается NRE связанное с ошибкой внутренних структур TypeBuilder, которое не знаю как исправить, боюсь что и в любых других способах добавления variant option будет NRE, есть ли у сообщества мысли по поводу решения этой проблемы?
Re: баги вариантов в квазицитатах
От: catbert  
Дата: 20.07.11 11:31
Оценка:
использовать <[case: .... ]> (не уверен, что именно case), или просто вручную создать кусок AST это не баг, просто парсеру не хватает контекста
Re: баги вариантов в квазицитатах
От: hardcase Пират http://nemerle.org
Дата: 20.07.11 11:59
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>, но нужно добавлять динамически VariantOption пытался сделать квазицитатой:

CU>
CU><[decl: | $(name : usesite) {} ]>
CU>

CU>, но он распознает это как EnumOption, вопрос первый как создать цитату VariantOption ?

Возможно что вот так заработает:
<[ decl: | $(name : usesite) { ..$([]) } ]>
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: баги вариантов в квазицитатах
От: CodingUnit Россия  
Дата: 20.07.11 12:22
Оценка:
Здравствуйте, hardcase, Вы писали:

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


CU>>, но нужно добавлять динамически VariantOption пытался сделать квазицитатой:

CU>>
CU>><[decl: | $(name : usesite) {} ]>
CU>>

CU>>, но он распознает это как EnumOption, вопрос первый как создать цитату VariantOption ?

H>Возможно что вот так заработает:

H>
H><[ decl: | $(name : usesite) { ..$([]) } ]>
H>




<[ case: ]>

превращается жестко в MatchCase
Пишу такой код:

def decl = <[ decl: | $(name : usesite) { ..$([]) } ]>;


ошибка компилятора гласит: only variant options can hold options with members

это косяк, получается невозможно создать variant option
Re[2]: баги вариантов в квазицитатах
От: CodingUnit Россия  
Дата: 20.07.11 12:24
Оценка:
Здравствуйте, catbert, Вы писали:

C>использовать <[case: .... ]> (не уверен, что именно case), или просто вручную создать кусок AST это не баг, просто парсеру не хватает контекста


вручную создать кусок Ast я пробовал, но после как я сказала при компиляции в TypeBuilder получается NRE
Re: баги вариантов в квазицитатах
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.07.11 17:26
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Наткнулся не непонятности с вариантами, все дело в том что понадобилось создать вариант в макросе уровня класса, добавить вариант можно так обычным способом

CU>
CU><[ variant Test {} ]>
CU>

CU>, но нужно добавлять динамически VariantOption пытался сделать квазицитатой:
CU>
CU><[decl: | $(name : usesite) {} ]>
CU>

CU>, но он распознает это как EnumOption, вопрос первый как создать цитату VariantOption ?

Вот пример из стандартной библиотеки макросов:
<[ case: | x is $(param.Type) => this.$(m.header.PName : name) (x) ]>

И вообще, если возникают вопросы по макрам, то лучший выход (ну, кроме вопросов здесь) — это чтение исходников компилятора и стандартной библиотеки.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: баги вариантов в квазицитатах
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.07.11 17:54
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>это косяк, получается невозможно создать variant option


Да можно. И примеров тому, в компиляторе и стандартной библиотеке макросов, великое множество.

Ищи на "case:".
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: баги вариантов в квазицитатах
От: hardcase Пират http://nemerle.org
Дата: 21.07.11 05:14
Оценка:
Здравствуйте, CodingUnit, Вы писали:

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


C>>использовать <[case: .... ]> (не уверен, что именно case), или просто вручную создать кусок AST это не баг, просто парсеру не хватает контекста


CU>вручную создать кусок Ast я пробовал, но после как я сказала при компиляции в TypeBuilder получается NRE


Какой этап компиляции? Compile вызывать нужно не на Option-е, а на самой варианте.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: баги вариантов в квазицитатах
От: Ziaw Россия  
Дата: 21.07.11 12:53
Оценка:
Здравствуйте, VladD2, Вы писали:

CU>>, но он распознает это как EnumOption, вопрос первый как создать цитату VariantOption ?


VD>Вот пример из стандартной библиотеки макросов:

VD>
VD><[ case: | x is $(param.Type) => this.$(m.header.PName : name) (x) ]>
VD>

VD>И вообще, если возникают вопросы по макрам, то лучший выход (ну, кроме вопросов здесь) — это чтение исходников компилятора и стандартной библиотеки.

Влад, разговор идет не о ветке матча, а о ветке варианта.
Re[3]: баги вариантов в квазицитатах
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.07.11 14:17
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Влад, разговор идет не о ветке матча, а о ветке варианта.


А... сори. Торможу.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: баги вариантов в квазицитатах
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.07.11 16:22
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Наткнулся не непонятности с вариантами, все дело в том что понадобилось создать вариант в макросе уровня класса, добавить вариант можно так обычным способом

CU>
CU><[ variant Test {} ]>
CU>

CU>, но нужно добавлять динамически VariantOption пытался сделать квазицитатой:
CU>
CU><[decl: | $(name : usesite) {} ]>
CU>

CU>, но он распознает это как EnumOption, вопрос первый как создать цитату VariantOption?

Похоже, что это упущение. Постараюсь исправить его в ближайшее время.

CU>Далее пытался создать обходными путями например так:

CU>создать пустышку
CU>
CU>def td= <[
CU>  variant Dummy 
CU>  {
CU>    | $(name : usesite) {}
CU>  } ]>;
CU>def opt = td.td.GetMembers().Head;

Это какой-то уж очень обходной путь :).


CU>def opts = // .. собираем множество options
CU>def decl=<[ variant Test 
CU>{
CU>  ..$opts
CU>} ]>;
CU>


CU>но после когда запускаем ty.DefineNested(decl).Compile();

CU>Выдается NRE

Типы нужно добавлять с помощью метода DefineNestedType. NRE, скорее всего, связан с этим.
Но сама идея, создавать вхождения вариантов в левых вариантах, не самая хорошая. Могут появиться другие проблемы.
Ниже я привел пример как создать вхождение варианта вручную (без квази-цитирования). Пока в компиляторе не поддерживается цитата для этого, лучше поступать так.

Код макро-атрибута создающего вхождение по заданному имени:
using Nemerle;
using Nemerle.Collections;
using Nemerle.Compiler;
using Nemerle.Compiler.Parsetree;
using Nemerle.Text;
using Nemerle.Utility;

using System;
using System.Collections.Generic;
using System.Linq;

namespace MacroLibrary1
{
  
  [MacroUsage(MacroPhase.BeforeInheritance, MacroTargets.Class)]
  macro DefineVariantOption(tb : TypeBuilder, optionName) 
  {
    DefineVariantOptionImpl.DoTransform(tb, Macros.ImplicitCTX(), optionName)
  }
  
  module DefineVariantOptionImpl
  {
    public DoTransform(tb : TypeBuilder, typer : Typer, optionName : PExpr) : void
    {
      Macros.DefineCTX(typer);

      def optionNameStr = optionName.ToString();
      def name = Splicable.Name(Macros.UseSiteSymbol(optionNameStr));
      def modifiers = Modifiers(0, []);
      def variantOption = 
        ClassMember.TypeDeclaration(name, modifiers, 
          TopDeclaration.VariantOption(name, modifiers, Typarms.Empty, []));
      
      def variantOptionBuilder = tb.DefineNestedType(variantOption);
      variantOptionBuilder.Compile();
    }
  }
}


Использование макроса:
using System.Console;
using MacroLibrary1;

[DefineVariantOption(GeneratedOption1)]
variant Test
{
}

module Program
{
  Main() : void
  {
    WriteLine(Test.GeneratedOption1().GetType().Name);
    _ = ReadLine();
  }
}
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: баги вариантов в квазицитатах
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.07.11 19:00
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Какой этап компиляции? Compile вызывать нужно не на Option-е, а на самой варианте.


Не, Compile нужно вызвать на вхождении, но добавлять его нужно DefineNestedType. Надо бы пофиксить этот баг и вместо NRE выдавать полноценное исключение.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: баги вариантов в квазицитатах
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.07.11 20:58
Оценка: 6 (1)
Здравствуйте, CodingUnit, Вы писали:

CU>Наткнулся не непонятности с вариантами, все дело в том что понадобилось создать вариант в макросе уровня класса, добавить вариант можно так обычным способом

CU>
CU><[ variant Test {} ]>
CU>

CU>, но нужно добавлять динамически VariantOption пытался сделать квазицитатой:
CU>
CU><[decl: | $(name : usesite) {} ]>
CU>

CU>, но он распознает это как EnumOption, вопрос первый как создать цитату VariantOption ?

Исправил эту недоработку. Теперь создавать вхождения вариантов можно будет так:
def variantOptionBuilder = tb.DefineNestedType(
        <[ variant_option: | $(optionNameStr : usesite) ]>);

variantOptionBuilder.Compile();
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: баги вариантов в квазицитатах
От: CodingUnit Россия  
Дата: 27.07.11 08:15
Оценка: +1
Здравствуйте, VladD2, Вы писали:

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


CU>>Наткнулся не непонятности с вариантами, все дело в том что понадобилось создать вариант в макросе уровня класса, добавить вариант можно так обычным способом

CU>>
CU>><[ variant Test {} ]>
CU>>

CU>>, но нужно добавлять динамически VariantOption пытался сделать квазицитатой:
CU>>
CU>><[decl: | $(name : usesite) {} ]>
CU>>

CU>>, но он распознает это как EnumOption, вопрос первый как создать цитату VariantOption ?

VD>Исправил эту недоработку. Теперь создавать вхождения вариантов можно будет так:

VD>
VD>def variantOptionBuilder = tb.DefineNestedType(
VD>        <[ variant_option: | $(optionNameStr : usesite) ]>);

VD>variantOptionBuilder.Compile();
VD>


Влад, ну молодец!, ничего не скажешь, быстро сделал.
Re[2]: баги вариантов в квазицитатах
От: CodingUnit Россия  
Дата: 03.08.11 13:32
Оценка:
Здравствуйте, VladD2, Вы писали:

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


CU>>Наткнулся не непонятности с вариантами, все дело в том что понадобилось создать вариант в макросе уровня класса, добавить вариант можно так обычным способом

CU>>
CU>><[ variant Test {} ]>
CU>>

CU>>, но нужно добавлять динамически VariantOption пытался сделать квазицитатой:
CU>>
CU>><[decl: | $(name : usesite) {} ]>
CU>>

CU>>, но он распознает это как EnumOption, вопрос первый как создать цитату VariantOption ?

VD>Исправил эту недоработку. Теперь создавать вхождения вариантов можно будет так:

VD>
VD>def variantOptionBuilder = tb.DefineNestedType(
VD>        <[ variant_option: | $(optionNameStr : usesite) ]>);

VD>variantOptionBuilder.Compile();
VD>


Это хорошо работает на фазе BeforeInheritance, но не работает на BeforeTypedMembers, тот самый null при вызове Compile(), странно, можно ли это исправить, обычно на этой фазе можно добавлять подклассы?
Re[3]: баги вариантов в квазицитатах
От: CodingUnit Россия  
Дата: 10.08.11 10:07
Оценка:
Здравствуйте, CodingUnit, Вы писали:

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


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


CU>>>Наткнулся не непонятности с вариантами, все дело в том что понадобилось создать вариант в макросе уровня класса, добавить вариант можно так обычным способом

CU>>>
CU>>><[ variant Test {} ]>
CU>>>

CU>>>, но нужно добавлять динамически VariantOption пытался сделать квазицитатой:
CU>>>
CU>>><[decl: | $(name : usesite) {} ]>
CU>>>

CU>>>, но он распознает это как EnumOption, вопрос первый как создать цитату VariantOption ?

VD>>Исправил эту недоработку. Теперь создавать вхождения вариантов можно будет так:

VD>>
VD>>def variantOptionBuilder = tb.DefineNestedType(
VD>>        <[ variant_option: | $(optionNameStr : usesite) ]>);

VD>>variantOptionBuilder.Compile();
VD>>


CU>Это хорошо работает на фазе BeforeInheritance, но не работает на BeforeTypedMembers, тот самый null при вызове Compile(), странно, можно ли это исправить, обычно на этой фазе можно добавлять подклассы?


Так никто и не отвечает, вызываю DefineNestedType, но возникнает null, такое видится только на фазах BeforeTypedMembers и выше, должно ли так быть? добавление обычных классов на этой фазе обычно проходит?
Re[4]: баги вариантов в квазицитатах
От: CodingUnit Россия  
Дата: 10.08.11 18:14
Оценка:
Здравствуйте, CodingUnit, Вы писали:

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


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


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


CU>>>>Наткнулся не непонятности с вариантами, все дело в том что понадобилось создать вариант в макросе уровня класса, добавить вариант можно так обычным способом

CU>>>>
CU>>>><[ variant Test {} ]>
CU>>>>

CU>>>>, но нужно добавлять динамически VariantOption пытался сделать квазицитатой:
CU>>>>
CU>>>><[decl: | $(name : usesite) {} ]>
CU>>>>

CU>>>>, но он распознает это как EnumOption, вопрос первый как создать цитату VariantOption ?

VD>>>Исправил эту недоработку. Теперь создавать вхождения вариантов можно будет так:

VD>>>
VD>>>def variantOptionBuilder = tb.DefineNestedType(
VD>>>        <[ variant_option: | $(optionNameStr : usesite) ]>);

VD>>>variantOptionBuilder.Compile();
VD>>>


>Это хорошо работает на фазе BeforeInheritance, но не работает на BeforeTypedMembers, тот самый null при вызове Compile(), странно, можно ли это исправить, обычно на этой фазе можно добавлять подклассы?


>Так никто и не отвечает, вызываю DefineNestedType, но возникнает null, такое видится только на фазах BeforeTypedMembers и выше, должно ли так быть? добавление обычных классов на этой фазе обычно проходит?


Продолжаю трубить.
Re[4]: баги вариантов в квазицитатах
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.08.11 00:51
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>>Это хорошо работает на фазе BeforeInheritance, но не работает на BeforeTypedMembers, тот самый null при вызове Compile(), странно, можно ли это исправить, обычно на этой фазе можно добавлять подклассы?


CU>Так никто и не отвечает, вызываю DefineNestedType, но возникнает null, такое видится только на фазах BeforeTypedMembers и выше, должно ли так быть? добавление обычных классов на этой фазе обычно проходит?



Это баг. Поправил.

На будущее...

1. Не стоит так оверквотить. Цитировать надо только то, что нужно для понимания написанного тобой.
2. Если чувствуешь, что нашел баг, стоит завести issue и в форуме уже дать ссылку на него. Это ускорит процесс исправления багов.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.