(somewhat) Simple LISP Interpreter

I encourage people not only to try the project, but to make their own LISP with extra features!

for example, when I made a version of this, I added some extra words: def, let, dict, ins, outs, and explode (https://onlinegdb.com/yUQJzfI-2).

This is a forum for SNAP projects, not Python…

Oh:

You should add the project link whenever making a post.. Sorry for the confusion!

I might be stupid

Sorry for the confusion. I added the project now. Anyways, I hope you try it out and tell me if it elicits anything from you.

Interesting. I would have had an easier time looking for interesting things to try if you’d included arithmetic. (Yes, I know, all you need is lambda. That doesn’t mean it’s fun with only lambda!)

I would be less inclined to wrap NEW around everything you return. If you ever add list mutation, you’d want to preserve the identity of values. (Oh, and a little related quibble, the function you call EQ should be called EQUAL?; EQ tests identity, the same location in memory, not just equal values.)

I found it hard to read your code because of all the complicated OOP stuff you use. I’m not convinced that actually buys you much.

I’m not sure at what level to comment, because I don’t know what you already know. For example, have you read SICP?

(Have you seen the Lisp interpreter someone wrote in Scratch? Is it still on their site? What a tour de force! Old Scratch, no user-defined procedures.)

  • Good idea, will add that. Although, of course, this is really more of a exercise than a real dialect of LISP.
  • I only use NEW in EVIL to replace cons, and to act as quote for atoms. If I do add list mutation, I might think about it.
    • Because this exercise mostly deals with implementing EVIL in a LISP-like way, I didn’t want to add memory stuff like this. However, because of this, the only easy way I could add EQ would then be to pretend that garbage collecting existed, and therefore all atoms are equal but not lists. EQUAL? would probably be simpler to implement (=).
  • In hindsight, it’s only two uses were to 1. make things easier to read (If you see the definition of the cons block, you can tell this was not my goal) and 2. to make implementing the c_r block easier.
  • Before I started caring about, then only background I had of it was that its syntax had a bunch of parentheses. I’m still a beginner at LISP, but I do find it fascinating. I haven’t read SICP, but I’ve read some history on Scheme.
  • Don’t know what project you talk about, but I’ve made this half-working LISP on Scratch: https://scratch.mit.edu/projects/1375993937/

Not as related to this, how does one export some code to the snap blocks format in these forums? It’s certainly not LISP.

(report
    (call 
        (item 2 
            (or 
                (list " " 
                    (get e)
                ) 
                (find 
                    (pred 
                        (call 
                            (item 1 nil)
                        )
                    ) 
                    (get c)
                )
            )
        )
    )
)

Usually, you create the Snapblocks yourself:

I believe there was a tool to convert a script, but I couldn’t find it.

Have you been granted image access yet? Most people use script pics after image access was granted anyway.

Proprietary XML format attached to *.png . Can be imported when dropped to :snap: scripting area.

untitled script pic (3)

Huh, I see there are several Lisp interpreter projects on Scratch now! There was only one, back in the Scratch 1.4 days, and it was really complete and featureful, amazing when you consider that you couldn’t create custom blocks back then. Its author never published any other projects and I don’t think anyone knows who he or she is.

About CAR and CDR: The basic underlying data structure in Lisp is the pair, which is just a (Snap!) list of length 2. So CAR is ITEM 1 OF, and CDR is ITEM 2 OF. The “(Snap!)” above is because Lisp lists are made out of pairs, so even though Lisp pairs are made of Snap! lists, Lisp lists aren’t just Snap! lists, and a pair isn’t a Lisp list unless its cdr is a Lisp list.

If you read SICP, Chapter 4 is about a Scheme interpreter written in Scheme. It’s amazingly little code.

If I were going to do Lisp in Snap! myself, I think I’d try to inherit the primitive functions (not the special forms such as COND) from Snap!. That is, if the user says (+ 2 3) I’d look for a Snap! block whose title text is +, and I’d find a block labelled _ + _ so that’s what I’d use. Then I could focus my efforts on parsing and on the process of calling a function.

But the main thing I want to say is that the result of parsing a Lisp expression shouldn’t have any parentheses in it! It should be a list structure, e.g., you’d parse
(car (cons 'a 'b))
into


So once you’re past parsing, the actual evaluation wouldn’t involve parenthesis tokens.

This is a cool project, but I found it confusing to use. What functions are defined in the project?

Do you have the URL/project ID saved anywhere? I’d really like to take a look at it sometime.

I will just reply to the last 2 paragraphs for now.

  • While I could do that…it is, for me, a little boring. Again, I would consider the crux of the project to be the EVIL block.
  • I think you might be confused. the lex block is what separates the input into tokens. It’s so simple I thought about whether to just not make it a block. the parse block turns this into a Lisp expression, which then gets evaluated by EVIL. Does this make EVIL a meta-circular evaluator? I’m not sure.

you should use singular “they” instead. it is shorter, clearer, and includes the possibility of the original author of the interpreter being non-binary (more likely than you’d think!)

jan pi toki ale?

lon!

toki! kin please keep posts on topic from this point, if you can.

No, only if you implemented it in Lisp (rather than in Snap!).

Search snap to snapblocks:

Okay, I’ve added the four functions for arithmetic. (+ '1 '2)