LINUX.ORG.RU

Qod. Опубликовал исходники компилятора, над которым работаю

 , qod, ,


2

5

Финально определился с названием языка, подчистил разные хвосты и написал README. Теперь наконец-то можно посмотреть на нечто большее, чем просто фрагменты кода в постах на форуме: https://github.com/wandrien/qod/

Драфты по дизайну языка пока еще не готовы. Если перед НГ завала работы не будет, то может выложу их в течение пары недель. Черновики пишу на русском, осилить всё чётко сформулировать на английском в разумные сроки я точно не смогу. На русском-то не всегда получается.

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

А пока можно посмотреть на сам код вживую.

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

Планирую сделать break и exit отдельными операторами:

break; // Прерывает самый внутренний цикл
break имя; // Прерывает указанный цикл. Если метка не соответствует циклу - ошибка.
exit имя; // Прерывает указанный блок, который не является циклом. Если метка соответствует циклу - ошибка.
wandrien ★★
() автор топика
Ответ на: комментарий от wandrien

не обратил внимания что параметр шаблона - целое.

можно тогда писать

my_template with (параметры шаблона) (параметры инстанциированного обьекта)

в данном случае

foo(10) - вызов варианта функции с шаблонным параметром 0 и параметром 10.

foo with (10) - просто функция с шаблонным параметром 10
foo with (10)(10) - вызов функции с шаблонным параметром 10 и параметром 10.

короче придумай любое ключевое слово для префикса списка параметров шаблона

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

И потом у вас все будут писать:

when x > 0: begin
  A();
  B(x);
  C(y);
end;

И чем это от if отличаться? Блоки в языке должны быть полюбому, хотя бы для RAII.

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

И потом у вас все будут писать:

Писать на брейнфаке можно на любом языке.

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

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

Блоки в языке должны быть полюбому, хотя бы для RAII.

Это, кстати, далеко не «полюбому». Автоматический деструктор плохо ложится на линейные типы, например.

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

записывать операторы более надёжно

Откуда появляется надёжность от альтернативного синтаксиса if? Про надёжность от borrow checker в Rust понимаю. Про надёжность альтернативного синтаксиса if не понимаю. Грабли на пустом месте.

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

Даже для RAII по типу оператора defer нужны блоки кода.

Это автоматический деструктор на костылях и в профиль.

Смысл линейного типа, что ты не можешь деть его экземпляр «никуда», ты его должен разрушить строго один раз.

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

ты его должен разрушить строго один раз.

Как вы представляете компилятор будет это проверять? Особенно с учётом наличия указателей.

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

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

Это решается через обязательные скобки

Отлично. У меня как раз их есть:

if foo() then
   if a < b then
     x = 0;
   end
else
   printf("Как вы там, потомки, решили проблему висячего else?\n");
end

А теперь более кратко:

if foo() then
   when a < b:
     x = 0;
else
   printf("Как вы там, потомки, решили проблему висячего else?\n");
end

Непонятно, откуда столько негодования, будто вам ключевое слово на ногу наступило.

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

Как вы представляете компилятор будет это проверять? Особенно с учётом наличия указателей.

Читайте, образовывайтесь, изучайте передовую литературу.

Был вы вопрос без претензии задан, я бы ответил. А так – гугл в помощь.

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

А теперь более кратко:

ЗАЧЕМ??? Так сложно написать end? Решительно не понимаю. Такое чувство что у вас появилась глубокая травма от того, что долго разбирались почему не работает код из-за того что else относился не к тому if.

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

Такое чувство что у вас появилась глубокая травма от того, что долго разбирались почему не работает код из-за того что else относился не к тому if.

Зря я тебя когда-то из игнора вытащил. Общаться прилично ты так и не научился.

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

ЗАЧЕМ???

За тем

