OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Суббота, 20 Апрель, 2024 15:07

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 8 ] 
Автор Сообщение
СообщениеДобавлено: Среда, 12 Апрель, 2023 14:07 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1565
Где есть? Если нет на Обероне, в крайнем случае подойдёт на каком-нибудь родственном языке. Сразу для тех, кто скажет, что это нельзя сделать на Обероне. Делается так: заводится тип "вариант" (обычно он есть в Оберонах, в A2/ЯОС их штуки 3, наверное, тут описывал https://tvoygit.ru/budden/ja-o-s/src/branch/главная/док/язык-и-библиотека/динамически-типизированный-укль-и-вариантные-типы.md ), и конструкторы для него. Далее создаётся массив аргументов. В A2/ЯОС это можно (наверное) сделать через конструктор мат. массивов, будет как-то так:
Код:
MODULE Пример;
IMPORT Вариант;

VAR Аргументы : ARRAY 2 OF Вариант.Вариант;
BEGIN
IF этоA2 OR этоЯОС THEN
    Аргументы := [В.Ц(5),В.С("абв")]; // A2/ЯОС, если возможен мат.массив указателей или записей
ELSE
    Аргументы[0] := В.Ц(5);
    Аргументы[1] := В.С("абв") END;
printf("форматный вывод %d, %s",Аргументы) ENDIF END Пример.


В более продвинутой реализации можно сделать и функцию с произвольными аргументами. В A2/ЯОС уже есть встроенная процедура TRACE, в которой уже встроен механизм произвольных аргументов, разбираемых во время компиляции, и я уже освоил клонирование этого механизма, когда делал процедуру пПиши (одна из частей реализации тут https://tvoygit.ru/budden/ja-o-s/src/co ... .Mod#L6376 , но в целом реализация размазана по всему компилятору ) . Мне нужен только лишь механизм разбора форматной строки.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 12 Апрель, 2023 16:04 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1449
Откуда: Киев
Если не пытаться следовать С до буквы, то «форматная строка» на AO и CP может выглядеть так:
Код:
Print.s("форматный вывод ").d(5).s(", ").s("абв");
Без механизма разбора форматной строки, как и без возможных ошибок разбора во время исполнения.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 12 Апрель, 2023 16:32 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1565
Не до буквы, но по мотивам. В принципе, для текущей задачи можно и такой костыль применить. Спасибо, не догадался сам. Но он не сработает, к примеру, если есть задача хранить форматные сообщения на разных языках. Впрочем, в такой ситуации и printf не сработает. Касаемо разбора форматной строки, он должен производиться в приличной реализации во время компиляции, вместе с анализом типов аргументов. Не знаю, как в Си, а в Окамле неверное просто не скомпилируется. Другое дело, что эта же причина затрудняет и локализацию в Окамле, т.к. не помню, что там бывает с форматными строками, не являющимися литералами.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 12 Апрель, 2023 23:01 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1449
Откуда: Киев
Это очень распространённый паттерн даже не в AO и CP, а вообще. Естественно, на его основе можно сделать и вариант с локализацией, просто выглядеть будет немного иначе. Правда, форматированный вывод в журнал - это сам по себе костыль, которому локализация не нужна.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 17 Апрель, 2023 11:49 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1565
В A2/ЯОС в интерпретаторе есть интерполяция выражений. Это менее популярная техника, чем форматные строки, для маленьких шаблонов, и более популярная для больших (вспоминаем PHP и другие шаблонизатора). Выглядит так:

Код:
LisInterpreter.ТестУтилитаИнтерполируйСтроки
   "Это строчка ?{15*2*20+4:2058}? , ага."
   "Остаток этой строки будет вычислен ?{3+5 = 20}?"
   "?{ 100*15"
   "конструктор множества в интерполяции строки ?{{1,2,4}}?"
   ~

печатает следующее:
Код:
Результат: Это строчка 604 , ага.
Результат: Остаток этой строки будет вычислен FALSE
Результат: 1500
Результат: конструктор множества в интерполяции строки {4, 2..1}

Естественно, тут можно и подставлять значения переменных интерпретатора.

Если так вдуматься, то, наверное так и получится: для простых шаблонов оптимальнее форматные строки, а для сложных - интерполяция. Но это не точно. Интерполяция, позволяющая вставлять выражения прямо внутрь строки - это штука, конечно, мощная, но стрёмноватая.
Сомнительно, что она подходит под понятие "пути Оберона" вообще. С другой стороны, этот форум написан на PHP, где интерполяция вообще была изначально основным, ради чего создавался инструмент, и в движке данного форума она вовсю используется.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 17 Апрель, 2023 12:00 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1565
Видимо, для текущей задачи хватит такого решения:

  • добавляем встроенную процедуру СклейВСтроку или как-нибудь так.
  • первый аргумент - поток
  • остальные аргументы - произвольного типа, они печатаются каждая своим способом. Очевидный недостаток здесь, что нельзя задать параметры, например, ширину поля для целого числа. Ага, это плохо. Значит, метод Константина лучше.

Ну что ж, тогда придётся продублировать некоторые процедуры потока, чтобы они возврщали поток. Если нам будет нужна строка, то получится как-то так:

Код:
Строки8.ЯвиСтрокодел().Строку("2 ").пЦел64(2,0).ДайЗначение();

Дикость, конечно, в том же JS можно написать гораздо проще:
Код:
'2'+2

Зато минималистично. Соответствующий класс Строки8.Строкодел (да и Строки32.Строкодел) уже есть.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 17 Апрель, 2023 17:02 

Зарегистрирован: Пятница, 11 Январь, 2019 19:26
Сообщения: 293
Откуда: Russia
Код:
MODULE Test77;
IMPORT Streams;
PROCEDURE Do*;
VAR buffer := NEW Streams.Buffer(256);
BEGIN
   buffer := buffer + "Hello" + 20X + 123 + 20X + 567.89;
   VAR data := buffer.GetStringCopy();
   TRACE(data^);
END Do;
END Test77.

Test77.Do~
System.Free Test77~

>>>
{Test77.Do@185:data^= Hello 123 5.6789E+2;}


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 18 Апрель, 2023 11:13 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1565
Спасибо, я уже сделал по мотивам идеи, высказанной Константином, примерно так:

Код:
KernelLog.String(ЯвиСтрокодел().С8("Текст").Ч64(345,0).пВК_ПС().Рез()^);


Строкодел - это и есть Strings.Buffer, просто я добавил к нему несколько методов. Согласен, что выглядит уродливо, но это временный костыль, и вообще, мы в мире Оберона, где такое принято терпеть. Зато при выводе числа можно передать в качестве параметра ширину поля, а в ситуации с операцией "+" этого сделать нельзя. Это стало решающим фактором. Кроме того, я стараюсь избегать переопределения операций в A2/ЯОС, т.к. мне не нравится, как там сделан полиморфизм. И, как я уже писал, я считаю, что конкатенация (в т.ч. конкатенация строк) должна обозначаться другим значком, а не плюсом.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 8 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB