Skip to content

Instantly share code, notes, and snippets.

@monsonite
Created January 15, 2016 09:06
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save monsonite/55143b1c76ac91a07dbd to your computer and use it in GitHub Desktop.
Save monsonite/55143b1c76ac91a07dbd to your computer and use it in GitHub Desktop.
VTL - A Very Tiny Language for Arduino
// Very Tiny Language T. Nakagawa 2004/05/23 2004/06/26
#include <uart.h>
#include <avr/io.h>
#define F_CPU 16000000UL // define the clock frequency as 16MHz
#define BAUD 115200*2
#include <util/setbaud.h> // Set up the Uart baud rate generator
#ifndef _SYSTEM_H_
#define _SYSTEM_H_
#define Lct ((unsigned char *)0x260) /* RAM‚̐擪ƒAƒhƒŒƒX */
#define MEMSIZE ((unsigned short)4* 512 - 260) /* ƒƒ‚ƒŠƒTƒCƒY */
#define READB(adrs) (*(Lct + (adrs)))
#define WRITEB(adrs, data) (*(Lct + (adrs)) = (data))
#define READW(adrs) (*(Lct + (adrs)) * 256 + *(Lct + ((adrs) + 1)))
#define WRITEW(adrs, data) (*(Lct + (adrs)) = (data) / 256, *(Lct + ((adrs) + 1)) = (data) % 256)
#define Nbf 0x82 /* ”Žšo—Í—pƒoƒbƒtƒ@ˆÊ’u */
#define Lbf 0x88 /* s“ü—Í—pƒoƒbƒtƒ@ˆÊ’u */
#define Svp ((2 + '!') * 2)
#define Pcc ((2 + '#') * 2)
#define Rmd ((2 + '%') * 2)
#define Bnd ((2 + '&') * 2)
#define Rnd ((2 + '\'') * 2)
#define Lmt ((2 + '*') * 2)
#define Obj 0x108 /* ƒvƒƒOƒ‰ƒ€ƒGƒŠƒAˆÊ’u */
void initl(void);
unsigned char getchr(void);
void putchr(unsigned char c);
#endif
static int fndln(unsigned short *ptr);
static unsigned short nxtln(unsigned short ptr);
static void getln(unsigned short lbf);
static int getnm(unsigned short *ptr, unsigned short *n);
static int num(unsigned short ptr);
static void ordr(unsigned short ptr);
static void expr(unsigned short *ptr, unsigned short *val);
static void factr(unsigned short *ptr, unsigned short *val);
static void term(unsigned short *ptr, unsigned short *val);
static void getvr(unsigned short *ptr, unsigned char *c, unsigned short *adr);
static void putl(unsigned short *ptr, unsigned char d);
static void crlf(void);
static void putnm(unsigned short x);
static void putstr(char *str);
// Setup the various arrary and initialisation routines
void setup()
{
uart_init(); // Enable UART
DDRD = DDRD | B11111100; // Sets pins 2 to 7 as outputs without changing the value of pins 0 & 1, which are RX & TX
DDRB = DDRB | B11111111; // Port B (Pin 9 - 13) is also output
PORTB &= B11111110; // Set pin 8 low
}
void initl(void) {
WRITEW(Lmt, MEMSIZE); /* RAM End */
WRITEW(Bnd, Obj); /* Program End */
return;
}
unsigned char getchr(void) {
unsigned char c;
loop_until_bit_is_set(UCSR0A, RXC0); /* Wait until data exists. */
c = UDR0;
putchr(c);
return c;
}
void putchr(unsigned char c) {
loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */
UDR0 = c;
return;
}
int main(void) {
unsigned short ptr;
unsigned short n;
initl();
putstr("VTL-C\r\n");
for (; ; ) {
ptr = Lbf + 2;
getln(ptr);
if (!getnm(&ptr, &n)) {
unsigned short line;
line = Lbf;
WRITEW(line, 0);
WRITEW(Pcc, 0);
for (; ; ) {
ordr(ptr);
if (READW(Pcc) == 0 || READW(Pcc) == READW(line)) {
// no branch
if (line == Lbf) break; //
line = nxtln(line);
if (line == READW(Bnd)) break //
} else {
// branch
WRITEW(Svp, READW(line) + 1);
if (fndln(&line)) break;
}
WRITEW(Pcc, READW(line));
ptr = line + 2 + 1;
}
} else {
if (n == 0) {
// LIST
for (ptr = Obj; ptr != READW(Bnd); ) {
putnm(READW(ptr));
ptr += 2;
putl(&ptr, '\0');
crlf();
}
} else {
unsigned short cur, src, dst, tmp;
unsigned short m;
// DELETE
WRITEW(Pcc, n);
if (!fndln(&cur) && READW(cur) == n) {
src = nxtln(cur);
for (dst = cur; src != READW(Bnd); WRITEB(dst++, READB(src++))) ;
WRITEW(Bnd, dst);
}
/* INSERT */
if (READB(ptr) == '\0') continue;
for (m = 3, tmp = ptr; READB(tmp) != '\0'; m++, tmp++) ;
if (READW(Bnd) + m < READW(Lmt)) {
src = READW(Bnd);
WRITEW(Bnd, READW(Bnd) + m);
for (dst = READW(Bnd); src != cur; WRITEB(--dst, READB(--src))) ;
WRITEW(src, n);
src += 2;
while (WRITEB(src++, READB(ptr++)) != '\0') ;
continue;
}
}
}
putstr("\r\nOK");
}
return 0;
}
static int fndln(unsigned short *ptr) { //
for (*ptr = Obj; *ptr != READW(Bnd); *ptr = nxtln(*ptr)) {
if (READW(*ptr) >= READW(Pcc)) return 0;
}
return 1;
}
static unsigned short nxtln(unsigned short ptr) { //
for (ptr += 2; READB(ptr++) != '\0'; ) ;
return ptr;
}
static void getln(unsigned short lbf) { //
int p;
unsigned char c;
for (p = 0; ; ) {
c = getchr();
if (c == '\b') {
if (p > 0) p--;
} else if (c == '\r') {
WRITEB(lbf + p, '\0');
putchr('\n');
return;
} else if (c == 0x15 || p + 1 == 74) {
crlf();
p = 0;
} else if (c <= 0x1f) {
} else {
WRITEB(lbf + p++, c);
}
}
}
static int getnm(unsigned short *ptr, unsigned short *n) { //
if (!num(*ptr)) return 0;
*n = 0;
do {
*n *= 10;
*n += READB((*ptr)++) - '0';
} while (num(*ptr));
return 1;
}
static int num(unsigned short ptr) { //
return ('0' <= READB(ptr) && READB(ptr) <= '9');
}
static void ordr(unsigned short ptr) { //
unsigned char c;
unsigned short adr;
getvr(&ptr, &c, &adr);
ptr++;
if (READB(ptr) == '"') {
ptr++;
putl(&ptr, '"');
if (READB(ptr) != ';') crlf();
} else {
unsigned short val;
expr(&ptr, &val); //
if (c == '$') {
putchr(val & 0xff);
} else if ((c -= '?') == 0) {
putnm(val);
} else {
unsigned short r;
WRITEW(adr, val);
r = READW(Rnd);
r += val;
r = (r << 8) + (r >> 8);
WRITEW(Rnd, r);
}
}
return;
}
static void expr(unsigned short *ptr, unsigned short *val) { //
unsigned char c;
factr(ptr, val);
while ((c = READB(*ptr)) != '\0' && c != ')') { // Get expresion
term(ptr, val);
}
(*ptr)++;
return;
}
static void factr(unsigned short *ptr, unsigned short *val) { //
unsigned char c;
if (READB(*ptr) == '\0') {
*val = 0;
return;
}
if (getnm(ptr, val)) return;
c = READB((*ptr)++);
if (c == '?') {
unsigned short tmp;
tmp = Lbf;
getln(tmp);
expr(&tmp, val);
} else if (c == '$') {
*val = getchr();;
} else if (c == '(') {
expr(ptr, val);
} else {
unsigned short adr;
(*ptr)--;
getvr(ptr, &c, &adr);
*val = READW(adr); //
}
return;
}
static void term(unsigned short *ptr, unsigned short *val) { // Evaluate maths operations
unsigned char c;
unsigned short val2;
c = READB((*ptr)++);
factr(ptr, &val2);
if (c == '*') {
*val *= val2;
} else if (c == '+') {
*val += val2;
} else if (c == '-') {
*val -= val2;
} else if (c == '/') {
WRITEW(Rmd, *val % val2);
*val /= val2;
} else if (c == '=') {
*val = (*val == val2);
} else if (c == '>') {
*val = (*val >= val2);
} else {
*val = (*val < val2);
}
return;
}
static void getvr(unsigned short *ptr, unsigned char *c, unsigned short *adr) { // Get Variable
unsigned short val;
*c = READB((*ptr)++);
if (*c == ':') {
expr(ptr, &val);
*adr = READW(Bnd) + val * 2;
} else {
*adr = ((*c & 0x3f) + 2) * 2;
}
return;
}
static void putl(unsigned short *ptr, unsigned char d) { //
while (READB(*ptr) != d) putchr(READB((*ptr)++));
(*ptr)++;
return;
}
static void crlf(void) { // CRLF
putchr('\r');
putchr('\n');
return;
}
static void putnm(unsigned short x) { // Put Number
unsigned short ptr;
unsigned char y;
ptr = Nbf + 5;
WRITEB(ptr, '\0');
do {
y = x % 10;
x /= 10;
WRITEB(--ptr, y + '0');
} while (x != 0);
putl(&ptr, '\0');
return;
}
static void putstr(char *str) { //
while (*str != '\0') putchr(*(str++));
crlf();
return;
}
void uart_init(void) // UART Routines
{
UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE;
#if USE_2X
UCSR0A |= _BV(U2X0);
#else
UCSR0A &= ~(_BV(U2X0));
#endif
UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* 8-bit data */
UCSR0B = _BV(RXEN0) | _BV(TXEN0); /* Enable RX and TX */
}
void u_putchar(char c) {
loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */
UDR0 = c;
}
char u_getchar(void) {
loop_until_bit_is_set(UCSR0A, RXC0); /* Wait until data exists. */
return UDR0;
}
//-----------------------------------------------------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment