Made a practical c-ish interpreter that fits: wrench

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
tinker_curt
 
Posts: 7
Joined: Wed Mar 31, 2021 11:06 am

Made a practical c-ish interpreter that fits: wrench

Post by tinker_curt »

So I developed this on my Trinket M0, although I plan to design a custom board for it to land on.

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, without having to teach them arcane language concepts.

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, ram the SAMD21 doesn't have.

wrench:
  • - can execute bytecode from ROM, or dynamically load it with a callback (like an I2C EEPROM)
    - has a very small RAM footprint when running, on the order of 500 bytes is the base it requires.
    - execute speed is on par with lua for the basic profiling I've done so far
    - interpreter fits into around 32k of program space (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 (the command-line tool will generate byte-code headers for #include in the actual project)
    - 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, wrench.h is pretty well commented and lexicon.txt shows what the interpreter can understand (just about everything c does). Examples are included. It runs on win32 (visual studio) linux, arduino and Raspberry Pi, the platforms I have easy access to. I generally valgrind it to catch my stupidity, and so far it's clean.

Still a work in progress but functioning now and driving my board! Thought I'd post it now and get the ball rolling on feedback.

I'm attaching the current snapshot but I'll be iterating on it a lot, latest will always be on: http://northarc.com/wrench-current.zip

Please forgive my spartan documentation, its hard to be polished when there is no audience.

Here is a complete example:

Code: Select all

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

void log( WRState* w, const WRValue* argv, const 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()
{}
Attachments
wrench-current.zip
(130.32 KiB) Downloaded 3 times

User avatar
tinker_curt
 
Posts: 7
Joined: Wed Mar 31, 2021 11:06 am

Re: Made a practical c-ish interpreter that fits: wrench

Post by tinker_curt »

wrench-1.4.zip
(141.85 KiB) Downloaded 1 time
Have improved it quite a bit since the initial release, and even had an enterprising user benchmark it to find it quite a bit faster than most interpreters, including beating out lua by 50% on a computationally-intensive loop.

The interpreter-only fits in around 38k (with compiler it's still only 65k) and the bytecode is very compact.

If you just need a wrench without the fluff, this might be worth a look.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”