Como adicionar recursos de rastreamento/depuração a uma linguagem implementada em python?

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

Pergunta

Estou usando python para implementar outra linguagem de programação chamada 'foo'.Todo o código de foo será traduzido para python e também será executado no mesmo interpretador python, portanto, o JIT será traduzido para python.

Aqui está um pequeno pedaço do código do foo:

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

que se traduzirá em:

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

O 'watchdog' é um greenlet (o código gerado também está sendo executado em um contexto de greenlet) que monitorará/limitará o uso de recursos, uma vez que a linguagem executará código não confiável.

Como pode ser visto no exemplo, antes de o código python ser gerado, pequenas alterações serão feitas na árvore de análise para adicionar opções de watchdog e fazer pequenas alterações nos identificadores de função.

Para atender a todos os requisitos, devo também adicionar recursos de rastreamento/depuração à linguagem, para que quando o tempo de execução do python lançar uma exceção, o que o usuário verá é o rastreamento do código de foo (em vez de mostrar o rastreamento do código python gerado).

Considere que o usuário cria um arquivo chamado ‘program.foo’ com o seguinte conteúdo:

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 traduzirá em:

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

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

watchdog.switch()
_foo()

Então, a saída de 'program.foo' deve ser algo como:

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

Existe uma maneira fácil de fazer isso?Eu preferiria uma solução que não envolvesse a instrumentação do bytecode python, já que é interno à implementação do intérprete, mas se não houver mais nada, a instrumentação do bytecode também servirá.

Foi útil?

Solução

Você pode decorar cada função Python gerada com um decorador que registra o contexto (nome do arquivo, função, número da linha, etc.) em uma pilha global.Então você poderia derivar sua própria classe Exception e capturá-la no nível superior do intérprete.Finalmente, você imprime o que quiser, usando informações da pilha de depuração global.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top