LINUX.ORG.RU

Pattern matching на чистом Си

 


0

2

Попробовал сделать алгебраический тип данных и pattern matching на чистом C без плюсов, как оказалось, это таки довольно просто: https://ideone.com/y3LQKb

Есть предложения, что можно здесь изменить/улучшить?

Можно ли совместить его с ООП? Видимо, тогда вместо enum для определения варианта надо сделать указатель на VMT?

Это нужно для собственного языка, в текущей версии компилятор переводит его в C код.

Ответ на: комментарий от Liz812

When Stroustrup started working in AT&T Bell Labs, he had the problem of analyzing the UNIX kernel with respect to distributed computing.

Но тут написано, что

Когда труп страуса начал работать в AT&T Bell Labs, у него возникла проблема анализа ядра UNIX в контексте распределенных вычислений.

То есть, это не люди в Bell Labs обосрались, а труп старуса ниасилил анализ кода на Си, и высрал Cи с классами.

shkolnick-kun ★★★★★
()
Последнее исправление: shkolnick-kun (всего исправлений: 1)
Ответ на: комментарий от shkolnick-kun

Собственно, это все, что нужно знать о создателях очередных убийц всех остальных ЯП.

shkolnick-kun ★★★★★
()
Ответ на: комментарий от anonymous

[b]Кто-то[/b] и книги [b]по диагонали читает[/b], потом удивляясь: почему Муму написал Чехов, а памятник поставили Пушкину.

Например, вы: Муму написал Тургенев, а не Пушкин.

//чё-то, ЛОРкод сломался, ну и хрен с ним

next_time ★★★★★
()
Последнее исправление: next_time (всего исправлений: 2)
Ответ на: комментарий от anonymous

Мне что, память свою некуда девать, да? До тех, пока пока в справке по ЛОР-коду не поправите, буду писать, как раньше. Чините либо справку, либо ЛОР-код.

next_time ★★★★★
()
Ответ на: комментарий от Laz

В примерах да, но в реализацию лучше не смотреть, водки может не хватить, чтобы потом себя в чувство вернуть.

anonymous
()
Ответ на: комментарий от Laz

Там даже exhaustive matching для std::variant не осилили, а вы про pattern matching на макросах.

RazrFalcon ★★★★★
()
Ответ на: комментарий от Den_Zurin

В том, что ты можешь матчить по значениям членов структуры. Попробуй в C заматчить по строке, например.

hateyoufeel ★★★★★
()
Ответ на: комментарий от anonymous

сложно читать из-за begin-end, значит их там перебор.

Кончайте тупить на пару с Pattern matching на чистом Си (комментарий)

Начало / конец блока - это самая распространённая конструкция на процедурных языках. Если маркировать её 8-ю символами вместо двух, абсолютный объём символов вырастает ровно в 4 (прописью - четыре) раза, а удельная масса этих символов в общем объёме кода начинает достигать 7-10%. Из которых три четверти - семантический мусор.

Добрые 20-30% успеха сишечки в её годы - это замена идиотских многобуквенных слов на спецсимволы.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Да, когда школьником работаешь с лабой, это не имеет никакого значения. Когда скроллишь код третий десяток лет - начинаешь ценить.

LamerOk ★★★★★
()
Ответ на: комментарий от Liz812

дадада. а я «историю развития и создания» помню на личном опыте использования. и имею опыт написания больших проектов на сишечке. так что ваши школоло-познания меня менее всего беспокоят.

Iron_Bug ★★★★★
()
Ответ на: комментарий от Laz

окамель всё равно всех делает ^_^

anonymous
()

как оказалось, это таки довольно просто
*портянка на 285 строк, которая выводит 12 чисел на консоль.

Ух и силушка у сишечки.

ox55ff ★★★★★
()
Ответ на: комментарий от Den_Zurin

Но вот в том же Обероне все-таки не хватает некоторых вещей. Хотелось бы нормальных коллекций (с генериками), лямбд и пресловутого pattern maching’а (кстати, в первом Паскале зачатки алгебраического типа были - записи с вариантами), т.к. все это позволяет писать более короткий и понятный код. И немного подправить синтаксис - убрать наконец эти устаревшие ; из 70-х, сделать блоки фигурными скобками и т.д.

