brundonsmith / rust_lisp

A Rust-embeddable Lisp, with support for interop with native Rust functions
239 stars 19 forks source link

[Bug] Wierd name interpretation panic #6

Closed alexmozaidze closed 2 years ago

alexmozaidze commented 2 years ago

There are 2 kind of names that make the program panic: one type of name, like inf, makes interpreter panic on trying to define a function with that name. Another type of name, like i32 or i64, makes interpreter panic on calling a function with such name. It goes something like this

(defun i32 () ()) ; Things are fine
(i32) ; Panics trying to execute it as a lambda (dunno why)

(defun inf () ()) ; Panics on trying to get "inf" as symbol

This bug happens on both my fork and this repo, and I have no idea why.

brundonsmith commented 2 years ago

Hmm, I'll take a look and see if it jumps out at me

brundonsmith commented 2 years ago

Found two separate bugs here

First, something about this name is messing it up, so that's a pretty big problem:

> (defun lol () (print 12))
NIL
> (lol)
12
12
> (defun i32 () (print 12))
NIL
> (i32)
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src\interpreter.rs:273:46

Second, it has a non-user-friendly error when attempting to call a lambda whose body is NIL:

> (defun foo () ())
NIL
> (foo)
Runtime error: Attempted to apply car on nil

This second one is much less important, and I'm not even sure this should be allowed... but if it's going to be invalid then at the very least it should yield a descriptive error, probably at definition time

brundonsmith commented 2 years ago

Looks like tokenization doesn't handle digits in identifiers:

["(", "i", "32", ")"]
brundonsmith commented 2 years ago

Oh, wow. This does err on its own:

(defun inf () ())

and... I think it's because Rust's .parse::<f32>() parses it as infinity

brundonsmith commented 2 years ago

I decided to just have it more gracefully message about invalid definition names:

> (defun inf () ())
Runtime error: Function name must by a symbol; received "inf", which is a float

Going to call this one done