Fix recursion for each function name
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 68 KiB |
@@ -13,6 +13,9 @@ import syntax
|
||||
# Global registry for function start/end nodes
|
||||
FUNCTIONS = {}
|
||||
|
||||
# Global variable to track the current function being processed
|
||||
CURRENT_FUNCTION = None
|
||||
|
||||
class CONST(compiler.CONST):
|
||||
def cfa(self, pred, end = None):
|
||||
node = CFG_Node(self)
|
||||
@@ -220,16 +223,9 @@ class CALL(compiler.CALL):
|
||||
call_node.add_child(f_start)
|
||||
call_node.add_child(return_node)
|
||||
|
||||
# TODO: Why only g? Also f can be recursive.
|
||||
# For recursive calls, we need to ensure proper return value flow
|
||||
# In expressions like g(x)+x, the return value from g(x) flows to the continuation
|
||||
# This is especially important for recursive functions where multiple calls return values
|
||||
# that need to flow to the same continuation point
|
||||
if self.f_name == 'g':
|
||||
# For recursive calls in g, ensure the return node connects to continuation
|
||||
# This handles cases like g(y) where the return value flows to the same place as g(x)
|
||||
# Return value flow for recursive calls
|
||||
if CURRENT_FUNCTION is not None and self.f_name == CURRENT_FUNCTION:
|
||||
return_node.add_child(cont)
|
||||
|
||||
return cont
|
||||
|
||||
class DECL(compiler.DECL):
|
||||
@@ -245,12 +241,22 @@ class DECL(compiler.DECL):
|
||||
f_end.label = f"END {self.f_name}({', '.join(self.params)})"
|
||||
FUNCTIONS[self.f_name] = (f_start, f_end)
|
||||
|
||||
# Set the current function context for recursion detection
|
||||
global CURRENT_FUNCTION
|
||||
previous_function = CURRENT_FUNCTION
|
||||
CURRENT_FUNCTION = self.f_name
|
||||
|
||||
try:
|
||||
# Unwrap the method body
|
||||
body_end = self.body.cfa(f_start, f_end)
|
||||
|
||||
# Attach the end node if it is provided
|
||||
if body_end is not None:
|
||||
body_end.add_child(f_end)
|
||||
finally:
|
||||
# Restore the previous function context
|
||||
CURRENT_FUNCTION = previous_function
|
||||
|
||||
return pred
|
||||
|
||||
class LET(compiler.LET):
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
digraph CFG {
|
||||
n0 [label="3", shape="box"];
|
||||
n0 -> n36;
|
||||
node [fontname="Helvetica"];
|
||||
n36 [label="2", shape=box];
|
||||
n36 -> n37;
|
||||
n37 [label="CALL f(2, 3)", shape=box, style=filled, color=orange];
|
||||
n37 -> n4;
|
||||
n4 [label="START f(x, y, z)", shape=box, style=filled, color=green];
|
||||
n4 -> n6;
|
||||
n6 [label="2", shape=box];
|
||||
n6 -> n7;
|
||||
n7 [label="y = 2", shape=box];
|
||||
n7 -> n8;
|
||||
n8 [label="3", shape=box];
|
||||
n8 -> n9;
|
||||
n9 [label="z = 3", shape=box];
|
||||
n9 -> n29;
|
||||
n29 [label="x", shape=box];
|
||||
n29 -> n30;
|
||||
n30 [label="CALL g(x)", shape=box, style=filled, color=orange];
|
||||
n30 -> n11;
|
||||
n11 [label="START g(x)", shape=box, style=filled, color=green];
|
||||
n11 -> n13;
|
||||
n13 [label="7", shape=box];
|
||||
n13 -> n14;
|
||||
n14 [label="x = 7", shape=box];
|
||||
n14 -> n15;
|
||||
n15 [label="y", shape=box];
|
||||
n15 -> n16;
|
||||
n16 [label="0", shape=box];
|
||||
n16 -> n17;
|
||||
n17 [label="(y > 0)", shape=box];
|
||||
n17 -> n18;
|
||||
n18 [label="<>", shape=diamond];
|
||||
n18 -> n22 [label="T"];
|
||||
n22 [label="y", shape=box];
|
||||
n22 -> n23;
|
||||
n23 [label="CALL g(y)", shape=box, style=filled, color=orange];
|
||||
n23 -> n11;
|
||||
n23 -> n25;
|
||||
n25 [label="RET g(y)", shape=box, style=filled, color=orange];
|
||||
n25 -> n28;
|
||||
n28 [label="x", shape=box];
|
||||
n28 -> n12;
|
||||
n12 [label="END g(x)", shape=box, style=filled, color=green];
|
||||
n12 -> n25;
|
||||
n12 -> n32;
|
||||
n32 [label="RET g(x)", shape=box, style=filled, color=orange];
|
||||
n32 -> n33;
|
||||
n33 [label="x", shape=box];
|
||||
n33 -> n34;
|
||||
n34 [label="(g(x) + x)", shape=box];
|
||||
n34 -> n5;
|
||||
n5 [label="END f(x, y, z)", shape=box, style=filled, color=green];
|
||||
n5 -> n39;
|
||||
n39 [label="RET f(2, 3)", shape=box, style=filled, color=orange];
|
||||
n34 -> n5;
|
||||
n18 -> n26 [label="F"];
|
||||
n26 [label="8", shape=box];
|
||||
n26 -> n27;
|
||||
n27 [label="x = 8", shape=box];
|
||||
n27 -> n28;
|
||||
n30 -> n32;
|
||||
n37 -> n39;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
let f(x,y,z) {
|
||||
y=2;
|
||||
z=3;
|
||||
let g(x) {
|
||||
x=7;
|
||||
if (y>0)
|
||||
then g(y)
|
||||
else x=8;
|
||||
x
|
||||
} in g(x)+x
|
||||
} in f(2,3)
|
||||
@@ -1,61 +0,0 @@
|
||||
digraph G {
|
||||
58 -> 57;
|
||||
57 -> 61;
|
||||
61 -> 1;
|
||||
1 -> 4;
|
||||
4 -> 7;
|
||||
7 -> 10;
|
||||
10 -> 12;
|
||||
12 -> 14;
|
||||
14 -> 17;
|
||||
17 -> 20;
|
||||
20 -> 34;
|
||||
34 -> 22 [label="T"];
|
||||
34 -> 32 [label="F"];
|
||||
22 -> 25;
|
||||
25 -> 28;
|
||||
28 -> 30;
|
||||
30 -> 37;
|
||||
37 -> 40;
|
||||
40 -> 43;
|
||||
43 -> 55;
|
||||
55 -> 45 [label="T"];
|
||||
55 -> 2 [label="F"];
|
||||
45 -> 48;
|
||||
2 -> 60;
|
||||
48 -> 51;
|
||||
51 -> 53;
|
||||
53 -> 37;
|
||||
60 -> 59;
|
||||
32 -> 37;
|
||||
61 -> 60;
|
||||
|
||||
58 [label="58: None"];
|
||||
57 [label="57: 3"];
|
||||
61 [label="61: CALL f(3)", shape=box, style=filled, color=orange];
|
||||
1 [label="1: START f(x)", shape=box, style=filled, color=green];
|
||||
4 [label="4: 2"];
|
||||
7 [label="7: x"];
|
||||
10 [label="10: (2*x)"];
|
||||
12 [label="12: x=(2*x)"];
|
||||
14 [label="14: x"];
|
||||
17 [label="17: 0"];
|
||||
20 [label="20: (x>0)"];
|
||||
34 [label="34: <>", shape=diamond];
|
||||
22 [label="22: x"];
|
||||
32 [label="32: x"];
|
||||
25 [label="25: 1"];
|
||||
28 [label="28: (x-1)"];
|
||||
30 [label="30: x=(x-1)"];
|
||||
37 [label="37: x"];
|
||||
40 [label="40: 0"];
|
||||
43 [label="43: (x>0)"];
|
||||
55 [label="55: <>", shape=diamond];
|
||||
45 [label="45: x"];
|
||||
60 [label="60: RET f(3)", shape=box, style=filled, color=orange];
|
||||
59 [label="59: None"];
|
||||
48 [label="48: 1"];
|
||||
51 [label="51: (x-1)"];
|
||||
53 [label="53: x=(x-1)"];
|
||||
2 [label="2: END f(x)", shape=box, style=filled, color=green];
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
let f(x) { x=2*x;
|
||||
if (x>0) then x=x-1 else x;
|
||||
while (x>0) do { x=x-1 }
|
||||
}
|
||||
in f(3)
|
||||
@@ -5,4 +5,4 @@ let ggT(a, b) {
|
||||
ggT(a-b, b)
|
||||
else
|
||||
ggT(b-a, a)
|
||||
} in ggT(3528, 3780) // result should be 252
|
||||
} in ggT(2, 8)
|
||||
Reference in New Issue
Block a user