посмотри Аду ada-org.ru, компилятор GNAT. в первом приближении, это модула/оберон/паскаль, сделанный правильно. есть пакеты (и дочерние пакеты), модульность, generic пакеты, богатая система типов. есть исключения, ООП (tagged record) и многопоточность на уровне языка (task с мониторами и рандеву). в Ада2012 есть контракты и SPARK — расширение с доказательным программированием и контрактами.

и синтаксис человекочитаемый.

сделать блоки фигурными скобками и т.д.

странное пожелание. фигурные скобки с шифтом набирать неудобно (хотя есть программерские раскладки). операторные скобки рулят типа if .. elsif .. end if, procedure foo ... begin .. end foo; package x ... end x, type MyObject is tagged record ... end MyObject  — наглядно и человекочитаемо.

и компилятор с бекендом и кодогенератором от GCC, написанный на самой Аде на 95%, а не от каких-то там самозванцев.

единственное что иногда надо рантайм чуть посократить, но есть во-первых, профили рантайма, а во вторых он опять же написан на самой аде, так что это не архисложная задача.

курсы по Аде на гитхабе от AdaCore University

anonymous
()
Ответ на: комментарий от Den_Zurin

Я совершенно не представляю себе, как мы можем удерживать растущие программы в голове, когда из-за своей полнейшей вычурности язык программирования - наш основной инструмент, не так ли! - ускользает из-под контроля нашего интеллекта.

ну тупыыые!!! кстати, про Аду83 Никлаус Вирт похожим образом высказывался. посмотрел, потыкал сначала её потом Аду95, Аду2005 и Аду 2012. ничего подобного не заметил — С++ местами не то чтобы сложнее, скорее громоздче. особенно какой-нибудь С++20.

сложность С++ в том, что он не столько sophisticated (чтобы выразить сложные конструкции просто), сколько compicated (когда не могём выразиться проще и яснее ибо косноязычный говнокод).

ну что вы хочете, когда Ichbian, автор Ады защищал диссер по «синтаксическому анализу языков программирования на удобочитаемость», а Бьярне ниасилил ядро юникса в своём диссере, гы-гы-гы. одним блобом без всяких модулей. поэтому Бьярне взял классы отмоделированные как пакеты в Аде (но ниасилил дочерние) и запихнул свои «модули» в них. и асинхронного нодыжс накрутил поверх, типичный хипстер же.

правда, после С с классами шаблоны типа буста и прочее RTTI с исключениями нифига не влезло.

опять же, тот же Бьярне далее сознаётся что синтаксис сишечки с фигурными скобками в свой диссер прикрутил из маркетинговых соображений.

поэтому когда читаем стандарт С++ от того же Бьярне — он напоминает кулинарную книгу дурацких рецептов с оговорками, типа «тут добавить по вкусу», а вот на эти детские грабли не наступать. ну и есть некоторые реально полезные вещи типа семантики копирования/перемещения, которые опять же неоадепты сразу ниасиливают потому что у них нет опыта к чему это можно применить.

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

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

и хуже всего, что программисты на С++ — каждый третий такие вот неоадепты.

И если мне понадобится описать влияние, которое PL/1 может оказывать на своих пользователей, ближайшее сравнение, которое приходит мне в голову, - это наркотик

С++ это ещё больший наркотик, ога.

С++ — это язык для написания движков. а PL/1 или вот Ада — для написания систем целиком, с асинхронными тасками, модулями, подсистемами, контрактами и функциональными тестами и т.п.

ну правда же, читая исходники того же Multics и его версии Emacs на PL/1, у меня не возникало ощущения того говнокода, который ваяют типичные с++ неоадепты, когда в каждую строчку пытаются запихнуть по три фичи, обёрнутые говношаблонами. наоборот, вроде как все фичи там по месту. и асинхронные таски с мониторами и рандеву тоже.

