diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-01-04 15:34:49 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-01-04 15:34:49 -0200 |
| commit | f5bc6710309fb368e4bc84a019b8e50e82faab0b (patch) | |
| tree | 09f28a3225112d04ec967832c5743bb9728cc970 | |
| parent | d7294c6de8e8e2e5d124cfc20ff2ad1a1c2a84f5 (diff) | |
| download | lua-f5bc6710309fb368e4bc84a019b8e50e82faab0b.tar.gz lua-f5bc6710309fb368e4bc84a019b8e50e82faab0b.tar.bz2 lua-f5bc6710309fb368e4bc84a019b8e50e82faab0b.zip | |
"goto" for tail recursion changed to "while"
| -rw-r--r-- | lbuiltin.c | 27 |
1 files changed, 13 insertions, 14 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbuiltin.c,v 1.43 1998/12/30 13:16:50 roberto Exp $ | 2 | ** $Id: lbuiltin.c,v 1.44 1999/01/04 12:55:09 roberto Exp roberto $ |
| 3 | ** Built-in functions | 3 | ** Built-in functions |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -445,21 +445,20 @@ static int sort_comp (TObject *f, TObject *a, TObject *b) { | |||
| 445 | } | 445 | } |
| 446 | 446 | ||
| 447 | static void auxsort (Hash *a, int l, int u, TObject *f) { | 447 | static void auxsort (Hash *a, int l, int u, TObject *f) { |
| 448 | init: /* using goto's to optimize tail recursion */ | 448 | while (l < u) { /* for tail recursion */ |
| 449 | if (u <= l) return; /* 0 or 1 element */ | ||
| 450 | else { | ||
| 451 | TObject *P; | 449 | TObject *P; |
| 452 | int i, j; | 450 | int i, j; |
| 453 | /* sort elements a[l], a[(l+u)/2] and a[u] */ | 451 | /* sort elements a[l], a[(l+u)/2] and a[u] */ |
| 454 | if (sort_comp(f, luaH_getint(a, u), luaH_getint(a, l))) /* a[l]>a[u]? */ | 452 | if (sort_comp(f, luaH_getint(a, u), luaH_getint(a, l))) /* a[l]>a[u]? */ |
| 455 | swap(a, l, u); | 453 | swap(a, l, u); |
| 456 | if (u-l == 1) return; /* only 2 elements */ | 454 | if (u-l == 1) break; /* only 2 elements */ |
| 457 | i = (l+u)/2; | 455 | i = (l+u)/2; |
| 458 | if (sort_comp(f, luaH_getint(a, i), luaH_getint(a, l))) /* a[l]>a[i]? */ | 456 | P = luaH_getint(a, i); |
| 457 | if (sort_comp(f, P, luaH_getint(a, l))) /* a[l]>a[i]? */ | ||
| 459 | swap(a, l, i); | 458 | swap(a, l, i); |
| 460 | else if (sort_comp(f, luaH_getint(a, u), luaH_getint(a, i))) /* a[i]>a[u]? */ | 459 | else if (sort_comp(f, luaH_getint(a, u), P)) /* a[i]>a[u]? */ |
| 461 | swap(a, i, u); | 460 | swap(a, i, u); |
| 462 | if (u-l == 2) return; /* only 3 elements */ | 461 | if (u-l == 2) break; /* only 3 elements */ |
| 463 | P = L->stack.top++; | 462 | P = L->stack.top++; |
| 464 | *P = *luaH_getint(a, i); /* save pivot on stack (for GC) */ | 463 | *P = *luaH_getint(a, i); /* save pivot on stack (for GC) */ |
| 465 | swap(a, i, u-1); /* put median element as pivot (a[u-1]) */ | 464 | swap(a, i, u-1); /* put median element as pivot (a[u-1]) */ |
| @@ -477,15 +476,15 @@ static void auxsort (Hash *a, int l, int u, TObject *f) { | |||
| 477 | swap(a, u-1, i); /* swap pivot (a[u-1]) with a[i] */ | 476 | swap(a, u-1, i); /* swap pivot (a[u-1]) with a[i] */ |
| 478 | L->stack.top--; /* remove pivot from stack */ | 477 | L->stack.top--; /* remove pivot from stack */ |
| 479 | /* a[l..i-1] <= a[i] == P <= a[i+1..u] */ | 478 | /* a[l..i-1] <= a[i] == P <= a[i+1..u] */ |
| 480 | if (i-l < u-i) { /* check which "half" is bigger */ | 479 | /* adjust so that smaller "half" is in [j..i] and larger one in [l..u] */ |
| 481 | auxsort(a, l, i-1, f); /* call recursively the smaller one */ | 480 | if (i-l < u-i) { |
| 482 | l = i+1; goto init; /* auxsort(a, i+1, u, f); */ | 481 | j=l; i=i-1; l=i+2; |
| 483 | } | 482 | } |
| 484 | else { | 483 | else { |
| 485 | auxsort(a, i+1, u, f); | 484 | j=i+1; i=u; u=j-2; |
| 486 | u = i-1; goto init; /* auxsort(a, l, i-1, f); */ | ||
| 487 | } | 485 | } |
| 488 | } | 486 | auxsort(a, j, i, f); /* call recursively the smaller one */ |
| 487 | } /* repeat the routine for the larger one */ | ||
| 489 | } | 488 | } |
| 490 | 489 | ||
| 491 | static void luaB_sort (void) { | 490 | static void luaB_sort (void) { |
