More LISP

Well, not really.

But I’ve come close:

(print (eval (readline)))

I’ve done a lot, although some of the big milestones that make a language useful aren’t finished.

Implemented to some degree:
* math functions
* list literals (I’ve fixed everything I could find with them)
* strings in quotes “”, which allow spaces and common escape characters
* multi line comments (again, lua style –[[ … ]])
* eval!

Eval is important, because using it I think I can “fake” control structures like if, while by using quoted arguments. I may even be able to implement defun. However, that would be a stop gap solution, one that I imagine would be very slow. Currently I am thinking of quoting the arguments to if and while, and just interpreting them on the fly.

Later on, I might be able to add dedicated control instructions to the backend bytecode interpreter. Before they can be properly implemented I would need to change some of how the parser is implemented. For example, parsing (defun (x) (…)) would currently result is (x) as a function call to the value of a global called “x”. While I could just quote it (defun ‘(x) (…)), I need to allow certain functions to “default-quote” their arguments. I believe that these things are implemented (to some degree) by macros in LISP. I may have to add some support for the parser so that the parser can call LISP code during parsing. I have a feeling that is a great way to produce lots of bugs, so I am not going to do that just yet.

Current TODO list:
* equality
* functions
* if/while control structures
* add line numbers to the parser for better error messages

On the subject of equality – the equal function has some odd bugs where it seems not to see the correct types of its arguments reliably. I haven’t looked into this too much just yet, but I am surprised because there is no special code, it is very similar to the other math functions. It is probably some minor, stupid error.

Ideally, I’d like to soon be able to write a nice program, such as “guess the number”. Another goal is to implement a recursive function in LISP.

Here is my current “reference” script. I keep most of it commented out to prevent my console becoming full when executing the program.

-- functions!
(hello_world)

-- types!
(print (type 32))
(print (type 'jimmy))
(print (type nil))
(print (type hello_world))

-- quoted strings with embedded escape characters!
(print "I'm just testing some\n\"escape\" \'characters\', like this and\ta\tfew\ttabs\n..." )

-- variables!
(global 'secret 42)
(print "the secret is: " secret)

-- more variables!
(global 'foo hello_world)
(print "foo is now bound to: " hello_world)
(print "the type of foo is now: " (type foo))
(print "calling foo" )
(foo) -- prints "Hello, world"

-- io!
(print "enter some text please: " )
(print "you entered" (readline))

-- math!
(print "the sum of 1 2 3 4 is: " (plus 1 2 3 4))
(print "the difference between 1 and 2 is: " (diff 1 2))

(print "expression: " (plus (mul 2 (mod 17 5)) (div 4 (diff 10 5))))

-- using math shorthand!
(print "shorthand expression: " (+ (* 2 (% 17 5)) (/ 4 (- 10 5))))

-- equality, or lack thereof =(
(print "Does 1 equal 1? " (equal 1 1))
(print "Does 1 equal 2? " (equal 1 2))

--[[
this code typically crashes with an error because the types differ
even though my parser output says I am calling equal with two nil_constants!
(print "Does nil equal nil? " (equal nil '()))

this crashes too...
(print "are the strings \'jimmy\' and \'jimmy\' equal? " (equal 'jimmy 'jimmy))
]]

-- list literals!
(print '()) -- prints <nil>
(print '(1)) -- prints <list>

-- proper literals (two isn't a variable reference)
(print_list '( "one" (two 3) ( (4 5) ) ))

-- list builder function
(print_list (list 1 2 3 'a 'b '(etc etc etc)))

-- REP... waiting on the L!
(print "Enter some LISP code please: " )
(print (eval (readline)))

-- still not implemented... yet =)
-- (defun foo '(x y) '(print hello world))

Sample run:

Hello, world!
number
string
nil
function
I'm just testing some
"escape" 'characters', like this and    a       few     ta
...
the secret is:  42
foo is now bound to:  <lib_function>
the type of foo is now:  function
calling foo
Hello, world!
enter some text please:
sure
you entered sure
the sum of 1 2 3 4 is:  10
the difference between 1 and 2 is:  -1
expression:  4.8
shorthand expression:  4.8
1t 0 2t 0
Does 1 equal 1?  0
1t 0 2t 0
Does 1 equal 2?  0
<NIL>
<LIST>
(one (two 3)  ( (4 5) ) )
(1 2 3 a b (etc etc etc) )
Enter some LISP code please:
(print "the meaning of life: " (* 6 7))
the meaning of life:  42
<NIL>

The final nil is, of course, the return value of the (print) function.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: