Erro na função string.compile()

Iniciado por rafael, Novembro 08, 2018, 02:01:04 PM

tópico anterior - próximo tópico

rafael

Boa tarde,

Recentemente precisei compilar os fontes dos meus programas e me deparei com a seguinte situação:

segundo o manual para compilar uma string:

funcao mostre()
    imprima("123testando")
fim

s = string.compile (mostre)
tent = tente (carregue (s) )


///////--------
Aqui se eu chamar a função tent() ele vai imprimir: 123testando
Até aqui tudo bem.

O problema aqui é que ele compila apenas a função e não aceita strings de fora da função.
Eu compilei uma função e salvei em um arquivo e tentei rodar em outro computador
Mas ele roda apenas as funções, tudo que for string fica de fora e ele tenta buscar no outro computador.

Eu consegui resolver usando a biblioteca reg:

   reg.compile( ArqTemp, FuncaoASerCompilada() )


   local n = carreguearquivo(ArqTemp)

Agora eu tenho dentro da função n() tudo que salvei em FuncaoASerCompilada()

Mas não entendi porque não funcionou na função string.compile() sem precisar salvar o arquivo

Resumindo: a função string.compile() armazena a função para se executada depois
e a função reg.compile() armazena o retorno da função a ser compilada, neste caso consigo salvar uma tabela ou qualquer coisa em bytecode

???

adalberto

#1
E aí Rafael. Desculpe-me pela demora, vamos lá:

Esta função da biblioteca string (string.compile) tem esse comportamento: converte uma função, passada como parâmetro, em um trecho de bytecodes. Só é incluído no escopo global o que estiver no escopo da função. Não há como mudar isso, é uma característica de Lua e, portanto, de Prisma. Seria necessário mudar todo o mecanismo envolvido por baixo.

Ps. A função string.compile(), para quem ainda não sabe seu propósito, é muito útil para compilar trechos de comandos ou scripts inteiros em tempo de execução. Isso é uma das várias características de uma linguagem dinâmica.
Eu utilizei esta função para criar o compilador pric.prisma.

Com a função reg.compile dá certo porque ela funciona desta forma:

     1 - lê todo o arquivo ('script prisma').
     2 - transforma o arquivo lido numa única função.
     3 - esta função é compilada para string códigos bytes.
 
  Há duas saídas para você:

  1 -- usar a mesma técnica da biblioteca reg:    carreguearquivo();
     dê uma olhada no exemplo:
   
    execute_arquivo = carreguearquivo ( 'ola.prisma' );
    bytes = string.compile(execute_arquivo);


   Obs. há um outro modo, um pouco mais trabalhoso, mas funciona:
   *ler o arquivo com a função es.abra()    a:leia("*t") ...
   *pegar todo o conteúdo lido e usar a função carregue() (carrega uma string para uma função global);
   *e no fim usar a função string.compile() para compilar a função carregada.

2 - Criar uma grande função main e embutir dentro dela tudo o que quiser executar antes de usar a string.compile(), incluindo variáveis globais ou locais (até mesmo outras funções dentro)
   

    funcao inicio_programa()
           //...todo seu código aqui...
    fim //inicio_programa
    string.compile(inicio_programa);


  Obs. Basta acrescentar a função no início do script e um 'fim' no final dele.

Lembrando que se tiver variáveis globais, no trecho executado, elas serão visíveis no programa que o executou.