expand closures test
This commit is contained in:
parent
9b3b1056ba
commit
c04d520561
|
@ -397,6 +397,7 @@ proc addUpvalue(comp: Compiler, index: int): int =
|
|||
## and creates an upvalue in every function up until the one
|
||||
## including this local so that all of the function scopes in between
|
||||
## have the right upvalue in them (compile time)
|
||||
comp.error("addupvalue not implemented yet")
|
||||
discard
|
||||
|
||||
proc resolveLocal(comp: Compiler, name: string): tuple[index: int, upvalue: bool] =
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
// capturing closures in lists:
|
||||
|
||||
var f = funct() {
|
||||
var y = 5;
|
||||
var x = @[
|
||||
funct() print y,
|
||||
funct() y = y + 1
|
||||
];
|
||||
:result = x;
|
||||
};
|
||||
|
||||
//expect:5.0
|
||||
f()[0]();
|
||||
f()[1]();
|
||||
//expect:6.0
|
||||
f()[0]();
|
||||
|
||||
// capturing the result of a function:
|
||||
|
||||
var f2 = funct() {
|
||||
var x = { @f2
|
||||
:result = funct() {
|
||||
print :f2;
|
||||
};
|
||||
};
|
||||
x = 5;
|
||||
};
|
||||
|
||||
//expect:5.0
|
||||
f2()();
|
||||
|
||||
// oop: constructors, getters, setters
|
||||
|
||||
var newAnimal = funct(species, color) {
|
||||
var species = species; // copy it so that it's mutable, if args ever get immutable
|
||||
var animal = @{
|
||||
"getSpecies" = funct() :result = species,
|
||||
"setSpecies" = funct(newSpecies) species = newSpecies,
|
||||
"getColor" = funct() :result = color, // this captures an argument directly
|
||||
};
|
||||
:result = animal;
|
||||
};
|
||||
|
||||
var horse1 = newAnimal("horse", "brown");
|
||||
var horse2 = newAnimal("horse", "white");
|
||||
|
||||
var turtle = newAnimal("turtle", "brown");
|
||||
|
||||
//expect:horse
|
||||
print horse1["getSpecies"]();
|
||||
horse1["setSpecies"]("zebra");
|
||||
//expect:zebra
|
||||
print horse1["getSpecies"]();
|
||||
|
||||
//expect:brown
|
||||
print horse1["getColor"]();
|
||||
//expect:horse
|
||||
print horse2["getSpecies"]();
|
||||
//expect:white
|
||||
print horse2["getColor"]();
|
||||
//expect:turtle
|
||||
print turtle["getSpecies"]();
|
||||
|
||||
// closure examples from craftinginterpreters
|
||||
|
||||
// 1:
|
||||
|
||||
var makeClosure = funct(value) {
|
||||
var closure = funct() {
|
||||
print value;
|
||||
};
|
||||
:result = closure;
|
||||
};
|
||||
|
||||
var doughnut = makeClosure("doughnut");
|
||||
var bagel = makeClosure("bagel");
|
||||
//expect:doughnut
|
||||
doughnut();
|
||||
//expect:bagel
|
||||
bagel();
|
||||
|
||||
// 2: (multi level closures)
|
||||
|
||||
var outer = funct() {
|
||||
var x = "value";
|
||||
var middle = funct() {
|
||||
var inner = funct() {
|
||||
print x;
|
||||
};
|
||||
|
||||
print "create inner closure";
|
||||
:result = inner;
|
||||
};
|
||||
|
||||
print "return from outer";
|
||||
:result = middle;
|
||||
};
|
||||
|
||||
//expect:return from outer
|
||||
var mid = outer();
|
||||
//expect:create inner closure
|
||||
var in = mid();
|
||||
//expect:value
|
||||
in();
|
||||
|
||||
|
||||
// 3: (mixed multi level closures)
|
||||
|
||||
outer = funct() {
|
||||
var a = 1;
|
||||
var b = 2;
|
||||
var result;
|
||||
var middle = funct() {
|
||||
var c = 3;
|
||||
var d = 4;
|
||||
var inner = funct() {
|
||||
print a + c + b + d;
|
||||
};
|
||||
result = inner;
|
||||
};
|
||||
:result = result;
|
||||
};
|
||||
|
||||
//expect:10.0
|
||||
outer()();
|
||||
|
||||
// 4: manipulation of vals from closures
|
||||
|
||||
outer = funct() {
|
||||
var x = "before";
|
||||
var inner = funct() {
|
||||
x = "assigned";
|
||||
};
|
||||
inner();
|
||||
print x;
|
||||
};
|
||||
|
||||
//expect:assigned
|
||||
outer();
|
||||
|
||||
// 5: get/setters using globals
|
||||
|
||||
var globalSet;
|
||||
var globalGet;
|
||||
|
||||
var main5 = funct() {
|
||||
var a = "initial";
|
||||
|
||||
var set = funct() { a = "updated"; };
|
||||
var get = funct() { print a; };
|
||||
|
||||
globalSet = set;
|
||||
globalGet = get;
|
||||
};
|
||||
|
||||
main();
|
||||
globalGet();
|
||||
//expect:initial
|
||||
globalSet();
|
||||
globalGet();
|
||||
//expect:updated
|
||||
|
||||
// 6: multiple upvalues in a simple scope
|
||||
|
||||
{
|
||||
var a = 1;
|
||||
f = funct() {
|
||||
print a;
|
||||
};
|
||||
var b = 2;
|
||||
g = funct() {
|
||||
print b;
|
||||
};
|
||||
var c = 3;
|
||||
h = funct() {
|
||||
print c;
|
||||
};
|
||||
|
||||
print f();
|
||||
print g();
|
||||
print h();
|
||||
//expect:1
|
||||
//expect:2
|
||||
//expect:3
|
||||
};
|
||||
|
||||
// bonus: the last one with a list twist
|
||||
|
||||
var bonus = funct() {
|
||||
var a = 1;
|
||||
f = funct() {
|
||||
print a;
|
||||
};
|
||||
var b = 2;
|
||||
g = funct() {
|
||||
print b;
|
||||
};
|
||||
var c = 3;
|
||||
h = funct() {
|
||||
print c;
|
||||
};
|
||||
|
||||
:result = @[f, g, h];
|
||||
};
|
||||
|
||||
bonus = bonus();
|
||||
bonus[2]();
|
||||
bonus[0]();
|
||||
bonus[1]();
|
||||
//expect:3
|
||||
//expect:1
|
||||
//expect:2
|
|
@ -1,66 +0,0 @@
|
|||
//_d so the test doesn't run yet
|
||||
|
||||
// capturing closures in lists:
|
||||
|
||||
var f = funct() {
|
||||
var y = 5;
|
||||
var x = @[
|
||||
funct() print y,
|
||||
funct() y = y + 1
|
||||
];
|
||||
:result = x;
|
||||
};
|
||||
|
||||
//expect:5.0
|
||||
f()[0]();
|
||||
f()[1]();
|
||||
//expect:6.0
|
||||
f()[0]();
|
||||
|
||||
// capturing the result of a function:
|
||||
|
||||
var f2 = funct() {
|
||||
var x = { @f2
|
||||
:result = funct() {
|
||||
print :f2;
|
||||
};
|
||||
};
|
||||
x = 5;
|
||||
};
|
||||
|
||||
//expect:5.0
|
||||
f2()();
|
||||
|
||||
// oop: constructors, getters, setters
|
||||
|
||||
var newAnimal = funct(species, color) {
|
||||
var species = species; // copy it so that it's mutable, if args ever get immutable
|
||||
var animal = @{
|
||||
"getSpecies" = funct() :result = species,
|
||||
"setSpecies" = funct(newSpecies) species = newSpecies,
|
||||
"getColor" = funct() :result = color, // this captures an argument directly
|
||||
};
|
||||
:result = animal;
|
||||
};
|
||||
|
||||
var horse1 = newAnimal("horse", "brown");
|
||||
var horse2 = newAnimal("horse", "white");
|
||||
|
||||
var turtle = newAnimal("turtle", "brown");
|
||||
|
||||
//expect:horse
|
||||
print horse1["getSpecies"]();
|
||||
horse1["setSpecies"]("zebra");
|
||||
//expect:zebra
|
||||
print horse1["getSpecies"]();
|
||||
|
||||
//expect:brown
|
||||
print horse1["getColor"]();
|
||||
//expect:horse
|
||||
print horse2["getSpecies"]();
|
||||
//expect:white
|
||||
print horse2["getColor"]();
|
||||
//expect:turtle
|
||||
print turtle["getSpecies"]();
|
||||
|
||||
// TODO: tests for enclosing upvalues multiple levels up
|
Loading…
Reference in New Issue