LINUX.ORG.RU

Написание собственного высокоуровневого ЯП

 , ,


0

2

Привет, ЛОР. В очередной раз в голову приходят идеи по созданию своего ЯП (но я не открываю), однако в этот раз, кажется, я придумал что-то более-менее стоящее, чем и хочу поделиться.

Собственно, наткнулся я на функционально-распределенные Erlang и Elixir, и это оказались реально крутые языки. Однако мне кажется, что я смогу лучше - а если не получится лучше, то только прибавится уважение к тому, что есть, то есть везде одни плюсы.

Собственно, как с наименьшими потерями написать высокоуровневый язык? Я посмотрел на LLVM, QBE, FASM, GNU Assembler и другие крутые, продуманные вещи. И понял, что всё не то. После долгого поиска я задался правильным (на мой взгляд) вопросом - а на каком уровне абстракции ПО происходит вся высокоуровневая магия? И понял - уровень абстракции, интересующий меня - это уровень системных вызовов. Структура исполняемого файла, кодировка машинных инструкций, экспорт символов и релокации - это всё мне не интересно, интересна сама манипуляция данными, без раскуривания мануалов по AMD64 ISA. А с помощью какого инструмента проще, естественней всего взаимодействовать с системными вызовами? Да с помощью того, на котором и под который они были написаны - язык Си.

Итак, почему не генерить код на языке Си, а потом кормить компилятору? Как минимум, потому что хоть в Си и нет рантайма (параллельно запущенной системы, выполняющей служебные функции, например сборщик мусора), есть его подобие - стандартная библиотека. В ней аллокатор, в ней многопоточность, в ней много всего того, чего я бы хотел переписать по-своему. Так вот, почему не выдернуть с корнями libc и не написать свою, со стандартами Си не совместимую? Таким образом получаем полный контроль над системными вызовами, без нужды париться о низкоуровневых вещах и переносимости - язык Си всё делает за нас.

Вопрос - какие подводные камни? Насколько будут Си компиляторы терпеть мою LibC, функций стандартов Си не реализующую? И как бы вы подошли/уже подходили к задаче написания высокоуровневого ЯП?

Ответ на: комментарий от LINUX-ORG-RU

в haskell к примеру амперсант как знак связывания был бы вобще бомба, с их политикой об якобы отсутствии переменных. это было бы лучше

 x&z 
чем сейчас у них

x=y там то они как раз и пытались сказать что типа x=z икс равен зет, типа мы не присваиваем, так как у нас нет переменных. ну икс не равен зет выше вы были правы в этом. поэтому лучше было бы их связать хаскелистам.

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

Отвечаю на удалённое.

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

& не указатель, а ссылка & это не ссылка, это оператор операции излечения указателя по адресу которого начинается значение.

int   a = 5; 
int * b = &a; /*указатель тут "b", а не "a", ссылок тут вообще нету =) */

a&&b

&& занято логическим умножением в предиканте условного выражения if (a==3 && b==4) c=5;.

x&z

& занято, унарная логическая операция.

Теперь на новое

а<-b

Это, как вариант пойдёт, хотя бы ничего не ломает, но я читаю как b указывает/ссылается на a, но ведь логичнее с лева на право? Тогда -> но оно затято. Всё остальное ломает уже существующее. Эх ладно, мысль твою я понял, но вот реализация идеи идёт перебором :(

В целом, если хочется свой синтаксис то хорошо, это нормально, языков много и у каждого создателя языка своё видение как правильно. Ну так вот, но свой язык писать дело неблагодарное и бесполезное, но если хочется именно более приятный для себя и логичный синтаксис берёшь и пишешь препроцессор или парсер который просто будет заменять/транслировать из твоего синтаксиса в родной используемому языку и всё. И нет проблем. Мне вот в lua захотелось != вместо ~= делов на 5 строчек написать транслятор и красота. Так что возьми составь себе ТЗ и всё там остальное опиши концепт и видение и напиши транслятор с твоего синтаксиса в любой другой и всё, проблема решена! =))))))))) И ты доволен и ничего не сломалось и ничего нового придумывать не надо.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от Assembler

Не, я никого не оправдываю и коллег у меня нету ))) Я не программист. == я принял как данность, а контекст происходящего как условность выраженную банальным ограничением количества печатных не буквенных символов на клавиатуре с помощью которых люди кое как по разному, но в целом одинаково пытались упихнуть идеи и операции скрывающимися за ними. Ты так же можешь не просто хотеть заменить == на = а реализовать это или даже быть может найти язык в котором всё так и есть как ты хочешь. В этом нет ничего плохого и я с тобой не ругаюсь. И наверное надо было уточнить сразу я отвечал в контексте уже существующих языков и новых перенимающих синтаксис существующих в частности Си подобный.

С некоторыми вещами часто приходится просто мирится, но если есть силы, желание, время и прочее то… Так и рождаются новые языки которые делают всё тоже самое, но выглядят по другому часто плюс пару своих уникальных штук из коробки которые в других языках реализуются не не уровне синтаксиса, а на уровне реализации штуки. Вон частоя ругаются что воооот в вашей Сишке ничего нету, ну так, ниша то какая самая важная (несмотря на то что си универсальный и подходит для любых задач), а то чего нету реализуют на нём самом, порой не явно, а косвенно например вещи требующие взаимодействия с операционной системой и подобное, но всё же.

