Тут же возник еще один вопрос. После парсинга 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():
А, если надо квалифицированное имя из строки получить, то для этого нужно пользоваться или методом PExpr.FromQualifiedIdentifier или парсером (MainParser.ParseExpr). В именах типов ведь и параметры типов могут появиться (в которых могут быть и вложенные ссылки на сложные типы).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
V>В результате для YAML "Person: 1" выдается ошибка: error : unbound name `1'
Логично. node.BoxedValue.GetType().FullName выдаст имя типа в дотнетом (CLR-ном) формате. "`1" означает — с одним дженерик-параметром. А еще в этом имени могут быть "+". Они разделяют вложенные классы.
Надо определиться какие типы будут доступны и опделять их самостоятельно. Так же можно стипизировать выражения с помощью типизатора немерла и получить тип у него. Прочитай вот эту
V>>В результате для YAML "Person: 1" выдается ошибка: error : unbound name `1'
VD>Логично. node.BoxedValue.GetType().FullName выдаст имя типа в дотнетом (CLR-ном) формате. "`1" означает — с одним дженерик-параметром. А еще в этом имени могут быть "+". Они разделяют вложенные классы.
Теперь проблема с дефолтными значениями полей. В итоге на YAML "Person: 1" я хочу сгенерировать:
private mutable _Person: System.Int32 = 1;
Проблема с этой "1". Что у меня есть: переменная типа int в которой лежит единица (node.BoxedValue в сниппете выше).
Какие еще типы полей нужны: string, TimeSpan, Uri, bool, double и inner classes (которые я пытаюсь генерить чуть раньше, пока не выходит, но это другой вопрос).
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?
Я же тебе говорю, что так нельзя делать. FromQualifiedIdentifier может разобрать только простое квалифицированное имя где разделителем является точка.
V>Какие еще типы полей нужны: string, TimeSpan, Uri, bool, double и inner classes (которые я пытаюсь генерить чуть раньше, пока не выходит, но это другой вопрос).
V>Для полной ясности, вот из такого YAML
V>
А ты это средствами немерла парсишь? Думаю, что с "http://1.com/" могут быть проблемы.
К тому же не ясно как ты себе видишь эти твои "inner classes". Ты приведи более полный пример (с inner classes, датами и другими типами).
V>Проблема: как сгенерить = Uri("http://1.com/"), = "bar", = 30?
Ты должен получать эти свои "http://1.com/", "bar", 30 и т.п. в виде выражений и паттерн-матчингом определять, что это такое и их тип. Ну, а генерировать их очень просто. Подставляешь эти самые выражения в нужное место и все.
В общем, проще смотреть на код макрос. Так слишком много неизвестных. Не ясно как ты эти значения получаешь.
ЗЫ
Задачка более удобна для Nitra.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
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>В общем, проще смотреть на код макрос. Так слишком много неизвестных. Не ясно как ты эти значения получаешь.
Здравствуйте, vaskir, Вы писали:
V>Ну у меня строго System.Int32/Uri/Double/TimeSpan, так что должно работать.
V>...Нет, использую библиотеку SharpYaml, она выдает граф с уже выведенными простейшими типами (int, string, double), далее я из string вывожу Uri и TimeSpan.
Значит паттерн–матчингом получай типы и цитатами задавай топа:
match (value)
{
| x is string => <[ Systrem.String ]>
...
}
А позиции в тексте они выдают?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.