Skip to content

Comments

Adding Constants#61

Open
Jigokuraku01 wants to merge 6 commits intoGassaFM:masterfrom
Jigokuraku01:master
Open

Adding Constants#61
Jigokuraku01 wants to merge 6 commits intoGassaFM:masterfrom
Jigokuraku01:master

Conversation

@Jigokuraku01
Copy link

No description provided.

@Jigokuraku01
Copy link
Author

Jigokuraku01 commented Apr 6, 2025

На данный момент работает логика создания констант(но не массивов, для них вроде игнорируется)

function main(id, pr, n, a):
    const x := 1
    x := 2
    print(x)

Данный код выведет step 6, id 0, line 3: variable x is constant

В этом случае:

function main(id, pr, n, a):
 const const := 1
 print(const)

const будет расценена как преременная и выведется много единиц

function main(id, pr, n, a):
    const x := 1
    x += 1

Такая ситуация тоже расценивается как ошибка

source/runner.d Outdated
}
state.back.arrays[cur.dest.name] =
Array (new long [values[0].to !(size_t)]);
Array (new long [values[0].to !(size_t)], cur.isConst);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Зачем это? У нас же нет инициализации массива. То есть константный массив может состоять только из нулей. Лучше уж запретить его, пока это так.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ну да, я думал о том, что это немного бесполезно, но всё же запрещать-то зачем? Но хорошо, сейчас добавлю запрет

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Запрещать полезно, когда от этого в среднем меньше багов.

source/parser.d Outdated
while (!t.empty && (t.front.isDigit || t.front == '_'));
}
else if (t.front.isIdent)
else if (t.front.isIdent || t == "const")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ключевое слово лучше проверить до проверки на идентификатор.

{
foreach_reverse(ref curState; state)
{
if(dest.name in curState.vars)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

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

@Jigokuraku01
Copy link
Author

Jigokuraku01 commented Apr 6, 2025

В последнем коммите я сделал 2 основных изменения:
1). Запретил const ar := array(10)
2). Теперь подобные конструкции

x := 1
const x := 3
x := 1
const x := x

Также приводят к ошибке

source/parser.d Outdated
}
while (!t.empty && (t.front.isDigit || t.front == '_'));
}
else if (t.front.isIdent || t == "const")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Так, я понял бОльшую проблему. Что вообще const делает в tokenize? Тут же не разбираются отдельно for и if. Видимо, считается, что они просто isIdent.

Пока нет отдельной сущности "ключевые слова" -- токенайзер трогать не надо =)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Я думал, этот if уже в парсе, а не в tokenize. Не посмотрел на контекст, прошу прощения.

@GassaFM
Copy link
Owner

GassaFM commented Apr 6, 2025

Вообще, мне нравится, как пока что это коротко выглядит.
Из того, чего точно не хватает -- изменения syntax.txt в корне. Неужели их нет?
По-хорошему syntax.txt первичен, а функции в source/parser.d просто реализуют его.

syntax.txt Outdated
<const-decl>

<const-decl> is
const <name> = <expression0>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ну как минимум это точно неправда =) в языке всё ещё нет оператора =

<const-decl> is
const <name> = <expression0>

<assignment> is
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Мы же обсуждали изменение вида

<assignment> is
<variable> <assign-op> <expression0>
+const <variable> <assign-op> <expression0>

Соответственно, тогда понятно, что в parser.d меняется одна функция: parseAssignStatement.
Сейчас в коде так и есть, а в грамматике какой-то дебош вместо этого =)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Честно говоря, я не особо понимаю как работать с подобной грамматикой

syntax.txt Outdated
<constant>
<call>
( <expression0> )
<name>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

неправда, мы <name> разбираем внутри <variable>

@Jigokuraku01
Copy link
Author

Прямо сейчас const в ЯП работает так: Если парсер увидит const, то он уверен, что после него переменная, поэтому всё что дальше подчиняется правилу создания переменных с точностью до имени(имя любое). Поэтому, например, код:

function main(id, pr, n, a):
    const if := 1
    print(if)

Выведет много раз 1 и ошибку не выведет

@GassaFM
Copy link
Owner

GassaFM commented Apr 16, 2025

Прямо сейчас const в ЯП работает так: Если парсер увидит const, то он уверен, что после него переменная, поэтому всё что дальше подчиняется правилу создания переменных с точностью до имени(имя любое).

Да, ключевые слова никак не защищены. Но это отдельная проблема, которую нужно будет отдельно решать. В этом PR-е давай этим не заниматься.

@GassaFM
Copy link
Owner

GassaFM commented Apr 16, 2025

