Proyecto Final
Fundamentos de Lenguajes Programación
Carlos Andres Delgado S, Msc
[email protected] Mayo de 2024
1. Reglas del Proyecto
1. No se permite copiar código de Internet ni de sus compañeros. Si se encuentra código
copiado el proyecto será anulado por completo.
2. Puede trabajar en grupos de hasta 4 personas
3. La entrega del proyecto se realizará con un enlace a un repositorio Github o similar en el
campus virtual, este debe contener el código fuente y el informe en formato PDF
4. Este proyecto debe ser sustentado, la nota de sustentación es individual y va entre 0 y 1.
Esta nota es multiplicada por la nota obtenida en el proyecto. Por ejemplo si su grupo
obtuvo 5.0 en nota y usted 0.5 en la sustentación, su nota será 2.5. La sustentacion será
el Jueves 20 de Junio de 7am a 1pm en el salón de clase.
2. El temible Meta-lenguaje: !El concilio de los paradig-
mas de programación!
La Universidad del Valle, seccional Tulua, ha priorizado los programas STEM (Ciencia,
tecnologı́a, ingenierı́a y matemáticas), por ello ha decidido que los programas en Tecnologı́a en
Desarrollo de Software e Ingenierı́a de Sistemas incrementen su cupo de admisión a ∞, pero
tenemos el problema de la disponibilidad de las salas, por ello ha decidido fusionar los cursos de
fundamentos de programación imperativa, fundamentos de programación O.O, programación
orientada e eventos, programación funcional, fundamentos de lenguajes de programación e in-
fraestructuras paralelas en un super curso llamado Meta programación modalidad bootcamp,
esto posibilita que los estudiantes adquieran más de 20 resultados de aprendizaje en un semes-
tre. Para implementar esto ningún lenguaje de programación existente puede cumplir esta tarea,
por ello debe desarrollarse uno totalmente nuevo. Usted y su grupo de trabajo ha encontrado
al director de la sede muy triste sentado en una banca del parque chilocote, este le cuenta este
problema, por lo que ustedes deciden ayudarlo desarrollando este lenguaje de programación.
1
Figura 1: Recreación del profesor en el lago Chilocote
2.1. Especificacion del lenguaje
Los valores expresados son:
1. Números (tenemos varias representaciones)
2. Texto
3. Listas
4. Void (expresión vacı́a)
Los valores denotados son arboles de sintaxis abstracta, es decir en el ambiente almacenamos
de esta forma los valores
La sintaxis y semántica adaptada a la librerı́a SLLGEN.
2.2. Gramática del proyecto
Al final de cada producción aparece el nombre de la variante entre paréntesis.
; ;* ** * ** ** ** * ** * E s p e c i f i c a c i o n e s l é xicas * * * * * * * * * * * * * * * * *
<d i g i t o B i n a r i o > : : = " b " ( 0 | 1 ) ( 0 | 1 ) ∗
<d i g i t o D e c i m a l > : : = <d i g i t o ><d i g i t o >∗
<d i g i t o D e c i m a l > : : = " - " <d i g i t o ><d i g i t o >∗
<d i g i t o O c t a l > : : = " 0 x " ( 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 ) ( 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 ) ∗
<d i g i t o O c t a l > : : = " - " " 0 x " ( 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 ) ( 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 ) ∗
<h e x a d e c i m a l > : : = " hx " ( 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | " A " | " B " | " C " | " D " | " E " | " F " )
( 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | "A" | "B" | "C" | "D" | "E" | "F" ) ∗
<h e x a d e c i m a l > : : = " - " " hx " ( 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | " A " | " B " | " C " | " D " | " E " | " F " )
( 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | "A" | "B" | "C" | "D" | "E" | "F" ) ∗
<f l o t a n t e > : : = <d i g i t o ><d i g i t o >∗" . "<d i g i t o ><d i g i t o >∗
<f l o t a n t e > : : = " - " <d i g i t o ><d i g i t o >∗" . "<d i g i t o ><d i g i t o >∗
< i d e n t i f i c a d o r > : : = <s i m b o l o ><s i m b o l o >∗
<c o m e n t a r i o > : : = " \\ " ( not #\ n e w l i n e )
<e s p a c i o > : : = <w h i t e s p a c e >
; ;* ** * ** ** ** * ** * E s p e c i f i c a c i o n e s gramaticales * * * * * * * * * * * * * * * * *
<programa> : : = <s t r u c t − d e c l >∗ <e x p r e s i o n > ( a−programa )
2
<e x p r e s i o n > : : = <b o o l − e x p r e s i o n > ( bool−exp )
::= <i d e n t i f i c a d o r > ( var−exp )
: : = <numero> ( num−exp )
::= ’ " ’ < identificador > < identificador >* ’ " ’ ( cadena−exp )
: : = " list " " ( " (< e x p r e s i o n >) ∗ ( , ) " ) " ( l i s t a − e x p )
: : = " cons " " ( " <e x p r e s i o n > <e x p r e s i o n > " ) " ( cons−exp )
: : = " empty " ( empty−list−exp )
: : = " array " " ( " (< e x p r e s i o n >) ∗ ( , ) " ) " ( array−exp )
: : = <var−decl> ( decl−exp )
: : = " void " ( void−exp )
: : = " set " < i d e n t i f i c a d o r > " = " <e x p r e s i o n > ( set−exp )
; ; Primitiva num é rica
: : = " ( " <e x p r e s i o n > <p r i m i t i v a > <e x p r e s i o n > " ) " ( prim−num−exp )
; ; Primitiva listas
: : = p r i m i t i v a l L i s t a s " ( " <e x p r e s i o n > " ) " ( p r i m − l i s t − e x p )
; ; Primitiva booleanas
: : = p r i m i t i v a B o o l e a n a " ( " <e x p r e s i o n > ∗ ( , ) " ) " ( prim−bool−exp )
; ; Primitiva binaria
: : = p r i m i t i v a B i n a r i a " ( " <e x p r e s i o n > ∗ ( , ) " ) " ( prim−bin−exp )
; ; Primitiva de arrays
: : = p r i m i t i v a A r r a y " ( " <e x p r e s i o n > ∗ ( , ) " ) " ( prim−array−exp )
; ; Primitiva de cadenas
: : = p r i m i t i v a C a d e n a " ( " <e x p r e s i o n > ∗ ( , ) " ) " ( prim−cad−exp )
; ; Condicionales y estructuras de control
: : = " if " <e x p r e s i o n > " { " <e x p r e s i o n > " else " <e x p r e s i o n > " } " ( i f − e x p )
: : = " switch " " ( " e x p r e s i o n " ) " " { " ( " case " e x p r e s i o n " : " e x p r e s i o n ) ∗ " default " " : "
,→ e x p r e s i o n " } " ( switch−exp )
: : = " for " < i d e n t i f i c a d o r > " from " <e x p r e s i o n > " until " e x p r e s i o n " by " e x p r e s i o n " do "
,→ e x p r e s i o n ( for−exp )
: : = " while " <e x p r e s i o n > " { " <e x p r e s i o n > " } " ( while−exp )
; ; Secuenciaci ó n y asignaci ó n
: : = " begin " e x p r e s i o n ( " ; " <e x p r e s i o n >)∗ " end " ( begin−exp )
: : = " set " < i d e n t i f i c a d o r > " = " <e x p r e s i o n > ( set−exp )
; ; Funciones
: : = " func " " ( " (< i d e n t i f i c a d o r > ∗ ( , ) " ) " <e x p r e s i o n > ( func−exp )
: : = " call " <e x p r e s i o n > " ( " <e x p r e s i o n > ∗ ( , ) " ) " ( c a l l − e x p )
; ; Invocaci ó n y llamado de estructuras
: : = " new " < i d e n t i f i c a d o r > " ( " <e x p r e s i o n > ∗ ( , ) " ) " ( new−struct−exp )
: : = " get " <e x p r e s i o n > " . " < i d e n t i f i c a d o r > ( g e t − s t r u c t − e x p )
: : = " set-struct " <e x p r e s i o n > " . " < i d e n t i f i c a d o r > " = " <e x p r e s i o n > ( s e t − s t r u c t − e x p )
; ; R econocim iento de patrones
: : = " match " <e x p r e s i o n > " { " (< r e g u l a r − e x p > " = > " <e x p r e s i o n >)∗ " } " ( match−exp )
<numero−exp >::= <d i g i t o D e c i m a l > ( decimal−num )
: : = <d i g i t o B i n a r i o > ( bin−num )
: : = <d i g i t o O c t a l > ( octal−num )
: : = <d i g i t o H e x a d e c i m a l > ( hex−num )
: : = <f l o t a n t e > ( float−num )
<b o o l − e x p r e s i o n >
: : = " true " ( true−exp )
: : = " false " ( false−exp )
; ; Primitivas
<p r i m i t i v a > : : = + ( sum−prim ) ; ; Suma
: : = − ( minus−prim ) ; ; Resta
: : = ∗ ( mult−prim ) ; ; Multiplicaci ó n
: : = mod ( modulo−prim ) ; ; Modulo
: : = pow ( e l e v a r − p r i m ) ; ; Potencia
: : = < ( menor−prim ) ; ; Menor que
: : = > ( mayor−prim ) ; ; Mayor que
: : = <=(menorigual−prim ) ; ; Menor igual que
: : = >=(mayorigual−prim ) ; ; Mayor igual que
: : = !=( d i f e r e n t − p r i m ) ; ; Diferente
:= ==(i g u a l − p r i m ) ; ; Igual
<p r i m i t i v a B o o l e a n a >
: : = and ( and−prim ) ; ; Conjunci ó n
: : = or ( or−prim ) ; ; Disyuncti ó n
: : = x o r ( xor−prim ) ; ; Or exclusivo
3
: : = not ( not−prim ) ; ; negaci ó n
<p r i m i t i v a L i s t a s >
: : = first ( f i r s t − p r i m L i s t ) ; ; Primero
: : = rest ( r e s t − p r i m L i s t ) ; ; Resto
: : = empty ? ( empty−primList ) ; ; Vacio
<p r i m i t i v a B i n a r i a >
: : = && ( and−primBin ) ; ; and binario
: : = | | ( or−primBin ) ; ; or binario
: : = ˆˆ ( xor−primBin ) ; ; xor binario
; ; Declaraci ó n variables
<p r i m i t i v a A r r a y >
: : = length ( length−primArr ) ; ; Tama ~ no
: : = i n d e x ( index−primArr ) ; ; Acceso a elemento
: : = s l i c e ( s l i c e − p r i m A r r ) ; ; Acceso a subarray
: : = s e t l i s t ( s e t l i s t − p r i m A r r ) ; ; Cambiar elemento
<p r i m i t i v a C a d e n a s >
: : = c o n c a t ( concat−primCad ) ; ; concatenar
: : = s t r i n g − l e n g t h ( length−primCad ) ; ; Longitud
: : = elementAt ( index−primCad ) ; ; Acceso a elemento
<var−decl> : : = " var " (< i d e n t i f i c a d o r > " = " <e x p r e s i o n >)∗ " in " e x p r e s i o n ( lvar−exp )
: : = " let " < i d e n t i f i c a d o r > " = " <e x p r e s i o n >)∗ " in " e x p r s i o n l e t − e x p )
; ; Estructuras de datos
<s t r u c t − d e c l > : : = " struct " < i d e n t i f i c a d o r > " { " < i d e n t i f i c a d o r >∗ " } " ( struct−exp )
; ; match
<r e g u l a r − e x p > : : = < i d e n t i f i c a d o r > " :: " < i d e n t i f i c a d o r > ( list−match−exp ) ; ; listas
: : = " numero " " ( " < i d e n t i f i c a d o r > " ) " ( num−match−exp ) ; ; numeros
: : = " cadena " " ( " < i d e n t i f i c a d o r > " ) " ( cad−match−exp ) ; ; cadenas
: : = " boolean " " ( " < i d e n t i f i c a d o r > " ) " ( bool−match−exp ) ; ; booleanos
: : = " array " " ( " (< i d e n t i f i c a d o r >" ," ) ∗ " ) " ( array−match−exp ) ; ; arreglos
: : = " empty " ( empty−match−list ) ; ; lista vacia
: : = " default " ( default−match ) ; ; default
2.3. Valores denotados y expresados
Los valores denotados son referencias, dado que manejamos asignaciòn
Los valores expresados son números (en todas sus formas), booleanos, cadenas, void y valores
procedimiento.
2.4. Estructuras léxicas
Identificadores: Son secuencias de caracteres alfanuméricos que comienzan con una letra
Comentarios: Inician con // y terminan con fin de linea.
Números enteros: Los números son un conjunto de dı́gitos. Se dividen de la siguiente
forma:
1. Dı́gitos binarios del 0 y 1
2. Dı́gitos decimales del 0 al 9
3. Dı́gitos octales del 0 al 7
4. Dı́gitos hexadecimales del 0 al F.
Estos números pueden ser antecedidos por ”para indicar que son negativos.
4
Números flotantes: Los números son un conjunto de dı́gitos seguidos por un punto y
seguidos por un conjunto de dı́gitos. Estos números pueden ser antecedidos por ”para
indicar que son negativos. únicamente tenemos números decimales flotantes
Cadenas: Inician con comillas seguidas por un conjunto de dı́gitos o letras y terminadas
en comillas, estas admiten espacios :).
En el archivo proyecto.rkt se especifica la gramática completa
2.5. Datos
Los binarios se pueden expresar ası́:
b10101010
−b01010101
Los decimales
23213
−12312
Los octales
0 x213345
−0x23123
Los hexadecimales
hxFAB123
−hx99EA
Los flotantes
412312.2312
−23123.2312
Los booleanos
true
false
Las cadenas de texto:
" hola mundo "
" hola que tal "
2.6. Primitivas numéricas
Para este proyecto se tienen las primitivas numéricas, estas deben retornar el mismo tipo
numérico que se envio, ejemplo
( b1000 + b10 )
Debe retornar b1010
( 0 x77 + 0 x3 )
Debe retornar 0x102
( hx100 − hx2 )
Debe retornar FE
(123.2 − 1.2)
Debe retornar 122.0
5
2.7. Primitivas booleanas
Las primitivas booleanas esperan expresiones de valor expresado booleano, ejemplo:
and ( ( 1 > 2 ) , f a l s e )
Observese que la primitiva numérica > retorna un booleano
2.8. Listas
Las listas son agrupaciones de elementos, los cuales son inmutables (no pueden cambiar),
se declaran de la siguiente forma:
Ejemplo:
list ( 1 , 2 , 3 , 4 )
cons ( 1 cons ( 2 empty ) )
empty
Para la listas vamos a usar la representación de cabeza que es cualquier elemento y cola que
es una lista.
2.9. Primitivas de listas
Para las listas tenemos las siguiente primitivas
let
l = cons ( 1 cons ( 2 cons ( 3 empty ) ) )
in
list ( first ( l ) , rest ( l ) , empty ? ( rest ( l ) ) )
Va a retornar (1,list(2,3), false)
2.10. Arrays
Las arrays o arreglos son colecciones la listas ya que pueden cambiar.
Ejemplo:
array (1 ,2 ,3 ,4 ,5)
2.11. Primitivas de arrays
Las primitivas que tenemos son de acceso, modificación, longitud y slice.
Para conocer el tamaño tenemos lenght:
let
t = array (1 ,2 ,3 ,4 ,5)
in
length ( t )
Debe retornar 5
Para acceder a un elemento, el cual indexamos desde 0, tenemos index:
let
t = array (1 ,2 ,3 ,4 ,5)
in
index ( t , 2)
6
Debe retornar 3
Para acceder a sub-arreglo tenemos slice, el cual tendrá inicio y fin (ambos incluidos),
ejemplo:
let
k = list ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 1 0 )
in
s l i c e (k , 2 , 5)
Debe retornar list(3,4,5,6)
Para cambiar un elemento tenemos setlist, el cual recibe el arreglo, la posición y el valor:
let
t = array (1 ,2 ,3 ,4 ,5)
in
s e t l i s t ( t , 2 , 10)
Debe retornar array(1,2,10,4,5)
2.12. Primtivas de cadenas
Para las primitivas de candenas tenemos las siguientes:
2.12.1. length
let
s = " hola mundo cruel "
in
string−length ( s )
Debe retornar 16
2.12.2. elementAt
Este recibe una cadena y una posición numérica que inicia en 0.
let
s = " hola mundo cruel "
in
elementAt ( s , 5 )
Debe retornar “m”
2.12.3. concat
Permite pegar dos o más cadenas
let
a = " hola "
b = " mundo "
c = " cruel "
in
concat (a , b , c )
Retornará “holamundocruel”
2.13. Entornos de ligaduras y variables
Se tienen los entornos let el cual crea ligadura no modificable y var el cual crea ligadura
modificable, ambos trabajan similar, sólo que el var permite el uso de set y el let no.
7
var x = 10
i n b e g i n set x = 20 ; x end
Retornara 20.
let x = 10
i n b e g i n set x = 20 ; x end
Fallará porque no se puede modificar la ligadura.
Importante: Estos entornos son naturalmente recursivos:
var x = x i n x
Se quedará en un ciclo infinito.
Aqui también podemos aplicar funciones recursivas:
var f = f u n c ( x ) if ( x == 0 ) { 0 else ( x + c a l l f ( ( x − 1 ) ) ) }
in c a l l f (10)
Retornará 55
2.14. Condicionales
Retornará 40, dado que el x cambió a 30.
y i f ( a > 3 ) { 1 else 2 }
2.15. Estructuras de control
2.15.1. For
La estructura for es de la siguiente forma:
let
x = 0
in
begin
f o r i from 0 until 10 by 1 do set x = ( x + i ) ;
x
end
Retornará 45
2.15.2. While
El while es de la siguiente forma:
let
x = 0
in
begin
w h i l e ( x < 1 0 ) { set x = ( x + 1 ) } ;
x
end
Retornará 10
2.15.3. Switch
El switch es de la siguiente forma:
8
let
x = 0
in
begin
switch (x) {
case 1 : 1
case 2 : 2
default : 3
}
end
Retornará 3
2.16. Begin y set
El begin permite ejecutar una serie de instrucciones, siempre retornará la última:
b e g i n 1 ; 2; 3 end
Retornará 3
El set permite cambiar el valor de una variable, su valor de retorno es void-exp.
let
x = 0
in
set x = 10
Retornará void-exp
2.17. Funciones
Para las funciones tenemos func para su creación y call para su aplicación:
var
f = func ( x ) x
in
c a l l f (10)
Retornará 10.
Importante: Como el paradigma es imperativo las funciones si se ven afectadas por el valor
de una variable externa, es decir trabajarán con el que vean. Ejemplo:
var x = 10 f = f u n c ( a ) ( a + x )
in
let x = 30 i n c a l l f ( 1 0 )
2.18. Estructuras de datos
Las estructuras de datos son similares a los objetos, solamente que no poseen métodos, estas
se deben declarar y posteriormente se pueden extraer sus datos.
s t r u c t p e r r o { nombre edad c o l o r }
let
t = new p e r r o ( " lucas " , 1 0 , " verde " )
i n get t . nombre
Retonará “lucas”.
También podemos cambiar datos:
9
s t r u c t p e r r o { nombre edad c o l o r }
let
t = new p e r r o ( " lucas " , 1 0 , " verde " )
in
begin
s e t − s t r u c t t . nombre = " pepe " ;
get t . nombre
end
Retornará “pepe”.
Debe tomar en cuenta que set-struct retorna void como toda operación de efecto y no valor.
s t r u c t p e r r o { nombre edad c o l o r }
let
t = new p e r r o ( " lucas " , 1 0 , " verde " )
in
s e t − s t r u c t t . nombre = " pepe "
Retornará void-exp.
3. Reconocimiento de patrones
Para el reconocimiento de patrones usaremos match, podremos reconocer
1. Listas con expresiones del tipo x::xs
2. Números con expresiones del tipo numero(x)
3. Cadenas con expresiones del tipo cadena(x)
4. Booleanos con expresiones del tipo boolean(x)
5. Arrays con expresiones del tipo array(x,y,z), el último capturará el resto de elementos, si
se pasa del tamaño fallará.
6. Listas vacı́as con empty
Ejemplos:
let
x = list ( 1 , 2 , 3 , 4 , 5 )
in
match x {
x : : xs => xs
d e f a u l t => 0
}
Retornará list(2,3,4,5)
let
x = 10
in
match x {
numero ( x ) => x
d e f a u l t => 0
}
Retornará 10
10
let
x = " hola mundo "
in
match x {
cadena ( x ) => x
d e f a u l t => 0
}
Retornará “hola mundo”
let
x = true
in
match x {
b o o l e a n ( x ) => x
d e f a u l t => 0
}
Retonará true
let
x = array (1 ,2 ,3 ,4 ,5)
in
match x {
a r r a y ( x , y , z ) => list ( x , y , z )
d e f a u l t => 0
}
Retornará list(1,2,array(3,4,5))
Por ejemplo una función recursiva sobre listas usando empty.
let
f = func ( x )
match x {
empty => 0
x : : xs => ( x + c a l l f ( xs ) )
}
in
c a l l f ( list ( 1 , 2 , 3 , 4 , 5 ) )
Retornará 15
4. Entrega
Se debe entregar un enlace de github con el informe en formato PDF y el código del proyecto
(archivo rkt), recordar dejar el enlace público o agregar como colaborador al profesor (@cardel).
El informe debe contener capturas de pantalla con las pruebas realizadas, en las rùbricas de
evaluación se indicarán cómo deben ir.
5. Evaluación
El proyecto debe ser entregado a más tardar el dı́a 20 de Junio de 2024 a las 23:59:59 hora
de Colombia, a partir de allı́ aplicará 0.3 por hora o fracción de retraso, por ejemplo, si usted
entrega el 20 de Junio a las 00:01:00, se le descontará 0.3 de la nota obtenida, si entrega a las
01:00:01 se le descontará 0.6 y ası́ sucesivamente.
Ası́ mismo se aplicará las reglas expresadas al inicio del enunciado con respecto a la sus-
tentación como nota individual. La evaluación del proyecto se aplicará vı́a rubrı́ca, la cual será
socializada a los estudiantes en el transcurso de los próximos dı́as.
11