Created a practical interpreter for embedded systems, welcome to WRENCH

Not sure where to post this, but I've needed something like it several times and never found one, so I created it.

nutshell is this: I need to be able to execute scripts, small custom scripts that end-users will be creating*

Tried lua, wren, squirrel, etc, etc.. none work for the same reason, the interpreter fits into the available space but they all require massive amounts of RAM to actually do anything. Seemed to me it could be done without that.

wrench:

  • can execute bytecode from ROM, or dynamically load it with a callback (like an I2C EEPROM)
  • execute speed is on par with lua for the basic profiling I've done so far
  • interpreter fits into around 32k (currently, project is still in motion)
  • compiler+interpreter takes double that, all of 64k
  • supports everything a good interpreter should: if/then/else/do/while/for/functions/operators/etc..
  • bytecode is very compact, endian-neutral, compile anywhere run anywhere else
  • handles char/int/float/array types
  • can operate directly on native data arrays, no thunking required
  • quickly and easily call c from script and vice-versa
  • memory is garbage-collection model but only used for arrays and very sparingly
  • MIT license, share and enjoy.

Still working on documentation, but It runs on win32 (visual studio) linux, arduino and Raspberry Pi, the platforms I have easy access to :slight_smile: I have a test suite I run it through (included) and I generally valgrind it to catch my stupidity. I'm actually using this on a SAMD21 project and it's working! so I thought I'd post it now and get the ball rolling on feedback.

I'd attach a file but don't see how, here is a link to an archive: http://northarc.com/wrench-current.zip

code snapshot is here and includes a command-line utility. This is still early days
Here is a complete example:

#include <Arduino.h>
#include "wrench.h"

void log( WRState* w, WRValue* argv, int argn, WRValue& retVal, void* usr )
{
	char buf[512];
	for( int i=0; i<argn; ++i )
	{
		Serial.print( wr_valueToString(argv[i], buf) );
	}
}


const char* wrenchCode = 

"log( \"Hello World!\\n\" ); "
"for( i=0; i<10; i++ )       "
"{                           "
"    log( i );               "
"}                           ";
 

void setup()
{
	Serial.begin( 115200 );

	delay( 2000 ); // wait for link to come up for sample

	WRState* w = wr_newState(); // create the state

	wr_registerFunction( w, "log", log ); // bind a function

	unsigned char* outBytes; // compiled code is alloc'ed
	int outLen;
	
	int err = wr_compile( wrenchCode, strlen(wrenchCode), &outBytes, &outLen ); // compile it
	if ( err == 0 )
	{
		wr_run( w, outBytes, outLen ); // load and run the code!
		delete[] outBytes; // clean up 
	}

	wr_destroyState( w );
}

void loop()
{}

*yes really. it's a lighting board that allows custom effects to be written but must run stand-alone, so they will be uploaded into an on-board I2C EEPROM and executed from there.

2 Likes

Oh I should have mentioned, the /discrete_src is what I edit of course, but it automatically creates the /src directory and all you need to compile the whole project is the single .cpp/h file from there

wrench.h is meant to be the public interface obviously, and the calls should be pretty straightforward but I do need to make some documentation for how it works.. maybe just add a load of comments for now.. bah not enough hours in the day

Have you also seen FORTH with its absolutely minimal compiler? Once I used FORTH on our pdp-11/34 to diagnose a problematic disk drive, in about 15 minutes. The major problem with FORTH: it's not C-ish, and that's what makes FORTH so great :slight_smile:

1 Like

FORTH is a great example of a tiny interpreted language that would do this job. well half of this job, and unfortunately not the important half :frowning:

I could learn an arcane stack-based language and blink lights with it, sure, but I can't expect end-users to. My target audience will know scripting in a c#/c/javascript-ish way.

If I try to impose a Yoda language on users I fear it would reduce/eliminate any kind of adoption of the product.

Also I wanted to do this way of allowing others to add scripting to very small resource-limited systems but be intuitively easy to use and "get out of the way" so the real work can happen.

I hope it succeeds, it would be a shame if someone needed it and couldn't find it. I know I looked pretty hard for an interpreter that took common c-like syntax yet ran on limited ram, and found nothing :frowning:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.