Skip to content
Dmitry Ponyatov edited this page Aug 19, 2019 · 29 revisions

Язык metaL

Язык metaL не предназначен для программирования, это DML/DDL для формирования и модификации вычислительных структур на основе расширенной фреймовой модели Марвина Мински, и управлении EDS-интерпретатором. Другими словами, metaL это язык описания данных. Что это за данные, и что вы с ними будете делать, это уже ваше решение. Единственное накладываемое ограничение: каждый объект структуры данных может быть только фреймом -- экземпляром базового класса Frame, или любого класса, который его наследует.

metaL изначально задумывался как очень минималистичный язык для разработки программ для встраиваемых систем, используя метапрограммирование как основной подход к разработке ПО. Поэтому у него и такое название -- metaпрограммирование и Language (язык), и одновременно отсылка к baremetal.

Поскольку для метапрограммирования необходима языковая система со встроенной поддержкой гомоиконичности, была проделана определенная поисковая исследовательская работа по выбору модели данных и архитектуры абстрактной машины, которая бы использовала структуры данных, одновременно хорошо понятные человеку, и способные описать (и синтезировать) исходный код программ на языках Си и С++, обязательных к применению для встраиваемых систем при работе в группе. Из гомоиконичных языков наиболее известен Lisp, но списковое представление исходного кода показалось ужасно громоздким. В поиске удалось выйти на точную формулировку, какое направление информатики наиболее точно соответствует требуемой прикладной области -- Knowledge Representation & Reasoning, и универсальную модель фреймов, хорошо подходящую как к моделированию программного обеспечения так и задачам семантического ИИ.

Абстрактная машина языка metaL

Упрощенная реализация на Python доступна в подкаталоге проекта https://github.com/ponyatov/itstep/tree/master/metaL

Абстрактная машина языка metaL похожа на стековая машина языка Форт с использованием объектов и символьной адресацией памяти вместо целочисленных указателей, и состоит из следующих компонентов:

  • базовый класс Frame и его производные классы формируют базу для реализации гомоиконичной языковой системы
  • Context вычислительный контекст, содержит состояние нити/процесса
    • Ip точка выполнения программы (указатель инструций интерпретатора)
    • стек данных S хранит данные в процессе вычислений (экземпляр Stack)
    • словарь W содержит соответствия между именами и исполняемыми структурами данных (экземпляр Dict)
    • стек компиляции C
  • команды абстрактной машины Cmd
    • выполняют операции над несколькими верхними элементами стека S,
    • включают операции обмена данными между стеком S и словарем W,
    • операции ввода/вывода,
    • интерфейс с операционной системой,
    • классы-обертки для нескольких распространенных библиотек, и
    • произвольные пользовательские расширения, написанные на языке реализации ВМ
  • веб-интерфейс реализован на фреймворке Flask, обеспечивает визуализацию, командную консоль, и пользовательский интерфейс в браузере -- обеспечивает мультиплатформенность, возможность запуска системы на арендованном VDS-сервере, и возможность создания коммерческих приложений.

Объекты класса Symbol имеют в metaL особую роль -- это тип токенов по умолчанию, для них интерпретатор ищет в словаре существующее определение по имени символа, и запускает найденную структуру в текущем контексте.

########################################################## интерпретатор команд

# ( -- token ) парсер выделяет один токен из входного потока
def WORD(ctx):
    token = lexer.token()
    if token: ctx // token
    return token 

# ( symbol:token -- found | token ) поиск в словаре по имени
def FIND(ctx):
    token = ctx.pop()
    try:   ctx // ctx[token.val]  ; return True
    except KeyError: ctx // token ; return False
    
# ( str -- ... ) интерпретатор
def INTERPRET(ctx):
    lexer.input(ctx.pop().val)
    while True:
        if not WORD(ctx): break
        if isinstance(ctx.top(), Symbol):
            if not FIND(ctx): pass

# Read-Eval-Print-Loop
def REPL(ctx):
    while True:
        print(ctx)
        try:             ctx // String(input('\nok> ')) ; INTERPRET(ctx)
        except EOFError: BYE(ctx)
<context:metaL> @7f7a2d3cf6a0 #0

ok> 123 fdsf

<context:metaL> @7f7a2d3cf6a0 #0
	<integer:123> @7f7a2d3cf710 #1
	<symbol:fdsf> @7f7a2ceb2710 #1

ok> Ctrl-D exit...

система типов

Clone this wiki locally