Rocksolid Light

Welcome to RetroBBS

mail  files  register  newsreader  groups  login

Message-ID:  

I am NOMAD!


devel / comp.lang.lisp / tail call optimisation, lisp implemented in Forth

SubjectAuthor
* tail call optimisation, lisp implemented in Forthnone
`- Re: tail call optimisation, lisp implemented in Forthnone

1
tail call optimisation, lisp implemented in Forth

<nnd$7d844dab$52db8b4e@a0541ff0868dc0dd>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17436&group=comp.lang.lisp#17436

  copy link   Newsgroups: comp.lang.forth comp.lang.lisp
Newsgroups: comp.lang.forth,comp.lang.lisp
Subject: tail call optimisation, lisp implemented in Forth
X-Newsreader: trn 4.0-test77 (Sep 1, 2010)
From: albert@cherry (none)
Originator: albert@cherry.(none) (albert)
Message-ID: <nnd$7d844dab$52db8b4e@a0541ff0868dc0dd>
Organization: KPN B.V.
Date: Mon, 17 Jul 2023 10:56:19 +0200
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!feeder1.feed.usenet.farm!feed.usenet.farm!peer01.ams4!peer.am4.highwinds-media.com!news.highwinds-media.com!feed.abavia.com!abe004.abavia.com!abp002.abavia.com!news.kpn.nl!not-for-mail
Lines: 72
Injection-Date: Mon, 17 Jul 2023 10:56:19 +0200
Injection-Info: news.kpn.nl; mail-complaints-to="abuse@kpn.com"
X-Received-Bytes: 3515
 by: none - Mon, 17 Jul 2023 08:56 UTC

I'm following the instructions of mal (clojure)
https://github.com/kanaka/mal

The instruction in mal step 5 :
Several of the special forms that you have defined in EVAL end up
calling back into EVAL. For those forms that call EVAL as the last
thing that they do before returning (tail call) you will just loop
back to the beginning of eval rather than calling it again.

I come to realize that an implementation of a lisp without tail cal
optimisation is a joke. So this is all but mandatory.

In the context of my Forth implementation a function, say `` if ''
is looked up in the environment, it is special, so it leaves
evaluation of the rest of the list to the discretion of `` if ''.
The bottom line is that there is no way to construct an infinite
loop around special functions, as proposed, in the vein of
"
while true: // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
if not list?(ast): return eval_ast(ast, env)
if empty?(ast): return ast
switch ast[0]:
'def!: return env.set(ast[1], EVAL(ast[2], env))
'let*: env = ...; ast = ast[2] // TCO
'do: ast = eval_ast(ast[1..-1], env)[-1] // TCO
'if: EVAL(ast[1], env) ? ast = ast[2] : ast = ast[3] // TCO
'fn*: return new MalFunc(...)
_default_: f, args = eval_ast(ast, env)
if malfunc?(f): ast = f.fn; env = ... // TCO
else: return apply(f, args)
"
In Forth `` eval '' is a colon definition , that is, a machine code
pointer and an array of tokens. The machine code takes care that
the tokens are interpreted via the SI register (x86)
Nesting is accomplished by storing SI in the return stack
pointed to by the EBP register.
These are the instructions.

DOCOL: LEA EBP,[EBP - (CW*(1))] ; *
MOV [EBP],ESI ; *
MOV ESI,[EAX+(CW*(D_HOFFSET - C_HOFFSET))] ; *
LODSD ; NEXT
JMP DWORD[EAX]

Nesting is marked with *.
The NEXT code takes care that the following token is fetched an
executed. This changes SI.

TCO (tail call optimisation) is accomplished by leaving out the
nesting.
DOCOLPRIME:
LODSD ; NEXT
JMP DWORD[EAX]

So we have
: eval .... ;
and we can define an alias and we fix the code pointer CFA .
'eval ALIAS eval-prime
DOCOLPRIME 'eval-prime >CFA !

So we can change each terminating eval with eval-prime without
bothering with other functions that may or may not be special.

How cool is that!

Groetjes Albert
--
Don't praise the day before the evening. One swallow doesn't make spring.
You must not say "hey" before you have crossed the bridge. Don't sell the
hide of the bear until you shot it. Better one bird in the hand than ten in
the air. First gain is a cat spinning. - the Wise from Antrim -

Re: tail call optimisation, lisp implemented in Forth

<nnd$7e86fc7e$471f840d@f35175c57801cac4>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=17438&group=comp.lang.lisp#17438

  copy link   Newsgroups: comp.lang.forth comp.lang.lisp
Newsgroups: comp.lang.forth,comp.lang.lisp
Subject: Re: tail call optimisation, lisp implemented in Forth
References: <nnd$7d844dab$52db8b4e@a0541ff0868dc0dd>
X-Newsreader: trn 4.0-test77 (Sep 1, 2010)
From: albert@cherry (none)
Originator: albert@cherry.(none) (albert)
Message-ID: <nnd$7e86fc7e$471f840d@f35175c57801cac4>
Organization: KPN B.V.
Date: Mon, 17 Jul 2023 19:37:58 +0200
Path: i2pn2.org!i2pn.org!usenet.blueworldhosting.com!diablo1.usenet.blueworldhosting.com!peer03.iad!feed-me.highwinds-media.com!peer01.ams4!peer.am4.highwinds-media.com!news.highwinds-media.com!feed.abavia.com!abe006.abavia.com!abp001.abavia.com!news.kpn.nl!not-for-mail
Lines: 43
Injection-Date: Mon, 17 Jul 2023 19:37:58 +0200
Injection-Info: news.kpn.nl; mail-complaints-to="abuse@kpn.com"
X-Received-Bytes: 2307
 by: none - Mon, 17 Jul 2023 17:37 UTC

In article <nnd$7d844dab$52db8b4e@a0541ff0868dc0dd>,
none) (albert <albert@cherry.> wrote:
>I'm following the instructions of mal (clojure)
> https://github.com/kanaka/mal
>
>The instruction in mal step 5 :
>Several of the special forms that you have defined in EVAL end up
>calling back into EVAL. For those forms that call EVAL as the last
>thing that they do before returning (tail call) you will just loop
>back to the beginning of eval rather than calling it again.
>
<SNIP>
>Nesting is accomplished by storing SI in the return stack
>pointed to by the EBP register.
>These are the instructions.
>
>DOCOL: LEA EBP,[EBP - (CW*(1))] ; *
> MOV [EBP],ESI ; *
> MOV ESI,[EAX+(CW*(D_HOFFSET - C_HOFFSET))] ; *
> LODSD ; NEXT
> JMP DWORD[EAX]
>
>Nesting is marked with *.

This must be, of course:
DOCOL: LEA EBP,[EBP - (CW*(1))] ; *
MOV [EBP],ESI ; *
MOV ESI,[EAX+(CW*(D_HOFFSET - C_HOFFSET))]
LODSD ; NEXT
JMP DWORD[EAX]

(EAX points to the header and ESI must be loaded anew.)

>
>How cool is that!
>
>Groetjes Albert
--
Don't praise the day before the evening. One swallow doesn't make spring.
You must not say "hey" before you have crossed the bridge. Don't sell the
hide of the bear until you shot it. Better one bird in the hand than ten in
the air. First gain is a cat spinning. - the Wise from Antrim -

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor