Urbiscript es un lenguaje de programación para robótica. [3] Cuenta con soporte sintáctico para concurrencia y programación basada en eventos. Es un lenguaje de scripting orientado a objetos basado en prototipos . Es dinámico: la resolución de nombres se realiza durante la ejecución del programa ( enlace tardío ); se pueden agregar/eliminar ranuras ( variables miembro ) en tiempo de ejecución, e incluso se pueden cambiar prototipos ( superclases ) de un objeto en tiempo de ejecución.
La gestión de la memoria se realiza mediante el conteo de referencias .
Estrechamente vinculado a la plataforma Urbi, admite la integración perfecta de componentes C++/Java.
Desde el punto de vista sintáctico, urbiscript pertenece a la familia C de lenguajes de programación.
Su diseño orientado a objetos basado en prototipos fue influenciado por los lenguajes de programación Self e Io . [2]
Está diseñado para programar, pero también para interactuar con robots; [2] como tal, está influenciado por los shells de Unix y otros lenguajes que proporcionan un nivel superior interactivo de estilo bucle de lectura-evaluación-impresión . Sin embargo, a diferencia de otros, no hay un mensaje para la entrada del usuario, sino que las respuestas del sistema están precedidas por una marca de tiempo (en milisegundos) entre corchetes:
1 + 1; dormir(1s); 1 + 2 * 3;
Las declaraciones de urbiscript incluyen (entre otras): [4]
if
declaración , que ejecuta condicionalmente un bloque de código, junto con else
.for
La declaración tradicional , como en C, que itera sobre un objeto iterable, capturando cada elemento en una variable local para su uso por el bloque adjunto.for
declaración , que itera sobre un objeto iterable, capturando cada elemento en una variable local para su uso por el bloque adjunto.while
declaración , que ejecuta un bloque de código siempre que su condición sea verdadera.try
declaración , que permite que las excepciones lanzadas en su bloque de código adjunto sean capturadas y manejadas por catch
cláusulas. Se ejecuta una cláusula opcional else
si no se lanzó ninguna excepción. Se puede garantizar que el código de limpieza se ejecute en todos los casos cuando se proporciona en una finally
cláusula -.assert
declaración , se utiliza durante la depuración para verificar las condiciones que deben aplicarse. Urbiscript también cuenta con assert
bloques que se pueden usar para factorizar varias assert
declaraciones.En realidad, a diferencia de la mayoría de lenguajes tipo C y a pesar de lo que sugiere la sintaxis, las declaraciones "tienen un valor" y, por lo tanto, son expresiones, siempre que estén entre llaves:
var status = { if ( cerrado ) "cerrado" else "abierto" }; var pass = { try { foo } catch { false } else { true } };
En urbiscript, algunas construcciones de flujo de control vienen en varios "tipos": dos tipos de composición secuencial y dos tipos de composición concurrente. En segundo plano, la concurrencia se implementa mediante corrutinas . [5]
Al igual que en C, el punto y coma denota composición secuencial: a;b
significa "ejecutar sentencia a
y luego ejecutar sentencia " b
. Se pueden ejecutar otras tareas entre a
y b
. Otro separador de sentencias, la barra vertical, denota "composición secuencial estricta": no se puede ejecutar ninguna otra tarea entre a
y b
en a|b
.
De manera similar, urbiscript cuenta con dos medios para componer sentencias simultáneamente. Con a,b
, primero a
se ejecuta y en algún momento b
se ejecutará --- posiblemente mientras a
aún se esté ejecutando. Esto es muy similar al &
operador en los shells de Unix. Alternativamente, con a&b
, tanto a
y b
se inician juntos; en sesiones interactivas, esto significa que a
no se ejecutará hasta que b
se ingrese por completo y esté seguido correctamente por a ;
o a ,
.
Los alcances son límites para los trabajos en segundo plano, como se demuestra en el siguiente ejemplo: [5]
{ { dormir ( 2s ); eco ( 2 ) }, { dormir ( 1s ); eco ( 1 ) }, }; eco ( 3 );
La mayoría de las construcciones de bucle en urbiscript vienen en varios "tipos", que se basan en los cuatro separadores de declaraciones: ;
, |
, ,
, y &
.
Por ejemplo
// Esto en realidad es "para;". for ( var i : [ 0 , 1 , 2 ]) { echo ( i ); echo ( i ** 2 ); };
muestra
es decir, los cuerpos del bucle no se ejecutan secuencialmente, mientras que la for&
palabra clave ejecuta los cuerpos del bucle simultáneamente:
para& ( var i : [ 0 , 1 , 2 ]) { eco ( i ); eco ( i ** 2 ); };
Con el objetivo de desarrollar aplicaciones robóticas portátiles, [6] urbiscript se basa en construcciones sintácticas específicas para especificar comportamientos reactivos como "ir a la base de carga cuando la batería está baja", "reproducir un sonido amigable cuando se reconoce una cara conocida" o "detenerse cuando se detecta un obstáculo".
El manejo de eventos consta de tres pasos. Primero, definir un evento
var e = Evento . nuevo ;
En segundo lugar, especifique los controladores de eventos.
en ( e ?) echo ( "evento recibido e" );
En tercer lugar, "emitir" este evento
mi !;
Los eventos pueden tener cargas útiles, y los controladores de eventos disfrutan de la coincidencia de patrones en la carga útil:
en ( e ?( 1 , var x ) si x % 2 == 0 ) echo ( "evento recibido e(1, %s)" % x ); e !( 1 , 1 );
y !( 1 , 2 );
El lenguaje urbiscript también permite monitorizar expresiones:
en ( batteryLevel < = 0.2 ) robot.goToChargingDock ;
El siguiente ejemplo demuestra la característica:
var x = 0 ;
var y = 0 ;
var z = 0 ;
en ( x + y == z ) echo ( "%s + %s == %s" % [ x , y , z ]);
x = 1 ;
z = 1 ;