¿Cómo agregar capacidades de recuperación / depuración a un idioma implementado en Python?

StackOverflow https://stackoverflow.com//questions/9633363

Pregunta

Estoy usando Python para implementar otro lenguaje de programación llamado 'foo'. Todo el código de Foo se traducirá a Python, y también se ejecutará en el mismo intérprete de Python, por lo que se traducirá en Traducir a Python.

Aquí hay una pequeña pieza de código Foo:

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

que se traducirá a:

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

El 'Watchdog' es un Greenlet (el código generado también se está ejecutando en un contexto Greenlet) que supervisará / limitará el uso de recursos, ya que el idioma ejecutará el código de confianza.

Como se puede ver en el ejemplo, antes de que se genere el código de Python, se realizarán pequeños cambios en el árbol de análisis para agregar interruptores de vigilancia y realizar pequeños cambios en los identificadores de funciones.

Para cumplir con todos los requisibles, también debo agregar capacidades de rastreo / depuración al idioma, de modo que cuando el tiempo de ejecución de Python lanza una excepción, lo que verá el usuario es el código de devolución de datos de Foo (como se opuso a mostrar el código de devolución de código Python generado ).

Considere que el usuario crea un archivo llamado 'programa.foo' con los siguientes contenidos:

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();

que se traducirá a:

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

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

watchdog.switch()
_foo()

Luego, la salida de 'programa.foo' debe ser algo así:

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

¿Hay una manera fácil de hacer eso? Preferiría una solución que no implique el instrumento Python Bytecode, ya que es interno a la implementación del intérprete, pero si no hay nada más, entonces la instrumentación BYTECODE también lo hará.

¿Fue útil?

Solución

You could decorate each generated Python function with a decorator which record the context (filename, function, line number, etc.) to a global stack. Then you could derive your own Exception class and catch it at the top level of the interpreter. Finally, you print out what you like, using information from the global debug stack.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top