Написал оператор сложения для класса Calculable. Посмотрел, как всё это работает. Добавил возможность использовать в качестве параметра имена констант и переменных.
Получилось вот что:
$ + $ - работает
переменная + переменная - работает
константа + константа - работает
Но при этом стек получился как бы особого рода переменной. Например, нельзя написать
2 + 2 - это не работает
Нужно написать
2 - положить значение на стек
$ + 2 - сложить 2+2 и положить результат на стек
При этом, если рассматривать эту программу как калькулятор, то мы ожидаем, что 2 + 3 даст на стеке результат - 5. Но получилось, что на стеке останется 2 и добавится 5.
Нормально ли это? - спросил я самого себя.
Теоретически так и должно быть. Но на практике после каждой операции нужно будет добавлять удаление первого параметра со стека.
Возникает вопрос, а почему первый параметр должен удаляться со стека.
Потому что 2 + 2 это либо эквивалентно
2.add(2) => стек
Либо эквивалентно
add(2, 2) => стек
На уровне внутренней реализации это делается первым способом. Но на уровне пользовательского интерфейса это должно происходить способом вторым. Но даже в первом случае мы ожидаем, что первый параметр не останется на стеке. А по факту происходит следующее:
2 => стек
стек.add(2) => стек
И поэтому первая двойка как бы и не должна удаляться. Лежит себе на стеке и лежит.
Я понял, в чём причина этой ошибки - в логике обработки ввода.
Мне нужно сделать так: взять строку, извлечь команду, взять параметры, выполнить команду, положить результат на стек.
А у меня сделано так: я выделяю объект, применяю метод, который берёт параметры по мере выполнения, и сам кладёт результат на стек.
Стек при этом получается как бы просто переменной особого рода. Он как бы непонятно для чего нужен в принципе. Вот, в Python его же нет, а здесь как бы тот же Python, только через стек нужно с ним работать.
Но тогда возникает вопрос: а нужен ли стек в принципе. Ведь параметры для команды можно задавать без стека, и результат получать не через стек.
Может возникнуть вопрос, в чём именно кривизна. Кривизна в данном случае в адресации объектов на стеке. Допустим, что до выполнения команды мы имеем на стеке число. Его адрес $0. А после выполнения команды его адрес уже $1, а $0 - это адрес результата.
С точки зрения Форта - это нормально. Но с точки зрения читаемости кода это будет просто адский треш:
принтер1
$0 команда1
$1 команда2
$2 команда3
Понять, что в данном случае мы все эти команды выполняем с объектом принтер1, глядя на этот код, просто невозможно.
Тогда возникает вопрос, зачем нужен стек, если есть переменные и константы. И получается, что стек только всё запутывает.
Подытоживая всё это, я пребываю в размышлениях.
Комментариев нет:
Отправить комментарий