@@ -157,7 +157,8 @@ func (u *Ulp) buildAssemblyHelper(vm *VirtualMachine, header string) (string, er
157157 return "" , err
158158 }
159159 // optimize!
160- err = u .optimize ()
160+ optimizer := Optimizer {u }
161+ err = optimizer .Optimize ()
161162 if err != nil {
162163 return "" , err
163164 }
@@ -201,77 +202,6 @@ func (u *Ulp) buildAssemblyHelper(vm *VirtualMachine, header string) (string, er
201202 return strings .Join (i , "\r \n " ), nil
202203}
203204
204- func (u * Ulp ) optimize () error {
205- // mark all recursive words for later passes
206- err := u .tagRecursion ()
207- if err != nil {
208- return errors .Join (fmt .Errorf ("could not tag recursion during optimization" ), err )
209- }
210- err = u .putTailCalls ()
211- if err != nil {
212- return errors .Join (fmt .Errorf ("could not create tail calls, please file a bug report" ), err )
213- }
214- return nil
215- }
216-
217- // Mark the flag of every word that has recursion.
218- func (u * Ulp ) tagRecursion () error {
219- // unmark all of the words
220- for _ , w := range u .forthWords {
221- w .Entry .Flag .recursive = false
222- }
223- for _ , w := range u .forthWords {
224- u .clearVisited () // clear every word every time
225- for _ , c := range w .Cells { // check every cell in that word
226- if c .IsRecursive (w ) {
227- w .Entry .Flag .recursive = true
228- break
229- }
230- }
231- }
232- return nil
233- }
234-
235- // Put tail calls as an optimization.
236- func (u * Ulp ) putTailCalls () error {
237- for _ , w := range u .forthWords {
238- length := len (w .Cells ) - 1
239- for i := 0 ; i < length ; i ++ {
240- // check if the first cell is a forth word
241- firstAddress , ok := w .Cells [i ].(CellAddress )
242- if ! ok {
243- continue
244- }
245- word , ok := firstAddress .Entry .Word .(* WordForth )
246- if ! ok {
247- continue
248- }
249- // check if the second cell is an EXIT
250- secondAddress , ok := w .Cells [i + 1 ].(CellAddress )
251- if ! ok {
252- continue
253- }
254- if ! secondAddress .Entry .Flag .isExit {
255- continue
256- }
257- // replace both cells with the tail call!
258- tailCall := CellTailCall {word } // create the tail call
259- w .Cells [i ] = & tailCall // replace the word
260- before := w .Cells [:i + 1 ] // get the cells before, including the tail call
261- after := w .Cells [i + 2 :] // get the cells after, excluding the exit
262- w .Cells = append (before , after ... ) // recreate the list
263- length -= 1 // shift the length
264- }
265- }
266- return nil
267- }
268-
269- func (u * Ulp ) clearVisited () {
270- for _ , w := range u .forthWords {
271- w .Entry .ClearVisited ()
272- }
273- }
274-
275205// Convert list of used subroutine-threaded assembly
276206// words into a string.
277207func (u * Ulp ) buildAssemblyWords () (string , error ) {
0 commit comments