# 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.
Nace por la necesidad de un código intermedio para fines académicos. Específicamente para ser utilizado en el curso de Compiladores 2 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

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:
* $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
### Instrucciones simples y unarias

| 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

| 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

| 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

| 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

| 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

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

| 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

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.

## Programación
### Ejemplo 1

Ejemplo de un while escrito en lenguaje C:
Código equivalente en Augus:

### Ejemplo 2

Ejemplo de una función con llamada a otra función escrita en lenguaje C:
Código equivalente en Augus:

### Ejemplo 3

Ejemplo de la función factorial recursiva escrita en lenguaje C:
Código equivalente en Augus: