3º. 2º cuatrimestre. Itinerario de Computación. Grado en Ingeniería Informática. ULL
element
: Posibilidad de Indexar con mas de un Índicesub
deberá funcionar con los diccionarios/mapasAñada índices negativos (a la Ruby) para los arrays
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ cat examples/array-neg.egg
do{
def(x, array[1, array[2,3]]),
print(element(x, -1)), # [ 2, 3 ]
}
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ bin/egg.js examples/array-neg.egg
[ 2, 3 ]
element
: Posibilidad de Indexar con mas de un Índiceelement
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ cat examples/array-index.egg
do(
def(x, array[1, array[2,3]]),
print(element(x,0)), # 1
print(element(x,1)), # [ 2, 3 ]
print(element(x,1,1)), # 3
print(element(x,-1,-1)), # 3
print(element(x,-1,0)) # 2
)
Ejecución:
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ bin/egg.js examples/array-index.egg
1
[ 2, 3 ]
3
3
2
Extienda set
para que se puedan modificar elementos de los arrays
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ cat examples/array-set-index.egg
do(
def(x, array[1,2,3, array[9,8,7]]),
set(x, 2, 9),
print(x), # [ 1, 2, 9, [ 9, 8, 7 ] ]
set(x, 3, 1, 1000),
print(x) # [ 1, 2, 9, [ 9, 1000, 7 ] ]
)
Ejecución:
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ bin/egg.js examples/array-set-index.egg
[ 1, 2, 9, [ 9, 8, 7 ] ]
[ 1, 2, 9, [ 9, 1000, 7 ] ]
No se debería poder hacer un set
con índices de una variable no estructurada
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ cat examples/set-error.egg
do(
def(x,4),
set(x, 1, 2),
print(x)
)
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ bin/egg.js examples/set-error.egg
TypeError: The object '4' is not indexable!
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ cat examples/map.egg
do {
def(x, map["x", 4, "y", map["z", 3]]),
print(element(x, "x")), # 4
print(element(x, "y", "z")), # 3
set(x, "y", "z", 50),
print(element(x, "y", "z")) # 50
}
Ejecución:
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ bin/egg.js examples/map.egg
4
3
50
Nos gustaría poder escribir los hashes/mapas usando :
para separar el nombre de la clave del valor, como en este ejemplo:
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ cat examples/map-colon.egg
do {
def(x, map[x: 4, y: map[z: 3]]),
print(x["y"]["z"]), # 3
print(element(x, "x")), # 4
print(element(x, "y", "z")), # 3
set(x, "y", "z", 50),
print(element(x, "y", "z")) # 50
}
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ bin/egg.js examples/map-colon.egg
3
4
3
50
Una forma de hacer esto es empezar haciendo que el análisis léxico acepte el carácter :
para el token COMMA
const COMMA = new XRegExp(`
(
,|:(?!=) # : is an alias for comma ',' when not followed by '='
)
`, 'xy');
y trucando nuestro analizador léxico para que siempre que una WORD
vaya seguida de :
se retorne una STRING
nextToken = function() {
if (count < result.length) {
lookahead = result[count++];
if (lookahead && (lookahead.type === 'WORD') && (result[count] && result[count].value === ":")) {
lookahead.type = "STRING";
}
return lookahead;
}
else return null;
}
sub
deberá funcionar con los diccionarios/mapasHaga que los mapas tengan un método sub
que permita indexar los mapas:
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ cat examples/map-sub.egg
do(
def(x, map{a: 1, b: 4, c: map{d: 5, e: 3}}),
print(x["sub"]["a"]), # 1
print(x["sub"]["c"]["d"]), # 5
print(x["sub"]["c"]["e"]), # 3
print(x["sub"]["b"]) # 4
)
Ejecución:
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ bin/egg.js examples/map-sub.egg
1
5
3
4
Añada objetos al lenguaje Egg de manera que podamos escribir programas como este:
.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ cat examples/objects.egg
do (
def(x, object (
"c", 0,
"gc", ->{element[this, "c"]},
"sc", ->{value, =(this, "c", value)},
"inc", ->{=(this, "c", +(element[this, "c"],1))}
)),
print(x("gc")()), # 0
x("sc")(4),
print(x("gc")()), # 4
x("inc")(),
print(x("gc")()), # 5
)
Ejecución:
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ bin/egg.js examples/objects.egg
0
4
5
Syntactic Sugar: Introduzca el operador punto (dot) para poder acceder a los métodos y atributos de un objeto.
La idea es que una expresión como:
a.b.c(arg1)
es equivalente a esta otra expresión:
a("b")("c")(arg1)
Esto es,el dot es como una llamada/apply del objeto en el que el primer argumento es el atributo/método
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ cat examples/dot.egg
do(
def(x, array[1,4,5]),
def(s, x.join("-")), # The same as x("join")("-")
print(s), # 1-4-5
print(array[1,4,5].join("-").length) # 5
)
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ bin/egg.js examples/dot.egg
1-4-5
5
Otro ejemplo, esta vez con objetos Egg.
[~/.../crguezl-egg(private2019)]$ cat examples/dot-obj-2.egg
.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ cat examples/dot-obj-2.egg
do (
def(x, object (
c: 3,
gc: ->{this.c},
sc: ->{value, =(this, "c", value)},
inc: ->{=(this, "c", +(this.c, 1))}
)),
print(x["c"]), # 3
print(x.c), # 3
print(x.gc()), # 3
print(x.sc(5)),# 5
print(x.gc()) # 5
)
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ bin/egg.js examples/dot-obj-2.egg
3
3
3
5
5
Otro ejemplo con números:
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ cat examples/dot-num.egg
do{
print(4.toFixed(2)),
def(x, 4),
print(x("toFixed")(2)),
def(z, x.toFixed(2)),
print(z),
}
[.../p7-t3-egg-2-04-16-2020-03-13-25/davafons(casiano)]$ bin/egg.js examples/dot-num.egg
4.00
4.00
4.00
require
para que permita el uso de libreríasCódigo del Módulo: [~/…/crguezl-egg(private2019)]$ cat examples/require/module.egg
# module. Exports z
do {
print("inside module"),
:=(z, map{inc: ->{x,
+(x,1)
} # end fun
} # end map
), # end of :=
z # el último valor será exportado
}
Programa Cliente: [~/…/crguezl-egg(private2019)]$ cat examples/require/client.egg
do {
:=(z, require("examples/require/module.egg")),
print(z.inc(4)),
:=(w, require("examples/require/module.egg")),
}
Ejecución:
[~/.../crguezl-egg(private2019)]$ bin/egg.js examples/require/client.egg
inside module
5
Observe como inside module
aparece una sola vez pese a que el módulo es required dos veces
r/regexpExpression/
comenzando por r/
y terminando con una /
.[nsxAgimuy]*
regex
[.../p6-t3-egg-1-04-16-2020-03-13-25/davafons(master)]$ cat examples/regex-simple.egg
do {
:=(r, r/(\w+)
\s+
(\d+) # numero
/x),
:=(s, r.test("a 4")),
:=(m, r.exec(";;; a 42")),
print(s),
print(m),
}
[.../p6-t3-egg-1-04-16-2020-03-13-25/davafons(master)]$ bin/egg.js examples/regex-simple.egg
true
[ 'a 42', 'a', '42', index: 4, input: ';;; a 42', groups: undefined ]
Otro ejemplo:
[.../p6-t3-egg-1-04-16-2020-03-13-25/davafons(master)]$ cat examples/regex-2.egg
do {
:=(d, r/
(?<year> \d{4} ) -? # year
(?<month> \d{2} ) -? # month
(?<day> \d{2} ) # day
/x),
print(d("test")("1987-07-14")), # true
:=(m, d("exec")("1987-07-14")),
print(m), # [ '1987-07-14', '1987', '07', '14', index: 0, input: '1987-07-14' ]
print(m("index")), # 0
:=(x, RegExp("exec")("2015-02-22", d)),
/*
[ '2015-02-22',
'2015',
'02',
'22',
index: 0,
input: '2015-02-22',
year: '2015',
month: '02',
day: '22' ]
*/
print(x),
print(x("year")), # 2015
print(x("month")) # 02
}
[.../p6-t3-egg-1-04-16-2020-03-13-25/davafons(master)]$ bin/egg.js examples/regex-2.egg
true
[
'1987-07-14',
'1987',
'07',
'14',
index: 0,
input: '1987-07-14',
groups: undefined
]
0
[
'2015-02-22',
'2015',
'02',
'22',
index: 0,
input: '2015-02-22',
groups: undefined,
year: '2015',
month: '02',
day: '22'
]
2015
02
Extienda el lenguaje con uno o varios tipos de bucle for
[.../TFA-04-16-2020-03-22-00/davafons(casiano)]$ cat examples/for.egg
do(
for(define(x, 0), <(x, 5), ++(x),
print(x)
)
)
[.../TFA-04-16-2020-03-22-00/davafons(casiano)]$ bin/egg.js examples/for.egg
0
1
2
3
4
[.../TFA-04-16-2020-03-22-00/davafons(casiano)]$ cat examples/foreach.egg
do {
def(x, arr(1, 2, 3)),
foreach(x, x, print(x)), # Different x from inner and outer scope
def(y, map(a: 1, b: 2, c: 3)),
foreach(key, y.keys(), print(key.toUpperCase()))
}
[.../TFA-04-16-2020-03-22-00/davafons(casiano)]$ bin/egg.js examples/foreach.egg
1
2
3
A
B
C