Augus
Augus es un lenguaje de programación multiplataforma de mediano nivel, de código abierto e interpretado. Está basado en PHP y en MIPS. Su principal funcionalidad es ser un lenguaje intermedio, ni de alto nivel como PHP ni de bajo nivel como el lenguaje ensamblador de MIPS.
Augus | ||
---|---|---|
Desarrollador(es) | ||
Universidad de San Carlos de Guatemala Sitio web oficial | ||
Información general | ||
Extensiones comunes | .aug | |
Paradigma | imperativo | |
Apareció en | 2020 | |
Diseñado por | Luis Espino | |
Última versión estable | 0.1[1] (20 de mayo de 2020 (4 años, 5 meses y 30 días)) | |
Sistema de tipos | Dinámico, débil | |
Influido por | PHP, MIPS | |
Sistema operativo | Multiplataforma | |
Licencia | GNU GPL v3[2] | |
Nace por la necesidad de un código intermedio para fines académicos. Específicamente para ser utilizado en el curso de Compiladores 2[3] de la Universidad de San Carlos de Guatemala. El intérprete será construido en el mes de junio, próximamente se incluirá el enlace de descarga.
Características
editarEl lenguaje tiene algunas restricciones:
- Cada instrucción es una operación simple, correspondientes en su mayoría a las instrucciones de Assembler de MIPS
- En cada instrucción hay un máximo de dos operandos y su asignación, por eso el 3A de Three Address.
- En cuanto a los registros PHP y MIPS comparten la definición de registros o variables anteponiendo el símbolo $.
Es un lenguaje débilmente tipado, sin embargo, si se reconocen cuatro tipos de datos no explícitos: entero, punto flotante, cadena de caracteres y arreglo.
Para manejar el flujo de control se proporciona la declaración de etiquetas y la instrucción goto.
Registros, Augus utiliza registros similares a los de MIPS:[4]
- $t0..$tn: temporales
- $a0..$an: parámetros
- $v0: valor devuelto en función
- $ra: simulador de dirección de retorno mediante nivel de ejecución
- $s0..$sn: pila
- $sp: puntero de pila
Sintaxis
editarInstrucciones simples y unarias
editarInstrucción | Descripción |
---|---|
main: | Inicio del programa. |
label: | Definición del inicio de una etiqueta. |
goto label: | Salto incondicional hacia una etiqueta. |
$t1 = 10; | Asignación numérica. |
$t1 = 'hola'; | Asignación de una cadena de caracteres. |
$t1 = $t2; | Copia simple. |
$t1 = - $t2; | Negativo. |
$t1 = &t2; | $t1 es un puntero a la dirección de $t2. |
unset($t1); | Destruye la variable $t1. |
print($t1); | Imprime en pantalla el contenido de $t1. |
$t1 = read(); | Lee la entrada del teclado queda en $t1. |
#comment | Comentario de una sola línea. |
exit; | Finaliza la ejecución (es opcional). |
Instrucciones aritméticas
editarInstrucción | Descripción |
---|---|
$t1 = $t2 + $t3; | Suma. |
$t1 = $t2 - $t3; | Resta. |
$t1 = $t2 * $t3; | Multiplicación. |
$t1 = $t2 / $t3; | División. |
$t1 = $t2 % $t3 | Residuo. |
$t1 = abs($t2); | Valor absoluto. |
Instrucciones lógicas
editarInstrucción | Descripción |
---|---|
$t1 = !$t2; | Not, si $t2 es 0 $t1 es 1, si $t2 es 1 $t1 es 0. |
$t1 = $t2 && $t3; | And, 1 para verdadero, 0 para falso. |
$t1 = $t2 || $t3; | Or, 1 para verdadero, 0 para falso. |
$t1 = $t2 xor $t3; | Xor, 1 para verdadero, 0 para falso. |
Instrucciones bit a bit
editarInstrucción | Descripción |
---|---|
$t1 = ~$t2; | Not. |
$t1 = $t2 & $t3; | And. |
$t1 = $t2 | $t3; | Or. |
$t1 = $t2 ^ $t3; | Xor. |
$t1 = $t2 << $t3; | Shift de $t2, $t3 pasos a la izquierda. |
$t1 = $t2 >> $t3; | Shift de $t2, $t3 pasos a la derecha. |
Instrucciones relacionales
editarInstrucción | Descripción |
---|---|
$t1 = $t2 == $t3; | $t1 = 1 si $t2 es igual a $t3, sino 0. |
$t1 = $t2 != $t3; | $t1 = 1 si $t2 no es igual a $t3, sino 0. |
$t1 = $t2 >= $t3; | $t1 = 1 si $t2 es mayor o igual a $t3, sino 0. |
$t1 = $t2 <= $t3; | $t1 = 1 si $t2 es menor o igual a $t3, sino 0. |
$t1 = $t2 > $t3; | $t1 = 1 si $t2 es mayor a $t3, sino 0. |
$t1 = $t2 < $t3; | $t1 = 1 si $t2 es menor a $t3, sino 0. |
Arreglos, cadenas y estructuras
editarHay dos tipos de arreglos:
- El numérico funciona como los arreglos convencionales, por ejemplo, asignar en el índice 4 del arreglo el valor uno: $t1[4] = 1;.
- El asociativo funciona como un struct de C, o como una clase en C++ (solo datos), por ejemplo, $t1 es el registro con dos componentes uno llamado nombre de tipo cadena y otro llamado edad de tipo numérico: $t2['nombre'] = 'Carlos'; $t2['edad'] = 20;
Las cadenas de caracteres también son considerados arreglos.
Instrucción | Descripción |
---|---|
$t1 = array(); | Define $t1 como un arreglo o un struct, para diferenciarlos se utiliza ya sea el valor numérico o el nombre asociativo. |
$t1[4] = 1; | Asignación de un valor numérico (1) a un índice del arreglo (4). |
$t1['nombre'] = 'Carlos'; | Asignación de un valor cadena (Carlos) a un componente del struct (nombre). |
$t1 = $t1[4]; | Acceso a un índice del arreglo. |
$t1 = $t2['nombre']; | Acceso a un componente del struct. |
$t1 = 'hola';
print($t1[0]); #imprime h |
Acceder a un carácter de una cadena. |
Instrucciones de control
editarInstrucción | Descripción |
---|---|
if ($t1) goto label; | Salto condicional, si $t1 es 1 salto, sino sigue la siguiente instrucción, $t1 puede ser relacional. Las estructuras de control se implementan utilizando este salto condicional. |
Funciones y procedimientos
editarLa diferencia entre una función y un procedimiento radica en que si trae o no un valor de retorno. Dicho valor se tomará con el registro $v0, si hay llamadas a otras funciones se incrementará el índice de dicho registro, simulando el uso del STACK.
En vez de utilizar los conocidos CALL y RETURN, se utilizarán los registros de parámetros y el de valor de retorno, junto con los GOTO para simular la llamada como se hace en MIPS con jal y jr.[5]
Programación
editarEjemplo 1
editarEjemplo de un while escrito en lenguaje C:
int main()
{
int x = 0;
int a = 0;
while(x<4)
{
a = a + x;
x = x + 1;
}
printf("%d",a);
}
Código equivalente en Augus:
main:
$t1 = 0;
$t2 = 0;
while:
if ($t1>=4) goto end;
$t2 = $t2 + $t1;
$t1 = $t1 + 1;
goto while;
end:
print($t2);
Ejemplo 2
editarEjemplo de una función con llamada a otra función escrita en lenguaje C:
int f1(int a)
{
return f2(a);
}
int f2(int a)
{
return a*a;
}
int main()
{
int a = 5;
a = f1(a);
printf("%d",a);
}
Código equivalente en Augus:
main:
$a0 = 5;
goto f1;
ret0:
print($v0);
exit;
f1:
$a1 = $a0;
goto f2;
ret1:
$v0 = $v1;
goto ret0;
f2:
$v1 = $a1*$a1;
goto ret1;
Ejemplo 3
editarEjemplo de la función factorial recursiva escrita en lenguaje C:
int fact(int a)
{
if (a<=1)
return 1;
else
return a*fact(a-1);
}
int main()
{
printf("%d",fact(3));
}
Código equivalente en Augus:
main:
$a0 = 3;
$ra = 0; #level 0
goto fact;
ret0:
print($v0);
exit;
fact:
if ($a0>1) goto sino;
$v0 = 1;
if ($ra==0) goto ret0;
$ra = $ra - 1;
goto ret1;
sino:
$a0 = $a0 - 1;
$ra = $ra + 1; #level ++
goto fact;
ret1:
$a0 = $a0 + 1;
$v0 = $a0 * $v0;
if ($ra==0) goto ret0;
$ra = $ra - 1;
goto ret1;
Véase también
editarReferencias
editar- ↑ «Augus/version». GitHub. Consultado el 27 de mayo de 2020.
- ↑ «Augus/LICENSE at master». GitHub. Consultado el 27 de mayo de 2020.
- ↑ Curso de Compiladores 2, Universidad de San Carlos de Guatemala, Primer Semestre 2020.
- ↑ Patterson & Hennessy - Apéndice A (PDF), Página A-24 Figura A.6.1.
- ↑ Lectura No. 5 (PDF), Universidad de Washington, CSE378: Machine Organization & Assembly Language.
Enlaces externos
editar- Página web oficial
- Programmed Introduction to MIPS Assembly Language, Central Connecticut State University
- Tuple-Based Intermediate Representations, Loyola Marymount University