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. Wink 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 Sad

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 Sad 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
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement