From 36ef2fd23db7f559162557d011a2a799d51844cb Mon Sep 17 00:00:00 2001 From: Jan-Niclas Loosen Date: Wed, 21 Jan 2026 21:58:56 +0100 Subject: [PATCH] try to improve diagrams --- Project-02-03-04/Source.gv.png | Bin 0 -> 23190 bytes Project-02-03-04/cfg_build.py | 160 ++++++++---------- Project-02-03-04/example_cfg.dot | 64 +++++++ .../triplaprograms/example.tripla | 11 ++ 4 files changed, 143 insertions(+), 92 deletions(-) create mode 100644 Project-02-03-04/Source.gv.png create mode 100644 Project-02-03-04/example_cfg.dot create mode 100644 Project-02-03-04/triplaprograms/example.tripla diff --git a/Project-02-03-04/Source.gv.png b/Project-02-03-04/Source.gv.png new file mode 100644 index 0000000000000000000000000000000000000000..bde5764d8fadc187ae463ecf97a3ef3ffb0212fa GIT binary patch literal 23190 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�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 literal 0 HcmV?d00001 diff --git a/Project-02-03-04/cfg_build.py b/Project-02-03-04/cfg_build.py index 4e7ebfa..193d933 100644 --- a/Project-02-03-04/cfg_build.py +++ b/Project-02-03-04/cfg_build.py @@ -8,174 +8,150 @@ from cfg.CFG_Node import ( import compiler import syntax - -# ------------------------------------------------- -# Global function environment -# ------------------------------------------------- - -FUNCTIONS = {} # name -> (func_start, func_end) - - -# ------------------------------------------------- -# Expressions — NO CFG NODES -# ------------------------------------------------- +FUNCTIONS = {} class CONST(compiler.CONST): def cfa(self, pred, end): - return pred - + n = CFG_Node(self) + pred.add_child(n) + n.add_child(end) if end else None + return n class ID(compiler.ID): def cfa(self, pred, end): - return pred - + n = CFG_Node(self) + pred.add_child(n) + n.add_child(end) if end else None + return n class AOP(compiler.AOP): def cfa(self, pred, end): - return pred - + left_node = self.arg1.cfa(pred, None) + right_node = self.arg2.cfa(left_node, None) + op_node = CFG_Node(self) + right_node.add_child(op_node) + op_node.add_child(end) if end else None + return op_node class COMP(compiler.COMP): def cfa(self, pred, end): - return pred - + left_node = self.arg1.cfa(pred, None) + right_node = self.arg2.cfa(left_node, None) + comp_node = CFG_Node(self.operator) + right_node.add_child(comp_node) + comp_node.add_child(end) if end else None + return comp_node class EQOP(compiler.EQOP): def cfa(self, pred, end): - return pred - + left_node = self.arg1.cfa(pred, None) + right_node = self.arg2.cfa(left_node, None) + eqop_node = CFG_Node(self) + right_node.add_child(eqop_node) + eqop_node.add_child(end) if end else None + return eqop_node class LOP(compiler.LOP): def cfa(self, pred, end): - return pred - - -# ------------------------------------------------- -# Statements -# ------------------------------------------------- + n = CFG_Node(self) + pred.add_child(n) + n.add_child(end) if end else None + return n class ASSIGN(compiler.ASSIGN): def cfa(self, pred, end): - n = CFG_Node(self) - pred.add_child(n) - return n - + expr_node = self.expr.cfa(pred, None) + assign_node = CFG_Node(self) + expr_node.add_child(assign_node) + assign_node.add_child(end) if end else None + return assign_node class SEQ(compiler.SEQ): def cfa(self, pred, end): - mid = self.exp1.cfa(pred, end) + mid = self.exp1.cfa(pred, None) if mid is None: return None return self.exp2.cfa(mid, end) - class IF(compiler.IF): def cfa(self, pred, end): - # decision node (condition only) - cond = CFG_DIAMOND(self.cond) - pred.add_child(cond) - - # explicit branch entries + cond_node = self.cond.cfa(pred, None) + diamond = CFG_DIAMOND(self.cond) + cond_node.add_child(diamond) then_entry = CFG_Node() else_entry = CFG_Node() - cond.add_child(then_entry) - cond.add_child(else_entry) - - # join node + diamond.add_child(then_entry) + diamond.add_child(else_entry) join = CFG_Node() - - then_end = self.exp1.cfa(then_entry, end) - else_end = self.exp2.cfa(else_entry, end) - - if then_end is not None: - then_end.add_child(join) - if else_end is not None: - else_end.add_child(join) - + join.add_child(end) if end else None + then_end = self.exp1.cfa(then_entry, join) + else_end = self.exp2.cfa(else_entry, join) return join - class WHILE(compiler.WHILE): def cfa(self, pred, end): - # loop condition - cond = CFG_DIAMOND(self.cond) - pred.add_child(cond) - - # body entry + cond_node = self.cond.cfa(pred, None) + diamond = CFG_DIAMOND(self.cond) + cond_node.add_child(diamond) body_entry = CFG_Node() - cond.add_child(body_entry) - - body_end = self.body.cfa(body_entry, end) + diamond.add_child(body_entry) + body_end = self.body.cfa(body_entry, diamond) if body_end is not None: - body_end.add_child(cond) # back-edge - - # loop exit + body_end.add_child(diamond) after = CFG_Node() - cond.add_child(after) - + diamond.add_child(after) + after.add_child(end) if end else None return after - -# ------------------------------------------------- -# Functions / calls (interprocedural CFG) -# ------------------------------------------------- - class CALL(compiler.CALL): def cfa(self, pred, end): - call = CFG_CALL(self) - pred.add_child(call) + call_node = CFG_Node(self) + call_node.label = f"START {self.f_name}({', '.join(map(str, self.arg))})" + pred.add_child(call_node) - # continuation after return cont = CFG_Node() + cont.add_child(end) if end else None if self.f_name not in FUNCTIONS: raise RuntimeError(f"Call to undefined function '{self.f_name}'") f_start, f_end = FUNCTIONS[self.f_name] - # call → function entry - call.add_child(f_start) - - # function exit → continuation - f_end.add_child(cont) + # Create return node from function + return_node = CFG_Node(self) + return_node.label = f"END {self.f_name}({', '.join(map(str, self.arg))})" + f_end.add_child(return_node) + return_node.add_child(cont) + call_node.add_child(f_start) return cont - class DECL(compiler.DECL): def cfa(self, pred, end): - # function entry / exit f_start = CFG_Node(self) + f_start.label = f"START {self.f_name}({', '.join(self.params)})" f_end = CFG_Node(self) + f_end.label = f"END {self.f_name}({', '.join(self.params)})" - # register function FUNCTIONS[self.f_name] = (f_start, f_end) - - # build function body body_end = self.body.cfa(f_start, f_end) if body_end is not None: body_end.add_child(f_end) - - # function declaration does not alter current control flow return pred - class LET(compiler.LET): def cfa(self, pred, end): current = pred - decls = self.decl if isinstance(self.decl, list) else [self.decl] for d in decls: - current = d.cfa(current, end) + current = d.cfa(current, None) if current is None: return None - return self.body.cfa(current, end) - class RETURN(syntax.EXPRESSION): def cfa(self, pred, end): n = CFG_RETURN(self) pred.add_child(n) - n.add_child(end) # return to function exit - return None # no fallthrough + n.add_child(end) + return None diff --git a/Project-02-03-04/example_cfg.dot b/Project-02-03-04/example_cfg.dot new file mode 100644 index 0000000..8262d1b --- /dev/null +++ b/Project-02-03-04/example_cfg.dot @@ -0,0 +1,64 @@ +digraph CFG { + node [fontname="Helvetica"]; + n31 [label="START", shape=circle]; + n31 -> n59; + n59 [label="f(2,3)", shape=box]; + n59 -> n33; + n33 [label="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) }", shape=box]; + n33 -> n35; + n35 [label="2", shape=box]; + n35 -> n36; + n36 [label="y = 2", shape=box]; + n36 -> n37; + n37 [label="3", shape=box]; + n37 -> n38; + n38 [label="z = 3", shape=box]; + n38 -> n55; + n55 [label="g(x)", shape=box]; + n55 -> n39; + n39 [label="g(['x']) { x = 7; if ((y > 0)) then { g(y) } else { x = 8 }; x }", shape=box]; + n39 -> n41; + n41 [label="7", shape=box]; + n41 -> n42; + n42 [label="x = 7", shape=box]; + n42 -> n43; + n43 [label="y", shape=box]; + n43 -> n44; + n44 [label="0", shape=box]; + n44 -> n45; + n45 [label="(y > 0)", shape=box]; + n45 -> n46; + n46 [label="(y > 0)", shape=diamond]; + n46 -> n47; + n47 [label="", shape=box]; + n47 -> n50; + n50 [label="g(y)", shape=box]; + n50 -> n39; + n46 -> n48; + n48 [label="", shape=box]; + n48 -> n52; + n52 [label="8", shape=box]; + n52 -> n53; + n53 [label="x = 8", shape=box]; + n53 -> n49; + n49 [label="", shape=box]; + n49 -> n54; + n54 [label="x", shape=box]; + n54 -> n40; + n40 [label="g(['x']) { x = 7; if ((y > 0)) then { g(y) } else { x = 8 }; x }", shape=box]; + n40 -> n51; + n51 [label="", shape=box]; + n51 -> n49; + n40 -> n56; + n56 [label="", shape=box]; + n56 -> n57; + n57 [label="x", shape=box]; + n57 -> n58; + n58 [label="(g(x) + x)", shape=box]; + n58 -> n34; + n34 [label="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) }", shape=box]; + n34 -> n60; + n60 [label="", shape=box]; + n60 -> n32; + n32 [label="END", shape=doublecircle]; +} \ No newline at end of file diff --git a/Project-02-03-04/triplaprograms/example.tripla b/Project-02-03-04/triplaprograms/example.tripla new file mode 100644 index 0000000..249bb65 --- /dev/null +++ b/Project-02-03-04/triplaprograms/example.tripla @@ -0,0 +1,11 @@ +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