Created
January 15, 2016 09:06
-
-
Save monsonite/55143b1c76ac91a07dbd to your computer and use it in GitHub Desktop.
VTL - A Very Tiny Language for Arduino
This file contains hidden or 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
// 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