Lenguaje de programacion DvLang
- g++
- make
- coco-cpp
- libffi
- rapidjson
- mingw-w64
- mingw-std-threads solo es necesario cuando la compilacion se lleva a cabo en versiones muy antiguas de Windows
Luego de instalar los requerimientos, procedemos con la compilacion del codigo fuente.
$ git clone https://github.com/Davidc2525/DvLang.git
$ cd DvLang
$ mkdir out
$ make
$ cd src/compiler
$ make
$ cd ../../
Si la compilacion se lleva a cabo en windows
$ git clone https://github.com/Davidc2525/DvLang.git
$ cd DvLang
$ mkdir out
$ make -f Makefile.win
$ cd src/compiler
$ make
$ cd ../../
Nota: make -f Makefile.win se use igual para las otras partes donde se compila parte del codigo.
Luego de compilar es hora de programar en DvLang
//test/dvlang.dv
package main
{
/*
* Sumar dos numeros
* */
int sumar(int a, int b){
return a + b;
}
void main(){
print(sumar(20,5));
}
}
Luego compilamos el codigo fuente y ejecutamos
$ out/Dvc test/dvlang.dv -o out.dvc.json
Se muestra informacion sobre la compilacion
...
INST [16] : 5
INST [17] : 0
INST [18] : 0
INST [19] : 41
INST [20] : 7
INST [21] : 27
INST [22] : 28
INST [23] : 29
FILE out.dvc.json
MAIN 10
SIZE 24
libs: 0
compilado.
Luego de la compilacion, ejecutamos:
$ out/DvVm out.dvc.json
La salida de la ejecucion es la suma de los operandos en el codigo
25
La API de DvLang te permite ejecutar funciones nativas escritas en C/C++
Vamos a escribir y usar una libreria de C++
archivo: /src/libs_std/std/std.cpp C++
...
int println(DvVmEnv vm, dv_string str)
{
char *c_str = STRING::String::dv_str_to_c_srt(vm.process->heap, (str));
int size = vm.process->heap->get(str);
for (int x = 0; x < size; x++)
{
cout << c_str[x];
}
cout << endl;
free(c_str);
return size;
}
...
Descritas las funciones nativas que queremos usar de lado de DvLang, compilamos.
Nota: Todas las funciones descritas en C/C++ para usar como funciones nativas en DvLang, deben tener como primer parametro DvVmEnv vm que es una instancia del entorno de ejecucion, es auntomaticamente pasado cuando se llama a dicha funcion desde DvLang, los parametros que quieres usar, se describen luego del vm, como en este ejemplo, la funcion debe imprimir una cadena, la recibe como segundo parametro. Mas adelante se muestra un ejemplo.
En la rruta src/libs_std/std/, hay archivos que sirven como plantilla para crear otras librerias de funciones nativas.
Dentro de src/libs_std/std/ ejecutamos:
$ cd src/libs_std/std
$ make clear compile
$ cd ../../../
Eso nos deja una libreria DvLang/src/libs_std/std/libstd.so que usaremos en un archivo fuente de DvLang
archivo: DvLang/test/std.dv DvLang
package std
@load_lib "--tu_home--/DvLangVM/src/libs_std/std/libstd.so";
{
...
/**
* Native println, imprime str y al final coloca un salto de linea
*/
native int println(string str);
...
}
Se tiene que usar la sentencia: @load_lib "path.so" con la rruta de la libreia compilada para bincular con la declaracion dentro de DvLang, El compilador hace el resto.
Nota: Como se menciono anteriormente, en esta parte de la declaracion de la funcion nativa, solo se describe un solo parametro, ques la cadena que se quiere imprimir.
Luego hacemos uso de las funciones nativas creadas.
archivo: DvLang/test/dvlang_native.dv DvLang
package main
@include "test/std.dv";
{
string hola(string mundo){
return "hola " + mundo;
}
void main(){
println(hola("mundo c:"));
}
}
Compilamos el archivo fuente
$ out/Dvc test/dvlang_native.dv -o out.dvc.json
Se muestra informacino sobre la compilacion.
...
INST [101] : 39
INST [102] : 1
INST [103] : 0
INST [104] : 88
INST [105] : 41
INST [106] : 0
INST [107] : 1
INST [108] : 31
INST [109] : 27
INST [110] : 28
INST [111] : 29
FILE out.dvc.json
MAIN 98
SIZE 112
libs: 10
nueva lib: /home/david/DvLangVM/src/libs_std/std/libstd.so
[0] 1 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: std_itos
[1] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: println
[2] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: println_ref
[3] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: strlen
[4] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: std_u_sleep
[5] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: std_sleep
[6] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: std_malloc
[7] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: std_calloc
[8] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: std_realloc
[9] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: std_free
compilado.
Ahora ejecutamos.
$ out/DvVm out.dvc.json
Apreciemos su salida:
hola mundo c:
En DvLang se puede definir clases, veamos como se hace. Archivo: DvLang/test/clase1.dv DvLang
...
class Usuario {
string nombre;
int anios;
Usuario construct(string n,int a){
this.nombre = n;
this.anios = a;
return this;
}
}
{
void main(){
Usuario n1;
u1 = new Usuario("Lola",25);
println(u1.nombre+", tiene "+u1.anios+" aƱos.");
//se recomienda usar -> std_itos(u1.anios)
//para concatenar numero con cadena
}
}
...
Compilamos y ejecutamos
$ out/Dvc test/dvlang_native.dv -o out.dvc.json
$ out/DvVm out.dvc.json
Apreciemos su salida:
Lola, tiene 25 aƱos.
Nota: Es recomendable usar std_itos para cuando se quiera imprimir un numero por terminal.
No pueden faltar las listas o arrays, en DvLang se pueden crear lista de elementos y/o lista de objetos de un tipo de clase.
Archivo: DvLang/test/array1.dv DvLang
package main
@include "test/std.dv";
class Usuario {
string nombre;
int anios;
Usuario construct(string n,int a){
this.nombre = n;
this.anios = a;
return this;
}
}
{
void main(){
int cantidad,x;
Usuario u;
Usuario [] users;
cantidad = 100;
users = new Usuario[cantidad];
x = 0;
while (x < cantidad) {
users[x] = new Usuario("usuario_"+std_itos(x),x);
x = x + 1;
}
x = 0;
while (x < cantidad) {
u = users[x];
println(u.nombre+", tiene "+std_itos(u.anios)+" aƱos.");
x = x + 1;
}
}
}
Compilamos y ejecutamos
$ out/Dvc test/array1.dv -o out.dvc.json
$ out/DvVm out.dvc.json
Apreciemos su salida:
...
INST [206] : 163
INST [207] : 27
INST [208] : 28
INST [209] : 29
FILE out.dvc.json
MAIN 107
SIZE 210
libs: 10
nueva lib: /home/david/DvLangVM/src/libs_std/std/libstd.so
[0] 1 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: std_itos
[1] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: println
[2] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: println_ref
[3] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: strlen
[4] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: std_u_sleep
[5] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: std_sleep
[6] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: std_malloc
[7] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: std_calloc
[8] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: std_realloc
[9] 2 add symbol, lib: /home/david/DvLangVM/src/libs_std/std/libstd.so s: std_free
compilado.
usuario_0, tiene 0 aƱos.
usuario_1, tiene 1 aƱos.
usuario_2, tiene 2 aƱos.
usuario_3, tiene 3 aƱos.
usuario_4, tiene 4 aƱos.
usuario_5, tiene 5 aƱos.
usuario_6, tiene 6 aƱos.
...
DvLang cuenta con estructuras de control: while, if, if_else, veamos un ejemplo Archivo: DvLang/test/dvlang_flow.dv DvLang
package main
@include "test/std.dv";
{
void main(){
int x;
x = 25;
println("Primera comparacion");
if x == 25
println("x es igual a 25");
x = 26;
println("Segunda comparacion");
if x == 25
println("x es igual a 25");
else
println("x es diferente a 25");
x = 27;
println("Tercera comparacion");
if x == 25 {
println("x es igual a 25");
} else {
println("x es diferente a 25");
}
//Bucles
println("---------- Incrementar x ----------");
x = 1;
while x <= 10 {
println("Valor de x: "+std_itos(x));
x = x + 1;
}
println("---------- Decrementar x ----------");
x = 10;
while x >= 1 {
println("Valor de x: "+std_itos(x));
x = x - 1;
}
}
}
Compilamos y ejecutamos
$ out/Dvc test/dvlang_flow.dv -o out.dvc.json
$ out/DvVm out.dvc.json
Apreciemos su salida:
Primera comparacion
x es igual a 25
Segunda comparacion
x es diferente a 25
Tercera comparacion
x es diferente a 25
---------- Incrementar x ----------
Valor de x: 1
Valor de x: 2
Valor de x: 3
Valor de x: 4
Valor de x: 5
Valor de x: 6
Valor de x: 7
Valor de x: 8
Valor de x: 9
Valor de x: 10
---------- Decrementar x ----------
Valor de x: 10
Valor de x: 9
Valor de x: 8
Valor de x: 7
Valor de x: 6
Valor de x: 5
Valor de x: 4
Valor de x: 3
Valor de x: 2
Valor de x: 1
Los "(" ")" son opcionales en las sentencias if y while. Los "{" "}" en estas estructuras tambien son opcionales, a menos que se ejecuten mas de una lineas de codigo.
// sin ( ) y { }
if x == 1 print(x);
// con {}, por que hay mas de una linea
if( x==1 ){
print(x);
print(x+1);
}
- Llamadas a funciones como corrutinas
- Arrays multidimencionales
DvLang aun esta en desarrollo šØ, si quieres contribuir puedes contactarme š§.
Gmail: David25pcxtreme@gmail.com
Facebook: Colmenares David