Notícias:

SMF - Just Installed!

Main Menu

Posts recentes

#1
Avisos / Lançamento - Prisma 1.0.107
Último post por adalberto - Janeiro 01, 2024, 03:05:47 PM
Após muito tempo, fico contente em comunicar que está lançada a versão 1.0.107 de Prisma, com várias correções e melhorias.

Downloads:
Ubuntu 22.04 x86_64: Baixar arquivo. (Extraia o arquivo e dentro da pasta execute no terminal o ./instalar.sh)

Windows 10,11 x86_64: Baixar arquivo. (Extraia o arquivo e copie a pasta Prisma para o local de sua preferência, não requer instalação.)

CentOS 7.9 x86_64: Baixar arquivo. (Extraia o arquivo, dentro da pasta execute o shell script ./instalar.sh)

Prisma Wasm (WebAssembly): Baixar arquivo. (A pasta js/ e o arquivo prisma.data devem estar no mesmo diretório do html. Bastando incluir o script "js/webprisma.js")


Esta versão traz algumas novidades interessantes:

  • Operadores bitwise: << >> | & ~;
  • Customização de tipos através do metamétodo __tipo;
  • Funções para verificação de tipos em parâmetros de funções: N(); S(); F(); B(); T() entre outras;
  • Acesso aos caracteres de string por índice;
  • Correção das funções es.abra() e es.pabra(), mais especificamente o 2nd parâmetro.
  • Alterações e inclusão de novas funções na biblioteca mat;
  • Operador de condição ternário (adaptação);
  • Várias correções e melhoramento de códigos, por exemplo, a função string.apare();
  • Novas funções para a biblioteca base: escolha() e contador();
  • Comandos acentuados(utf8): então, não, função, senão, senãose, até (os comandos sem acento ainda são válidos);
  • Variáveis com acento (utf8), exemplos: local salário = 5000,00; função lê_comentários(); etc.
  • O interpretador Prisma compilado em webasm, rodando no navegador e acessando componentes html e funções javascript direto de Prisma.


Mais detalhes, visiste a página: http://linguagemprisma.br4.biz/Notas_da_versao_nov_2023.html

