Как стать автором
Обновить

Свой язык, или как я устал от ассемблера и С

Время на прочтение3 мин
Количество просмотров8.5K

Вступление

Это не гайд, не туториал и не исследование. Эта статья - просто история о том, как я решил создать свой язык для низкоуровневых штучек, отличного от ассемблера и С. Приятного прочтения!

Предыстория

Как вы знаете, я обожал (и до сих пор обожаю) язык ассемблера, а именно - fasm. Я уже давно его изучил и пользуюсь им, но постепенно стал давать слабину. Я устал писать код на ассемблере, так как это долго и довольно таки тяжело (рано, или поздно, это всё равно произошло бы). Понять мою любовь к этому языку можно прочитав мои предыдущие статьи: раз, два, три, четыре. Почему же я не стал использовать С? Он мне просто не нравится. Неудобно мне. Вот и всё.

Концепт

Концепт заключается в том, что человек указывает все данные для компиляции в главном файле с помощью директивы, например, format. Так же, есть два типа библиотек: встроенные (стандартные) и кастомные (пользовательские). Иначе говоря, либы и модули. Для использования shared object, dll и пр. будет отдельная директива. Указателей в языке не будет, а для разыменывания будет использоваться макрос OFFSET. Для работы с железом на все случаи жизни будут стдлибы. Синтаксис будет чем-то средним между Java, TS, fasm (для некоторых выражений) и Python.

Синтаксис

Это, пожалуй, первое, с чего я начал. Для начала, я написал пример кода, который устроит меня своим синтаксисом. Вышло как-то так:

format mbr.x86.16.executable;

use Bios;
use Console;

fn main() -> Void
{
    Bios.set_mode(3);
    Console.log("Hello, World!");
    return 0;
}

Я решил не сильно париться, поэтому использовал библиотеку parglare. Она очень легкая и удобная, всем рекомендую. Для описания синтаксиса парсер принимает строку в соответствующем формате, использует регулярные выражения (не надо осуждать регулярки, они всесильны!). Итак, вот такое описание синтаксиса у меня получилось:

sroot: sany*;

sany: sformat
    | suse
    | sfn
    | sdefine;

sformat: "format" tname ";";
suse: "using" tname ";";
sfn: "fn" tname "(" sargs? ")" "->" tname sbody;
sargs: sarg ("," sarg)*;
sarg: tname ":" tname;
sbody: "{" sline* "}";
sline: (scall | sequal | sdefine | sreturn) ";";
scall: tname "(" scallargs? ")";
scallargs: sexpr ("," sexpr)*;
sequal: tname "=" sexpr ";";
sdefine: sarg ("=" sexpr)* ";";
sreturn: "return" sexpr?;
sexpr:
     "(" sexpr ")"
    |(ssequence | tname) "[" tinteger "]"
    |sexpr "*" "*" sexpr
    |"-" sexpr
    |sexpr "*" sexpr
    |sexpr "/" sexpr
    |sexpr "+" sexpr
    |sexpr "-" sexpr
    |"!" sexpr
    |sexpr "&" sexpr
    |sexpr "|" sexpr
    |sexpr "^" sexpr
    |tinteger
    |tstring
    |tname
    |ssequence;
ssequence:
    "<" scallargs ">";

terminals

tstring: /"[^"]*"/;
tname: /([A-Za-z_]\w*\.)*[A-Za-z_]\w*/;
tinteger: /00?|[1-9]\d*/;

Вышло кратко. А краткость - сестра таланта. Да и к тому же, так будет проще.

Компиляция в язык ассемблера (fasm)

Я долго ломал голову, как это полаконичней сделать, и никак не мог придумать решение. Через пару дней я наткнулся на статью про pyast64 (на медиум, по-моему). Она раскрыла мне глаза. В коде этого скрипта было все что мне нужно: и работа со стеком, и соглашение о вызовах, и пр и тп. Я очень шустро накидал константы:

SIMPLE_BINOPS = (
	"add",
	"sub",
	"or",
	"and",
	"xor",
	"mul",
	"div"
)

SIMPLE_UNOPS = (
	"neg",
	"not"
)

SIMPLE_TYPES = (
	"integer",
	"string",
	"label"
)

COMPLEX_BINOPS = (
	"pow",
	"ind"
)

MUTABLE = (
    "integer"
)

ASM_BINOP = """
    pop qword rdx
    pop qword rax
    %s qword rax, rdx
    push qword rax"""

ASM_DEF = """
    %s d_%s %s"""

ASM_EQU = """
    pop qword rdx
    mov [%s], rdx"""

ASM_LDR = """
    push qword [%s]"""

ASM_LEA = """
    push qword %s"""

ASM_PTR = """
    push qword %s"""

ASM_RET = "\n   ret"

ASM_SEQ = """
    push %s
"""

Дописать транслятор в ассемблер я ещё не успел, но до этого не долго осталось. Весь исходный код опубликован здесь: группа Telegram, здесь же можно обсудить и/или поддержать проект. Спасибо за внимание!

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Насколько вам интересна тема этого проекта?
35.04% Очень41
23.93% Не очень28
41.03% Не интересна48
Проголосовали 117 пользователей. Воздержались 45 пользователей.
Теги:
Хабы:
Всего голосов 27: ↑13 и ↓14+2
Комментарии57

Публикации

Истории

Работа

Python разработчик
120 вакансий
Data Scientist
78 вакансий

Ближайшие события

7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань