Декларация типа по полному имени
От: vaskir Россия vaskir.blogspot.com
Дата: 16.01.16 16:39
Оценка:
Так работает:

def fieldName = $"_$name";
builder.Define(<[decl: private mutable $(fieldName: usesite): System.Int32 ]>);


И так работает:

def rawType = "int";
def fieldName = $"_$name";
builder.Define(<[decl: private mutable $(fieldName: usesite): $(rawType: usesite) ]>);


А вот так — не работает:

def rawType = "System.Int32";
def fieldName = $"_$name";
builder.Define(<[decl: private mutable $(fieldName: usesite): $(rawType: usesite) ]>);


error : unbound type name `System.Int32'

Похоже, полные имена типов надо как-то по особому передавать?
Re: Декларация типа по полному имени
От: hardcase Пират http://nemerle.org
Дата: 16.01.16 17:58
Оценка: 10 (1)
Здравствуйте, vaskir, Вы писали:

V>Похоже, полные имена типов надо как-то по особому передавать?


def typeName = PExpr.FromQualifiedIdentifier(builder.Manager, "System.Int32");
builder.Define(<[decl: private mutable $(fieldName: usesite): $typeName ]>);
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: Декларация типа по полному имени
От: vaskir Россия vaskir.blogspot.com
Дата: 16.01.16 18:59
Оценка:
Спасибо!

Тут же возник еще один вопрос. После парсинга YAML у меня есть для каждого листового узла его (типизированное) значение:

variant Scalar {
    | Int { v: int }
    | String { v: string }
    | TimeSpan { v: System.TimeSpan }
    | Bool { v: bool }
    | Uri { v: System.Uri }
    | Float { v: double; }
    
    public BoxedValue: object {
        get {
            match (this) {
            | Int(v) with x = v : object
            | String(x)
            | Bool(x)
            | TimeSpan(x)
            | Uri(x)
            | Float(x) => x
            }
        }
    }
}


Для каждого такого узла я хочу сгенерировать поле соответствующего типа (с этим разобрались) и присвоить дефолтное значение. Насколько я понимаю, передавать можно только литералы, поэтому делаем значению ToString():

def fieldType = PExpr.FromQualifiedIdentifier(builder.Manager, node.BoxedValue.GetType().FullName);
def fieldName = $"_$name";
def defaultValue = node.BoxedValue.ToString();
builder.Define(<[decl: private mutable $(fieldName: usesite): $fieldType = $(defaultValue: usesite); ]>);


В результате для YAML "Person: 1" выдается ошибка: error : unbound name `1'
Re: Декларация типа по полному имени
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.01.16 02:23
Оценка:
Здравствуйте, vaskir, Вы писали:

V>Похоже, полные имена типов надо как-то по особому передавать?


Ага. Выражениями:
def rawType = <[ System.Int32 ]>;
def fieldName = $"_$name";
builder.Define(<[decl: private mutable $(fieldName: usesite): $rawType ]>);


А, если надо квалифицированное имя из строки получить, то для этого нужно пользоваться или методом PExpr.FromQualifiedIdentifier или парсером (MainParser.ParseExpr). В именах типов ведь и параметры типов могут появиться (в которых могут быть и вложенные ссылки на сложные типы).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Декларация типа по полному имени
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.01.16 02:31
Оценка:
Здравствуйте, vaskir, Вы писали:

V>Насколько я понимаю, передавать можно только литералы, поэтому делаем значению ToString():


Куда передавать? И что передавать? Если речь идет о типах, то как они получаются?

V>
V>def fieldType = PExpr.FromQualifiedIdentifier(builder.Manager, node.BoxedValue.GetType().FullName);
V>def fieldName = $"_$name";
V>def defaultValue = node.BoxedValue.ToString();
V>builder.Define(<[decl: private mutable $(fieldName: usesite): $fieldType = $(defaultValue: usesite); ]>);
V>


V>В результате для YAML "Person: 1" выдается ошибка: error : unbound name `1'


Логично. node.BoxedValue.GetType().FullName выдаст имя типа в дотнетом (CLR-ном) формате. "`1" означает — с одним дженерик-параметром. А еще в этом имени могут быть "+". Они разделяют вложенные классы.