в аде вот тоже самое (хотя сильно много энтерпрайзного кода пока особо и не видел, так исходники одной ос на аде потыкал веточкой, пока вроде всё разумно).

когда посмотришь на тот говнокод который некоторые неоадепты-ниасиляторы С++ лабают — хочется дать им в руки блокнот и simple english, пускай хоть на эсперанто пишут прописными буквами. лишь бы мысль была ясна. а своей мысли-то у них и нет — так, всего лишь синтаксический мусор и нагромождение фич в каждой строчке.

anonymous
()
Ответ на: комментарий от Den_Zurin

Я помню лекцию в защиту PL/1, прочитанную на симпозиуме по языкам программирования высокого уровня человеком, который представился одним из его преданных пользователей. Но после похвал в адрес PL/1 в течение часа он умудрился попросить добавить к нему около пятидесяти новых «возможностей», не предполагая, что главный источник его проблем кроется в том, что в нем уже и так слишком уж много «возможностей». Выступающий продемонстрировал все неутешительные признаки пагубной привычки, сводящейся к тому, что он впал в состояние умственного застоя и может теперь только просить еще, еще, еще…

очевидно, что этот путь никуда не приведёт (когда там ждуны дождались лямбд в той же java)? а был бы язык модульным, расширяемым, с настраиваемым синтаксисом — так могли бы и сами добавить.

вот например, в guix про самораскрутку:

tl;dr:

These bootstrap binaries can now be re-created by doing

guix build bootstrap-binariesWork started three years ago with a simple LISP-1.5 interpreter.

A year later, Mes 0.5 had become a tiny Scheme interpreter written in simple subset of C that came with a simple C compiler in Scheme. And yes, these were mutual self-hosting.

The next step was to find a path towards compiling Guix’s default GCC (5.5.0). Sadly, bootstrapping GCC compilers has been becoming increasingly difficult over the years. We looked at GCC 1.42: not easy to bootstrap (100,000 LOC) and it depends on Bison. Reluctantly, we started looking for non-GNU alternatives 8cc, pcc, cc500 but finally settled on TinyCC. TinyCC (TCC) can compile GCC (4.7.4) which is currently the most recent release of GCC that can be built without a C++ compiler.

Another year later, Mes 0.13 has grown its own tiny C library and compiles a heavily patched and simplified TCC. This looked very promising and we suggested for TinyCC to help our bootstrapping effort by moving towards a simplified C subset. Instead we were encouraged to make MesCC a full blown C99 compliant compiler. That felt as a setback but it gave us the perspective of removing TCC from the bootstrap later on. Using Nyacc, the amazing parser framework with C99 parser by Matt Wette, has even made that a feasible perspective.

It took only half a year to mature into Mes 0.19 so that building TinyCC (25,000 LOC) now only takes ~8min instead of the initial 5h.

...

Currently, Mes consists of a mutual self-hosting scheme interpreter and C compiler. It also implements a C library. Mes, the scheme interpreter, is written in about 5,000 lines of code of simple C. MesCC, the C compiler, is written in scheme. Together, Mes and MesCC can compile a lightly patched TinyCC that is self-hosting. Using this TinyCC and the Mes C library, it is possible to bootstrap the entire Guix System for i686-linux and x86_64-linux.

tl;dr tl;dr: написали лисп, на котором написали компилятор С, которым собрали tcc, затем gcc, затем guix. сократили время раскрутки на порядки, потому что внезапно, полноценный gcc там и не нужен.

anonymous
()
Ответ на: комментарий от anonymous

можно было бы взять лисп или форт с тем же успехом, и написать компилятор условного паскаля. например в книге Креншоу «Let's make a compiler» так и делается — на форте написан простой компилятор паскаля.

затем на таком недопаскале написать более полноценный, например ту же аду. затем на ней написать всё остальное.

причем синтаксические+семантические фичи языка добавлять постепенно, постепенно расширяя парсер и компилятор на форте, интерактивно тестируя. в первом приближении, хватит и транспилятора паскаля в форт, например выражений в обратную польскую нотацию. затем взять модульность и добавлять фичи помодульно. нужен, правда лучше какой-то модульный форт (например, фактор с функциональщиной) или лисп (например, модульную схему).

или, внезапно, взять например тот же Nim. вполне себе паскаль семантически, но с синтаксисом почему-то питона. при этом транспилируется в си, и далее хвалёный зерокост сишечным компилятором. взять на нём ту же PEG библиотеку, прикрутить на ней парсер своего недопаскаля, транспилировать его в Nim либо в рантайме либо CTFE AST макросами.

в итоге можно получить простыми средствами такой себе расширяемый помодульно недопаскаль, с простым и минимальным рантаймом.

.... потом конечно его придётся выкинуть, потому что полноценный паскаль уже был изобретён неоднократно — тот же Ada + GNAT либо Оберон + компилятор от Васяна и самозванцев.

зато можно получить модульный и расширяемый. и не ждать фич от ждунов, а самому сразу добавить.

anonymous
()

Это нужно для собственного языка, в текущей версии компилятор переводит его в C код.

что за язык?

anonymous
()
Ответ на: комментарий от anonymous

Хотя до этого еще был D

С практически обязательным GC, что отпугивает многих потенциальных пользователей.

ну не совсем. если кто-то сподобится взять и переписать его стандартный рантайм, отвязать массивы, исключения, тайпинфо – может получиться.

но тогда получится нечто типа как в дельфи есть стандартный VCL где окошко с кнопкой 400 кб, а есть KOL где 15 кб и завязано на WinAPI напрямую. кстати, исходники этих рантаймов читать полезно – т.к. видно такую фичу языка дельфи как методы класса, из-за которой сильно можно спрямить иерархию наследования. методы класса компилируются в обычную функцию, невиртуальные методы класса или объекта – тоже в функцию, вирутальные – в функтор через указатель на VMT с дважды косвенной адресацией. поэтому хвалёный зерокост получается для невиртуальных методов класса/объекта, которые компилируются практически в аналогичные обычным функциям код.

так что в D [b]возможно[/b] отстрелить GC, но тогда придётся писать свою реализацию массивов со слайсами, строк, исключений и прочего. чтобы не вызывать лишних аллокаций, из-за которых нужен GC.

где-то была такая библиотека альтернативного рантайма для D в духе дельфи и KOL. со своей реализаций тёплого лампового TArray и прочими коллекциями.

вообще там нужен типа как в аде мемори пул и зональный аллокатор для коллекций.

anonymous
()
Ответ на: комментарий от Den_Zurin

Фигурные скобки четко выделяются на фоне остального кода и позволяют моментально определять начало и конец блока.

конец не позволяют, когда много вложенных скобок. в этом смысле … foo … end foo сразу позволяет видеть, конец этого к какому началу относится.

(напомню, замыканий в Паскале нет).

вроде как в Free Pascal лямбды добавили, а где лямбды, там и замыкания. но да, для практических применений вложенных процедур достаточно.

вообще нужно типа адовских [code]

declare foo:… … begin … end [/code] только не только с переменными, но и с лямбдами. или окамлевский where, let … in … хорош.

anonymous
()
Ответ на: комментарий от anonymous

слава БГ, что на ASM, таких вот «более-менее сложных программ» нет

ты будешь смеяться, но есть :))

вот есть hi level asm. там синтаксис от паскаля, но семантика с++. но ассемблер :))

у них есть свой аналог STL какой-то даже :))

anonymous
()
Ответ на: комментарий от anonymous

очевидно, что этот путь никуда не приведёт (когда там ждуны дождались лямбд в той же java)?

Достали уже, нет в джаве лямбд, то, что там называется лямбдами на самом деле блямбды — замыкания, анонимные функциональные классы, не более!

anonymous
()
15 августа 2021 г.
Ответ на: комментарий от anonymous

Нет, это указание на то, что текущее предписание закончено и не имеет отношение к последующим.

4.2

int x = 0; // оператор закончен
while (x < 10) {
  x++; // оператор закончен
} // оператор while не закончен? что за хуйня тут творится?!
printf("%d\n", x); // оператор закончен
anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.