Created
May 25, 2013 12:05
-
-
Save anonymous/5648871 to your computer and use it in GitHub Desktop.
SIMPL 12 - A Serial Interpreted Minimal Programming Language. This simple interpreted language allows you to control the I/O of an Arduino from a series of commands stored in RAM. You can create your own new command words and execute them as a program.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SIMPL 12 | |
// by Ken Boak May 2013 | |
// Inspired by and built upon Txtzyme - by Ward Cunningham | |
// SIMPL tries to take you back to an age of computing when things were simple | |
// So it compiles in under 6K - leaving lots of room for other stuff | |
// SIMPL allows new words to be defined by preceding them with colon : (Like Forth) | |
// New words use CAPITALS - so 26 words are possible in the vocabulary | |
// Words A-F have been predefined as musical tones - but you can write over them | |
// A word can be a maximum of 48 characters long | |
// Type ? to get a list of all defined words | |
// New interpreter commands added include < > j (jump) r (read RAM) w (write RAM) q (query RAM) | |
#define bufRead(addr) (*(unsigned char *)(addr)) | |
#define bufWrite(addr, b) (*(unsigned char *)(addr) = (b)) | |
unsigned char bite; | |
unsigned int x = 0; | |
unsigned int y = 0; | |
int len = 48; | |
char array[26][48] = { // Define a 26 x 48 array for the colon definitions | |
{"6d40{1o1106u0o1106u}"}, | |
{"6d45{1o986u0o986u}"}, | |
{"6d51{1o929u0o929u}"}, | |
{"6d57{1o825u0o825u}"}, | |
{"6d64{1o733u0o733u}"}, | |
{"6d72{1o690u0o691u}"}, | |
{"6d81{1o613u0o613u}"}, | |
{"_Hello World, and welcome to SIMPL_"}, | |
{"5{ABC}"}, | |
{""}, | |
{""}, | |
{""}, | |
{"_This is a test message - about 48 characters_}; | |
}; | |
int a = 0; // integer variables a,b,c,d | |
int b = 0; | |
int c = 0; | |
int d = 5; // d is used to denote the digital port pin for I/O operations | |
char name; | |
char* parray; | |
char buf[64]; | |
char* addr; | |
void setup() | |
{ | |
Serial.begin(115200); | |
pinMode(d,OUTPUT); | |
delay(2000); | |
Serial.println("Type H for Welcome or ? for Help"); | |
parray = &array[0][0]; // parray is the pointer to the first element | |
} | |
void loop() | |
{ | |
txtRead(buf, 64); | |
txtChk(buf); // check if it is a colon definition | |
txtEval(buf); | |
} | |
void txtRead (char *p, byte n) { | |
byte i = 0; | |
while (i < (n-1)) { | |
while (!Serial.available()); | |
char ch = Serial.read(); | |
if (ch == '\r' || ch == '\n') break; | |
if (ch >= ' ' && ch <= '~') { | |
*p++ = ch; | |
i++; | |
} | |
} | |
*p = 0; | |
} | |
void txtChk (char *buf) { // Check if the text starts with a colon and if so store in temp[] | |
if (*buf == ':') { | |
char ch; | |
int i =0; | |
while ((ch = *buf++)){ | |
if (ch == ':') { | |
Serial.println(*buf); // get the name from the first character | |
name = *buf ; | |
buf++; | |
} | |
bufWrite((parray + (len*(name-65) +i)),*buf); | |
i++; | |
} | |
x = 1; | |
} | |
} | |
void txtEval (char *buf) { | |
unsigned int k = 0; | |
char *loop; | |
char ch; | |
while ((ch = *buf++)) { | |
switch (ch) { | |
case '0': | |
case '1': | |
case '2': | |
case '3': | |
case '4': | |
case '5': | |
case '6': | |
case '7': | |
case '8': | |
case '9': | |
x = ch - '0'; | |
while (*buf >= '0' && *buf <= '9') { | |
x = x*10 + (*buf++ - '0'); | |
} | |
break; | |
case 'p': | |
Serial.println(x); | |
break; | |
case 'a': | |
a = x; | |
break; | |
case 'b': | |
b = x; | |
break; | |
case 'c': | |
c = x; | |
break; | |
case 'd': | |
d = x; | |
break; | |
case 'A': // Point the interpreter to the array containing the words | |
case 'B': | |
case 'C': | |
case 'D': | |
case 'E': | |
case 'F': | |
case 'G': | |
case 'H': | |
case 'I': | |
case 'J': | |
case 'K': | |
case 'L': | |
case 'M': | |
case 'N': | |
case 'O': | |
case 'P': | |
case 'Q': | |
case 'R': | |
case 'S': | |
case 'T': | |
case 'U': | |
case 'V': | |
case 'W': | |
case 'X': | |
case 'Y': | |
case 'Z': | |
name = ch - 65; | |
addr = parray + (len*name); | |
txtEval(addr); | |
break; | |
case '!': // store | |
y = x; | |
break; | |
case '@': | |
x = y; | |
break; | |
case '+': | |
x = x+y; | |
break; | |
case '-': | |
x = x-y; | |
break; | |
case '*': | |
x = x*y; | |
break; | |
case '/': | |
x = x/y; | |
break; | |
case '<': | |
if(x<y){x=1;} // If x<y x= 1 - can be combined with jump j | |
else x=0; | |
break; | |
case '>': | |
if(x>y){x=1;} // If x>y x= 1 - can be combined with jump j | |
else x=0; | |
break; | |
case 'j': // test if x = 1 and jump next instruction | |
if(x==1){*buf++;} | |
break; | |
case 'r': // read a byte from RAM | |
bite = bufRead(x); // x = address | |
x = bite; | |
Serial.write(x); // print the character | |
break; | |
case 'q': // read a block of x bytes of RAM at address y | |
for (int i=0; i<x; i++) { | |
bite = bufRead(y+i); // read the array | |
Serial.write(bite); // print the character to the serial port | |
} | |
break; | |
case 'w': // write a byte to RAM address in y, data in x | |
bufWrite(y,x); | |
break; | |
case '?': // Print out all the RAM | |
parray = &array[0][0]; // reset parray to the pointer to the first element | |
for (int j = 0; j<26; j++) { | |
Serial.write(j+65); // print the caps word name | |
Serial.write(20); // space | |
for (int i=0; i<len; i++) { | |
bite = bufRead( parray + (j *len )+i); // read the array | |
Serial.write(bite); // print the character to the serial port | |
} | |
Serial.println(); | |
} | |
for(int i = 0; i <11; i++) { | |
Serial.println(); | |
} | |
break; | |
case 'i': | |
x = digitalRead(d); | |
break; | |
case 'o': | |
digitalWrite(d, x%2); | |
break; | |
case 'm': | |
delay(x); | |
break; | |
case 'u': | |
delayMicroseconds(x); | |
break; | |
case '{': | |
k = x; | |
loop = buf; | |
while ((ch = *buf++) && ch != '}') { | |
} | |
case '}': | |
if (k) { | |
k--; | |
buf = loop; | |
} | |
break; | |
case 'k': | |
x = k; | |
break; | |
case '_': | |
while ((ch = *buf++) && ch != '_') { | |
Serial.print(ch); | |
} | |
Serial.println(); | |
break; | |
case 's': | |
x = analogRead(x); | |
break; | |
} | |
} | |
// Serial.println(" OK"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment