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

от автора

Вступление

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

Предистория

Как вы знаете, я обожал (и до сих пор обожаю) язык ассемблера, а именно — 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, здесь же можно обсудить и/или поддержать проект. Спасибо за внимание!

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Насколько вам интересна тема этого проекта?
20% Очень 3
20% Не очень 3
60% Не интересна 9
Проголосовали 15 пользователей. Воздержались 8 пользователей.

ссылка на оригинал статьи https://habr.com/ru/post/723400/