Компилятор отказывается это кушать
От: _Claus_  
Дата: 27.11.11 06:59
Оценка:
Всем привет! Имею метод, который формирует куски контекстного кода, чтобы потом сложить в генерируемый метод

 public create_string_prop() : void 
              
      mutable string_save_blocks = typeBuilder.UserData["data"] :> list[PExpr]            
      
      when (string_save_blocks == null)
        
        string_save_blocks = []
          
      //проблема здесь, указание ttype помогает убрать другие ошибки
      typeBuilder.UserData["data"] = \
      <[ttype:  
          when ($(has_saved : usesite))
      {
          datamap.write_string($(private_ref : usesite), exchange.$(fld_name : name)) 
                            
          $(has_saved : usesite) = false
      }
    ]> :: string_save_blocks 
      ...



компилятор отказывается это кушать, буйно ругаясь
C:\MyProjects\DBLib\DBLib\Macro1.n(147,9): error : Internal compiler error 'quoted code not supported: when ($((has_saved : usesite)))
{
datamap.write_string($((private_ref : usesite)), exchange.$((fld_name : name))) $ (has_saved : usesite) = false
}', please report a bug to bugs.nemerle.org. You can try modifying program near this location.
C:\Program Files\Nemerle\Net-4.0\Nemerle.MSBuild.targets(219,9): error : internal compiler error: assertion failed in file ncc\typing\Macros.n, line 603: quoted code not supported: when ($((has_saved : usesite)))
{
datamap.write_string($((private_ref : usesite)), exchange.$((fld_name : name))) $ (has_saved : usesite) = false
}
в Nemerle.Compiler.Macros.quoted_ttype(PExpr t) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Macros.n:строка 603
в Nemerle.Compiler.Typer.DoType(PExpr expression, TypeVar expected, Boolean is_toplevel_in_seq) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 2256
в Nemerle.Compiler.Typer.TypeExpr(PExpr expr, TypeVar expected, Boolean is_toplevel_in_seq) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 1397
в Nemerle.Compiler.Typer.TypeExpr(PExpr e, TypeVar expected) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 1366
в Nemerle.Compiler.Typer._N_refout_110734(_N_closure_110726 _N_TypeCall_cp_110733, String name, PExpr expr) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 3696
в Nemerle.Compiler.Typer._N_compile_parm__110746.apply(PExpr p) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 3714
в Nemerle.Collections.NList.Map[T,TOut](list`1 lst, Function`2 convert) в C:\MyProjects\rsdn-nemerle-25424df\lib\list.n:строка 938
в Nemerle.Core.list`1.Map[TOut](Function`2 convert) в C:\MyProjects\rsdn-nemerle-25424df\lib\list.n:строка 329
в Nemerle.Compiler.Typer.TypeCall(PExpr pfnc, list`1 parms, TypeVar expected, Boolean is_property) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 3717
в Nemerle.Compiler.Typer.DoType(PExpr expression, TypeVar expected, Boolean is_toplevel_in_seq) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 2004
в Nemerle.Compiler.Typer.TypeExpr(PExpr expr, TypeVar expected, Boolean is_toplevel_in_seq) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 1397
в Nemerle.Compiler.Typer.TypeExpr(PExpr e, TypeVar expected) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 1366
в Nemerle.Compiler.Typer.TypeExpr(PExpr e) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 1361
в Nemerle.Compiler.Typer.DoType(PExpr expression, TypeVar expected, Boolean is_toplevel_in_seq) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 2036
в Nemerle.Compiler.Typer.TypeExpr(PExpr expr, TypeVar expected, Boolean is_toplevel_in_seq) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 1397
в Nemerle.Compiler.Typer.TypeExpr(PExpr e, TypeVar expected) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 1366
в Nemerle.Compiler.Typer.DoType(PExpr expression, TypeVar expected, Boolean is_toplevel_in_seq) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 2172
в Nemerle.Compiler.Typer.TypeExpr(PExpr expr, TypeVar expected, Boolean is_toplevel_in_seq) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 1397
в Nemerle.Compiler.Typer.TypeExpr(PExpr e, TypeVar expected) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 1366
в Nemerle.Compiler.Typer.RunTyper() в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 408
в Nemerle.Compiler.Typer.RunFullTyping() в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Typer.n:строка 248
в Nemerle.Compiler.MethodBuilder.RunBodyTyper() в C:\MyProjects\rsdn-nemerle-25424df\ncc\hierarchy\ClassMembers.n:строка 932
в Nemerle.Compiler.MethodBuilder.Compile() в C:\MyProjects\rsdn-nemerle-25424df\ncc\generation\HierarchyEmitter.n:строка 1115
в Nemerle.Compiler.TypeBuilder.EmitImplementation() в C:\MyProjects\rsdn-nemerle-25424df\ncc\generation\HierarchyEmitter.n:строка 653
в Nemerle.Compiler.TypesManager._N_emit_impl__58456.apply_void(TypeBuilder ti) в C:\MyProjects\rsdn-nemerle-25424df\ncc\generation\HierarchyEmitter.n:строка 370
в Nemerle.Compiler.TypesManager._N_maybe_f__58691.apply_void(TypeBuilder ti) в C:\MyProjects\rsdn-nemerle-25424df\ncc\hierarchy\TypesManager.n:строка 257
в Nemerle.Collections.NList.Iter[T](list`1 l, FunctionVoid`1 f) в C:\MyProjects\rsdn-nemerle-25424df\lib\list.n:строка 926
в Nemerle.Core.list`1.Iter(FunctionVoid`1 f) в C:\MyProjects\rsdn-nemerle-25424df\lib\list.n:строка 317
в Nemerle.Compiler.TypesManager.Iter(list`1 builders, FunctionVoid`1 f) в C:\MyProjects\rsdn-nemerle-25424df\ncc\hierarchy\TypesManager.n:строка 264
в Nemerle.Compiler.TypesManager.Iter(FunctionVoid`1 f) в C:\MyProjects\rsdn-nemerle-25424df\ncc\hierarchy\TypesManager.n:строка 275
в Nemerle.Compiler.TypesManager.compile_all_tyinfos(Boolean aux_phase) в C:\MyProjects\rsdn-nemerle-25424df\ncc\generation\HierarchyEmitter.n:строка 397
в Nemerle.Compiler.TypesManager._N__N_lambda__57878__57982.apply_void() в C:\MyProjects\rsdn-nemerle-25424df\ncc\generation\HierarchyEmitter.n:строка 240
в Nemerle.Compiler.Solver.Enqueue(FunctionVoid action) в C:\MyProjects\rsdn-nemerle-25424df\ncc\typing\Solver.n:строка 199
в Nemerle.Compiler.TypesManager.EmitDecls() в C:\MyProjects\rsdn-nemerle-25424df\ncc\generation\HierarchyEmitter.n:строка 239
в Nemerle.Compiler.ManagerClass.Run() в C:\MyProjects\rsdn-nemerle-25424df\ncc\passes.n:строка 608
в Nemerle.CommandlineCompiler.MainClass.main_with_catching() в C:\MyProjects\rsdn-nemerle-25424df\ncc\main.n:строка 130
Построение проекта "DBLib.nproj" завершено с ошибкой.

как жить, что делать?



27.11.11 20:49: Ветка выделена из темы вопрос по метапрограммированию
Автор: _Claus_
Дата: 24.11.11
— VladD2
Re: Компилятор отказывается это кушать
От: CodingUnit Россия  
Дата: 27.11.11 09:22
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>Всем привет! Имею метод, который формирует куски контекстного кода, чтобы потом сложить в генерируемый метод


_C_>
_C_> public create_string_prop() : void 
              
_C_>      mutable string_save_blocks = typeBuilder.UserData["data"] :> list[PExpr]            
      
_C_>      when (string_save_blocks == null)
        
_C_>        string_save_blocks = []
          
_C_>      //проблема здесь, указание ttype помогает убрать другие ошибки
_C_>      typeBuilder.UserData["data"] = \
_C_>      <[ttype:  
_C_>          when ($(has_saved : usesite))
_C_>      {
_C_>          datamap.write_string($(private_ref : usesite), exchange.$(fld_name : name)) 
                            
_C_>          $(has_saved : usesite) = false
_C_>      }
_C_>    ]> :: string_save_blocks 
_C_>      ...
_C_>



_C_>как жить, что делать?


Здесь явно неверный тип квазицитаты, это раз, кусок кода надо изменить:

<[
   when ($(has_saved : usesite))
   {
     datamap.write_string($(private_ref : usesite), exchange.$(fld_name : name)) 
     $(has_saved : usesite) = false
   }
]> :: string_save_blocks



исходить надо из этого, ttype это типизированое указание типа, здесь его нет, это обычная квазицитата, а дальше смотреть если будут остальные ошибки. Здесь я не вижу всех объявлений поэтому не могу сказать какие еще могут быть ошибки.
Re: Компилятор отказывается это кушать
От: CodingUnit Россия  
Дата: 27.11.11 09:30
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>Всем привет! Имею метод, который формирует куски контекстного кода, чтобы потом сложить в генерируемый метод


_C_>
_C_> public create_string_prop() : void 
              
_C_>      mutable string_save_blocks = typeBuilder.UserData["data"] :> list[PExpr]            
      
_C_>      when (string_save_blocks == null)
        
_C_>        string_save_blocks = []
          
_C_>      //проблема здесь, указание ttype помогает убрать другие ошибки
_C_>      typeBuilder.UserData["data"] = \
_C_>      <[ttype:  
_C_>          when ($(has_saved : usesite))
_C_>      {
_C_>          datamap.write_string($(private_ref : usesite), exchange.$(fld_name : name)) 
                            
_C_>          $(has_saved : usesite) = false
_C_>      }
_C_>    ]> :: string_save_blocks 
_C_>      ...
_C_>



Привыкай к функциональному стилю, здесь ты используешь mutable, от них надо уходить, можно этот раздел переписать например так:

 // публичные методы надо писать в camel case в .net типа CreateStringProp()
 public create_string_prop() : void 
              
      // такие длинные имена переменных в методе тоже плохой стиль
      def blocks = typeBuilder.UserData["data"] :> list[PExpr]            
      
      def blocks = blocks ?? []; 
          

      typeBuilder.UserData["data"] = \
      <[
          when ($(has_saved : usesite))
      {
          datamap.write_string($(private_ref : usesite), exchange.$(fld_name : name)) 
                            
          $(has_saved : usesite) = false
          }
      ]> :: blocks
Re[2]: Компилятор отказывается это кушать
От: _Claus_  
Дата: 27.11.11 09:31
Оценка:
CU>исходить надо из этого, ttype это типизированое указание типа, здесь его нет, это обычная квазицитата, а дальше смотреть если будут остальные ошибки. Здесь я не вижу всех объявлений поэтому не могу сказать какие еще могут быть ошибки.


спасибо. без ttype компилируется. вдруг. хм..
Re[2]: Компилятор отказывается это кушать
От: _Claus_  
Дата: 27.11.11 10:31
Оценка:
CU>Привыкай к функциональному стилю, здесь ты используешь mutable, от них надо уходить, можно этот раздел переписать например так:

ок. к стати вот есть странность одна: я хочу объявить def поле класса, но рассчитать его могу только в конструкторе (из его параметров).
другие языки выкручиваются отслеживаем — только в конструкторе, или смешанным описанием класса и конструктора, как F#.
в N есть такая возможность?
Re[3]: Компилятор отказывается это кушать
От: CodingUnit Россия  
Дата: 27.11.11 14:15
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>ок. к стати вот есть странность одна: я хочу объявить def поле класса, но рассчитать его могу только в конструкторе (из его параметров).

_C_>другие языки выкручиваются отслеживаем — только в конструкторе

Не до конца понял что ты имел в виду. def поле класса, ты имеешь в виду read-only поле? Да их можно устанавливать только в конструкторе, если я правильно тебя понял, стоит осмыслить структуру программы, может в предметной области применения объекта не должно быть изменяемого состояния как такого, в таком случае изменение реад-онли поля будет порождать новый объект, для этого делаются спец.методы. Это функциональный стиль и повышает безопасность программы.

_C_>или смешанным описанием класса и конструктора, как F#. в N есть такая возможность?


Это не понял. Можешь подробней объяснить что ты имел в виду. В Н как видишь можно создавать и свойства и mutable и реад-онли поля, так что применяй стиль который нужен тебе для решения текущей задачи, красиво.
Re[3]: Компилятор отказывается это кушать
От: CodingUnit Россия  
Дата: 27.11.11 14:19
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>спасибо. без ttype компилируется. вдруг. хм..


Естественно, откуда ты вообще нашел применять здесь этот тип квази-цитаты, я в своей практике его вообще никогда не применял, он порождает FixedType или TypeVar, чтобы потом подставлять его в нужные места, в PExpr его никак не преобразовать.
Re[2]: Компилятор отказывается это кушать
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.11.11 16:37
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Привыкай к функциональному стилю, здесь ты используешь mutable, от них надо уходить, можно этот раздел переписать например так:


CU>
CU>      // такие длинные имена переменных в методе тоже плохой стиль
CU>      def blocks = typeBuilder.UserData["data"] :> list[PExpr]            
CU>      def blocks = blocks ?? []; 
CU>


Согласен. Только вторая переменная здесь лишняя. Лучше так:
def blocks = (typeBuilder.UserData["data"] :> list[PExpr])  ?? [];
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Компилятор отказывается это кушать
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.11.11 16:42
Оценка:
Здравствуйте, _Claus_, Вы писали:

CU>>Привыкай к функциональному стилю, здесь ты используешь mutable, от них надо уходить, можно этот раздел переписать например так:


_C_>ок. к стати вот есть странность одна: я хочу объявить def поле класса,


Что за "def поле"? Неизменяемое, что ли? В Немерле для полей def не применяется. По умолчанию все поля доступны только для чтения.

_C_>но рассчитать его могу только в конструкторе (из его параметров).

_C_>другие языки выкручиваются отслеживаем — только в конструкторе, или смешанным описанием класса и конструктора, как F#.
_C_>в N есть такая возможность?

Дык в Немреле так и есть. Поля доступные только для чтения можно инициализировать только в конструкторах или по месту (что в итогде все равно к конструкторы переписывается).

Кстати, в Немерле есть get-only-свойства. Вот так кой вот прикол. Они тоже могут инициализироваться только в конструкторах.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Компилятор отказывается это кушать
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.11.11 16:47
Оценка: 6 (1)
Здравствуйте, CodingUnit, Вы писали:

_C_>>или смешанным описанием класса и конструктора, как F#. в N есть такая возможность?


CU>Это не понял. Можешь подробней объяснить что ты имел в виду. В Н как видишь можно создавать и свойства и mutable и реад-онли поля, так что применяй стиль который нужен тебе для решения текущей задачи, красиво.


Это он об инлайт-конструкторах, скорее всего. В Немерле такого пока нет. В Н2 я планировал это дело прикрутить. Тогда можно будет вместо:
[Record]
class A
{
  private field : int;

  public Test() : int { field + 1 }
}

писать:
class A(field : int)
{
  public Test() : int { field + 1 }
}
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Компилятор отказывается это кушать
От: CodingUnit Россия  
Дата: 27.11.11 16:56
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Это он об инлайт-конструкторах, скорее всего. В Немерле такого пока нет. В Н2 я планировал это дело прикрутить. Тогда можно будет вместо:

VD>
VD>[Record]
VD>class A
VD>{
VD>  private field : int;

VD>  public Test() : int { field + 1 }
VD>}
VD>

VD>писать:
VD>
VD>class A(field : int)
VD>{
VD>  public Test() : int { field + 1 }
VD>}
VD>


Это интересно, если будет такой синтаксис, его можно попробовать сопрягать с Immutable стилем программирования, чтобы поля указанные в конструкторе фигурировали в построении новых объектов, например как то так:

class A(field : int)
{

public Test() : A { field %+ 1 } // то есть изменение поля порождает новый объект
}


Потому что поддержку неизменяемых объектов сейчас приходится производить вручную и если бы была поддержка на основе синтаксиса это было бы удобно, ну или макросом со своим синтаксисом.
Re[6]: Компилятор отказывается это кушать
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.11.11 18:13
Оценка:
Здравствуйте, CodingUnit, Вы писали:

CU>Это интересно, если будет такой синтаксис, его можно попробовать сопрягать с Immutable стилем программирования, чтобы поля указанные в конструкторе фигурировали в построении новых объектов, например как то так:


CU>
CU>class A(field : int)
CU>{

CU>public Test() : A { field %+ 1 } // то есть изменение поля порождает новый объект
CU>}
CU>


Это уже какой-то перебор. На фиг это надо?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Компилятор отказывается это кушать
От: CodingUnit Россия  
Дата: 27.11.11 18:15
Оценка: 5 (1)
Здравствуйте, VladD2, Вы писали:


CU>>
CU>>class A(field : int)
CU>>{

CU>>public Test() : A { field %+ 1 } // то есть изменение поля порождает новый объект
CU>>}
CU>>


VD>Это уже какой-то перебор. На фиг это надо?


Это заготовки для immutable программирования, но не знаю стоит ли их поддерживать на уровне языка, может будет достаточно и макросов.
Re[4]: Компилятор отказывается это кушать
От: _Claus_  
Дата: 28.11.11 11:33
Оценка:
VD>Что за "def поле"? Неизменяемое, что ли? В Немерле для полей def не применяется. По умолчанию все поля доступны только для чтения.

вот это и сбило с толку. объявляю поле с def впереди и получаю ошибку
error : parse error near keyword `def': expecting type declaration

я понятно догадался def убрать, хоть это и не следует из сообщения, но получается, в Nemerle
есть 3 типа полей, которые по разному описываются. в доках везде говорится что два.
то, что их именно три могу показать так

class x
   z = ""

   public this()
      z = "xx"

это валидный код, и z c "" становится "xx", но это отдельный тип, допускающий множество присвоений в контексте конструкторов.
ИМХО где-то пару строк про это добавить (в FAQ?) имеет смысл.
Re[5]: Компилятор отказывается это кушать
От: CodingUnit Россия  
Дата: 28.11.11 11:43
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>вот это и сбило с толку. объявляю поле с def впереди и получаю ошибку

_C_>error : parse error near keyword `def': expecting type declaration
само собой, потому что def нельзя использовать в этом контексте

_C_>я понятно догадался def убрать, хоть это и не следует из сообщения, но получается, в Nemerle

_C_>есть 3 типа полей, которые по разному описываются. в доках везде говорится что два.
_C_>то, что их именно три могу показать так
Какие три типа? Есть два типа полей, изменяемые mutable и неизменяемые, первые указываются с ключевым словом mutable, вторые без.

_C_>
_C_>class x
_C_>   z = ""

_C_>   public this()
_C_>      z = "xx"

_C_>


то что ты показал это объявление неизменяемого поля, которое меняется только в конструкторе, что ты и сделал. Подозреваю что здесь идет два раза изменение значения, первый раз это присвоение полю, оно будет вызвано до вызова тела явного конструктора, а потом вызов тела конструктора даст изменение z. Это валидная конструкция, первая запись только упрощенная версия второй, и тремя типами полей здесь не пахнет.
Re[6]: Компилятор отказывается это кушать
От: _Claus_  
Дата: 28.11.11 12:18
Оценка:
Здравствуйте, CodingUnit, Вы писали:

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


_C_>>вот это и сбило с толку. объявляю поле с def впереди и получаю ошибку

_C_>>error : parse error near keyword `def': expecting type declaration
CU>само собой, потому что def нельзя использовать в этом контексте

_C_>>я понятно догадался def убрать, хоть это и не следует из сообщения, но получается, в Nemerle

_C_>>есть 3 типа полей, которые по разному описываются. в доках везде говорится что два.
_C_>>то, что их именно три могу показать так
CU>Какие три типа? Есть два типа полей, изменяемые mutable и неизменяемые, первые указываются с ключевым словом mutable, вторые без.
ошибся немного. не три типа полей а три типа переменных: def, mutable, class const.
Re[7]: Компилятор отказывается это кушать
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.11.11 16:07
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>ошибся немного. не три типа полей а три типа переменных: def, mutable, class const.


Нет никаких трех типов переменных. Есть поля и локальные переменные. Каждый из них может быть изменяемым и нет. Просто для объявления локальных неизменяемых переменных используется def, а для объявления неизменяемых полей def не используется.

Еще поля могут быть статическими или экзеплярными.

А вот констант как таковых нет. Компилятор сам решает что сделать константой, а что переменной. На сегодня, правда, константами делаются только статические неизменяемые поля.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Компилятор отказывается это кушать
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.11.11 16:13
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>есть 3 типа полей, которые по разному описываются. в доках везде говорится что два.

_C_>то, что их именно три могу показать так
_C_>
_C_>class x
_C_>   z = ""

_C_>   public this()
_C_>      z = "xx"
_C_>

_C_>это валидный код, и z c "" становится "xx", но это отдельный тип, допускающий множество присвоений в контексте конструкторов.
_C_>ИМХО где-то пару строк про это добавить (в FAQ?) имеет смысл.

Нет никаких трех типов. То что ты привел это допустимый код, но ничего сверхестественного в нем нет. Точно так же можно сделать в C#, VB, F#, и скорее всего так можно сделать и в Boo.

Данный код переписывается в:
class x
   public this()
      z = ""
      z = "xx"


Реально в дотнете могут быть только функции. Ни свойств, ни инициализаторов полей на низком уровне не существует. Обращение к свойствам переписывается в обращение к их методам-эксесорам. А инициализаторы переносятся в конструкторы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.