OberonCore
https://forum.oberoncore.ru/

нужна реализация printf на любой версии Оберона
https://forum.oberoncore.ru/viewtopic.php?f=27&t=6929
Страница 1 из 1

Автор:  budden [ Среда, 12 Апрель, 2023 14:07 ]
Заголовок сообщения:  нужна реализация printf на любой версии Оберона

Где есть? Если нет на Обероне, в крайнем случае подойдёт на каком-нибудь родственном языке. Сразу для тех, кто скажет, что это нельзя сделать на Обероне. Делается так: заводится тип "вариант" (обычно он есть в Оберонах, в 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 , но в целом реализация размазана по всему компилятору ) . Мне нужен только лишь механизм разбора форматной строки.

Автор:  Comdiv [ Среда, 12 Апрель, 2023 16:04 ]
Заголовок сообщения:  Re: нужна реализация printf на любой версии Оберона

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

Автор:  budden [ Среда, 12 Апрель, 2023 16:32 ]
Заголовок сообщения:  Re: нужна реализация printf на любой версии Оберона

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

Автор:  Comdiv [ Среда, 12 Апрель, 2023 23:01 ]
Заголовок сообщения:  Re: нужна реализация printf на любой версии Оберона

Это очень распространённый паттерн даже не в AO и CP, а вообще. Естественно, на его основе можно сделать и вариант с локализацией, просто выглядеть будет немного иначе. Правда, форматированный вывод в журнал - это сам по себе костыль, которому локализация не нужна.

Автор:  budden [ Понедельник, 17 Апрель, 2023 11:49 ]
Заголовок сообщения:  Re: нужна реализация printf на любой версии Оберона

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

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

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

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

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

Автор:  budden [ Понедельник, 17 Апрель, 2023 12:00 ]
Заголовок сообщения:  Re: нужна реализация printf на любой версии Оберона

Видимо, для текущей задачи хватит такого решения:

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

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

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

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

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

Автор:  Sergej Durmanov [ Понедельник, 17 Апрель, 2023 17:02 ]
Заголовок сообщения:  Re: нужна реализация printf на любой версии Оберона

Код:
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;}

Автор:  budden [ Вторник, 18 Апрель, 2023 11:13 ]
Заголовок сообщения:  Re: нужна реализация printf на любой версии Оберона

Спасибо, я уже сделал по мотивам идеи, высказанной Константином, примерно так:

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


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

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/