Path: csiph.com!news.swapon.de!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Alex Newsgroups: comp.lang.forth Subject: Re: EXIT THEN Date: Tue, 7 Feb 2017 21:14:27 +0000 Organization: A noiseless patient Spider Lines: 67 Message-ID: References: <40682dd5-ba45-4b07-bd5c-7974b1119e78@googlegroups.com> <42c0521f-942a-43ca-8a08-2381f93b0a13@googlegroups.com> <2017Jan26.120712@mips.complang.tuwien.ac.at> <2017Feb7.185415@mips.complang.tuwien.ac.at> Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Tue, 7 Feb 2017 21:12:41 -0000 (UTC) Injection-Info: mx02.eternal-september.org; posting-host="09d225435846258236b956f79a1f1c7f"; logging-data="9525"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/LRECmFTX0b0yoyTWlNtzJuTRe8zEZqVA=" User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.7.0 In-Reply-To: <2017Feb7.185415@mips.complang.tuwien.ac.at> Cancel-Lock: sha1:SpNNFdQGw7W6t2MkssgyCQTwxLI= Xref: csiph.com comp.lang.forth:54694 On 2/7/2017 17:54, Anton Ertl wrote: > > Which brings me to the benefits of using THROW. THROW does the stack > and DO..LOOP cleanup by itself, and that really lowers the programming > burden. E.g., if you have > > IF 2drop rdrop true EXIT THEN > or > IF nip nip unloop exit THEN > > (taken from real code), you first have to write this code to clean up > the stacks, and when you change something in the word, you may have to > update it. By contrast, when you exit with > > ( flag ) condition# and throw > > all that goes away, and you can mostly think about the word (or at > least that part of the word) as if you were dealing with straight-line > code. Another advantage is that, like straight-line code, you can > factor parts of the code (including the THROW) out into separate > words, unlike code containing EXIT. This was exactly the technique I used in Win32Forth to support (pre the recognizer proposal) a stack of number conversion words. Each attempts to convert the number, and on failure, THROWs. CATCH then attempts the next in the list until the list is exhausted, when we issue -13 THROW (not found). Much easier than having to stack balance; apropos the recognizer proposal, it's a better technique IMHO than expensive stack cleaning and returning R:FAIL. > > The downsides are that you need to CATCH the conditions, and that > CATCH and THROW are typically not the fastest words around around. They're not desperately expensive if assembler is used. The register usage is not material, but it is worth noting that a non-zero THROW fiddles with the return stack, which might cause slowdowns on processors that are sensitive to RETs not matched with calls. code catch ( xt -- flag ) mov ecx eax ( save xt ) push ebp \ sp@ >r push { handler ebx } \ handler @ >r mov { handler ebx } esp \ rp @ handler ! mov eax { ebp } ( drop xt ) add ebp cell call ecx \ execute mov { -cell ebp } eax pop { handler ebx } \ r> handler ! sub ebp cell add esp cell ( junk old ebp ) xor eax eax \ 0 ret end-code code throw ( n -- ) test eax eax \ ?dup if jz ' drop ( drop if zero ) mov esp { handler ebx } \ handler @ rp! pop { handler ebx } \ r> handler ! pop ebp \ r> swap >r sp! drop r> ret end-code -- Alex