Автор Тема: Делаем строку на O7  (Прочитано 22059 раз)

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Делаем строку на O7
« Ответ #30 : Октябрь 12, 2013, 06:59:46 am »
А когда есть конкретный контекст, конкретные требования - то и вырабатываются решения. Которые потом иногда обобщаются.

Ну я и пошел от конкретного контекста - что в компиляторе уже сейчас можно переписать на O7. И сразу уперся в строки, потому что они везде :)

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Делаем строку на O7
« Ответ #31 : Октябрь 14, 2013, 10:43:57 am »
Итак, pure Oberon-07 (без динамических массивов). Пытаемся написать модуль для работы со строками любого размера.
Я на оберонах разучился писать, вот идея на псевдоязыке:

struct MemoryBlock
{
virtual size_t size () = 0;
virtual void put (size_t position, char value) = 0;
virtual char get (size_t position) = 0;
};

struct MemoryBlock8b: public MemoryBlock
{
char buffer[8];

size_t size ()
{
return 8;
}

void put (size_t position, char value)
{
this->buffer[position] = value;
}

char get (size_t position)
{
return this->buffer[position];
}
};

struct MemoryBlock16b: public MemoryBlock
{
char buffer[16];

size_t size ()
{
return 16;
}

void put (size_t position, char value)
{
this->buffer[position] = value;
}

char get (size_t position)
{
return this->buffer[position];
}
};

struct MemoryBlock24b: public MemoryBlock
{
char buffer[24];

size_t size ()
{
return 24;
}

void put (size_t position, char value)
{
this->buffer[position] = value;
}

char get (size_t position)
{
return this->buffer[position];
}
};

...и так далее...

MemoryBlock* allocate_memory_block (size_t size)
{
if (size <= 8)
{
return new MemoryBlock8b();
}
if (size <= 16)
{
return new MemoryBlock16b();
}
if (size <= 24)
{
return new MemoryBlock24b();
}
...и так далее...
return 0;
}

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Делаем строку на O7
« Ответ #32 : Октябрь 14, 2013, 11:10:18 am »
Вообще, для любых приложений 24*365 лучше использовать выделение только фиксированных размеров блоков. Дабы не нарваться на полную фрагментацию памяти. В целом, когда у вас нет кусков непредсказуемого размера, дин. память эффективнее используется.
Фиксированного размера нехорошо: будет перерасход памяти как на очень мелких так и на очень крупных объектах.  Надо выравнивание блока делать прогрессирующим: маленький блок - маленькое выравнивание; а крупнее блок - грубее выравнивание.

Можно и вообще делать спец. кучу для строк, где хранить их по ID. Кстати, Губанов, кажется, на такое переходил, когда избавлялся от managed memory в своём софте...
У меня было два сорта строк: постоянные и временные. Постоянную строку нельзя удалить, зато они внутре суть указатели указывающие на уникальное и неповторимое содержимое (при попытке создать ещё одну строку с уже существующим содержимым возвращается указатель на старое содержимое). Но это не имеет отношения к теме, здесь речь про временную строку: создал, поработал, удалил.

Jordan

  • Sr. Member
  • ****
  • Сообщений: 282
    • Просмотр профиля
Re: Делаем строку на O7
« Ответ #33 : Октябрь 15, 2013, 02:49:22 pm »
А вообще если отвлечься. Становится даже грустно. То, что на с++, питоны, джавы, руби делается двумя строками, да те самые контейнеры. На оберон языках нужно, рвать и метать... ???

В плане того, что О7 - пониженного уровня язык, я говорил, поэтому я не доказываю, что с ним в типовых задачах всё замечательно.
Но хочу заметить, что часто проблемы надумываются, пока не решается конкретная задача. Если сидеть и думать "А как же я буду делать вот это, если оно мне понадобится", то голову сломаешь. А когда есть конкретный контекст, конкретные требования - то и вырабатываются решения. Которые потом иногда обобщаются.

Можно обобщить, но только в динамике. Как сейчас делают в си и паскале, через union или record case(Данные алгоритмы могут быть использованы только в реализуемом проекте). И только потому, что бы не копипастить. Мне кажется это высокоуровневый хак.

kkkk

  • Full Member
  • ***
  • Сообщений: 135
    • Просмотр профиля
Re: Делаем строку на O7
« Ответ #34 : Ноябрь 08, 2013, 08:09:47 am »
Стоп. А как отсутствие массивов с размером неизвестным на этапе компиляции облегчает влезабельность в микроконтроллер?
Если почитать всякие рекомендации по написанию программ для встраиваемых устройств, например, промышленный стандарт MISRA C, то там Вы можете обнаружить (обязательное/рекомендационное) требование - не использовать динамическое выделение памяти, а значит прощай и динамические массивы. Оберон не настолько суров, но очевидно сделал шаг в этом направлении.

kkkk

  • Full Member
  • ***
  • Сообщений: 135
    • Просмотр профиля
Re: Делаем строку на O7
« Ответ #35 : Ноябрь 08, 2013, 08:18:18 am »
Ну я и пошел от конкретного контекста - что в компиляторе уже сейчас можно переписать на O7. И сразу уперся в строки, потому что они везде :)
Для компилятора, особенно Оберона, не нужны строки с произвольным доступом. Да и учитывая контекст задачи, её можно реализовать с такими накладными расходами по памяти, которые  недостижимы при использовании отдельных динамических строк. Просто не нужно пытаться делать обобщённое решение, в данном случае Оберон 07 к этому не располагает.

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Делаем строку на O7
« Ответ #36 : Ноябрь 08, 2013, 08:36:46 am »
Стоп. А как отсутствие массивов с размером неизвестным на этапе компиляции облегчает влезабельность в микроконтроллер?
Если почитать всякие рекомендации по написанию программ для встраиваемых устройств, например, промышленный стандарт MISRA C, то там Вы можете обнаружить (обязательное/рекомендационное) требование - не использовать динамическое выделение памяти, а значит прощай и динамические массивы. Оберон не настолько суров, но очевидно сделал шаг в этом направлении.
Я это и сам практикую когда под микроконтроллеры пишу - динамическое выделение памяти там вовсе ни к чему. Тем более что в Си прям таки в языке нет средств для этого :-) (есть в стандартной либе).

Но если бы это был шаг в ту сторону, то прежде всего нужно было бы запретить в Обероне NEW вообще (перетащить его в SYSTEM или в другой псевдомодуль). Убирание лишь одной разновидности NEW никак не избавляет от кучи. И не упрощает работу менеджера памяти.

Кроме того, чтобы при этом жилось таки легче, нужно было сделать возможность создания массивов на стеке длиной неизвестной на этапе компиляции. Как это сделано в С99, и как это сделано расширизмом в Astrobe.

То есть этот момент в Обероне сейчас явно как-то не доработан. Повсему выходит, что Оберон (если не менять основы языка) нужно расширять несколькими опциональными стандартными псевдомодулями, вынося туда тот же NEW например. Будет Oberon report и у нему несколько Annex'ов для разных применений.
Y = λf.(λx.f (x x)) (λx.f (x x))

kkkk

  • Full Member
  • ***
  • Сообщений: 135
    • Просмотр профиля
Re: Делаем строку на O7
« Ответ #37 : Ноябрь 08, 2013, 08:56:31 am »
Цитировать
Убирание лишь одной разновидности NEW никак не избавляет от кучи. И не упрощает работу менеджера памяти.
Не могу судить однозначно, зависит от реализации, но по-моему упрощает, ибо все динамически выделенные штуки имеют постоянный размер, их можно проще складировать/замещать друг другом.

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Делаем строку на O7
« Ответ #38 : Ноябрь 08, 2013, 09:40:53 am »
Цитировать
Убирание лишь одной разновидности NEW никак не избавляет от кучи. И не упрощает работу менеджера памяти.
Не могу судить однозначно, зависит от реализации, но по-моему упрощает, ибо все динамически выделенные штуки имеют постоянный размер, их можно проще складировать/замещать друг другом.

Ну, про это я уже писал: http://oberspace.dyndns.org/index.php/topic,552.msg18360.html#msg18360

Менеджер памяти ничего не знает о множестве типов (и их размеров соответственно) которыми будет оперировать данный конкретный модуль или совокупность модулей. Так что он в любом случае должен быть готов ко всему. Упрощения тут нет.
Y = λf.(λx.f (x x)) (λx.f (x x))

kkkk

  • Full Member
  • ***
  • Сообщений: 135
    • Просмотр профиля
Re: Делаем строку на O7
« Ответ #39 : Ноябрь 08, 2013, 10:00:12 am »
Это всё на уровне кажется. Я и писал, что не могу судить однозначно, но очевидно дополнительное свойство, а насколько оно полезно, можно будет сказать, помахав кувалдой да посозерцав за полученным.

adva

  • Sr. Member
  • ****
  • Сообщений: 385
    • Просмотр профиля
Re: Делаем строку на O7
« Ответ #40 : Ноябрь 10, 2013, 02:41:58 am »
Подскажите, пожалуйста, а LEN(v, ind) для массивов, чего возвращает, константную длину массива, или количество заполненных значений? Если второе, то можно наверное было бы использовать для создания строки ARRAY 10, 10, 10 ... OF CHAR? Хотя не знаю, был бы выигрыш тут, или нет

adva

  • Sr. Member
  • ****
  • Сообщений: 385
    • Просмотр профиля
Re: Делаем строку на O7
« Ответ #41 : Ноябрь 10, 2013, 02:58:59 am »
Хотя вижу, что возвращает 10, а если как нибудь нулевыми символами забить, или в массивах другой принцип?

kkkk

  • Full Member
  • ***
  • Сообщений: 135
    • Просмотр профиля
Re: Делаем строку на O7
« Ответ #42 : Ноябрь 10, 2013, 10:13:49 am »
Для любых массивов, хоть литерных, хоть каких-либо других LEN должна вернуть длину массива, а не строки.

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Делаем строку на O7
« Ответ #43 : Март 15, 2014, 05:19:34 am »
Вот что получилось в oberonjs:
https://github.com/vladfolts/oberonjs/wiki/eberon-strings
Критикуйте :)

Jordan

  • Sr. Member
  • ****
  • Сообщений: 282
    • Просмотр профиля
Re: Делаем строку на O7
« Ответ #44 : Март 15, 2014, 02:47:43 pm »
Вот что получилось в oberonjs:
https://github.com/vladfolts/oberonjs/wiki/eberon-strings
Критикуйте :)

Что критиковать? Отличная работа, теперь в языке нормальные строки, которые должны быть.
Как дела обстоят с юникодом? Будет отдельный тип вроде WSTRING, или при компиляции можно выбрать, считать STRING unicod'ом?

Во free pascal'е 2 вариант, есть ключ компиляции, который string заменяет на wstring. Исходники переделывать не нужно. По умолчанию utf8. Как мне кажется, лучше сделать по умолчанию utf32, а уже в зависимости от системы, внутренние функции будут конвертировать в системную кодировку. К примеру в windows utf16, в linux utf8.