Надо определиться какие типы будут доступны и опделять их самостоятельно. Так же можно стипизировать выражения с помощью типизатора немерла и получить тип у него. Прочитай вот эту
Автор(ы): Владислав Юрьевич Чистяков
Дата: 03.09.2009
В данной части статьи рассказывается о том, как работает система вывода типов Nemerle, о том, как с ней могут взаимодействовать макросы Nemerle, и что это дает
статью.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Декларация типа по полному имени
От: vaskir Россия vaskir.blogspot.com
Дата: 17.01.16 08:08
Оценка:
VD>Куда передавать? И что передавать? Если речь идет о типах, то как они получаются?

Нет, не типы, конкретные значения. Сейчас поясню.

V>>
V>>def fieldType = PExpr.FromQualifiedIdentifier(builder.Manager, node.BoxedValue.GetType().FullName);
V>>def fieldName = $"_$name";
V>>def defaultValue = node.BoxedValue.ToString();
V>>builder.Define(<[decl: private mutable $(fieldName: usesite): $fieldType = $(defaultValue: usesite); ]>);
V>>


V>>В результате для YAML "Person: 1" выдается ошибка: error : unbound name `1'


VD>Логично. node.BoxedValue.GetType().FullName выдаст имя типа в дотнетом (CLR-ном) формате. "`1" означает — с одним дженерик-параметром. А еще в этом имени могут быть "+". Они разделяют вложенные классы.


Проблема не в типах. С типами стало всё ок после

def fieldType = PExpr.FromQualifiedIdentifier(builder.Manager, node.BoxedValue.GetType().FullName);


Теперь проблема с дефолтными значениями полей. В итоге на YAML "Person: 1" я хочу сгенерировать:

private mutable _Person: System.Int32 = 1;


Проблема с этой "1". Что у меня есть: переменная типа int в которой лежит единица (node.BoxedValue в сниппете выше).

Какие еще типы полей нужны: string, TimeSpan, Uri, bool, double и inner classes (которые я пытаюсь генерить чуть раньше, пока не выходит, но это другой вопрос).

Для полной ясности, вот из такого YAML

Foo: 1
Person:
  Name: "bar"
  Age: 30
  Addr: http://1.com/


должен получиться такой класс:

public class Yaml {
    mutable _Foo: int = 1;
    _Person: Person_Type = Person_Type();
        
    public Foo: int { get { _Foo }}
    public Person: Person_Type { get { _Person }}
        
    public class Person_Type {
        mutable _Name: string = "bar";
        mutable _Age: int = 30;
        mutable _Addr: Uri = Uri("http://1.com");
                
        public Name: string { get { _Name }}
        public Age: int { get { _Age }}
        public Addr: Uri { get { _Addr }}
    }
}


Проблема: как сгенерить = Uri("http://1.com/"), = "bar", = 30?
Re[5]: Декларация типа по полному имени
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.01.16 13:04
Оценка:
Здравствуйте, vaskir, Вы писали:

V>Проблема не в типах. С типами стало всё ок после


V>
V>def fieldType = PExpr.FromQualifiedIdentifier(builder.Manager, node.BoxedValue.GetType().FullName);
V>


Я же тебе говорю, что так нельзя делать. FromQualifiedIdentifier может разобрать только простое квалифицированное имя где разделителем является точка.

V>Какие еще типы полей нужны: string, TimeSpan, Uri, bool, double и inner classes (которые я пытаюсь генерить чуть раньше, пока не выходит, но это другой вопрос).


V>Для полной ясности, вот из такого YAML


V>
V>Foo: 1
V>Person:
V>  Name: "bar"
V>  Age: 30
V>  Addr: http://1.com/
V>


А ты это средствами немерла парсишь? Думаю, что с "http://1.com/" могут быть проблемы.

К тому же не ясно как ты себе видишь эти твои "inner classes". Ты приведи более полный пример (с inner classes, датами и другими типами).

V>Проблема: как сгенерить = Uri("http://1.com/"), = "bar", = 30?


Ты должен получать эти свои "http://1.com/", "bar", 30 и т.п. в виде выражений и паттерн-матчингом определять, что это такое и их тип. Ну, а генерировать их очень просто. Подставляешь эти самые выражения в нужное место и все.

В общем, проще смотреть на код макрос. Так слишком много неизвестных. Не ясно как ты эти значения получаешь.

ЗЫ

Задачка более удобна для Nitra.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Декларация типа по полному имени
От: vaskir Россия vaskir.blogspot.com
Дата: 17.01.16 14:45
Оценка:
VD>Я же тебе говорю, что так нельзя делать. FromQualifiedIdentifier может разобрать только простое квалифицированное имя где разделителем является точка.