bool T_Equal(word T1, T2)
	when T1 >= nDict:
		StopInternal(__FILE__, __LINE__);

	when Dict[T1].Class != cTYPE:
		StopInternal(__FILE__, __LINE__);

	when T2 >= nDict:
		StopInternal(__FILE__, __LINE__);

	when Dict[T2].Class != cTYPE:
		StopInternal(__FILE__, __LINE__);

	when T1 == T2:
		return true;

	if Dict[T1].Sub == Dict[T2].Sub then
		select
		case Dict[T1].Sub == sBASE_UINT | Dict[T1].Sub == sBASE_SINT:
			when Dict[T1].TypeSize == Dict[T2].TypeSize:
				return true;
		end:select
	end:if

	return false;
end

За тем

void DictAddToNamespace(word P; word pNamespace)
	when P >= nDict:
		StopInternal(__FILE__, __LINE__);
	when Dict[P].pNamespace != nDICT:
		StopInternal(__FILE__, __LINE__);
	when Dict[P].pNext != nDICT:
		StopInternal(__FILE__, __LINE__);
	when Dict[pNamespace].pFirst != nDICT & Dict[pNamespace].pLast == nDICT:
		StopInternal(__FILE__, __LINE__);
	when Dict[pNamespace].pFirst == nDICT & Dict[pNamespace].pLast != nDICT:
		StopInternal(__FILE__, __LINE__);
	/* FIXME: когда глобальное пространство имён будет реализовано отдельным объектом namespace, убрать этот return */
	when pNamespace == nDICT:
		return;
	when pNamespace >= nDict:
		StopInternal(__FILE__, __LINE__);

	Dict[P].pNamespace = pNamespace;
	if Dict[pNamespace].pLast < nDICT then
		Dict[Dict[pNamespace].pLast].pNext = P;
		Dict[pNamespace].pLast = P;
	else
		Dict[pNamespace].pFirst = P;
		Dict[pNamespace].pLast = P;
	end:if
end

И за этим

bool T_IsFuctTypesIdentical(word T1; word T2)
	when T1 >= nDict:
		StopInternal(__FILE__, __LINE__);

	when T2 >= nDict:
		StopInternal(__FILE__, __LINE__);

	when T1 == T2:
		return true;

	when !((Dict[T1].Class == cTYPE & Dict[T1].Sub == sFUNCTYPE) | (Dict[T1].Class == cFUNC)):
		return false;

	when !((Dict[T2].Class == cTYPE & Dict[T2].Sub == sFUNCTYPE) | (Dict[T2].Class == cFUNC)):
		return false;

	when Dict[T1].pType != Dict[T2].pType:
		return false;

	word pARGS1 = FindInNamespace("args", T1);
	word pARGS2 = FindInNamespace("args", T2);
	when pARGS1 >= nDICT | pARGS2 >= nDICT:
		StopInternal(__FILE__, __LINE__);

	word P1 = Dict[pARGS1].pFirst;
	word P2 = Dict[pARGS2].pFirst;
	forever do
		when P1 == nDICT & P2 == nDICT:
			return true;

		when P1 == nDICT & P2 != nDICT:
			exit;
		when P1 != nDICT & P2 == nDICT:
			exit;
		when Dict[P1].pType != Dict[P2].pType:
			exit;

		P1 = Dict[P1].pNext;
		P2 = Dict[P2].pNext;
	end:forever

	return false;
end

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

у utf8 много парных для скобок

Тебе Agda мало? К ней идёт режим ввода для Emacs, и на ней адекватно можно писать только в этом самом Emacs как раз из-за юникодного синтаксиса.

hateyoufeel ★★★★★
()
Ответ на: комментарий от wandrien
when P1 == nDICT & P2 == nDICT:
			return true;

when P1 == nDICT & P2 != nDICT:
			exit;
when P1 != nDICT & P2 == nDICT:
			exit;

тут 6 сравнений вместо двух. со всеми вытекающими. от эффективности кода, до читаемости и потенциала к ошибкам.

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

до читаемости и потенциала к ошибкам.

Да, вот так должно выглядеть:

forever do
  when P1 == nDICT & P2 == nDICT:
    return true;

  when P1 == nDICT:
    return false;
  when P2 == nDICT:
    return false;
  when Dict[P1].pType != Dict[P2].pType:
    return false;

  P1 = Dict[P1].pNext;
  P2 = Dict[P2].pNext;
