NGC — Как я написал интерпретатор простого языка

в 9:42, , рубрики: автоматизация, Скриптинг, язык программирования
Меня зовут Богдан Николаев. Сразу хотелось бы предупредить вас о том, что данный пост не является пиаром, а скорее моим желанием показать проект людям.

Итак, начнём. Как-то раз я загорелся желанием написать простой компилятор какого-нибудь языка. Дело было летом 2015. И я взялся за дело.

За вечер написанный кривенький компилятор паскаль-подобного языка, генерирующего листинге на ассемблере и пинающего это дело в nasm работал неплохо. Но всё равно этого было мало. Ведь тот «компилятор» не поддерживал ни переменных, ни циклов, ни ООП, ни условий.

И долгое время я учился парсингу, учился как лучше писать парсеры языков, синтаксические анализаторы, и однажды, через год (08 июня 2016) я загорелся идеей написать интерпретатор простого basic-подобного языка, для написания скриптов автоматизации. И я принялся за работу. За несколько дней была написана база интерпретатора, с базовыми фичами:

1. Два типа сравнение — если и если не
2. Возможность в рантайме деаттачинга от консоли, и превращение в GUI приложение
3. Возможность прямо в рантайме подгрузить посредине одного скрипта подгрузить другой, выполнить его, и при этом сохранить состояние всех переменных
4. Реализованы некоторые WinAPI функции(MessageBox etc)
5. Реализованы вызовы функций из DLL, что делает язык безграничным в возможностях
6. Динамическая система типов, на лету можно присвоить переменной типа int значение string
7. Мультимедийные функции — проиграть звук и.т.д
8. Полный File IO
9. Поддержка INI конфигураций для скриптов, очень юзабельно для систем сборки(кто билдил ядро линуп, тот поймёт)

Примеры простых программ:

Hello world:

println 'Hello, world!'

Get user input:

quest
print ' Hello, '
print answer

Variables:

varcreate 'myvar'
varset 'myvar', 'myval'
println $myvar

В процессе разработки интерпретатора возникали проблемы, в первую очередь с парсингом (к примеру, токенизатор неправильно опозновал символ доллара, а за ним имя переменной), но это было быстро решено переходом на рельсы TParser(встроенный в делфи класс для парсинга dfm, извращенцы вроде меня могут и яп на нем написать). API NGC формировался прямо на лету(и сейчас дополняется, каждые несколько часов обновление на гитхабе), сначала всё самое простое (writeln, readln), затем уже посложнее (fileio), затем функции без которых просто не может обойтись нормальный ЯП. Я сразу планировал два режим работы:

1. Интерактивный — пользователь в реальном времени вводит команды, и даже может работать с файлами (прямо в консоли, в интерактивном режиме, вводя команды);
2. Исполнение скрипта — пользователь запускает интерпретатор с параметром 1 == имя скрипта, и интерпретатор построчно исполняет скрипт.

Реализовать было достаточно просто, поскольку ядро интерпретатора — функция ExecuteCommand принимала строку в виде String, и в нёё можно строку хоть из MemoryStream «натравить», хоть с сервера украсть.

Что же касается быстродействия, то одна команда исполняется достаточно быстро, я даже мелодию написал на NGC(простую, на бипере, но всё же. Посмотреть можете в папке samples/media/music.ngs в репозитории), так что по скорости NGC примерно как PHP или чуть медленее.

Можно сделать вывод что NGC достаточно хорош для нпаисания скрипотв автоматизации, систем сборки, и простых (и не очень — есть же вызов DLL) приложенией.

Проект открытый, репозиторий проекта на гитхабе: GitHub.

Спасибо, надеюсь, вам понравится.

Автор: bodyawm

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js