#2
Publique aqui / mki - criando arquivos *.run (...
Último post por adalberto - Agosto 24, 2019, 01:44:10 PM
Instalador:   http://www.mediafire.com/file/41v74pv8tl5vvk5/mki-0.4.run/file
Fontes: http://www.mediafire.com/file/5saj8uun8nye9qk/mki-fontes.run/file
Você já deve ter visto ou usado um instalador com extensão *.run em Linux. Basta executá-lo em terminal que a mágica acontece: ele é extraído e executa um instalador.

O que talvez vc não saiba é que esse arquivo é um auto-extraível, um script shell com um arquivo compactado anexado. Os comandos do script shell presentes no arquivo separa o anexo e o extrai, após isso chama o scritp shell instalador, ou apenas extrai se for o caso.

Facinado por essa técnica, após pesquisar muito, criei um script personalizado que gera automaticamente um arquivo *.run auto-extraível chamado mki (make installer=crie instalador). Com ele será possível criar instaladores para seus projetos, scripts ou até mesmo uma imagem de fundo, ou ainda fazer backups. Compatível somente com linux e derivados.

Basta executá-lo em terminal, veja os comandos:

mki -x pasta arquivo.run (compacta 'pasta' e cria um arquivo auto-extraível arquivo.run)

mki -i pasta instalador.run (cria um instalador auto-extraível, que chama "instalar.sh" após a extração);

mki -o PastaAlvo Nome.run ./inicio.sh (cria instalador que chama "./inicio.sh", assim vc pode personalizar qual scritp será executado após a extração)

mki -h  (mostra algumas informações sobre o programa)


O instalador mki-0.4.run foi criado usando o próprio script mki que instala ele mesmo em seu sistema.

Compatível com qualquer distribuição que possua interpretador bash

Lembrando que o nome de seu instalador não precisa ter a extensão *.run, veja abaixo alguns nomes possíveis:

exemplo.run     exemplo.bin      exemplo (sem extensão)

Baixe os fontes do instalador mki-0.4 e veja os scripts conf.sh, instalar.sh, lib.sh e licenca.txt que possuem funções prontas para um instalador, modifique e faça seus próprios instaladores.

Instalador:   http://www.mediafire.com/file/41v74pv8tl5vvk5/mki-0.4.run/file
Fontes: http://www.mediafire.com/file/5saj8uun8nye9qk/mki-fontes.run/file

(Após baixar os arquivos acima execute no terminal: ./arquivo.run   ou  bash arquivo.run, substitua arquivo pelo nome do arquivo baixado)
#3
Materiais / pmicrotar-0.4
Último post por adalberto - Agosto 21, 2019, 05:15:58 PM
Baixar-> http://www.mediafire.com/file/wre1o0nd81huofv/pmicrotar.zip/file

Quem é do mundo *nix já deve conhecer o formato *.tar, muitas vezes confundido com um tipo de compressão de arquivo. Na verdade, trata-se de um formato de empacotamento, apenas une vários arquivos ou, até mesmo, diretórios.

O formato TAR pode ser usado em conjunto com bibliotecas de compressão de dados dando assim origem a extensões como tar.gz, tar.xz ou tar.7z. Isto significa que os dados foram comprimidos e empacotados no formato TAR.

Pensando na importância de criar e manipular arquivos no formato TAR é que fiz uma biblioteca pequena, mas poderosa, baseada no microtar da linguagem C.

Com ela será possível ler, criar e manipular arquivos *.tar, tanto no Linux quanto Windows. Apenas o empacotamento, ela não faz a compressão, para isso veja as bibliotecas de compressão em Prisma.

Outro fato importante é que esta biblioteca não lê os arquivos, apenas monta o empacotamento, ficando a cargo do programador carregar os arquivos em string, empacotá-los e depois gravar em disco.

Veja um simples exemplo de escrita (para mais detalhes veja o manual e exemplos na pasta do download)

local mtar = inclua'pmicrotar'


funcao leia_arquivobin(n)
  local a,err = es.abra(n,'leiturabin');
  se nao a entao retorne falso, err; fim
  local txt = a:leia('*t');
  a:feche();
  retorne txt;
fim

 
local dado1 = leia_arquivobin('dados/arq1.txt'); //lemos um arquivo para uma variável string.
   
local tar,err = mtar.abra("simples.tar",'escrita');//abrimos um arquivo tar para escrita (gravar dados nele)
 
se nao tar entao imprima('Erro:',err,'\nEnter para sair...'); leia(); sis.saia(1) fim //se der erro o programa imprime e sai.
 
mtar.escreva_cabecalho_arquivo(tar,"dados/arq1.txt",#dado1);//criamos um cabeçalho com o nome do arquivo (diretório completo)
  //note que na função acima é necessário passar o tamanho da string dado '#dado1';
mtar.escreva_dado(tar,dado1)//agora podemos gravar os dados.
  //aqui no meio poderia escrever muitos outros arquivos antes de finalizar e fechar.
mtar.finalize(tar);
mtar.feche(tar); 

poe('Processo terminado, verifique o arquivo "simples.tar", ENTER para sair...');
leia();



#4
Publique aqui / Biblioteca RJSON
Último post por rafael - Maio 16, 2019, 06:04:29 AM
 ;D

Bom dia !!!

Agora são exatamente 7h da manhã, acabei de portar mais uma biblioteca json. agora com opção de identação:
Também usei as funções cod_arquivo e decod_arquivo da biblioteca anterior se me permite.

FAÇAM BOM USO!


/*
    MIT License

    Copyright (c) 2018 xiedacon

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    SOFTWARE.

    Biblioteca JSON portada por Rafael Alves Lemos
    na madrugada de 16/maio/2019 as 0h as 6h
    não tem mudanças significativas em relação a lib json anterior prisma
    apenas na identação com opção de escolher os espaços
    inclusive portei as funções de cod_arquivo e decod_arquivo

    USO:
    local json = inclua 'rjson'
    local cod = json.cod({

        a=verdadeiro,
        b=falso,
        c='string',
        d=1,
        [0]={'matriz','de','valores'}

    },nulo,4) //<-- o quanto é a tabulação

    imprima(cod)
    local dec = json.decod(cod)
    imprima(tipo(dec))
    para i,v em pares(dec) inicio
        imprima(i,v)
    fim





saida:

{
    "d": 1,
    "c": "string",
    "b": false,
    "a": true,
    "0": [
        "matriz",
        "de",
        "valores"
    ]
}
tabela
d   1
c   string
b   falso
a   verdadeiro
0   tabela: 0x1ea14a0



*/


//*****************************Constant
local Constant = {
    ESC_MAP = {
        ["\\"] = [[\]],
        ["\""] = [[\"]],
        ["/"] = [[\/]],
        ["\b"] = [[\b]],
        ["\f"] = [[\f]],
        ["\n"] = [[\n]],
        ["\r"] = [[\r]],
        ["\t"] = [[\t]],
        ["\a"] = [[\u0007]],
        ["\v"] = [[\u000b]]
    },

    UN_ESC_MAP = {
        b = "\b",
        f = "\f",
        n = "\n",
        r = "\r",
        t = "\t",
        u0007 = "\a",
        u000b = "\v"
    },

    NULL = defmetatabela({}, {
        __tostring = funcao() retorne "nulo" fim
    })
}






//*****************************Serializer

local NULL = Constant.NULL
local ESC_MAP = Constant.ESC_MAP

local funcao kind_of(obj)
    se tipo(obj) ~= "tabela" entao retorne tipo(obj) fim
    se obj == NULL entao retorne "nulo" fim

    local i = 1
    para _ em pares(obj) inicio
        se obj[i] ~= nulo entao i = i + 1 senao retorne "tabela" fim
    fim

    se i == 1 entao
        retorne "tabela"
    senao
        retorne "matriz"
    fim
fim

local funcao escape_str(s)
    para k, v em pares(ESC_MAP) inicio
        s = s:troque(k, v)
    fim

    retorne s
fim

local Serializer = {
    print_address = falso,
    max_depth = 100
}

defmetatabela(Serializer, {
    __call = funcao(este, opts)
        local serializer = {
            depth = 0,
            max_depth = opts.max_depth,
            print_address = opts.print_address,
            stream = opts.stream
        }

        defmetatabela(serializer, { __index = Serializer })

        retorne serializer
    fim
})

funcao Serializer:space(n)
    local stream = este.stream
    para i = 1, n ou 0 inicio
        stream:write(" ")
    fim

    retorne este
fim

funcao Serializer:key(key)
    local stream = este.stream
    local kind = kind_of(key)

    se kind == "matriz" entao
        erro("Can't encode matriz as key.")
    senaose kind == "tabela" entao
        erro("Can't encode tabela as key.")
    senaose kind == "string" entao
        stream:write("\"", escape_str(key), "\"")
    senaose kind == "numero" entao
        stream:write("\"", convstring(key), "\"")
    senaose kind == 'booleano' entao
        se key entao
            stream:write('true')
        senao
            stream:write('false')
        fim
    senaose kind == 'nulo' entao
        stream:write('null')
    senaose este.print_address entao
        stream:write(convstring(key))
    senao
        erro("Unjsonifiable tipo: " .. kind .. ".")
    fim

    retorne este
fim

funcao Serializer:matriz(arr, replacer, indent, space)
    local stream = este.stream

    stream:write("[")
    para i, v em ipares(arr) inicio
        se replacer entao v = replacer(k, v) fim

        stream:write(i == 1 e "" ou ",")
        stream:write(space > 0 e "\n" ou "")
        este:space(indent)
        este:json(v, replacer, indent + space, space)
    fim
    se #arr > 0 entao
        stream:write(space > 0 e "\n" ou "")
        este:space(indent - space)
    fim
    stream:write("]")

    retorne este
fim

funcao Serializer:tabela(obj, replacer, indent, space)
    local stream = este.stream

    stream:write("{")
    local len = 0
    para k, v em pares(obj) inicio
        se replacer entao v = replacer(k, v) fim

        se v ~= nulo entao
            stream:write(len == 0 e "" ou ",")
            stream:write(space > 0 e "\n" ou "")
            este:space(indent)
            este:key(k)
            stream:write(space > 0 e ": " ou ":")
            este:json(v, replacer, indent + space, space)
            len = len + 1
        fim
    fim
    se len > 0 entao
        stream:write(space > 0 e "\n" ou "")
        este:space(indent - space)
    fim
    stream:write("}")

    retorne este
fim

funcao Serializer:json(obj, replacer, indent, space)
    local stream = este.stream
    local kind = kind_of(obj)

    este.depth = este.depth + 1
    se este.depth > este.max_depth entao erro("Reach max depth: " .. convstring(este.max_depth)) fim

    se kind == "matriz" entao
        este:matriz(obj, replacer, indent, space)
    senaose kind == "tabela" entao
        este:tabela(obj, replacer, indent, space)
    senaose kind == "string" entao
        stream:write("\"", escape_str(obj), "\"")
    senaose kind == "numero" entao
        stream:write(convstring(obj))
    senaose kind == "booleano" entao
        se obj entao
            stream:write('true')
        senao
            stream:write('false')
        fim
    senaose kind == "nulo" entao
        stream:write("null")
    senaose este.print_address entao
        stream:write(convstring(obj))
    senao
        erro("Unjsonifiable tipo: " .. kind)
    fim

    retorne este
fim

funcao Serializer:toString()
    retorne este.stream:toString()
fim



//*****************************Parser


local NULL = Constant.NULL
local UN_ESC_MAP = Constant.UN_ESC_MAP

local funcao next_char(str, pos)
    pos = pos + #str:separe("^%s*", pos)
    retorne str:corte(pos, pos), pos
fim

local funcao syntax_error(str, pos)
    retorne erro("Sintaxe JSON inválida iniciando em " .. pos .. ": " .. str:corte(pos, pos + 10))
fim

local Parser = {}

defmetatabela(Parser, {
    __call = funcao(este, opts)
        local parser = {
            without_null = opts.without_null
        }

        defmetatabela(parser, { __index = Parser })

        retorne parser
    fim
})

funcao Parser:numero(str, pos)
    local num = str:separe("^-?%d+%.?%d*[eE]?[+-]?%d*", pos)
    local val = convnumero(num)
    se nao val entao
        syntax_error(str, pos)
    senao
        retorne val, pos + #num
    fim
fim

funcao Parser:string(str, pos)
    pos = pos + 1
   
    local i = 1
    local chars = {} //tabela.new(#str - pos - 1, 0)
    enquanto(pos <= #str) inicio
        local c = str:corte(pos, pos)

        se c == "\"" entao
            retorne tabela.concat(chars, ""), pos + 1
        senaose c == "\\" entao
            local j = pos + 1

            local next_c = str:corte(j, j)
            para k, v em pares(UN_ESC_MAP) inicio
                se str:corte(j, j + #k - 1) == k entao
                    next_c = v
                    j = j + #k - 1
                fim
            fim

            c = next_c
            pos = j
        fim

        chars[i] = c
        i = i + 1
        pos = pos + 1
    fim

    syntax_error(str, pos)
fim

funcao Parser:matriz(str, pos)
    local arr = {} //tabela.new(10, 0)
    local val
    local i = 1
    local c
   
    pos = pos + 1
    enquanto verdadeiro inicio
        val, pos = este:json(str, pos)
        arr[i] = val
        i = i + 1

        c, pos = next_char(str, pos)
        se (c == ",") entao
            pos = pos + 1
        senaose (c == "]") entao
            retorne arr, pos + 1
        senao
            syntax_error(str, pos)
        fim
    fim

    retorne arr
fim

funcao Parser:tabela(str, pos)
    local obj = {} //tabela.new(0, 10)
    local key
    local val
    local c

    pos = pos + 1
    enquanto verdadeiro inicio
        c, pos = next_char(str, pos)

        se c == "}" entao retorne obj, pos + 1
        senaose c == "\"" entao key, pos = este:string(str, pos)
        senao syntax_error(str, pos) fim

        c, pos = next_char(str, pos)
        se c ~= ":" entao syntax_error(str, pos) fim

        val, pos = este:json(str, pos + 1)
        obj[key] = val

        c, pos = next_char(str, pos)
        se c == "}" entao
            retorne obj, pos + 1
        senaose c == "," entao
            pos = pos + 1
        senao
            syntax_error(str, pos)
        fim
    fim
fim

funcao Parser:json(str, pos)
    local first = falso
    local val
    local c

    se nao pos ou pos == 1 entao first = verdadeiro fim
    pos = pos ou 1

    se tipo(str) ~= "string" entao erro("str should be a string")
    senaose pos > #str entao erro("Reached unexpected fim of input") fim

    c, pos = next_char(str, pos)

    se c == "{" entao
        val, pos =  este:tabela(str, pos)
    senaose c == "[" entao
        val, pos = este:matriz(str, pos)
    senaose c == "\"" entao
        val, pos = este:string(str, pos)
    senaose c == "-" ou c:procure('%d')  entao
        val, pos = este:numero(str, pos)
    senao
        para k, v em pares({ ["true"] = verdadeiro, ["false"] = falso, ["null"] = NULL }) inicio
            se (str:corte(pos, pos + #k - 1) == k) entao
                val, pos = v, pos + #k
                quebre
            fim
        fim

        //se val == nulo entao syntax_error(str, pos) fim
    fim

    se first e pos <= #str entao syntax_error(str, pos) fim
    se este.without_null e val == NULL entao val = nulo fim

    retorne val, pos
fim







//************************JSON





local json = {
    _VERSION = "0.1",
    null = Constant.NULL
}

funcao json.cod(obj, replacer, space, print_address)
    se tipo(space) ~= "numero" entao space = 0 fim

    retorne Serializer({
        print_address = print_address,
        stream = {
            fragments = {},
            write = funcao(este, ...)
                para i = 1, #{...} inicio
                    este.fragments[#este.fragments + 1] = ({...})[i]
                fim
            fim,
            toString = funcao(este)
                retorne tabela.concat(este.fragments)
            fim
        }
    }):json(obj, replacer, space, space):toString()
fim

funcao json.decod(str, without_null)
    retorne Parser({ without_null = without_null }):json(str, 1)
fim


local es_abra = es.abra;

funcao json.decod_arquivo(arq)
  local a, err = es_abra(arq,'leitura');
  se nao a entao retorne falso, err fim
  local str = a:leia'*t'; //lê todo o arquivo.
  a:feche();
 
  retorne json.decod(str); //retorna a tabela. 
fim

funcao json.cod_arquivo(arq, tab)
  se tipo(tab)<> 'tabela' entao
    retorne falso, ('\n\nErro arg #2, espera-se tabela ao invés de ' .. tipo(tab) .. '\n\n');
  fim
  local str = json.cod(tab);
  local a, err = es_abra(arq,'escrita');
  se nao a entao retorne falso, err fim
  a:escreva(str);
  a:feche();
  retorne verdadeiro;
fim


retorne json


#5
Discussões Gerais sobre a linguagem / Re:libreadline6 aumentar supor...
Último post por adalberto - Dezembro 26, 2018, 10:24:18 PM
Para compilar Prisma com libreadline7 é necessário ligar com a biblioteca ncurses.

Não precisa modificar os fontes, apenas o arquivo Makefile dentro da pasta "prisma" onde estão os fontes.

Siga os passos:
 
  1 - Entre na pasta onde estão os fontes C de Prisma e Lua.
  2 - Abra o arquivo "Makefile" num editor
  3 - Procure as linhas:
linux:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"


4 - Acrescente logo após  -lreadline as libs  -lhistory e -lncurses -- ficando assim:
linux:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline -lhistory  -lncurses"



Tenta aí e retorna se deu certo ok.

Sobre o MariaDB client vou ver também depois, tá certo.
#6
Publique aqui / Re:biblioteca UTF8 em prisma
Último post por adalberto - Novembro 13, 2018, 08:09:16 AM
Boa Rafael, valeu! :D :D
#7
Lista de Bugs / Re:Erro na função string.compi...
Último post por adalberto - Novembro 13, 2018, 08:03:35 AM
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.
#8
Lista de Bugs / Re:Erro json.cod() 'boolean' -...
Último post por adalberto - Novembro 13, 2018, 07:34:04 AM
Valeu Rafael

Como estou meio parado em relação à programação, vai demorar um pouco para eu atualizar os downloads.
Então deixo aqui o código corrigido:


local json = {}


// Internal functions.

local funcao kind_of(obj)
  se tipo(obj) <> 'tabela' entao retorne tipo(obj) fim
  local i = 1
  para _ em pares(obj) inicio
    se obj[i] <> nulo entao i = i + 1 senao retorne 'tabela' fim
  fim
  se i == 1 entao retorne 'tabela' senao retorne 'array' fim
fim

local funcao escape_str(s)
  local in_char  = {'\\', '"', '/', '\b', '\f', '\n', '\r', '\t'}
  local out_char = {'\\', '"', '/',  'b',  'f',  'n',  'r',  't'}
  para i, c em ipares(in_char) inicio
    s = s:troque(c, '\\' .. out_char[i])
  fim
  retorne s
fim

// Returns pos, did_find; there are two cases:
// 1. Delimiter found: pos = pos after leading space + delim; did_find = verdadeiro.
// 2. Delimiter not found: pos = pos after leading space;     did_find = falso.
// This throws an error if err_if_missing is true and the delim is not found.
local funcao skip_delim(str, pos, delim, err_if_missing)
  pos = pos + #str:separe('^%s*', pos)
  se str:corte(pos, pos) <> delim entao
    se err_if_missing entao
      retorne falso, ('Esperado ' .. delim .. ' próximo da posição ' .. pos)
    fim
    retorne pos, falso
  fim
  retorne pos + 1, verdadeiro
fim

// Expects the given pos to be the first character after the opening quote.
// Returns val, pos; the returned pos is after the closing quote character.
local funcao parse_str_val(str, pos, val)
  val = val ou ''
  local early_end_error = 'Fim de input encontrado durante a análise da string.'
  se pos > #str entao retorne falso, (early_end_error) fim
  local c = str:corte(pos, pos)
  se c == '"'  entao retorne val, pos + 1 fim
  se c <> '\\' entao retorne parse_str_val(str, pos + 1, val .. c) fim
  // We must have a \ character.
  local esc_map = {b = '\b', f = '\f', n = '\n', r = '\r', t = '\t'}
  local nextc = str:corte(pos + 1, pos + 1)
  se nao nextc entao retorne falso, (early_end_error) fim
  retorne parse_str_val(str, pos + 2, val .. (esc_map[nextc] ou nextc))
fim

// Returns val, pos; the returned pos is after the number's final character.
local funcao parse_num_val(str, pos)
  local num_str = str:separe('^-?%d+%.?%d*[eE]?[+-]?%d*', pos)
  local val = convnumero(num_str)
  se nao val entao retorne falso, ('Erro ao analisar numero na posição ' .. pos .. '.') fim
  retorne val, pos + #num_str
fim


// Public values and functions.

funcao json.cod(obj, as_key)
  local s = {}  // We'll build the string as an array of strings to be concatenated.
  local kind = kind_of(obj)  // This is 'array' if it's an array or type(obj) otherwise.
  se kind == 'array' entao
    se as_key entao retorne falso, ('Não é possível codificar uma matriz como uma chave.') fim
    s[#s + 1] = '['
    para i, val em ipares(obj) inicio
      se i > 1 entao s[#s + 1] = ', ' fim
      s[#s + 1] = json.cod(val)
    fim
    s[#s + 1] = ']'
  senaose kind == 'tabela' entao
    se as_key entao retorne falso, ('Não é possível codificar tabela como uma chave.') fim
    s[#s + 1] = '{'
    para k, v em pares(obj) inicio
      se #s > 1 entao s[#s + 1] = ', ' fim
      s[#s + 1] = json.cod(k, verdadeiro)
      s[#s + 1] = ':'
      s[#s + 1] = json.cod(v)
    fim
    s[#s + 1] = '}'
  senaose kind == 'string' entao
    retorne '"' .. escape_str(obj) .. '"'
  senaose kind == 'numero' entao
    se as_key entao retorne '"' .. convstring(obj) .. '"' fim
    retorne convstring(obj)
  senaose kind == 'booleano' entao
    retorne convstring(obj)
  senaose kind == 'nulo' entao
    retorne 'null'
  senao
    retorne falso, ('Tipo não compatível com json: ' .. kind .. '.')
  fim
  retorne tabela.concat(s)
fim

json.null = {}  // This is a one-off tabela to represent the null value.

funcao json.decod(str, pos, end_delim)
  pos = pos ou 1
  se pos > #str entao retorne falso , ('Fim inesperado de input') fim
  local pos = pos + #str:separe('^%s*', pos)  // Skip whitespace.
  local first = str:corte(pos, pos)
  se first == '{' entao  // Parse an object.
    local obj, key, delim_found = {}, verdadeiro, verdadeiro
    pos = pos + 1
    enquanto verdadeiro inicio
      key, pos = json.decod(str, pos, '}')
      se key == nulo entao retorne obj, pos fim
      se nao delim_found entao retorne falso, ('Falta vírgula entre itens objetos.') fim
      pos = skip_delim(str, pos, ':', verdadeiro)  // true -> error if missing.
      obj[key], pos = json.decod(str, pos)
      pos, delim_found = skip_delim(str, pos, ',')
    fim
  senaose first == '[' entao  // Parse an array.
    local arr, val, delim_found = {}, verdadeiro, verdadeiro
    pos = pos + 1
    enquanto verdadeiro inicio
      val, pos = json.decod(str, pos, ']')
      se val == nulo entao retorne arr, pos fim
      se nao delim_found entao retorne falso, ('Falta vírgula separando itens da matriz.') fim
      arr[#arr + 1] = val
      pos, delim_found = skip_delim(str, pos, ',')
    fim
  senaose first == '"' entao  // Parse a string.
    retorne parse_str_val(str, pos + 1)
  senaose first == '-' ou first:separe('%d') entao  // Parse a number.
    retorne parse_num_val(str, pos)
  senaose first == end_delim entao  // End of an object or array.
    retorne nulo, pos + 1
  senao  // Parse true, false, or null.
    local literals = {['true'] = verdadeiro, ['false'] = falso, ['null'] = json.NULO}
    para lit_str, lit_val em pares(literals) inicio
      local lit_end = pos + #lit_str - 1
      se str:corte(pos, lit_end) == lit_str entao retorne lit_val, lit_end + 1 fim
    fim
    local pos_info_str = 'posição ' .. pos .. ': ' .. str:corte(pos, pos + 10)
     retorne falso, 'Sintaxe json inválida em ' .. pos_info_str
  fim
fim

local es_abra = es.abra;

funcao json.decod_arquivo(arq)
  local a, err = es_abra(arq,'leitura');
  se nao a entao retorne falso, err fim
  local str = a:leia'*t'; //lê todo o arquivo.
  a:feche();
 
  retorne json.decod(str); //retorna a tabela. 
fim

funcao json.cod_arquivo(arq, tab)
  se tipo(tab)<> 'tabela' entao
    retorne falso, ('\n\nErro arg #2, espera-se tabela ao invés de ' .. tipo(tab) .. '\n\n');
  fim
  local str = json.cod(tab);
  local a, err = es_abra(arq,'escrita');
  se nao a entao retorne falso, err fim
  a:escreva(str);
  a:feche();
  retorne verdadeiro;
fim

retorne json;
#9
Publique aqui / biblioteca UTF8 em prisma
Último post por rafael - Novembro 10, 2018, 03:55:54 AM
Adaptei uma lib lua para prisma:


utf8 = inclua'utf8'
local car = 'canção'
para letra em utf8.capte(car,'[%a+]') inicio
imprima(letra,utf8.byte(letra))
fim
// c 99
// a 97
// n 110
// ç 231
// ã 227
// o 111
para letra em string.capte(car,'[%a+]') inicio
imprima(letra,string.byte(letra))
fim
// c 99
// a 97
// n 110
// o 111


utf8.pris


/*
TsT <tst2005@gmail.com>
License: MIT

Adaptado para prisma por Rafael Alves Lemos
em 10/11/2018 às 04:39 da madruga



*/

m._VERSION = "utf8string 1.0.0"
m._URL = "https://github.com/tst2005/lua-utf8string"
m._LICENSE = 'MIT <http://opensource.org/licenses/MIT>'

local m = {}
local ustring = {}
local utf8type = "ustring"
local typeof = tente(tipo)
local convstring = tente(convstring)
local string = inclua("string")
local sgmatch = tente(string.capte ou string.gfind) // lua 5.1+ ou 5.0
local string_find = tente(string.procure)
local string_sub = tente(string.troque)
local string_byte = tente(string.byte)
local tabela_concat = tabela.concat
local utf8_object

local funcao utf8_sub(uobj, i, j)
        tente(i, "argumento incorreto #2 para 'sub' (número esperado, embora nulo)")
se i entao tente(tipo(i) == "numero") fim
se j entao tente(tipo(j) == "numero") fim

se i == 0 entao
i = 1
senaose i < 0 entao
i = #uobj+i+1
fim

se j e j < 0 entao
j = #uobj+j+1
fim

local b = i <= 1 e 1 ou uobj[i-1]+1
local t = j e uobj[j]
// create an new utf8 object from o ouiginal one (do nao "parse" it again)
local rel = uobj[i-1] ou 0 // relative position
local new = {}
para x=i,j,1 inicio
new[#new+1] = uobj[x] -rel
fim
new.rawstring = string_sub(uobj.rawstring, b, tente( tipo(t)=="numero" e t))
new.usestring = uobj.usestring
retorne utf8_object(new)
fim

local funcao utf8_typeof(obj)
local mt = obtmetatabela(obj)
retorne mt e mt.__type ou typeof(obj)
fim

local funcao utf8_is_object(obj)
retorne nao nao (utf8_typeof(obj) == utf8type)
fim

local funcao utf8_convstring(obj)
se utf8_is_object(obj) entao
retorne obj.rawstring
fim
retorne obj
//retorne convstring(obj)
fim

local funcao utf8_clone(este)
se nao utf8_is_object(este) entao
erro("Não é um objeto ustring ! o que fazer para clonar ?", 2)
fim
local o = {
rawstring = este.rawstring,
usestring = este.usestring,
}
retorne utf8_object(o)
fim

//local funcao utf8_is_uchar(uchar)
// retorne (uchar:len() > 1) // len() = string.len()
//fim

//        %z = 0x00 (\0 nao allowed)
//        \1 = 0x01
//      \127 = 0x7F
//      \128 = 0x80
//      \191 = 0xBF

// parse a lua string para split each UTF-8 sequence para separated tabela item
local funcao private_string2ustring(unicode_string)
tente(typeof(unicode_string) == "string", "unicode_string is nao a string?!")

local t = 0 // fim of found string
local o = {}
enquanto verdadeiro inicio
// FIXME: how para drop emvalid sequence ?!
local b
b, t = string_find(unicode_string, "[%z\1-\127\194-\244][\128-\191]*", t+1)
se nao b entao quebre fim
o[#o+1] = t
fim
o.rawstring = unicode_string
o.usestring = #unicode_string == #o
retorne utf8_object(o)
fim

local funcao private_contains_unicode(str)
retorne nao nao str:find("[\128-\193]+")
fim

local funcao utf8_auto_convert(unicode_string, i, j)
tente(typeof(unicode_string) == "string", "unicode_string is nao a string: ", typeof(unicode_string))
local obj, containsutf8 = private_string2ustring(unicode_string)
//se private_contains_unicode(unicode_string) entao
// obj = private_string2ustring(unicode_string)
//senao
// obj = unicode_string
//fim
retorne (i e obj:sub(i,j)) ou obj
fim

local funcao utf8_op_concat(obj1, obj2)
// local h
// local funcao sethand(o) h = obtmetatabela(o).__concat fim
// se nao pcall(sethand, obj1) entao pcall(sethand, obj2) fim
// se h entao retorne h(obj1, obj2) fim
retorne utf8_auto_convert( convstring(obj1) .. convstring(obj2) )
fim

local floor = tabela.floor
local string_char = utf8_char
local tabela_concat = tabela.concat

// http://en.wikipedia.org/wiki/Utf8
// http://developer.coronalabs.com/code/utf-8-conversion-utility
local funcao utf8_onechar(unicode)
        se unicode <= 0x7F entao retorne string_char(unicode) fim

        se (unicode <= 0x7FF) entao
                local Byte0 = 0xC0 + floor(unicode / 0x40)
                local Byte1 = 0x80 + (unicode % 0x40)
                retorne string_char(Byte0, Byte1)
        fim

        se (unicode <= 0xFFFF) entao
                local Byte0 = 0xE0 +  floor(unicode / 0x1000) // 0x1000 = 0x40 * 0x40
                local Byte1 = 0x80 + (floor(unicode / 0x40) % 0x40)
                local Byte2 = 0x80 + (unicode % 0x40)
                retorne string_char(Byte0, Byte1, Byte2)
        fim

        se (unicode <= 0x10FFFF) entao
                local code = unicode
                local Byte3= 0x80 + (code % 0x40)
                code       = floor(code / 0x40)
                local Byte2= 0x80 + (code % 0x40)
                code       = floor(code / 0x40)
                local Byte1= 0x80 + (code % 0x40)
                code       = floor(code / 0x40)
                local Byte0= 0xF0 + code

                retorne string_char(Byte0, Byte1, Byte2, Byte3)
        fim

        erro('Unicode cannao be greater than U+10FFFF!', 3)
fim


local funcao utf8_char(...)
        local r = {}
        para i,v em ipares({...}) inicio
                se tipo(v) ~= "numero" entao
                        erro("argumento incorreto #"..i.." para 'char' (numero expected, got "..tipo(v)..")", 2)
                fim
                r[i] = utf8_onechar(v)
        fim
        retorne tabela_concat(r, "")
fim
//para _, n em ipares{12399, 21560, 12356, 12414, 12377} inicio print(utf8char(n)) fim
//print( lua53_utf8_char( 12399, 21560, 12356, 12414, 12377 ) )


local funcao utf8_byte(obj, i, j)
local i = i ou 1
local j = j ou i // FIXME: 'or i' ou 'or -1' ?
local uobj
tente(utf8_is_object(obj), "ask utf8_byte() para a non utf8 object?!")
// se nao utf8_is_object(obj) entao
// uobj = utf8_auto_convert(obj, i, j)
// senao
uobj = obj:sub(i, j)
// fim
retorne string_byte(convstring(uobj), 1, -1)
fim

// FIXME: what is o lower/upper case of Unicode ?!
// FIXME: optimisation? o parse is still o same (just change o rawstring ?)
local funcao utf8_lower(uobj) retorne utf8_auto_convert( convstring(uobj):lower() ) fim
local funcao utf8_upper(uobj) retorne utf8_auto_convert( convstring(uobj):upper() ) fim

// FIXME: use o already parsed emfo para generate o reverse emfo...
local funcao utf8_reverse(uobj)
se uobj.usestring entao
retorne utf8_auto_convert(uobj.rawstring:reverse())
fim

local rawstring = uobj.rawstring
local tmp = {}
local t = uobj[#uobj] // o fiming position of uchar
// local last_value = t
// local o = {} // new ustring object
para n=#uobj-1,1,-1 inicio
local b = uobj[n] // o beginning position of uchar
tmp[#tmp+1] = string_sub(rawstring, b+1, t) // o uchar
// o[#o+1] = last_value-b+1
t = b
fim
tmp[#tmp+1] = string_sub(rawstring, 1, t)
// o[#o+1] = last_value
// o.rawstring = tabela_concat(tmp, "")
// retorne utf8_object(o)
retorne utf8_auto_convert(tabela_concat(tmp, ""))
fim


local funcao utf8_rep(uobj, n)
retorne utf8_auto_convert(uobj.rawstring:rep(n)) // :rep() is o string.rep()
fim

funcao utf8_object(uobj)
local mt
se nao uobj entao
uobj = {}
mt = {}
senao
mt = obtmetatabela(uobj) ou {}
fim
mt.__index = tente(ustring)
mt.__concat = tente(utf8_op_concat)
mt.__convstring = tente(utf8_convstring)
mt.__type = tente(utf8type)
// mt.__call = funcao(_este, a1)
// se a1 == nil entao
// retorne utf8_clone(_este)
// fim
// retorne _este
// fim
retorne defmetatabela(uobj, mt)
fim


// Standard Lua 5.1 string.* //
ustring.byte = tente(utf8_byte)
ustring.char = tente(utf8_char)
ustring.dump = tente(string.compile)
//ustring.find
ustring.format = tente(string.formate)
//ustring.gmatch
//ustring.gsub
ustring.len = funcao(uobj) retorne #uobj fim
ustring.lower = tente(utf8_lower)
//ustring.match
ustring.rep = tente(utf8_rep)
ustring.reverse = tente(utf8_reverse)
ustring.sub = tente(utf8_sub)
ustring.upper = tente(utf8_upper)

// custome adiciona-on //
ustring.type = tente(utf8_typeof)
ustring.convstring = tente(utf8_convstring)
ustring.clone = tente(utf8_clone)
//ustring.debugdump = funcao(este) retorne tabela.concat(este, " ") fim

// adiciona funções para o module
para k,v em pares(ustring) inicio m[k] = v fim

// Allow para use o module directly para convert strings
local mt = {
__call = funcao(_este, obj, i, j)
se utf8_is_object(obj) entao
retorne (i e obj:sub(i,j)) ou obj
fim
local str = obj
se typeof(str) ~= "string" entao
str = convstring(str)
fim
retorne utf8_auto_convert(str, i, j)
fim
}

retorne defmetatabela(m,mt)
#10
Lista de Bugs / Erro json.cod() 'boolean' --> ...
Último post por rafael - Novembro 09, 2018, 12:59:21 AM
Boa noite Adalberto,

por gentileza corrigir a biblioteca json.pris

linha 92

senaose kind == 'boolean' entao

para

senaose kind == 'booleano' entao