1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
use test;
use parser;
class CopyTracker {
init(Str data) {
init {
data = data;
copies = 0;
}
}
init(CopyTracker x) {
init {
data = x.data;
copies = x.copies + 1;
}
}
Str data;
Nat copies;
}
// No-op function, but requires copies if threading is wrong.
CopyTracker threadFn(CopyTracker x) on Compiler {
x;
}
threadParser : parser(recursive descent) on Compiler {
start = Start;
CopyTracker Start();
Start => threadFn(x) : Other() x;
CopyTracker Other();
Other => CopyTracker(str) : "[A-Z]+" str;
}
test ThreadParser {
var result = threadParser("ABC");
check result.value.any;
if (x = result.value) {
check x.data == "ABC";
// One copy, when transitioning from the parser to this function.
check x.copies == 1;
}
Str data = "ABC";
result = threadParser(data, data.begin + 1);
check result.value.any;
if (x = result.value) {
// If this breaks, iterators are not copied properly.
check x.data == "BC";
// One copy, when transitioning from the parser to this function.
check x.copies == 1;
}
}
|