Как добавить возможности трассировки / отладки в язык, реализованный в python? - PullRequest
5 голосов
/ 09 марта 2012

Я использую python для реализации другого языка программирования с именем 'foo'.Весь код foo будет переведен на python, а также будет запущен в том же интерпретаторе python, поэтому он будет JIT транслироваться на python.

Вот небольшой фрагмент кода foo:

function bar(arg1, arg2) {
    while (arg1 > arg2) {
        arg2 += 5;
    }
    return arg2 - arg1;
}

, что будет переводить на:

def _bar(arg1, arg2):
    while arg1 > arg2:
        arg2 += 5
        watchdog.switch()
    watchdog.switch()
    return arg2 - arg1

«Сторожевой таймер» - это гринлет (сгенерированный код также работает в контексте гринлета), который будет контролировать / ограничивать использование ресурсов, поскольку язык будет работать без довериякод.

Как видно из примера, перед созданием кода Python в дерево разбора будут внесены небольшие изменения, чтобы добавить сторожевые переключатели и внести небольшие изменения в идентификаторы функций.

Чтобы выполнить все требования, я также должен добавить возможности трассировки / отладки к языку, чтобы, когда среда выполнения Python выдает исключение, пользователь увидит трассировку кода foo (вместо показа сгенерированной трассировки кода Python).

Предположим, что пользователь создает файл с именем 'program.foo' со следующим содержимым:

1  function bar() {
2      throw Exception('Some exception message');
3  }
4
5  function foo() {
6      output('invoking function bar');
7      bar();
8  }
9
10 foo();

, который будет преобразован в:

def _bar():
    watchdog.switch()
    raise Exception('Some exception message')

def _foo():
    print 'invoking function bar'
    watchdog.switch()
    _bar()

watchdog.switch()
_foo()

Затем выводиз 'program.foo' должно быть что-то вроде:

invoking function bar
Traceback (most recent call last):
  File "program.foo", line 10
    foo();
  File "program.foo", line 7, inside function 'foo'
    bar();
  File "program.foo", line 2, inside function 'bar'
    throw Exception('Some exception message');
Exception: Some exception message

Есть ли простой способ сделать это?Я бы предпочел решение, которое не включает инструментирование байт-кода python, поскольку оно является внутренним для реализации интерпретатора, но если ничего другого нет, то инструментальное байт-код также сделает это.

1 Ответ

2 голосов
/ 09 марта 2012

Вы можете декорировать каждую сгенерированную функцию Python декоратором, который записывает контекст (имя файла, функцию, номер строки и т. Д.) В глобальный стек. Затем вы можете получить свой собственный класс Exception и поймать его на верхнем уровне интерпретатора. Наконец, вы распечатываете то, что вам нравится, используя информацию из глобального стека отладки.

...