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
???
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.