<commit_before>module Jana.Invert where

import Jana.Ast


invertMain :: ProcMain -> ProcMain
invertMain (ProcMain vdecls body pos) = ProcMain vdecls (invertStmts body) pos

invertProc :: Proc -> Proc
invertProc proc = proc { body = invertStmts $ body proc }

invertStmts :: [Stmt] -> [Stmt]
invertStmts = reverse . map invertStmt

invertStmt :: Stmt -> Stmt
invertStmt (Assign modOp lval expr pos) =
  Assign (invertModOp modOp) lval expr pos
  where invertModOp AddEq = SubEq
        invertModOp SubEq = AddEq
        invertModOp XorEq = XorEq
invertStmt (If e1 ifPart elsePart e2 pos) =
  If e2 (invertStmts ifPart) (invertStmts elsePart) e1 pos
invertStmt (From e1 doPart loopPart e2 pos) =
  From e2 (invertStmts doPart) (invertStmts loopPart) e1 pos
invertStmt (Push id1 id2 pos) = Pop  id1 id2 pos
invertStmt (Pop  id1 id2 pos) = Push id1 id2 pos
invertStmt (Local assign1 body assign2 pos) =
  Local assign2 (invertStmts body) assign1 pos
invertStmt (Call funId args pos) =
  Uncall funId args pos
invertStmt (Uncall funId args pos) =
  Call funId args pos
invertStmt stmt@(Swap{}) = stmt
invertStmt (Skip pos) = Skip pos

<commit_msg>Implement inversion of print statements<commit_after>module Jana.Invert where

import Jana.Ast


invertMain :: ProcMain -> ProcMain
invertMain (ProcMain vdecls body pos) = ProcMain vdecls (invertStmts body) pos

invertProc :: Proc -> Proc
invertProc proc = proc { body = invertStmts $ body proc }

invertStmts :: [Stmt] -> [Stmt]
invertStmts = reverse . map invertStmt

invertStmt :: Stmt -> Stmt
invertStmt (Assign modOp lval expr pos) =
  Assign (invertModOp modOp) lval expr pos
  where invertModOp AddEq = SubEq
        invertModOp SubEq = AddEq
        invertModOp XorEq = XorEq
invertStmt (If e1 ifPart elsePart e2 pos) =
  If e2 (invertStmts ifPart) (invertStmts elsePart) e1 pos
invertStmt (From e1 doPart loopPart e2 pos) =
  From e2 (invertStmts doPart) (invertStmts loopPart) e1 pos
invertStmt (Push id1 id2 pos) = Pop  id1 id2 pos
invertStmt (Pop  id1 id2 pos) = Push id1 id2 pos
invertStmt (Local assign1 body assign2 pos) =
  Local assign2 (invertStmts body) assign1 pos
invertStmt (Call funId args pos) =
  Uncall funId args pos
invertStmt (Uncall funId args pos) =
  Call funId args pos
invertStmt stmt@(Swap{}) = stmt
invertStmt stmt@(Prints{}) = stmt
invertStmt (Skip pos) = Skip pos


{'fraction_non_alphanumeric': 0.07502131287297528, 'fraction_numerical': 0.017050298380221655, 'mean_word_length': 4.203991130820399, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6094252', 'n_tokens_mistral': 870, 'n_tokens_neox': 873, 'n_words': 299}