Decidi por abrir algumas informações sobre um projeto que iniciei a alguns anos atrás... que ficou bastante tempo parado e agora estou dando uma olhada nele novamente, esse projeto denominei ele de Clipper++, que é um estudo que iniciei sobre o dev. de compiladores... depois de obter muito conhecimento no desenvolvimento de compiladores, como com o meu projto, Zinnia Language, decidi iniciar a implementação da minha versão do CA-Clipper, com a ideia de ser compativel com CA-Clipper 5.3b.
Bom, esse projeto tem algumas diferenças bastante fortes, comparado com o funcionamento do Clipper / Harbour / xBase++ e seus derivados, a grande diferença é que o meu compilador gera código nativo de maquina, diferente do CA-Clipper/Harbour e etc, que gera um código C com todos os P-Codes dentro de um array, que é interpretado em tempo de execução.
Outra diferença é que o Clipper++ surgiu com a ideia ja da orientação a objetos, mesmo o que é considerado função no Clipper, como QOUT, na verdade é um metodo dentro da classe STD da runtime da linguagem, um pequeno exemplo da classe STD:
*****************************************************************************
*** Arquivo CONSOLE.PRG
*****************************************************************************
PARTIAL CLASS CLPSTD
PRIVATE:
STATIC METHOD COUT(__STRING STR)
PUBLIC:
STATIC METHOD QOUT(...)
ENDCLASS
STATIC METHOD COUT(__STRING STR) CLASS CLPSTD
LOCAL __INT32 NPRTCHR := 0
LOCAL __STRING TMPSTR := ""
IF STR == NIL
TMPSTR := "NIL"
ENDIF
NPRTCHR := EXTERNAL("msvcrt.dll", "printf", "%s", TMPSTR)
RETURN NPRTCHR
STATIC METHOD QOUT(...) CLASS CLPSTD
LOCAL __INT32 NARGS := 0
LOCAL __ARRAY AARGS := {}
NARGS := ARGCOUNT()
IF NARGS <= 0
CLPSTD:COUT("")
RETURN NIL
ELSE
CLPSTD:COUT(CLPSTD:CRLF)
ENDIF
FOR I := 0 TO NARGS
IF I > 0
CLPSTD:COUT(" ")
ENDIF
CLPSTD:COUT(AARGS[I])
NEXT
RETURN NIL
Claro, que isso é um pequeno exemplo, existem diversas outras coisas ja implementadas, mas, após verificar muitas coisas, decidi por alterar muitas coisas na runtime, como o acesso a funções externas, no caso, atualmente é utilizando o "keyword" __EXTERNAL, a tipagem das variáveis são necessárias apenas para a chamada de funções externas, definidas em DLLs, que existem a tipagem correta.
Devido a natureza do compilador, não é necessário ficar mixando código C com xBase, pois, o compilador compila o código xBase diretamente para nÃvel de maquina, portanto, toda a runtime do compilador é escrito na propria linguagem do compilador...
Atualmente, o compilador ainda é closed source, mas, assim que terminar algumas modificações, irei liberar o código fonte no seguinte repositório, ( https://github.com/bencz/ClipperPlusPlus ).
Segue um pequeno exemplo de um código que o compilador já é capaz de compilar e executar com sucesso:
PROCEDURE MAIN()
LOCAL ASTRUCT1 := { { "CODIGO", "C", 3, 0 }, { "NOME" , "C", 30, 0 }}
DBCREATE( "CLIENTES", ASTRUCT1 )
dbUseArea( .T.,, "CLIENTES",, if(.F. .OR. .F., !.F., NIL), .F.,, )
dbCreateIndex( "CLI1", "CODIGO", {|| CODIGO}, if( .F., .T., NIL ) )
CLIENTES->( DBAPPEND() )
_FIELD->CODIGO := "001" ; _FIELD->NOME := "ALEXANDRE BENCZ"
CLIENTES->( DBAPPEND() )
_FIELD->CODIGO := "002" ; _FIELD->NOME := "RICARDO BENCZ"
CLIENTES->( DBAPPEND() )
_FIELD->CODIGO := "003" ; _FIELD->NOME := "CARLOS BENCZ"
dbGoTop()
while !EOF()
QOut( CLIENTES->CODIGO, CLIENTES->NOME )
dbSkip(1)
ENDDO
dbCloseAll()
dbSelectArea( "1" )
FERASE("CLIENTES.DBF")
FERASE("CLI1.NTX")
RETURN NIL
Esse mesmo código, usando os padrões do xBase ( que tem um monte de coisas que são convertidas no pré-processamento.. ), fica igual ao seguinte código:
PROCEDURE MAIN()
LOCAL ASTRUCT1 := { ;
{ "CODIGO", "C", 3, 0 }, ;
{ "NOME" , "C", 30, 0 }}
DBCREATE( "CLIENTES", ASTRUCT1 )
USE CLIENTES NEW
INDEX ON CODIGO TO CLI1
CLIENTES->( DBAPPEND() )
REPLACE CODIGO WITH "001", NOME WITH "ALEXANDRE BENCZ"
CLIENTES->( DBAPPEND() )
REPLACE CODIGO WITH "002", NOME WITH "RICARDO BENCZ"
CLIENTES->( DBAPPEND() )
REPLACE CODIGO WITH "003", NOME WITH "CARLOS BENCZ"
GO TOP
DO WHILE !EOF()
? CLIENTES->CODIGO, CLIENTES->NOME
SKIP
ENDDO
CLOSE ALL
FERASE("CLIENTES.DBF")
FERASE("CLI1.NTX")
RETURN NIL
Tenho planos para implementar o pré-processador... mas, isso fica para outros tempos...., um dia implemento o carinha
Enfim, vale ressaltar aqui que esse é um projeto de estudos...., esse projeto não tem o intuito de ser um produto comercial, ou seja eu não irei cobrar para utilizar ele ou qualquer coisa parecida...
Por este motivo, o projeto é 100% open-source e regido sob a licença do LGPL v3 ( podendo ser alterada a qualquer momento, para uma licença mais rÃgida, caso seja necessário... )