Пока что меня смущает, как вообще всё работает и до, и после изменений:

function solution (id, pr, n, a):
	a := array (const n) ### line 2: expected ,, found: n
	id := 0 ### step 2, id 0, line 3: variable id is constant
	a[0] := 0 ### step 2, id 0, line 4: array a is constant
	a := array (n) ### works?
	a[0] := 0 ### works?

Только строка 2 падает в compile time. Сообщение об ошибке оставляет желать лучшего.

Строки 3 и 4 падают лишь в run time. Действительно ли мы в compile time не можем понять, что они точно упадут? Кажется, что в программе нет путей, когда в контекст попала одна и та же переменная, но разной константности.

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

Но это всё проблемы, которые были и до изменений.

@GassaFM
Copy link
Owner

GassaFM commented Apr 16, 2025

test 1:

function solution (id, pr, n, a):
	x := 0
	const x := 1 ### step 6, id 0, line 3: refidinition of var x to const

Наверное, надо redefinition of variable x as constant, но смысл правильный.

@GassaFM
Copy link
Owner

GassaFM commented Apr 16, 2025

test 2:

function solution (id, pr, n, a):
	const x := 1
	x := 2 ### step 6, id 0, line 3: variable x is constant

Работает.

@GassaFM
Copy link
Owner

GassaFM commented Apr 16, 2025

test 3:

function solution (id, pr, n, a):
	const x := 1
	if id == 0:
		const x := 2 ### step 11, id 0, line 4: variable x is constant

Работает, во внутреннем контексте тоже не создаёт.

@GassaFM
Copy link
Owner

GassaFM commented Apr 16, 2025

test 4:

function solution (id, pr, n, a):
	x := 1
	const y := 1
	x := y
	if id == 0:
		x := x + 1

Работает без проблем: присваивание не переносит константность на x.

@GassaFM
Copy link
Owner

GassaFM commented Apr 16, 2025

test 5:

function solution (id, pr, n, a):
	const b := array (n) ### step 2, id 0, line 2: array: array cannot be const

Писать const или constant -- надо определиться и сделать везде одинаково.
А так работает, нам действительно бессмысленно создавать константные массивы.

@Jigokuraku01
Copy link
Author

Jigokuraku01 commented Apr 16, 2025

Пока что меня смущает, как вообще всё работает и до, и после изменений:

function solution (id, pr, n, a):
	a := array (const n) ### line 2: expected ,, found: n
	id := 0 ### step 2, id 0, line 3: variable id is constant
	a[0] := 0 ### step 2, id 0, line 4: array a is constant
	a := array (n) ### works?
	a[0] := 0 ### works?

Только строка 2 падает в compile time. Сообщение об ошибке оставляет желать лучшего.

Строки 3 и 4 падают лишь в run time. Действительно ли мы в compile time не можем понять, что они точно упадут? Кажется, что в программе нет путей, когда в контекст попала одна и та же переменная, но разной константности.

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

Но это всё проблемы, которые были и до изменений.

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

const ar := array(1)

То будет честная ошибка

@GassaFM
Copy link
Owner

GassaFM commented Apr 16, 2025

test 6:

function solution (id, pr, n, a):
	b := array (n)
	const b[0] := 1
	b[0] := 2

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

@GassaFM
Copy link
Owner

GassaFM commented Apr 16, 2025

test 7:

function solution (id, pr, n, a):
	b := array (n)
	b[0] := (const 1)

Работает, тут const его не интересует, пока нет такого имени, и правильно.
Заодно я понял предыдущее сообщение об ошибке с двумя запятыми.

@GassaFM
Copy link
Owner

GassaFM commented Apr 16, 2025

test 8:

function solution (id, pr, n, a):
	b := array (n)
	const b := 1
	b[0] := 1
	b := 2 ### step 12, id 0, line 5: variable b is constant

Работает: array b и var b в разных пространствах имён и не влияют на константность друг другу.
Ну то есть как работает. Можно было бы проверять, что имени переменной нет в массивах и наоборот.
Но это тема какого-то другого PR. Сейчас это место работает как раньше.

@GassaFM
Copy link
Owner

GassaFM commented Apr 16, 2025

test 9:

function solution (id, pr, n, a):
	x := 1
	x := 2
	const x := 3 ### step 10, id 0, line 4: refidinition of var x to const

Работает (ну только слова надо поправить, но это уже обсуждается выше).

@GassaFM
Copy link
Owner

GassaFM commented Apr 16, 2025

В общем, пока только тест 6 не работает.
Ну и текст надо чуть поправить.

@Jigokuraku01 Jigokuraku01 requested a review from GassaFM December 26, 2025 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants