about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2017-12-07 15:59:48 -0800
committerKartik K. Agaram <vc@akkartik.com>2017-12-07 16:00:02 -0800
commit07de3e9536fc1f3fc8f8f77f833c4730b6de1b7d (patch)
tree77278540a072945823364e0abf80d134a98ecb57
parentba2729b2011da0c7e644d1c25a5ff75fca6bb848 (diff)
downloadmu-07de3e9536fc1f3fc8f8f77f833c4730b6de1b7d.tar.gz
4151 - specializing calls returning continuations
-rw-r--r--072recipe.cc13
-rw-r--r--076continuation.cc19
2 files changed, 30 insertions, 2 deletions
diff --git a/072recipe.cc b/072recipe.cc
index d05e8575..eaf1baf3 100644
--- a/072recipe.cc
+++ b/072recipe.cc
@@ -205,7 +205,17 @@ def f x:point -> y:point [
 +error: main: product 0 has the wrong type at '2:num <- call {1: (recipe point -> point)}, 34'
 
 :(before "End resolve_ambiguous_call(r, index, inst, caller_recipe) Special-cases")
-if (inst.name == "call" && !inst.ingredients.empty() && inst.ingredients.at(0).type && inst.ingredients.at(0).type->atom && inst.ingredients.at(0).type->name == "recipe-literal") {
+if (inst.name == "call" && first_ingredient_is_recipe_literal(inst)) {
+  resolve_indirect_ambiguous_call(r, index, inst, caller_recipe);
+  return;
+}
+:(code)
+bool first_ingredient_is_recipe_literal(const instruction& inst) {
+  if (inst.ingredients.empty()) return false;
+  const reagent& ingredient = inst.ingredients.at(0);
+  return ingredient.type && ingredient.type->atom && ingredient.type->name == "recipe-literal";
+}
+void resolve_indirect_ambiguous_call(const recipe_ordinal r, int index, instruction& inst, const recipe& caller_recipe) {
   instruction inst2;
   inst2.name = inst.ingredients.at(0).name;
   for (int i = /*skip recipe*/1;  i < SIZE(inst.ingredients);  ++i)
@@ -215,7 +225,6 @@ if (inst.name == "call" && !inst.ingredients.empty() && inst.ingredients.at(0).t
   resolve_ambiguous_call(r, index, inst2, caller_recipe);
   inst.ingredients.at(0).name = inst2.name;
   inst.ingredients.at(0).set_value(get(Recipe_ordinal, inst2.name));
-  return;
 }
 
 :(after "Transform.push_back(check_instruction)")
diff --git a/076continuation.cc b/076continuation.cc
index df6d0e67..94c3f97a 100644
--- a/076continuation.cc
+++ b/076continuation.cc
@@ -260,6 +260,25 @@ def g [
 # ..even though we never called the continuation
 -app: continuation called
 
+//: Allow shape-shifting recipes to return continuations.
+
+:(scenario call_shape_shifting_recipe_with_continuation_mark)
+def main [
+  1:num <- call-with-continuation-mark f, 34
+]
+def f x:_elem -> y:_elem [
+  local-scope
+  load-ingredients
+  y <- copy x
+]
++mem: storing 34 in location 1
+
+:(before "End resolve_ambiguous_call(r, index, inst, caller_recipe) Special-cases")
+if (inst.name == "call-with-continuation-mark" && first_ingredient_is_recipe_literal(inst)) {
+  resolve_indirect_ambiguous_call(r, index, inst, caller_recipe);
+  return;
+}
+
 //: Ensure that the presence of a continuation keeps its stack frames from being reclaimed.
 
 :(scenario continuations_preserve_local_scopes)
m?h=devel&id=90119066adf6a9a2e8d779d4955637c6dd99aba3'>^
2df9b442c ^
f44a4362b ^

ce23b814a ^
e25474154 ^
f317807a8 ^
0761b449e ^












f317807a8 ^
0761b449e ^


e25474154 ^
a1f677980 ^
0761b449e ^

5b28d0820 ^
0761b449e ^

e25474154 ^
f317807a8 ^
e25474154 ^
ce23b814a ^












5cd933a44 ^
2df9b442c ^
ce23b814a ^


f317807a8 ^

ce23b814a ^





f317807a8 ^
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
84
85
86
87
88
89
90
91
92