Lisp is coming to TI calculators. I have been working on porting 8kLisp, the z80 assembly predecessor to PicoLisp. The code I am starting from is almost 30 years old and for CP/M, but luckily it was coded very well and portably. So far, I have basic input and output working, and I have a start on getting program input/output working. So far I got a hello world program working. Most things should also work, but it's not quite releasable yet.
Screenshot:
Lisp code:
Code: <DE HW ( ) (PRIN1 '(HELLO WORLD) ) >
The source is now up on Github!
https://github.com/fortytwopar/lisp8x There is also a binary there.
For the most part it works pretty well. Beware that there is no clean way to exit the program, so expect ram clears on exit. File I/O is bad and I'm hoping to implement an easy way to load files. Any ideas on how I should do that or what it should look like?
This is really amazing stuff, Hooloovoo, and I'm sorry I didn't get around to responding and encouraging you sooner. I'm particularly impressed that you managed to get this all done with barely a clue on IRC that you were working on it.

As far as files, reading files from AppVars (and possibly programs) sounds like a good plan to me, given that you come up with a logical header of some sort to distinguish your files.
Impressive work porting the lisp implementation! I still need to get my lisp implementation from scratch moved from my hg repository to github.
How well is its performance and memory usage?
I'm not quite sure about performance actually. Memory is currently just allocated inside the binary, and is used from there. right now it has 2K of memory, but I could expand that, and I could expand it more if we don't care about TI-OS. That seems like a bad system, but it might not be very easy to change.
EDIT: looks like I can allocate space at start-up, so I can make an appvar when the program begins. Luckily this is interpreted, so I can extend data past C000 easily.
I meant how much RAM gets allocated when executing those sorts of things in your screenshot?
Right now 4096 bytes is allocated for the heap and stack.
Well, Lisp uses dynamically allocated objects, so the 4KB heap you assign it can be used however the Lisp implementation wants. I was just wondering how much of that heap is allocated when you run simple instructions as well as how much garbage collection runs. Just want to know how much data needs to get allocated for getting to run basic things.
I do not believe there is a standard way in lisp to get the free space in the heap, not sure if there is a convenient way to get the size with your port.
There is a way to get the free space. With (MFREE) you can check the free memory, and with (GC) you can force a garbage collect. when I just started the program there were 3575 free bytes in the heap, which is because there is a 512 byte safety zone for the stack, which is at the end of the free memory so as not to break TI-OS when the stack gets large.
I've never touched LISP, but this does seem like it couldbe fun for some people! Awesome porting job!
Hello,
do you have any idea to implement the cond function? I tried but no luck
It is a very convenient function . It avoids multiples if
Thanks in advance
I think the cond function works, though I haven't really tested all that thoroughly. This project is slightly dead though right now

I'll see what I can do, but no promises.
EDIT: The cond function does not work, and did not work in the source as I first found it. I don't have the time right now to look into it, but I will try to get to it sometime in the next week.
You might look into the implementation used by Spencer's
scheme and see if that's working.
Hello,
no news about the implementation of the cond instruction. I am still stuck there.
Thanks in advance
Perhaps you can elaborate on what specifically you are stuck on.
My problem: cond function is very like the unless function. The only difference is that in the cond function there are several fields to take in account
a rough cond implementation (that does not work)
cond:
CALL POPLIST
LD A,H
RET Z
PUSH HL
CALL UNLESS
POP HL
JR cond
To compare with the picolisp
// (unless 'any . prg) -> any
any doUnless(any x) {
any a;
x = cdr(x);
if (!isNil(a = EVAL(car(x)))) {
val(At) = a;
return Nil;
}
return prog(cdr(x));
}
// (cond ('any1 . prg1) ('any2 . prg2) ..) -> any
any doCond(any x) {
any a;
while (isCell(x = cdr(x))) {
if (!isNil(a = EVAL(caar(x)))) {
val(At) = a;
return prog(cdar(x));
}
}
return Nil;
}
Finally, I managed to implement the cond function: Hurray!!! Here is the code if you are interested in implementing it for the TI calcs
Code:
COND:
CALL POPLIST
PUSH HL
EX DE,HL
CALL POPLIST
PUSH HL
CALL EVALDE ;CONDITION
LD A,H
OR A
POP HL ;BODY
JR Z,COND1
POP BC ;AVOID HL LEAK
CALL POPLIST
EX DE,HL
JP EVAL
COND1:
POP HL
LD A,H
OR A
RET Z
JR COND