end:forever

от эффективности кода

А вот это буллшит.

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

Вот кстати, фишка. Допустим я убрал return false в самом конце, но забыл заменить один из exit на return false:

	word P1 = Dict[pARGS1].pFirst;
	word P2 = Dict[pARGS2].pFirst;
	forever do
		when P1 == nDICT & P2 == nDICT:
			return true;

		when P1 == nDICT:
			return false;
		when P2 == nDICT:
			return false;
		when !T_Equal(Dict[P1].pType, Dict[P2].pType):
			exit;

		P1 = Dict[P1].pNext;
		P2 = Dict[P2].pNext;
	end:forever
end

Получаем ошибку компиляции:

ошибка: Функция должна возвращать значение
wandrien ★★
() автор топика
Ответ на: комментарий от qulinxao3

входной алфавит языка обрыдлый ascii7 ?

И это правильно. Ни один язык из условного TOP-10 не подвязывает свой синтаксис на что-то внешнее по отношению к ASCII-7, а если подобное и есть, то оно там сильно опционально.

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

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

Такое чувство что у вас появилась глубокая травма от того, что долго разбирались почему не работает код из-за того что else относился не к тому if.

Явное лучше неявного. Например, синтаксис C и C++ пестрит такой огромной кучей неявностей и неопределённостей, что многие крупные IT-компании составляют собственные километровые «coding conventions» мануалы, чтобы избежать типичных ошибок, которые были набиты полувековым опытом программирования на этих языках.

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

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

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

Я не понимаю какую проблему тут пытаются решить. Сократить чтобы не писать end?

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

Я не понимаю какую проблему тут пытаются решить.

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

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

Это, кстати, далеко не «полюбому». Автоматический деструктор плохо ложится на линейные типы, например.

Для линейных типов автоматический деструктор не нужен по определению. Но у тебя же не одни лишь линейные типы в языке?

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

Читабельно-то как…

	if P >= nDict then
		StopInternal(__FILE__, __LINE__);
	end
	if Dict[P].pNamespace != nDICT then
		StopInternal(__FILE__, __LINE__);
	end
	if Dict[P].pNext != nDICT then
		StopInternal(__FILE__, __LINE__);
	end
	if Dict[pNamespace].pFirst != nDICT & Dict[pNamespace].pLast == nDICT then
		StopInternal(__FILE__, __LINE__);
	end
	if Dict[pNamespace].pFirst == nDICT & Dict[pNamespace].pLast != nDICT then
		StopInternal(__FILE__, __LINE__);
	end
wandrien ★★
() автор топика
Ответ на: комментарий от X512

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

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

Если я вдруг захочу «показать класс», как я могу писать рабочий код из говна и палок, я всегда могу взять GAS.

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

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

Я просто не поникаю в чём трудность писать end после каждого if и что там трудночитаемого. Не понимает мой разум этого и всё. Видимо это вопрос личных привычек и предпочтений.

Если его так лень писать, то есть шаблоны кода в IDE по сочетаниям клавиш.

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

ширшее алфавит лаконичный длинные(информативные) идентификаторы

плотнее код при

E=mc 2 

латех не помню(знаю) так что широкий алфавит позволяет выбором поднабора занавать синтаксис подобно colorforth где цвет значим - а при печати в книге чб было выбрано курсивно жирность подчёрк для эмуляции

как в старых не очень средах служебные жырные

так что знания алфавита в 1024 разных символа полезно если весь коллектив - в конце та концов интегралы и прочие наблы

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

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

В частности, к этому случаю относится типовая ошибка после копипаста, которая порой может оставаться незамеченной годами, а ля:

a.x = b.x;
a.y = b.y;
a.z = b.x;

Так вот в примере выше мозг видит прежде всего это:

if
end
if
end
if
end

А должен бы - это:

when
  StopInternal
when
  StopInternal
when
  StopInternal
when
  StopInternal
wandrien ★★
() автор топика