Каков наилучший способ реализации оператора break на интерпретаторе?

Я разрабатывал интерпретатор для Brain (язык, похожий на Brainfuck), и у меня есть некоторые опасения относительно дизайна оператора break.

Рассмотрим код ниже в JS:

var Stmt = (function() {
  var Stmt = function() {};
    Stmt.prototype = {
      update_expression: function(update) { return false; },
      value: function() { return this; },
      exec: function(delegate) { },
      zerofy: function (tapeObj) {
        if (tapeObj.data[tapeObj.d_ptr] === undefined) {
          tapeObj.data[tapeObj.d_ptr] = 0;
      }
    }
  };

  return Stmt;
})();

var BreakStmt = (function() {
  var BreakStmt = function(){ };
  BreakStmt.prototype = Object.create(Stmt.prototype);
  return BreakStmt;
})();

var LoopStmt = (function() {
  var LoopStmt = function(stmts, type) {
    this.type = 'undefined';
    this.stmts = null;

    if (tokens[type] === 'TT_BEGIN_WHILE'
      || tokens[type] === 'TT_BEGIN_FOR') {
      this.type = type;
      this.stmts = stmts;
    }
  };

  LoopStmt.prototype = Object.create(Stmt.prototype);
  return LoopStmt;
})();

var IfStmt = (function() {
  var IfStmt = function(stmts_then) {
    this.stmts_then = stmts_then;
    this.stmts_else = null;
  };

  IfStmt.prototype = Object.create(Stmt.prototype);
  IfStmt.prototype.set_else = function(stmts_else) {
      this.stmts_else = stmts_else;
  };

  return IfStmt;
})();

Парсер будет рекурсивно просматривать операторы и затем возвращать AST. Теперь представьте AST со следующими утверждениями:

LoopStmt
  IfStmt
    IfStmt
      BreakStmt
...

Элементы exec функция идет также рекурсивно. Несмотря на то, что у меня появилось много идей для этой реализации, после многих исследований я все еще не могу найти лучший способ рекурсивной остановки этой рекурсивности (если это имеет смысл), пока не найду ближайший LoopStmt.

Каков лучший дизайн для этого? Любая помощь будет отличной, спасибо!

1 ответ

После долгих исследований, я думаю, я нашел ответ.

Реализация подхода накопления деревьев была бы одной из лучших идей для моего дизайна. Фактически, для этого мы будем использовать только метод восходящего накопления, где каждый узел (в данном случае мой Stmts) имеет информацию о своих потомках.

В этом случае для упомянутого АСТ:

1. LoopStmt 
2.  IfStmt
3.    IfStmt
4.      BreakStmt
   ...

Все, что нам нужно сделать, это хранить (или накапливать) информацию #4 Stmt в #3 Stmt, информация о #3 в #2, и наконец #2 в #1, Затем мы рекурсивно прерываем выполнение операторов до ближайшего цикла.

Надеюсь, я помогу всем!

Другие вопросы по тегам