nondescript/tests/closures.nds

266 lines
3.9 KiB
Plaintext
Raw Permalink Normal View History

// cascade
2022-02-09 06:58:51 +01:00
var f1 = proc() {
var x = 1;
var y = 5;
2022-02-09 06:58:51 +01:00
proc() {
var z = 8;
2022-02-07 05:35:07 +01:00
print (x);
x = x + 1;
2022-02-09 06:58:51 +01:00
proc() {
2022-02-07 05:35:07 +01:00
print (x);
x = x + 1;
2022-02-09 06:58:51 +01:00
proc() {
2022-02-07 05:35:07 +01:00
print (x);
print (y);
print (z);
x = x + 1;
2022-02-09 06:58:51 +01:00
proc() {
2022-02-07 05:35:07 +01:00
print (x);
x = x + 1;
2022-02-09 06:55:34 +01:00
}
}
}
}
};
f1()()()()();
//expect:1.0
//expect:2.0
//expect:3.0
//expect:5.0
//expect:8.0
//expect:4.0
2022-02-05 12:56:07 +01:00
// capturing closures in lists:
2022-02-09 06:58:51 +01:00
var f = proc() {
2022-02-05 12:56:07 +01:00
var y = 5;
var x = @[
2022-02-09 06:58:51 +01:00
proc() print (y),
proc() y = y + 1
2022-02-05 12:56:07 +01:00
];
2022-02-09 06:55:34 +01:00
x
2022-02-05 12:56:07 +01:00
};
2022-02-06 10:04:49 +01:00
var inst = f();
2022-02-05 12:56:07 +01:00
//expect:5.0
2022-02-06 10:04:49 +01:00
inst[0]();
inst[1]();
2022-02-05 12:56:07 +01:00
//expect:6.0
2022-02-06 10:04:49 +01:00
inst[0]();
2022-02-05 12:56:07 +01:00
2022-02-06 10:04:49 +01:00
// multiple different labels
2022-02-05 12:56:07 +01:00
2022-02-09 06:58:51 +01:00
var f2 = proc() { @result
2022-02-06 10:04:49 +01:00
var x = { @a @b
// this captures the internal value, not whatever it returns is assigned to
:result = @{
2022-02-09 06:58:51 +01:00
get = proc() print (:a),
["set"] = proc(n) :b = n,
2022-02-05 12:56:07 +01:00
};
};
x = 5;
};
2022-02-06 10:04:49 +01:00
var inst2 = f2();
inst2["get"]();
//expect:nil
inst2["set"](5.2);
inst2["get"]();
//expect:5.2
// capturing args
2022-02-09 06:58:51 +01:00
var argcap = proc(n)
proc() print(n)
2022-02-06 10:04:49 +01:00
;
//expect:8.1
argcap(8.1)();
2022-02-05 12:56:07 +01:00
// oop: constructors, getters, setters
2022-02-09 06:58:51 +01:00
var newAnimal = proc(species, color) { @result
var species = species; // copy it so that it's mutable, if args ever get immutable
2022-02-05 12:56:07 +01:00
var animal = @{
2022-02-09 06:58:51 +01:00
["getSpecies"] = proc() species,
["setSpecies"] = proc(newSpecies) species = newSpecies,
["getColor"] = proc() color, // this captures an argument directly
2022-02-05 12:56:07 +01:00
};
:result = animal;
};
var horse1 = newAnimal("horse", "brown");
var horse2 = newAnimal("horse", "white");
var turtle = newAnimal("turtle", "brown");
//expect:horse
2022-02-07 05:35:07 +01:00
print (horse1["getSpecies"]());
2022-02-05 12:56:07 +01:00
horse1["setSpecies"]("zebra");
//expect:zebra
2022-02-07 05:35:07 +01:00
print (horse1["getSpecies"]());
2022-02-05 12:56:07 +01:00
//expect:brown
2022-02-07 05:35:07 +01:00
print (horse1["getColor"]());
2022-02-05 12:56:07 +01:00
//expect:horse
2022-02-07 05:35:07 +01:00
print (horse2["getSpecies"]());
2022-02-05 12:56:07 +01:00
//expect:white
2022-02-07 05:35:07 +01:00
print (horse2["getColor"]());
2022-02-05 12:56:07 +01:00
//expect:turtle
2022-02-07 05:35:07 +01:00
print (turtle["getSpecies"]());
2022-02-05 12:56:07 +01:00
// closure examples from craftinginterpreters
// 1:
2022-02-09 06:58:51 +01:00
var makeClosure = proc(value) { @result
var closure = proc() {
2022-02-07 05:35:07 +01:00
print (value);
2022-02-05 12:56:07 +01:00
};
:result = closure;
};
var doughnut = makeClosure("doughnut");
var bagel = makeClosure("bagel");
//expect:doughnut
doughnut();
//expect:bagel
bagel();
// 2: (multi level closures)
2022-02-09 06:58:51 +01:00
var outer = proc() { @result
2022-02-05 12:56:07 +01:00
var x = "value";
2022-02-09 06:58:51 +01:00
var middle = proc() { @result
var inner = proc() {
2022-02-07 05:35:07 +01:00
print (x);
2022-02-05 12:56:07 +01:00
};
2022-02-07 05:35:07 +01:00
print ("create inner closure");
2022-02-05 12:56:07 +01:00
:result = inner;
};
2022-02-07 05:35:07 +01:00
print ("return from outer");
2022-02-05 12:56:07 +01:00
:result = middle;
};
//expect:return from outer
var mid = outer();
//expect:create inner closure
var in = mid();
//expect:value
in();
// 3: (mixed multi level closures)
2022-02-09 06:58:51 +01:00
outer = proc() { @result
2022-02-05 12:56:07 +01:00
var a = 1;
var b = 2;
var result;
2022-02-09 06:58:51 +01:00
var middle = proc() {
2022-02-05 12:56:07 +01:00
var c = 3;
var d = 4;
2022-02-09 06:58:51 +01:00
var inner = proc() {
2022-02-07 05:35:07 +01:00
print (a + c + b + d);
2022-02-05 12:56:07 +01:00
};
result = inner;
};
2022-02-06 10:04:49 +01:00
middle();
2022-02-09 06:58:51 +01:00
:result = proc() result;
2022-02-05 12:56:07 +01:00
};
//expect:10.0
2022-02-06 10:04:49 +01:00
outer()()();
2022-02-05 12:56:07 +01:00
// 4: manipulation of vals from closures
2022-02-09 06:58:51 +01:00
outer = proc() {
2022-02-05 12:56:07 +01:00
var x = "before";
2022-02-09 06:58:51 +01:00
var inner = proc() {
2022-02-05 12:56:07 +01:00
x = "assigned";
};
inner();
2022-02-07 05:35:07 +01:00
print (x);
2022-02-05 12:56:07 +01:00
};
//expect:assigned
outer();
// 5: get/setters using globals
var globalSet;
var globalGet;
2022-02-09 06:58:51 +01:00
var main5 = proc() {
2022-02-05 12:56:07 +01:00
var a = "initial";
2022-02-09 06:58:51 +01:00
var set = proc() { a = "updated"; };
var get = proc() { print (a); };
2022-02-05 12:56:07 +01:00
globalSet = set;
globalGet = get;
};
main5();
2022-02-05 12:56:07 +01:00
globalGet();
//expect:initial
globalSet();
globalGet();
//expect:updated
// 6: multiple upvalues in a simple scope
{
var a = 1;
2022-02-09 06:58:51 +01:00
var f = proc() {
2022-02-07 05:35:07 +01:00
print (a);
2022-02-05 12:56:07 +01:00
};
var b = 2;
2022-02-09 06:58:51 +01:00
var g = proc() {
2022-02-07 05:35:07 +01:00
print (b);
2022-02-05 12:56:07 +01:00
};
var c = 3;
2022-02-09 06:58:51 +01:00
var h = proc() {
2022-02-07 05:35:07 +01:00
print (c);
2022-02-05 12:56:07 +01:00
};
2022-02-06 10:04:49 +01:00
f();
g();
h();
//expect:1.0
//expect:2.0
//expect:3.0
2022-02-05 12:56:07 +01:00
};
// bonus: the last one with a list twist
2022-02-09 06:58:51 +01:00
var bonus = proc() { @result
2022-02-05 12:56:07 +01:00
var a = 1;
2022-02-09 06:58:51 +01:00
var f = proc() {
2022-02-07 05:35:07 +01:00
print (a);
2022-02-05 12:56:07 +01:00
};
var b = 2;
2022-02-09 06:58:51 +01:00
var g = proc() {
2022-02-07 05:35:07 +01:00
print (b);
2022-02-05 12:56:07 +01:00
};
var c = 3;
2022-02-09 06:58:51 +01:00
var h = proc() {
2022-02-07 05:35:07 +01:00
print (c);
2022-02-05 12:56:07 +01:00
};
:result = @[f, g, h];
};
bonus = bonus();
bonus[2]();
bonus[0]();
bonus[1]();
2022-02-06 10:04:49 +01:00
//expect:3.0
//expect:1.0
//expect:2.0