Path: csiph.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Paul Rubin Newsgroups: comp.lang.forth Subject: Re: Implementing lisp in Forth. Chapter 4. Date: Wed, 31 Aug 2016 14:23:36 -0700 Organization: A noiseless patient Spider Lines: 52 Message-ID: <8737lkpr8n.fsf@jester.gateway.pace.com> References: <87bn0bplpm.fsf@jester.gateway.pace.com> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: mx02.eternal-september.org; posting-host="7bfc8f5b1c0c0e2e29d3a5c3abe51644"; logging-data="15130"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/s127NIRdxorKgNa6ZjCm0" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) Cancel-Lock: sha1:P1z05WAOmeQ9IZVMZKPTE/8k9XI= sha1:vAoecDQ/Hqdfb8Z1kHv9fYoIXfY= Xref: csiph.com comp.lang.forth:50585 albert@cherry.spenarnc.xs4all.nl (Albert van der Horst) writes: > Native Types ... > Which of those are in the 1000 lines toy lisps that is written > in Forth or c anyway? That is all pretty standard, though 1kloc may be a bit light. You could look at the early versions of SIOD (Scheme In One Day) by George Carrette, or more recently Tinyscheme (used in GIMP etc). > Thanks for the comment. I hope you will look at the next chapters too. > The next step is parsing. It generates data structures. It will require > major design decisions how to do that in Forth. My hope is that by > allocating part of those structures (objects) on the data stack, much > of the freeing will be swift and painless. That's not realistic, a useful Lisp needs garbage collection. I'm not impressed by that book's approach to parsing either (using fancy parser combinators written in C). Lisp is syntactically very simple, almost like Forth. Forth just uses non-whitespace tokens delimited by whitespace, giving a linear structure. Lisp adds parentheses to denote lists of conses, so you get tree structure. I haven't completely thought this through so maybe there is a fatal flaw, but if I wanted to write a Lisp in Forth, I'd consider this approach: - write the reader and printer in Lisp, using an existing Lisp for bootstrapping and testing. - Write the usual Lisp primitives (CONS, CAR, CDR) etc. as Forth words that call alloc to get storage for new conses. - Have the reader intern new symbols into the Forth dictionary (might need carnal knowledge or hacking of your Forth) putting DEFER around everything, since Lisp uses late binding. Self-evaluating symbols would call a Forth word that takes an address arg. (define (f x) ...) would make an IS to actually bind the "f" symbol (earlier interned as a deferred) to a code address. - Use Anton's Boehm-style garbage collector instead of attempting precise GC - Don't have an evaluator but instead have a compiler written in Lisp, that tree-walks Lisp functions and emits Forth code, either as threaded code to be run by your Forth's address interpreter, or as Forth source code that you'd pass through a text interpreter. (It wouldn't look like human-written code because of all the deferred symbols, the use of special Lisp operators like "Lisp+" instead of "+" that would have to dispatch on types, etc. But still, now your Lisp code can call Forth words and vice versa, maybe using a small FFI to convert between tagged and untagged values.