Эх ладно. Садись и пиши спеку для своего синтаксиса, а потом транслятор с него в другой язык или найди тот язык который подходит под твои требования и всё =) Повторяюсь уже конечно…

А то что есть, ну вот так оно есть что поделать :( Где то приходится просто учить и принимать всё как есть, а где то можно позволить себе сделать по своему. Так и живём.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

А знак присвоения ты тогда как сделаешь, через ==? Ведь = будет занято.

А в чем проблема? Паскаль, где := уже упоминали. Где-то видел еще вариант с<-

Опять же выражения типа x=f(y) икс равно эфь оть игрек

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

P.S. А вместо ещё используется a!=b

Вот это косяк, да. ТСу надо будет это учесть.

P.P.S. А так я понять чисто по человечески тебя могу, меня вот откровенно тошнить от фичи python в виде принудительных отступов, ну вот бесят они меня, ну вот не могу я такое терпеть.

Искренне поддерживаю!

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

Вот с указателями в Си не очень-то хорошо получилось. * это и умножение, и объявление указателя, и разыменование.

С другой стороны, нужны ли для ЯВУ вообще указатели? Тот же Питон вон прекрасно без них обходится, Lua и Bash тоже.

Сввяжем, а извлечь/разыменовывать указатель то теперь каким символом?

Дык ptr[0] :-)

Ладно, допустим что делать с «факториалом» != и с ещё десятками и десятками несхождений с математикой и интуитивностью?

Возвращаясь к Паскалю, там неравенство записывается как <>. Не сказать чтобы сильно интуитивнее…

COKPOWEHEU
()
Ответ на: комментарий от LINUX-ORG-RU

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

Эм-м-м… @Assembler и ТС @lostghost1 это, наверное, разные люди. Или @Assembler тоже хочет свой язык написать?

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

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

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

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Мысль у меня была одна, == лишь капля в море =)

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

=

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

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

амперсант похож на узел

Одна международная корпорация с давних пор любит этот значок

&TRACE
&ERROR &EXIT &RETCODE
&TYPE Enter three numbers you want to add:
&READ ARGS
&IF &N = 3 &GOTO -ADDNUMS
&TYPE You must enter three numbers
&READ ARGS
&IF &N = 3 &GOTO -ADDNUMS
&GOTO -ERROR
-ADDNUMS
&TYPE1  = &DATATYPE OF &1
&TYPE2  = &DATATYPE OF &2
&TYPE3  = &DATATYPE OF &3
&IF &TYPE1 NE NUM &GOTO -ERROR
&IF &TYPE2 NE NUM &GOTO -ERROR
&IF &TYPE3 NE NUM &GOTO -ERROR
&SUM = &1 + &2 + &3
&TYPE The sum of  &1  &2  and  &3  is  &SUM
&EXIT
-ERROR
&TYPE You did not enter three valid items.  This program is ending.
&EXIT
vM ★★
()
Ответ на: комментарий от Assembler

это не ТСу надо учесть, а тем кто утверждает стандарты!

Стандартизаторов Си все устраивает. А те, кого не устраивает, пользуются / пишут другие языки. Вот и получается, что надо это вам с ТСом.

не равно уже давно обозначили /=

Это не неравенство, а деление a /= 10; оно же a = a / 10;

Можно, конечно, =/= написать, но для такой частой операции три символа уже перебор.

все сразу не сделаешь и все в один момент не поправишь. но стараться и пытаться надо.

И как, у вас уже есть план по исправлению? Когда новый язык от вас ждать?

COKPOWEHEU
()

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

ИМХО много «интересного», но мне «ближе» разработка «нужного».

Ныне вот в freetype и SDL:
 - добавляю новое API;

 - убрал из SDL исходники из директории libm, так как она теперь может использовать исходники из uClibc-0.9.33.2\libm (в которые добавил API, для использования функций с типом аргумента float);

 - унифицирую названия типов данных.
   Многие проекты для обеспечения кроссплатформенности всегда содержат
   *.h, в котором для разных платформ и ЯП с использованием макросов
   задают названия типов, которые затем используют в проекте.
   Необходимость в этом возникает из-за того, что в разных платформах и ЯП их название отличаются.

   ИМХО так как нет унифицированного подхода к использованию названий типов данных в кроссплатформенных проектах, то все они используют разные названия.

   Вот этот бардак и устраняю всегда (в частностости в freetype и     
 SDL)

 - много чего полезного делается;

 - ...

Когда нибудь исходники этих проектов опубликую.
Ныне нет смысла, так как они в «работе».
Никому 100% не понравится, что в новых релизах многое изменено и несовместимо с предыдущими,

 ИМХО нужной и более того, необходимой работы МНОГО.

Впрочем это все «теория», а на практике лишь 0.005% что-то полезное и разрабатывает для open source.

У остальных весьма уважительные причины ничего не делать, так как они «ЗАНЯТЫ».

Весь open souerce именно таков.

 0.005% разработчиков и 99.995% флудящих, "ратующих" и "бьющих себя в грудь", что open source это ХОРОШО и НУЖНО.

Шутка

Улыбнуло обсуждение приемлемого синтаксиса для присваивания значений.
Требую эшо «новаций».

Forum0888
()
Последнее исправление: Forum0888 (всего исправлений: 3)
Ответ на: комментарий от Forum0888

Из трёх возможных обозначений импликации ⇒ → ⊃ можно оставить только одно, к тому же в современном программировании импликация используется не так уж часто.

Тогда ⇒ освободится для обозначения преобразования данных.

vM ★★
()
Ответ на: удаленный комментарий

Определение данных в секции .text не соответствует стандарту и может вызвать проблемы при работе с программой.

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

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

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

конструируя новый автомобиль вы там принялись спорить о его цвете.

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

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

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

вот что неправильно в сишной грамматике, это разыменование. то что у них разыменование идет ДО разыменуемого выражения приводит к к тому, что нужно вводить еще значок -> как селектор поля структуры -> . если бы они ставили разыменование ПОСЛЕ выражения, по паскалевскому типу, то все выглядело бы куда изящней.

сравниваем:

паскаль:
ptr^
ptr^.field

си

*ptr
(*ptr).field
ptr->field

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

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

вы уже понаделали «нормально» такую дичь выдумать чтоб надо год курить наркоту. и ведь главное что? да то что почти все знаки что используются в ЯП имеют одинаковое значение... это говорит что коллективный разум разработчиков ЯП просто тупо копировал, не имея сил и фантазии для чего то нового.

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

а коллективный разум тех кто выписывает стандарты просто боиться обнаружить свою некомпетентность и поэтому тупо утверждает любую дичь. благо что она не разнообразна и монотонна из за узости разработчиков ЯП.

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

В ЯП 1С символ «=» используется и для присвоения и для сравнения.
Что касаемо C или C++, то в нем компилятор целиком доверяет программисту.
Например:
if ( iVp01 = 1 ) {
if ( iVp01 == 1 ) {
являются синтаксически верными.

Извиняюсь за повтор суждения, которое в других тредах уже постил.br]

Никто и никогда с использованием грамматик не сумеет разработать ЯП высокого уровня с простым синтаксисом.

Forum0888
()
Последнее исправление: Forum0888 (всего исправлений: 3)
Ответ на: комментарий от Forum0888

Что касаемо C или C++, то в нем компилятор целиком доверяет программисту.

Компиляторы нынче умные пошли:

$ cat main.c
#include <stdio.h>

int main(){
  int iVp01 = 0;
  if( iVp01 = 1 ){}
  if( iVp01 == 1 ){}
}
$ gcc main.c -Wall
main.c: In function ‘main’:
main.c:5:7: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
    5 |   if( iVp01 = 1 ){}

Если программист действительно хочет выстрелить себе в ногу, придется добавить скобок: if( (iVp01 = 1) ){}

COKPOWEHEU
()

Многие комриляторы Си умеют компилировать код без использования стандартной библиотеки. Можешь посмотреть на osdev.org, обычно таким интересуются разработчики ОС. Если кратко, то -ffreestanding -fnostdlib для GCC.

Проблема в том, что в какой-то момент ты захочешь использовать библиотеки.

Например, то же окошко вывести, наверняка хочется обмазаться gtk/qt, либо на худой конец xcb/xlib/wayland. OpenGL/Vulkan может хотеться использовать. Это то что с нуля писать прям ужасная идея, ибо эти библиотеки является мостами к другим системным компонентам за которые ты не отвечаешь (и юзер не будет ставить твой графический сервер, твою DE и т. д.) и ты не будешь поспевать за их обновлениями.

Также ты вряд ли хочешь становиться экспертом по всему и писать с нуля zlib, libjpeg и тонну других библиотек. Поверь, тебе хватит самодельных ассоциативных контейнеров, которые придёт разработать для стандартной библиотеки.

То есть любой уважающий себя язык должен иметь возможность вызова сишных либ. В Java есть JNI, в некоторых других языках это называют FFI, но суть одна. А для того, чтобы это всё работало, часть функций libc таки придётся использовать. Как минимум, чтобы у тебя есть у вызываемой либы был один и тот же аллокатор памяти и т. п. При этом ничто не мешает иметь две кучи - одну выделить одним огромным mmap и извращаться там со своими сборками мусора, а в другой выделять сишными malloc/free и использовать для общения с сишным кодом. Так что freestanding вне разработки ядер ОС сомнителен.

Сама же идея компилировать в Си не нова. Например, Vala. Из истории можно вспомнить, что первый компилятор C++ транслировал их в C.

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

Поэтому сейчас популярнее использовать LLVM.

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

А в чем проблема? Паскаль, где := уже упоминали. Где-то видел еще вариант с<-

Так Хаскелл же. Для операций, где нужно именно чтение значения.

do
   a <- readLine
   b <- readLine
monk ★★★★★
()