diff options
| -rw-r--r-- | src/Grasp/Interpreter.hs | 34 | 
1 files changed, 30 insertions, 4 deletions
diff --git a/src/Grasp/Interpreter.hs b/src/Grasp/Interpreter.hs index 2d04226..e009e5e 100644 --- a/src/Grasp/Interpreter.hs +++ b/src/Grasp/Interpreter.hs @@ -79,7 +79,7 @@ execute g (cur:rest) out =                      "new" -> newI g node                      "del" -> delI g node                      "push" -> pushI g node -                    "pop" -> popI g node +                    "pop" -> popI g node >>= (\x -> return (garbageCollect x ((cur:rest) ++ out)))                      "pick" -> pickI g node                      "add" -> addI g node                      "mul" -> mulI g node @@ -252,11 +252,37 @@ popI :: GraspProgram -> Node -> IO GraspProgram  popI g node =      let edges = Graph.out g node -        stackN = targetNodes (getByLabel "stack" edges) -        outL = targetLabels g (getByLabel "out" edges) +        stackNs = targetNodes (getByLabel "stack" edges) +        outN = targetNodes (getByLabel "out" edges)          emptyL = targetLabels g (getByLabel "empty" edges) -    in return g +    in if (length stackNs /= 1) then error ("Instruction " ++ (show node) ++ +                                            " should have one stack argument") + +       else let stackN = head stackNs +                nextN = targetNodes (getByLabel "next" (Graph.out g stackN)) + +            in case nextN of +                x | length x > 1 -> error ("Stack node " ++ (show node) ++ +                                            " should only have one next edge") + +                x | length x == 1 -> +                    let label = fromJust (Graph.lab g stackN) +                        g' = foldl' (\gr n -> reLabel gr n label) g outN + +                        s = head x +                        edgesToDel = Graph.inn g' s +                        edgesToAdd = map (\(x,y,z) -> (x,s,z)) edgesToDel + +                        g'' = foldl' (flip Graph.delLEdge) g' edgesToDel +                        g''' = Graph.insEdges edgesToAdd g'' +                    in return g''' + +                x -> +                    if (emptyL == []) then return g +                    else (getStdRandom (randomR (0,length emptyL - 1))) >>= +                         (\x -> return (foldl' (\gr n -> reLabel gr n (emptyL !! x)) g outN)) +  | 
