запилил процедуры, локальные переменные, рекурсию, `IF` и `WHILE`.

с рекурсией не всё так просто: у Nanojit нет инструкции: «вызови то, не знаю что, потом пропатчим». адрес вызова должен быть известен на момент компиляции инструкции. так что рекурсия сделана через косвенные вызовы по указателю, который суют в область констант. компилятор достаточно умён чтобы делать это только когда надо, вне зависимости от порядка объявления процедур.

также у Nanojit есть ещё один квирк: аргументы функций изменять нельзя. вообще. никак. нет таких инструкций. можно только читать. оно, конечно, красиво и правильно, но в обероне-то можно! пришлось сделать в компилере хак: если он обнаруживает присваивание аргументу, то генерит пролог с копированием оного аргумента в стековый локал, и потом при генерации кода прозрачно работает с этим локалом. ну, кривовато. зато it works.

заодно бампнул максимальное количество аргументов в Nanojit с восьми до шестидесяти трёх. на самом деле самая большая проблема с этим в том, что нано паковал типы аргументов и результата в `uint32_t` — отсюда и ограничение на восемь. эту часть пришлось переделать на битовый массив.

в общем, теперь умеем в вот такое:
## Код:
```
MODULE n0test_00;

IMPORT Log;

TYPE
  INT = INTEGER;

  MyRec = RECORD
    a: INT;
    b: FLOAT;
    r: RECORD
      d: INT;
    END
  END;

  MyRec1 = RECORD
    ival: INT;
  END;

  MyRec3Ptr = POINTER TO MyRec3;
  MyRec4Ptr = POINTER TO MyRec4;

  MyRec2 = RECORD
    r: MyRec1;
    a: INT;
    (*pp: MyRec3Ptr;*)
    b: FLOAT;
  END;

  MyRec3 = RECORD
    x: DOUBLE;
    y: MyRec4Ptr;
  END;

CONST
  Love = Base + 69;
  Hell = Base + 666;
  Base = 10000;

VAR
  a0: INT;
  r0: MyRec;
  r2: MyRec2;


PROCEDURE Proc (arg: INTEGER);
BEGIN
  Log.String("IN `Proc`: arg="):Int(arg):Ln;
  Proc1(arg + 3);
END Proc;

PROCEDURE Proc1 (a: INTEGER);
BEGIN
  Log.String("IN `Proc1`: arg="):Int(a):Ln;
  IF a = 666 THEN Log.String("***HELL**"):Ln
  ELSIF a = 669 THEN Log.String("***LOVE**"):Ln
  END IF;
END Proc1;


PROCEDURE Recurse (a: INTEGER);
BEGIN
  Log.String("R-ENTER: a="):Int(a):Ln;
  IF a > 0 THEN Recurse(a - 1) END IF;
  Log.String("R-EXIT: a="):Int(a):Ln;
END Recurse;


PROCEDURE ProcWhile (a: INT);
VAR cnt: INT;
BEGIN
  Log.String("ProcWhile: start: a="):Int(a):Ln;
  cnt := a;
  WHILE cnt # 0 DO
    Log.String("  PWW: cnt="):Int(cnt):Ln;
    (*a := a - 1;*)
    DEC(cnt);
  END WHILE;
  Log.String("ProcWhile: end: a="):Int(a):Ln;
END ProcWhile;


PROCEDURE ProcWhile1 (a: INT);
BEGIN
  Log.String("ProcWhile1: start: a="):Int(a):Ln;
  WHILE a # 0 DO
    Log.String("  PWW: a="):Int(a):Ln;
    (*a := a - 1;*)
    DEC(a);
  END WHILE;
  Log.String("ProcWhile1: end: a="):Int(a):Ln;
END ProcWhile1;


PROCEDURE ProcWhile2 (a: INT);
BEGIN
  Log.String("ProcWhile2: start: a="):Int(a):Ln;
  WHILE a # 0 DO
    Log.String("  PWW: a="):Int(a):Ln;
    a := a - 1;
  END WHILE;
  Log.String("ProcWhile2: end: a="):Int(a):Ln;
END ProcWhile2;


BEGIN
  Log.String("HI"+"!"):Ln;
  r0.a := 666_69;
  r0.r.d := Love;
  r0.b := 666.999;
  Log.String("r0.a="):Int(r0.a):Ln;
  Log.String("r0.b="):Float(r0.b):Ln;
  Log.String("r0.r.d="):Int(r0.r.d):Ln;

  r2.a := 666_69;
  r2.b := 666.999;
  r2.r.ival := Hell;
  Log.String("r2.a="):Int(r2.a):Ln;
  Log.String("r2.b="):Float(r2.b):Ln;
  Log.String("r2.r.ival="):Int(r2.r.ival):Ln;

  a0 := 69;
  Log.String("a0="):Int(a0):Ln;

  Log.Float(66.9):Ln;
  Log.String("a0(real)="):Float(a0):Ln;

  Log.Float(6.69):Ln;
  Log.Int(660 + 9):Ln;
  Log.Int(29AH); Log.Ln;
  Log.Int(16%29A):Ln();
  Log.Int($29A); Log.Ln();

  Proc($290 + 10);

  Recurse(4);

  a0 := 3;
  WHILE a0 # 0 DO
    Log.String("W: a0="):Int(a0):Ln;
    (*a0 := a0 - 1;*)
    DEC(a0);
  END WHILE;

  ProcWhile(5);
  ProcWhile1(5);
  ProcWhile2(5);
END n0test_00.
```
