среда, 27 января 2021 г.

Решил, что нужно всё переделать

 Написал оператор сложения для класса Calculable. Посмотрел, как всё это работает. Добавил возможность использовать в качестве параметра имена констант и переменных.

Получилось вот что:

$ + $ - работает
переменная + переменная - работает
константа + константа - работает

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

2 + 2 - это не работает

Нужно написать

2 - положить значение на стек
$ + 2 - сложить 2+2 и положить результат на стек

При этом, если рассматривать эту программу как калькулятор, то мы ожидаем, что 2 + 3 даст на стеке результат - 5. Но получилось, что на стеке останется 2 и добавится 5.

Работа программы с переменной типа Float

Нормально ли это? - спросил я самого себя.

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

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

Потому что 2 + 2 это либо эквивалентно

2.add(2) => стек

Либо эквивалентно

add(2, 2) => стек

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

2 => стек
стек.add(2) => стек

И поэтому первая двойка как бы и не должна удаляться. Лежит себе на стеке и лежит.

Я понял, в чём причина этой ошибки - в логике обработки ввода.

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

А у меня сделано так: я выделяю объект, применяю метод, который берёт параметры по мере выполнения, и сам кладёт результат на стек.

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

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

Может возникнуть вопрос, в чём именно кривизна. Кривизна в данном случае в адресации объектов на стеке. Допустим, что до выполнения команды мы имеем на стеке число. Его адрес $0. А после выполнения команды его адрес уже $1, а $0 - это адрес результата.

С точки зрения Форта - это нормально. Но с точки зрения читаемости кода это будет просто адский треш:

принтер1
$0 команда1
$1 команда2
$2 команда3

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

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

Подытоживая всё это, я пребываю в размышлениях.

Комментариев нет: