Práctica 8 (26/10)
Orden del día:
- Explicación lab 6 + criterios de corrección
- Repaso de JsonLang/CompIR0
- Presentación de JsonAsm/CompIR5
- Comparación CompIR0 vs CompIR5
- Arquitectura propuesta
- CompIR0 a CompIR1: Traducir estructuras de control
- CompIR1 a CompIR2: Eliminar variables y scopes
- CompIR2 a CompIR3: Eliminar expresiones
- CompIR3 a CompIR4: Eliminar funciones
- CompIR4 a CompIR5: Eliminar labels
Bibliografía: esta vez no hay
Explicación Lab 6 + criterios de corrección#
- Aceptar el assignment (link ahora o en el mail luego)
- Clonar el assignment si quieren
- Puntaje (hasta 11! punto extra):
- Entrega (Pasan los test): 6 puntos
- 5 ó más tests que contienen la palabra "extra" en la descripción: +2 puntos
- El último commit del PR tiene fecha previa al 8/11 23:59: +1 puntos
- El último commit del PR tiene fecha previa al 15/11 23:59: +2 puntos
Repaso de JsonLang#
export type TopStatement<Expr> = /* estructuras de control */| { if: { cond: Expr; then: Statement<Expr> }[]; else?: Statement<Expr>;}| { while: Expr; do: Statement<Expr> }| Statement<Expr>[]| { iterator: string; from: Expr; to: Expr; step?: Expr; do: Statement<Expr> }| { do: Statement<Expr>; until: Expr }| "break"| "continue"
/* variables con scopes */| { declare: string; value: Expr }| { set: string; value: Expr }
/* funciones/procedimientos */| { call: string; args: Expr[] }| { return: Expr }| { function: string; args: string[]; block: Stmt;}Presentación de JsonAsm#
export type Statement =/* manejo de stack */ | { push: Memdir | { literal: number }|"pc" } | { pop: Memdir | "pc" }/* branches, jumps */ | { bz: Offset } | { bnz: Offset } | { jmp: Offset }/* aritmética */ | Binops | Unops;
type Offset = number;type Memdir = number;type Binops = "+" | "-" | "*" | "/" | "<=" | ">" | "==" | "and" | "or" /* etc */;type Unops = "neg" | "!" | "~";Comparación CompIR0 vs CompIR5#
| categoría | CompIR0/JsonLang | CompIR5/JsonAsm |
|---|---|---|
| control de flujo | if, while, iterator | jmp, bnz, bz |
| modelo de memoria | variables | memoria indexada |
| operaciones aritméticas | expresiones | operaciones sobre el stack |
| soporte de subprogramas | funciones | stack, operaciones sobre el PC |
Arquitectura propuesta#

CompIR0 a CompIR1: Traducir estructuras de control#
- Recorrido recursivo del AST (recursividad estructural)
- Agregar labels, branches condicionales y
pushde expresiones para replicar la semántica de las estructuras de control - Ver ejemplo while, if en starter
- Llegan:
lbl,push,bnz,bz,jmp,functionIntro,functionEnd,enterBlock,exitBlock - Se van:
if else,while do,iterator do,do until,break,continue - Flashback:
GeneralExecutor
CompIR1 a CompIR2: Eliminar variables#
- Mapeo.
- Flashback: clase
Context.functionIntro,enterBlock, etc. Invocan métodos deContext.- En vez de un diccionario de valores tiene un diccionario de IDs
- Se van: todas las variables,
functionIntro,functionEnd,enterBlock,exitBlock,declare
CompIR2 a CompIR3: Eliminar expresiones#
- Mapeo (
flatMap) de comandos, recursion dentro de las expresiones. - Calculadora postfija.
1 + 2se traduce a[{push: 1},{push:2},"+"] - En el caso de las invocaciones a funciones se debe agregar
callBeginantes de pushear los argumentos. - Se van:
push,set,call - Llegan:
callStart,callEnd
CompIR3 a CompIR4: Eliminar funciones#
returnse convierte en{pop:"pc"}. Pero qué pongo enpc?- El caller debe mandar el PC, sin perder su propio PC de retorno.
- Mi solución (es mejorable) (cada subprograma almacena su PC de retorno en
-3). Efecto sobre el stack de cada instrucción:callBegin:[]->[callerRetAddr]. (callerRetAddrestá en-3siempre)callEnd:[callerRetAddr,arg1,arg2,arg3]->[retval]functionIntro:[callerRetAddr,arg1,arg2,arg3,calledRetAddr]->[callerRetAddr]return:[callerRetAddr,retVal]->[callerRetAddr,retVal]. hace{pop:"pc"}de su dirección de retorno + 2.
- Pueden hacer casi todo el lab sin esta parte. Es conveniente que piensen de forma genérica en qué efecto tiene cada instrucción.
CompIR4 a CompIR5: Eliminar labels#
- Se van:
lbl - Algoritmo:
- Primera pasada: Crear un mapa de posiciones absolutas de cada label
- Segunda pasada: Reemplazar los labels por offsets
Orden recomendado de trabajo#
- Completar CompIR4Translator.ts con la implementación correcta, utilizando el unit test provisto.
- Completar CompIR3Translator.ts con "no-ops". Hay pocos ejemplos con funciones!
- Construir algunos (pocos!) unit tests para CompIR2Translator.ts
- Implementar CompIR2Translator.ts a partir de esos unit tests
- Implementación de CompIR1Translator.ts que ignore funciones y bloques.
- Workflow: Ejecutar los unittests, iterar ajustes de forma que pasen cada vez más tests.