diff --git a/Project-02-03-04/Source.gv.png b/Project-02-03-04/Source.gv.png index f5245bf..9321a00 100644 Binary files a/Project-02-03-04/Source.gv.png and b/Project-02-03-04/Source.gv.png differ diff --git a/Project-02-03-04/cfg_build.py b/Project-02-03-04/cfg_build.py index c88e4ec..c859e20 100644 --- a/Project-02-03-04/cfg_build.py +++ b/Project-02-03-04/cfg_build.py @@ -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) - # Unwrap the method body - body_end = self.body.cfa(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 - # Attach the end node if it is provided - if body_end is not None: - body_end.add_child(f_end) return pred class LET(compiler.LET): diff --git a/Project-02-03-04/cfg_examples/example.dot b/Project-02-03-04/cfg_examples/example.dot deleted file mode 100644 index 09fd28c..0000000 --- a/Project-02-03-04/cfg_examples/example.dot +++ /dev/null @@ -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; -} \ No newline at end of file diff --git a/Project-02-03-04/cfg_examples/example.tripla b/Project-02-03-04/cfg_examples/example.tripla deleted file mode 100644 index 249bb65..0000000 --- a/Project-02-03-04/cfg_examples/example.tripla +++ /dev/null @@ -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) \ No newline at end of file diff --git a/Project-02-03-04/cfg_examples/simpleExpressionSequence.dot b/Project-02-03-04/cfg_examples/simpleExpressionSequence.dot deleted file mode 100644 index dbfa7af..0000000 --- a/Project-02-03-04/cfg_examples/simpleExpressionSequence.dot +++ /dev/null @@ -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]; -} diff --git a/Project-02-03-04/cfg_examples/simpleExpressionSequence.tripla b/Project-02-03-04/cfg_examples/simpleExpressionSequence.tripla deleted file mode 100644 index 38264e8..0000000 --- a/Project-02-03-04/cfg_examples/simpleExpressionSequence.tripla +++ /dev/null @@ -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) \ No newline at end of file diff --git a/Project-02-03-04/triplaprograms/ggT_euclid_rec.tripla b/Project-02-03-04/triplaprograms/ggT_euclid_rec.tripla index bc0fb08..9cbc90d 100644 --- a/Project-02-03-04/triplaprograms/ggT_euclid_rec.tripla +++ b/Project-02-03-04/triplaprograms/ggT_euclid_rec.tripla @@ -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 \ No newline at end of file +} in ggT(2, 8) \ No newline at end of file