Lisp scripting for C

On another thread we were discussing scripting languages that could be hooked up to C, and I suggested my Tinyscript language, which is a very simple scripting language parsed directly out of the string provided. Tinyscript is very simple and has a nice (I think) syntax, but it does have a number of limitations, including no user defined functions, no string datatype, no arrays, and subroutines cannot have parameters.

So I've written another scripting language: Proplisp. (I hope the name isn't taken!). As you can guess, it's based on Lisp. It's a very simple, cut down version of Lisp, but it is certainly Turing complete. Unlike Tinyscript you can define functions: in fact you can define anonymous functions, and functions are first class objects. The C interface is similar to Tinyscript's, and the code footprint is about the same. I had hoped to make it smaller, but although the parser is much simpler than Tinyscript's the garbage collector and more complicated eval pretty much canceled that out. As with Tinyscript the data footprint is strictly bounded; Proplisp only uses the block of RAM you give it at startup. It does need more stack than Tinyscript, and it can use up the provided RAM pretty fast, although the garbage collector helps (Tinyscript has no dynamic allocation so it doesn't need GC).

The code is primarily intended as an embedded scripting language for other C applications, but I did write a simple test framework with a read-eval-print loop.

I've uploaded the binary for those who want to play with Lisp on the Propeller, but since there's no way to load/save it's not really very practical. It would be great if someone could do a proper editor and/or interface with the SD card (the SD reader on my C3 board doesn't work, so I can't really try this; I guess saving to EEPROM might also be feasible, does anyone have code to do that?)

Eric

Comments

  • 6 Comments sorted by Date Added Votes
  • Very cool! I wonder if Parallax might be willing to send you a new C3? They seem to be closing them out anyway.
  • Oh, here's the blinky: (blink pin n) will blink a pin n times, with a pause delay based on the global variable delay. I've cut and pasted my terminal session with the Prop. The ">" is the prompt. If you hit enter without enough closing parens, the editor repeats what you started to type and then keeps accepting characters until the closing paren. The final value of the blink function ends up being the result of (waitms delay), which is just delay.
    > (define delay 500)
    (define delay 500)
    500
    > (define blink (lambda (pin n)(begin
    (define blink (lambda (pin n)(begin
       (define i 0)
       (while (< i n)(begin      
         (set! i (+ i 1))
         (pinout pin 1)
         (waitms delay)
         (pinout pin 0)
         (waitms delay)))
       )))
    #<lambda>
    > (blink 20 4)
    (blink 20 4)
    500
    
  • Does the runtime stack come from the block of memory you pass to the init function or does it just use the C stack?
  • David Betz wrote: »
    Does the runtime stack come from the block of memory you pass to the init function or does it just use the C stack?

    It just uses the C stack, so recursion can blow up the C stack (unfortunately).


  • I've been interesting in writing/porting a terminal text editor for quite some time now. I don't currently have the skillset to do so, and haven't been able to find anything in my searches of someone else that has written a text editor running on a microcontroller.

    I think my biggest question is what happens when a user changes something in the middle of a file? How is this handled in memory? If, for instance, I add one character to the middle of a file, does the entire second half of the buffer have to get shifted, one character at a time? Seems monstrously wasteful, but I can't imagine any other way to do it that isn't also wasteful.

    And then there's the problem of the in-memory buffer size. With SD card routines being so large, there isn't much HUB RAM left. We have to impose one of the following limitations: only very small files, requires one of the XMM modes, or the file will be partially "saved" at any moment so that the local changes can be flushed out HUB.
    David
    PropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
  • I'm going to start a new thread for the text editor.... and I'm probably going to give it a try. Should be quite the challenge....
    David
    PropWare: C++ HAL (Hardware Abstraction Layer) for PropGCC; Robust build system using CMake; Integrated Simple Library, libpropeller, and libPropelleruino (Arduino port); Instructions for Eclipse and JetBrain's CLion; Example projects; Doxygen documentation
Sign In or Register to comment.