blob: 87cf12e306bcb428bab211fc0ecc0ed7ce427e33 (
plain) (
blame)
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
//: Continuations are a powerful primitive for constructing advanced kinds of
//: control *policies* like back-tracking. They're usually provided using a
//: primitive called 'call-cc': http://en.wikipedia.org/wiki/Call-with-current-continuation)
//: But in mu 'call-cc' is constructed out of a combination of two primitives:
//: 'current-continuation', which returns a continuation, and
//: 'continue-from', which takes a continuation to switch to.
//: todo: implement continuations in mu's memory
:(before "End Globals")
map<long long int, call_stack> Continuation;
long long int Next_continuation_id = 0;
:(before "End Setup")
Continuation.clear();
Next_continuation_id = 0;
:(before "End Mu Types Initialization")
type_number continuation = Type_number["continuation"] = Next_type_number++;
Type[continuation].name = "continuation";
:(before "End Primitive Recipe Declarations")
CURRENT_CONTINUATION,
:(before "End Primitive Recipe Numbers")
Recipe_number["current-continuation"] = CURRENT_CONTINUATION;
:(before "End Primitive Recipe Implementations")
case CURRENT_CONTINUATION: {
Continuation[Next_continuation_id] = Current_routine->calls; // deep copy because calls have no pointers
products.resize(1);
products.at(0).push_back(Next_continuation_id);
++Next_continuation_id;
break;
}
:(before "End Primitive Recipe Declarations")
CONTINUE_FROM,
:(before "End Primitive Recipe Numbers")
Recipe_number["continue-from"] = CONTINUE_FROM;
:(before "End Primitive Recipe Implementations")
case CONTINUE_FROM: {
assert(scalar(ingredients.at(0)));
long long int c = ingredients.at(0).at(0);
Current_routine->calls = Continuation[c]; // deep copy because calls have no pointers
// refresh instruction_counter to next instruction after current-continuation
instruction_counter = current_step_index()+1;
continue; // skip the rest of this instruction
}
:(scenario continuation)
# simulate a loop using continuations
recipe main [
1:number <- copy 0:literal
2:continuation <- current-continuation
{
#? $print 1:number
3:boolean <- greater-or-equal 1:number, 3:literal
break-if 3:boolean
1:number <- add 1:number, 1:literal
continue-from 2:continuation # loop
}
]
+mem: storing 1 in location 1
+mem: storing 2 in location 1
+mem: storing 3 in location 1
-mem: storing 4 in location 1
:(scenario continuation_inside_caller)
recipe main [
1:number <- copy 0:literal
2:continuation <- loop-body
{
3:boolean <- greater-or-equal 1:number, 3:literal
break-if 3:boolean
continue-from 2:continuation # loop
}
]
recipe loop-body [
4:continuation <- current-continuation
1:number <- add 1:number, 1:literal
]
+mem: storing 1 in location 1
+mem: storing 2 in location 1
+mem: storing 3 in location 1
-mem: storing 4 in location 1
|