Ну у меня строго System.Int32/Uri/Double/TimeSpan, так что должно работать.

VD>А ты это средствами немерла парсишь? Думаю, что с "http://1.com/" могут быть проблемы.


Нет, использую библиотеку SharpYaml, она выдает граф с уже выведенными простейшими типами (int, string, double), далее я из string вывожу Uri и TimeSpan.

VD>К тому же не ясно как ты себе видишь эти твои "inner classes". Ты приведи более полный пример (с inner classes, датами и другими типами).


Ну в примере был как раз inner class (Person_Type). Или правильнее говорить nested?

VD>Ты должен получать эти свои "http://1.com/", "bar", 30 и т.п. в виде выражений и паттерн-матчингом определять, что это такое и их тип. Ну, а генерировать их очень просто. Подставляешь эти самые выражения в нужное место и все.


SharpYaml выдает уже готовые значения. Т.е. у меня есть реальная переменная типа double со значением 3.2. Как мне из нее сгенерировать "mutable _foo: double = 3.2;"?

VD>В общем, проще смотреть на код макрос. Так слишком много неизвестных. Не ясно как ты эти значения получаешь.


Весь код здесь

VD>Задачка более удобна для Nitra.


Сначала надо с немерлом разобраться
Re[7]: Декларация типа по полному имени
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.01.16 21:09
Оценка:
Здравствуйте, vaskir, Вы писали:

V>Ну у меня строго System.Int32/Uri/Double/TimeSpan, так что должно работать.


V>...Нет, использую библиотеку SharpYaml, она выдает граф с уже выведенными простейшими типами (int, string, double), далее я из string вывожу Uri и TimeSpan.


Значит паттерн–матчингом получай типы и цитатами задавай топа:
match (value)
{
  | x is string => <[ Systrem.String ]>
  ...
}


А позиции в тексте они выдают?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Декларация типа по полному имени
От: STDray http://stdray.livejournal.com
Дата: 18.01.16 15:33
Оценка: 10 (1)
Здравствуйте, vaskir, Вы писали:

V>
V>def fieldType = PExpr.FromQualifiedIdentifier(builder.Manager, node.BoxedValue.GetType().FullName);
V>def fieldName = $"_$name";
V>def defaultValue = node.BoxedValue.ToString();
V>builder.Define(<[decl: private mutable $(fieldName: usesite): $fieldType = $(defaultValue: usesite); ]>);
V>


V>В результате для YAML "Person: 1" выдается ошибка: error : unbound name `1'


Надо написать функцию преобразования скаляра в квазицитату, что-то вроде

    ToExpr(scalar : Scalar) : PExpr
    {
      | Int(v)      => <[ $v ]>;
      | String(v)   => <[ $v ]>;
      | TimeSpan(v) => <[ TimeSpan.FromMilliseconds($(v.TotalMilliseconds)) ]>
      | Bool(v)     => <[ $v ]>;
      | Uri(v)      => <[ Uri($(v.OriginalString)) ]>
      | Float(v)    => <[ $v ]>
    }


Потом
def defaultValue = ToExpr(node);
builder.Define(<[decl: private mutable $(fieldName: usesite): $fieldType = $defaultValue; ]>);
Отредактировано 18.01.2016 15:33 STDray . Предыдущая версия .
Re[4]: Декларация типа по полному имени
От: vaskir Россия vaskir.blogspot.com
Дата: 18.01.16 16:39
Оценка:
STD>Надо написать функцию преобразования скаляра в квазицитату, что-то вроде

STD>
STD>    ToExpr(scalar : Scalar) : PExpr
STD>    {
STD>      | Int(v)      => <[ $v ]>;
STD>      | String(v)   => <[ $v ]>;
STD>      | TimeSpan(v) => <[ TimeSpan.FromMilliseconds($(v.TotalMilliseconds)) ]>
STD>      | Bool(v)     => <[ $v ]>;
STD>      | Uri(v)      => <[ Uri($(v.OriginalString)) ]>
STD>      | Float(v)    => <[ $v ]>
STD>    }
STD>


STD>Потом

STD>
STD>def defaultValue = ToExpr(node);
STD>builder.Define(<[decl: private mutable $(fieldName: usesite): $fieldType = $defaultValue; ]>);
STD>


О, да. Это оно Работает. Спасибо!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.