Pull to refresh

Comments 22

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

Очень жаль. Мне казалось, он подает большие надежды.
                Opcode::SubAssign(n) => {
                    let mut value = self.pop();
                    value += n;
                    self.stack.push(value);
                }


У тебя тут баг
можно подробнее?
для меня, как для человека ни разу не писавшего на расте, всё выглядит логично.
там у автора копипаст и value += n; повторяется в AddAssign и в SubAssign.
ну может так и задумывалось — автор же так и не рассказал, что должны делать эти операции )
Спасибо за поправку, уже исправил
Что будет, если в стеке не окажется нужного количества значений?
Если кратко, то паника из-за того что в стеке не будет чисел, но если ловить ошибки благодаря Result этого можно избежать
> let value = self.pop() — self.pop();

А в Rust так можно? Если мне не изменяет память, в C++ порядок вычисления аргументов был неопределён, так что результат мог оказаться с противоположным знаком.
В Расте порядок строго определён, т.к. нужен для borrow checker'а. Правило: слева-направо и изнутри-наружу, т.е. вот эта строчка a.quuz(a.foo(a.bar(), a.baz()), a.quux()) будет выполняться в следующем порядке: a.bar(), a.baz(), a.foo(), a.quux(), a.quuz().
Как насчет примера реализации цикла? К примеру, для вычисления факториала или чисел фибоначчи?
С тем набором опкодов что есть в данной виртальной машине не выйдет, но здесь есть пример в самом низу README и можете после того как программа выполнится посмотреть файл opcode.txt, все опкоды записаны туда
Олег, если нужна скорость, почему Rust, а не Си?

Скорость у программ на Rust и C с одинаковыми алгоритмами примерно одинаковая. Почему Rust? Удобная система сборки, алгебраические типы, дженерики, встроенный статический анализатор (borrow checker), модули и прочее.

Я бы порекомендовал реализовать примитивные базовые (не пересекающиеся между собой) операции, необходимые для написания любого интерпретатора (ну хотя бы тот же брейнфак). Так, операции AddAssign и SubAssign являются лишними, но не хватает операции Assign.

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

И последнее: всё описанное с легкостью реализуется на любом ЯП, не только Rust, но и C\C++, Java\C#, Python\Ruby etc.
И еще, по поводу интерпретаторов: виртуальная машина — только первый шаг, потребуется также реализовать парсер+лексер для выбранной грамматики — что по себе очень серьезная задача, особенно если писать самостоятельно (и чем дальше от семантики ассемблера, тем сложнее).
Поэтому зачастую проще взять существующую ВМ, сторонний парсер+интерпретатор, и только написать для этого парсера понятную ему грамматику.

Либо (если похожий язык есть, но нужно его расширить\изменить) — можно написать транспилер в целевой язык и положиться на свойства платформы этого языка. Этот способ привлекателен тем, что сам транспилер не обязан быть быстрым, многие конструкции просто перенести 1:1, и реализовать его можно хоть на любимых регулярках.
Для языка Си как основы вообще может оказаться достаточным применение макросов и его препроцессора
Ну в конце статьи есть ссылка на ЯП Neo который я пытаюсь доделать до вменяемого состояния, там так же используется стековая Vm

Решил в рамках разминки слегка добавить коду из статьи идиоматичности, и в итоге так увлёкся, что аж жалко стало выбрасывать. Поэтому предлагаю вашему вниманию несколько альтернативную имплементацию ровно той же машины, что описал автор:
https://gist.github.com/mexus/0dbdf5af2367719c00bb70c5288d9cc9


P.S.
Дабы запихнуть всё в один файл нагородил mod'ов, в реальной жизни всё их содержимое конечно ушло бы в отдельные файлы.

«ча и ща пишем через а.»

Можно просто так минусовать и ничего за это не будет?
Спрашиваю для самообразования.
Минусуют, потому что подобные сообщения нужно отправлять автору статьи в личку. Это объяснение есть наверное на каждой третьей статье на хабре под таким же комментарием, но их все ровно пишут и пишут, годами. Пора за них бан вводить.
Sign up to leave a comment.

Articles