diff --git a/Pystan/config/__pycache__/cfg.cpython-313.pyc b/Pystan/config/__pycache__/cfg.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a1b43133d0d138251d84d400414c3119bf8b396a Binary files /dev/null and b/Pystan/config/__pycache__/cfg.cpython-313.pyc differ diff --git a/Pystan/config/__pycache__/iteration.cpython-313.pyc b/Pystan/config/__pycache__/iteration.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..182a45b4a0a91969ff332ede1ed6756552b48b86 Binary files /dev/null and b/Pystan/config/__pycache__/iteration.cpython-313.pyc differ diff --git a/Pystan/config/__pycache__/opsem.cpython-310.pyc b/Pystan/config/__pycache__/opsem.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..79a2596fa34922e20fe962b6c42ebccc13aee2b8 Binary files /dev/null and b/Pystan/config/__pycache__/opsem.cpython-310.pyc differ diff --git a/Pystan/config/__pycache__/opsem.cpython-313.pyc b/Pystan/config/__pycache__/opsem.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7cbea5bbeba042ccddd82dd2230166ee2e866f35 Binary files /dev/null and b/Pystan/config/__pycache__/opsem.cpython-313.pyc differ diff --git a/Pystan/config/__pycache__/syntax.cpython-310.pyc b/Pystan/config/__pycache__/syntax.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef799cfcba2d0b265f8588cb7e820aa7eca923ca Binary files /dev/null and b/Pystan/config/__pycache__/syntax.cpython-310.pyc differ diff --git a/Pystan/config/__pycache__/syntax.cpython-313.pyc b/Pystan/config/__pycache__/syntax.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..945336a8d6f58b0ce7fb602288da251f872a3357 Binary files /dev/null and b/Pystan/config/__pycache__/syntax.cpython-313.pyc differ diff --git a/Pystan/config/iteration.py b/Pystan/config/iteration.py index f91169661c566371dc324842b44f562fe95b4d76..231a61b6ef4f90f33cdf0659b7f9eaf61a51200d 100644 --- a/Pystan/config/iteration.py +++ b/Pystan/config/iteration.py @@ -43,4 +43,34 @@ def fixpoint_iteration[T](transfer: Transfer[T], cfg: Cfg) -> dict[Node,T]: output maps each node to the computed state """ - raise NotImplementedError + states: dict[Node, T] = {node: transfer.bottom() for node in cfg.g.nodes} + states[cfg.init_node] = transfer.init_state() + worklist: list[tuple[Node, Node, Label]] = [] + + for dest, label in cfg.init_node.succs: + worklist.append((cfg.init_node, dest, label)) + + while worklist: + src, dst, label = worklist.pop(0) + s_src = states[src] + if isinstance(label, LSkip): + s_new = transfer.tr_skip(s_src) + elif isinstance(label, LSet): + s_new = transfer.tr_set(s_src, label.var, label.expr) + elif isinstance(label, LTest): + s_new = transfer.tr_test(s_src, label.cond) + elif isinstance(label, LErr): + s_new = transfer.tr_err(s_src, label.err) + else: + raise ValueError(f"Étiquette inconnue: {label}") + + s_dst_old = states[dst] + + if not transfer.included(s_new, s_dst_old): + states[dst] = transfer.join(s_dst_old, s_new) + + for dest2, label2 in dst.succs: + worklist.append((dst, dest2, label2)) + + return states + diff --git a/Pystan/config/opsem.py b/Pystan/config/opsem.py index 1313e985e2c11ca43cc8fcaa926eec02eba135f1..0ff1722a5e06c834ae1995d505eedda502fe4a05 100644 --- a/Pystan/config/opsem.py +++ b/Pystan/config/opsem.py @@ -12,39 +12,68 @@ def eval_aexp(env: dict[str,int], exp: ArithExpr) -> int | None: """evaluates an arithmetic expression""" match exp: case AECst(value): - raise NotImplementedError + return value case AEVar(var): - raise NotImplementedError + return env.get(var,None) case AEUop(uop,expr): - raise NotImplementedError + val = eval_aexp(env,expr) + if val is None: + return None + else: + return val case AEBop(bop,left_expr,right_expr): - raise NotImplementedError + v1 = eval_aexp(env,left_expr) + v2 = eval_aexp(env,right_expr) + if v1 is None or v2 is None: + return None + if bop == Bop.ADD: + return eval_aexp(env,left_expr) + eval_aexp(env,right_expr) + elif bop == Bop.MUL: + return eval_aexp(env,left_expr) * eval_aexp(env,right_expr) + elif bop == Bop.DIV: + if eval_aexp(env,right_expr) == 0: + return None + return eval_aexp(env,left_expr) / eval_aexp(env,right_expr) case _: assert False def eval_bexp(env: dict[str,int], exp:BoolExpr) -> bool | None: """evaluates a boolean expression""" match exp: case BEPlain(aexpr): - raise NotImplementedError + if eval_aexp(env,aexpr) == 0: + return False + return True case BEEq(left_expr,right_expr): - raise NotImplementedError + if eval_aexp(env,left_expr) == eval_aexp(env,right_expr): + return True + return False case BELeq(left_expr,right_expr): - raise NotImplementedError + if eval_aexp(env,left_expr) <= eval_aexp(env,right_expr): + return True + return False case BENeg(expr): - raise NotImplementedError + if eval_bexp(env,expr): + return False + return True case _: assert False def eval_instr(env: dict[str,int], instr: Instr) -> dict[str,int] | None: """evaluates an instruction""" match instr: case ISkip(): - raise NotImplementedError + return env case ISet(var,expr): - raise NotImplementedError + envf = env.copy() + envf[var] = eval_aexp(env,expr) + return envf case ISeq(first,second): - raise NotImplementedError + return eval_instr(eval_instr(env,first),second) case ICond(cond,true_branch,false_branch): - raise NotImplementedError + if eval_bexp(env,cond): + return eval_instr(env,true_branch) + return eval_instr(env,false_branch) case ILoop(cond,body): - raise NotImplementedError + while eval_bexp(env,cond): + env = eval_instr(env,body) + return env case _: assert False diff --git a/Pystan/config/syntax.py b/Pystan/config/syntax.py index c0938bda1f9a7554cc4db3a13763d0d68732c5bc..9007e0d1c0341b08cf7bab473a189b7ea4b1282f 100644 --- a/Pystan/config/syntax.py +++ b/Pystan/config/syntax.py @@ -67,7 +67,15 @@ class AEBop(ArithExpr): right_expr: ArithExpr def __str__(self): #TODO: only put parentheses if necessary - return f"({self.left_expr}) {self.bop} ({self.right_expr})" + if isinstance(self.left_expr, AEBop) or isinstance(self.left_expr, AEBop): + return f"({self.left_expr}) {self.bop} ({self.right_expr})" + elif isinstance(self.left_expr, AEBop): + return f"{self.left_expr} {self.bop} ({self.right_expr})" + elif isinstance(self.right_expr, AEBop): + return f"({self.left_expr}) {self.bop} {self.right_expr}" + else: + return f"{self.left_expr} {self.bop} {self.right_expr}" + @dataclass class BoolExpr(Expr): diff --git a/RapportsTP/Rapport_AnaStat_1.pdf b/RapportsTP/Rapport_AnaStat_1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3b6f4de45fcf3245fa53fa23a012ab3a05ed1a18 Binary files /dev/null and b/RapportsTP/Rapport_AnaStat_1.pdf differ