265 lines
4.1 KiB
Plaintext
265 lines
4.1 KiB
Plaintext
// cascade
|
|
|
|
var f1 = funct() { @result
|
|
var x = 1;
|
|
var y = 5;
|
|
:result = funct() { @result
|
|
var z = 8;
|
|
print (x);
|
|
x = x + 1;
|
|
:result = funct() { @result
|
|
print (x);
|
|
x = x + 1;
|
|
:result = funct() { @result
|
|
print (x);
|
|
print (y);
|
|
print (z);
|
|
x = x + 1;
|
|
:result = funct() {
|
|
print (x);
|
|
x = x + 1;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
f1()()()()();
|
|
//expect:1.0
|
|
//expect:2.0
|
|
//expect:3.0
|
|
//expect:5.0
|
|
//expect:8.0
|
|
//expect:4.0
|
|
|
|
// capturing closures in lists:
|
|
|
|
var f = funct() { @result
|
|
var y = 5;
|
|
var x = @[
|
|
funct() print (y),
|
|
funct() y = y + 1
|
|
];
|
|
:result = x;
|
|
};
|
|
|
|
var inst = f();
|
|
|
|
//expect:5.0
|
|
inst[0]();
|
|
inst[1]();
|
|
//expect:6.0
|
|
inst[0]();
|
|
|
|
// multiple different labels
|
|
|
|
var f2 = funct() { @result
|
|
var x = { @a @b
|
|
// this captures the internal value, not whatever it returns is assigned to
|
|
:result = @{
|
|
get = funct() print (:a),
|
|
["set"] = funct(n) :b = n,
|
|
};
|
|
};
|
|
x = 5;
|
|
};
|
|
|
|
var inst2 = f2();
|
|
inst2["get"]();
|
|
//expect:nil
|
|
inst2["set"](5.2);
|
|
inst2["get"]();
|
|
//expect:5.2
|
|
|
|
// capturing args
|
|
|
|
var argcap = funct(n)
|
|
funct() print (n)
|
|
;
|
|
|
|
//expect:8.1
|
|
argcap(8.1)();
|
|
|
|
|
|
// oop: constructors, getters, setters
|
|
|
|
var newAnimal = funct(species, color) { @result
|
|
var species = species; // copy it so that it's mutable, if args ever get immutable
|
|
var animal = @{
|
|
["getSpecies"] = funct() species,
|
|
["setSpecies"] = funct(newSpecies) species = newSpecies,
|
|
["getColor"] = funct() 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) { @result
|
|
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() { @result
|
|
var x = "value";
|
|
var middle = funct() { @result
|
|
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() { @result
|
|
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;
|
|
};
|
|
middle();
|
|
:result = funct() 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;
|
|
};
|
|
|
|
main5();
|
|
globalGet();
|
|
//expect:initial
|
|
globalSet();
|
|
globalGet();
|
|
//expect:updated
|
|
|
|
// 6: multiple upvalues in a simple scope
|
|
|
|
{
|
|
var a = 1;
|
|
var f = funct() {
|
|
print (a);
|
|
};
|
|
var b = 2;
|
|
var g = funct() {
|
|
print (b);
|
|
};
|
|
var c = 3;
|
|
var h = funct() {
|
|
print (c);
|
|
};
|
|
|
|
f();
|
|
g();
|
|
h();
|
|
//expect:1.0
|
|
//expect:2.0
|
|
//expect:3.0
|
|
};
|
|
|
|
// bonus: the last one with a list twist
|
|
|
|
var bonus = funct() { @result
|
|
var a = 1;
|
|
var f = funct() {
|
|
print (a);
|
|
};
|
|
var b = 2;
|
|
var g = funct() {
|
|
print (b);
|
|
};
|
|
var c = 3;
|
|
var h = funct() {
|
|
print (c);
|
|
};
|
|
|
|
:result = @[f, g, h];
|
|
};
|
|
|
|
bonus = bonus();
|
|
bonus[2]();
|
|
bonus[0]();
|
|
bonus[1]();
|
|
//expect:3.0
|
|
//expect:1.0
|
|
//expect:2.0
|