@@ -53,10 +53,10 @@ instance Show Instruction where
5353 show (Split n) = " split " ++ show n
5454 show Print = " print"
5555
56- -- TODO: show output in "structured form" (Exercise 3.36); also requires
56+ -- Show output in "structured form" (Exercise 3.36); also requires
5757-- changes in the print opcode
5858showOutput :: [GmState ] -> String
59- showOutput trace = gmOutput state where state = last trace
59+ showOutput trace = printTree $ gmOutput state where state = last trace
6060
6161showTrace :: [GmState ] -> String
6262showTrace states = iDisplay $ iConcat
@@ -96,7 +96,7 @@ showInstructions is = iConcat
9696
9797showState :: GmState -> Iseq
9898showState state = iConcat
99- [ showOutput' state
99+ [ showOutput'
100100 , iNewline
101101 , showStack state
102102 , iNewline
@@ -105,12 +105,9 @@ showState state = iConcat
105105 , showInstructions $ gmCode state
106106 , iNewline
107107 ]
108-
109- -- Show the GmOutput (different from `showOutput`, which is part of the
110- -- interface for the compiler); introduced in Mark 6
111- showOutput' :: GmState -> Iseq
112- showOutput' state =
113- iConcat [iStr " Output:\" " , iStr $ gmOutput state, iStr " \" " ]
108+ where
109+ showOutput' =
110+ iConcat [iStr " Output: \"\n " , iStr $ showOutput [state], iStr " \" " ]
114111
115112showStack :: GmState -> Iseq
116113showStack state = iConcat
@@ -170,3 +167,58 @@ shortShowStack s =
170167showStats :: GmState -> Iseq
171168showStats state =
172169 iConcat [iStr " Steps taken = " , iNum $ statGetSteps $ gmStats state]
170+
171+ -- Inorder to tree
172+ printToTree :: [PrintPreorderNode ] -> Maybe PrintTreeNode
173+ printToTree [] = Nothing
174+ printToTree inord = getResult $ printToTree' [(1 , PTNStruct (- 1 ) [] )] inord
175+ where
176+ getResult (Just [(0 , PTNStruct (- 1 ) [n])]) = Just $ reverseTree n
177+ getResult Nothing = Nothing
178+ getResult _ = error " printToTree: invalid tree"
179+ reverseTree n@ (PTNNum _) = n
180+ reverseTree (PTNStruct tag children) =
181+ PTNStruct tag $ reverse $ reverseTree <$> children
182+
183+ -- Helper function for inorder -> tree
184+ printToTree'
185+ :: [(Int , PrintTreeNode )]
186+ -> [PrintPreorderNode ]
187+ -> Maybe [(Int , PrintTreeNode )]
188+ -- Done
189+ printToTree' final@ [(0 , _)] [] = Just final
190+ -- 0 elements left, pop the stack
191+ printToTree' ((0 , n) : (arity, PTNStruct tag children) : ppns) inord =
192+ printToTree' ((arity, PTNStruct tag (n : children)) : ppns) inord
193+ printToTree' ((arity, PTNStruct tag children) : ppns) (n : ns) = printToTree''
194+ n
195+ where
196+ printToTree'' (PPNNum n') =
197+ printToTree' ((arity - 1 , PTNStruct tag (PTNNum n' : children)) : ppns) ns
198+ printToTree'' (PPNStruct tag' arity') = printToTree'
199+ ((arity', PTNStruct tag' [] ) : (arity - 1 , PTNStruct tag children) : ppns)
200+ ns
201+ printToTree' _ _ = Nothing
202+
203+ -- Print tree
204+ printTree :: [PrintPreorderNode ] -> String
205+ printTree = toString . printToTree
206+ where
207+ toString Nothing = " "
208+ toString (Just tree) = iDisplay $ printTree' tree
209+
210+ printTree' :: PrintTreeNode -> Iseq
211+ printTree' (PTNNum n ) = iNum n
212+ printTree' (PTNStruct tag children) = printNode tag $ length children
213+ where
214+ printNode 1 0 = iStr " False"
215+ printNode 2 0 = iStr " True"
216+ printNode 3 0 = iStr " Nil"
217+ printNode 4 2 = regularStruct $ iStr " Cons"
218+ printNode n _ = regularStruct $ iNum n
219+ regularStruct tag' = iConcat
220+ [ tag'
221+ , iStr " {"
222+ , iIndent $ iInterleave (iStr " ,\n " ) $ printTree' <$> children
223+ , iStr " }"
224+ ]
0 commit comments