x86128: (Default)
[personal profile] x86128
В качестве эксперимента затеял сделать минимально возможный компилятор языка похожего на Oberon. Так сказать пощупать руками компиляторостроение.

Почитал по диагонали профильную литературу, но рукам, конечно, не терпится сразу приступить к делу :).

Сегодня заработал самый минимально живущий интерпретатор-компилятор, который я изготовил на Python.

Поскольку код крайне сырой, планирую несколько итераций по причёсыванию кода (замена туплей на объекты и т.д.) чтобы привести его в более идеоматический Python.

Пока нет оператора IF, циклов кроме WHILE, поддержки массивов (поэтому и строк), составных типов, только целые типы - только хардкор. Так же нет тестов.

Парсер LL(1) грамматики, на основе входного потока токенов от лексера, строит подобие синтаксического дерева. Далее "дерево" обходится компилятором который строит код для абстрактной стековой машины. Далее виртуальная машина выполняет код используя стек данных и стек фреймов (куда напресовываются рабочие области процедур (locals)).

MODULE Samples;

procedure gcd(a,b : integer);
    var t : integer;
begin
    while b > 0 do
        t := b;
        b := a mod b;
        a := t
    end;

    writeint(a)
end gcd;

begin
    gcd(27+25*3-(10 div 5),15)

END Samples.


На выходе имеем готовое к употреблению интерпретатором:

MODULE Samples
{'decls': {'consts': {},
           'procs': {'gcd': {'args': [('a', 'integer'), ('b', 'integer')],
                             'decls': {'consts': {},
                                       'procs': {},
                                       'vars': {'a': (0, 'integer'),
                                                'b': (0, 'integer'),
                                                't': (0, 'integer')}},
                             'text': [('STOR', 'b'),
                                      ('STOR', 'a'),
                                      ('LABEL', 'L0'),
                                      ('LOAD', 'b'),
                                      ('CONST', '0'),
                                      ('RELOP', '>'),
                                      ('BR_ZERO', 'L1'),
                                      ('LOAD', 'b'),
                                      ('STOR', 't'),
                                      ('LOAD', 'a'),
                                      ('LOAD', 'b'),
                                      ('BINOP', 'mod'),
                                      ('STOR', 'b'),
                                      ('LOAD', 't'),
                                      ('STOR', 'a'),
                                      ('BR', 'L0'),
                                      ('LABEL', 'L1'),
                                      ('LOAD', 'a'),
                                      ('CALL', 'writeint')]}},
           'vars': {}},
 'name': 'Samples',
 'text': [('CONST', '27'),
          ('CONST', '25'),
          ('CONST', '3'),
          ('BINOP', '*'),
          ('BINOP', '+'),
          ('CONST', '10'),
          ('CONST', '5'),
          ('BINOP', 'div'),
          ('BINOP', '-'),
          ('CONST', '15'),
          ('CALL', 'gcd'),
          ('STOP', '')]}


Что в результате дает:
5
STOP at 11

Profile

x86128: (Default)
x86128

April 2023

S M T W T F S
      1
2345678
9101112131415
16171819202122
232425 26272829
30      

Style Credit

Expand Cut Tags

No cut tags
Page generated May. 22nd, 2025 06:09 am
Powered by Dreamwidth Studios