265 lines
4.0 KiB
Plaintext
265 lines
4.0 KiB
Plaintext
// cascade
|
|
|
|
var f1 = funct() {
|
|
var x = 1;
|
|
var y = 5;
|
|
:result = funct() {
|
|
var z = 8;
|
|
print x;
|
|
x = x + 1;
|
|
:result = funct() {
|
|
print x;
|
|
x = x + 1;
|
|
:result = funct() {
|
|
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() {
|
|
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() {
|
|
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)
|
|
:result = funct() print n
|
|
;
|
|
|
|
//expect:8.1
|
|
argcap(8.1)();
|
|
|
|
|
|
// oop: constructors, getters, setters
|
|
|
|
var newAnimal = funct(pspecies, color) {
|
|
var species = pspecies; // 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;
|
|
};
|
|
middle();
|
|
:result = funct() :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;
|
|
};
|
|
|
|
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() {
|
|
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
|