Like the motor repository, it's been a while and I wasn't even sure the motor ran. It does, although the degreex10kRelative(&x, -900000); line in valve5.def doesn't move 90 degrees as I thought it should.
This submission, along with the one in motor, adds the build-in io functions like reading and writing to io lines and reading from the ADC and temperature sensor. None of that has been tested on hardware, although the motor does still run correctly.
One thing that will definitely need tested is the conversion of ADC counts to temperature. The algorithm in the TI technical manual differs from the one we submitted to io.cpp in the motor repository.
Added 2 built-in functions, get current position and system reset.
Noticed from the script that motor wasn't returning to original position. Think this is due to round-off error so need to get current position to make sure you can get back to where you started.
Not tested on hardware yet.
Added io initialization to beginning of the interpreter run() routine. Can't do this when the io class is constructed because the system clock isn't running yet.
Some fixes for accessing variables on the symbol table.
Tested on hardware
Noticed that the number of statements executed per sec on the processor is not that large. No optimization is about 50/s; with optimization ~100/s
Going to try optimizing by running under Cygwin since it's easier. Several places to start like: interpret::_pushTemporarySymbolOnEvaluationStack(). The commented out lines there take a constructor out of the execution path. They're commented out right now so I can get a baseline reading on the time.
Also in interpret.cpp there's an example (comments out) of how to force a function to be run from RAM rather than flash. When you turn this on it's reflected in the map file (see motor repository).

The while loop of 1000 iterations in valve5.def is to give a benchmark.
Also in that file we're able to read temperature and input lines.

Tested on hardware.
Add profiling option to g++. Need to find out why throughput is so low.
Change to makefile to get gprof to run.
For profiling, increased the number of iterations from 1000 to 10000 under Cygwin.
Saving log file with 5000 entries rather than 10000. The later is too large for Git to do a diff which we need to make sure speed optimizations don't affect abstract syntax tree.
Performance improvement from modifying interpret::_pushTemporarySymbolOnEvaluationStack()
Getting a baseline on interpret::_findFirstAvailableNodeInSymbolTable() before optimizing.
Saving log file with 1000 rather than 5000 iterations of interpreter. Due to Git unable to handle large diffs like this.
Optimize interpret::_findFirstAvailableNodeInSymbolTable()
Baseline for interpret::symbolTableIndexMorph()
Baseline for profiling interpret::_updateProgramIndex()
Turned off profiler code from interpret::_updateProgramIndex() although you can still see it in that function in case profiling is necessary in the future.
Tried running this code on a Release build on hardware and a 100000 iteration in a while loop takes about 5 sec. That's about 20k instructions/sec if you only count the increment statement. That's a lot better than the original Debug version which limped along at 100 instructions/sec.
New profiler file that is only meant to be used under Windows/Cygwin. Removed the gmon.out which is generated by the -pg compiler option and then used by gprof to generate interpretProfile.txt. That's quite informative but didn't have the resolution we needed.
Remove unused class members. the Linux gettimeofday() doesn't have the resolution we need (milliseconds) under Cygwin.
Instructions to the interpreter sent over the virtual COM port have been reduced to 2 letter HTML-like patterns. They use the first and last letter of the instruction, so a symbol would be sent down like this: <SL> 15 2 -4 <sl> and a StatemenT looks like this: <ST> 0 ROOT Operator 261 <st>
Note that a change was made in the motor repository for the Python transfer code in transfer.py
Introduced the interpreter state which can be one of: {STATE_HALT, STATE_RUN, STATE_CONTINUE, STATE_FLASH, STATE_POWER_UP}
When device powers up it retrieves the program and symbol table from flash memory and starts running (STATE_RUN). If there's no program in flash then it reverts to STATE_HALT where it waits for further commands. You can halt the program and either continue it or flash the program from sram to flash. WARNING, make sure you download a fresh program before flashing it. If you don't you'll get the current symbol table which is in mid-stream and probably won't work when you start at power-up.

The other tricky thing we did here is save the _symbolTableIndex in the very last symbolTable. We need to restore this when coming from flash into sram. Probably a better way to do this, but for now it works.