Byte-code — не мой язык.

iky.
iky.
Nov 3 · 2 min read

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

Для простоты использования я соединил прошлые файлы в один, что теперь имеет имя: ovm.py . Также используем такую интересную вещь как перечисления. Они есть в стандартом наборе, в модуле enum.

from ovm import VM
from enum import Enum, auto

Далее напишу вновь самый обыкновенный класс и перечисления.

class TypeCommand(Enum):
PUSH = auto()
POP = auto()
PEEK = auto()
ADD = auto()
SUB = auto()
MIL = auto()
DIV = auto()
HALT = auto()
SET = auto()
GET = auto()
class ByteCode:
def __init__(self, code):
self.__code = code
self.__vm = VM()

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

def execute(self):
pos = 0
lenCode = len(self.__code)
while pos < lenCode:
current = self.__code[pos]
if current == TypeCommand.PUSH:
pos += 1
self.__vm.push(self.__code[pos])
elif current == TypeCommand.POP:
print(self.__vm.pop())
elif current == TypeCommand.PEEK:
print(self.__vm.peek())
elif current == TypeCommand.ADD:
self.__vm.add()
elif current == TypeCommand.SUB:
self.__vm.sub()
elif current == TypeCommand.MUL:
self.__vm.mul()
elif current == TypeCommand.DIV:
self.__vm.div()
elif current == TypeCommand.HALT:
self.__vm.halt(status=0)
elif current == TypeCommand.SET:
pos += 2
self.__vm.set(self.__code[pos - 1],self.__code[pos])
elif current == TypeCommand.GET:
pos += 1
print(self.__vm.get(self.__code[pos]))
pos += 1

В приведённом выше коде мы идём по всему списку элементов и считываем их, то есть выполняем.

Теперь хотелось бы, чтоб мы могли набирать самый обыкновенный текст и он смог выполняться. Хм… Для этого чуда из говно кода я сделаю статический метод.

@staticmethod
def read(src):
lst = src.split()
commands = []
for index, el in enumerate(lst):
# print(f"{index} - {el}")
if el == "push":
index += 1
commands.append(TypeCommand.PUSH)
commands.append(int(lst[index]))
elif el == "pop": commands.append(TypeCommand.POP)
elif el == "peek": commands.append(TypeCommand.PEEK)
return commands

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

$ python -i bytecode.py

Пример.

>>> bc = ByteCode(ByteCode.read("push 7 pop"))
>>> bc.execute()

И вновь у меня очень маленькая статья. По моему, её даже статьишкой назвать нельзя, а скорее запиской. Ссылки никаких давать не буду ибо на это сложно смотреть без слёз. До новых бед!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade