Augus

Lenguaje de programación

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

editar

El 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

editar

Instrucciones simples y unarias

editar
Instrucció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

editar
Instrucció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

editar
Instrucció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

editar
Instrucció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

editar
Instrucció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

editar

Hay 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

editar
Instrucció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

editar

La 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

editar

Ejemplo 1

editar

Ejemplo 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

editar

Ejemplo 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

editar

Ejemplo 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

editar

Referencias

editar
  1. «Augus/version». GitHub. Consultado el 27 de mayo de 2020. 
  2. «Augus/LICENSE at master». GitHub. Consultado el 27 de mayo de 2020. 
  3. Curso de Compiladores 2, Universidad de San Carlos de Guatemala, Primer Semestre 2020.
  4. Patterson & Hennessy - Apéndice A (PDF), Página A-24 Figura A.6.1.
  5. Lectura No. 5 (PDF), Universidad de Washington, CSE378: Machine Organization & Assembly Language.

Enlaces externos

editar