interpreter integration

This commit is contained in:
Clyne Sullivan 2018-01-23 08:23:46 -05:00
parent a93e506b78
commit bf230d6a74
9 changed files with 329 additions and 16 deletions

View File

@ -16,9 +16,6 @@ OUTDIR = out
OFILES = $(patsubst src/%.c, $(OUTDIR)/%.o, $(CFILES)) \
$(patsubst src/%.s, $(OUTDIR)/%.asm.o, $(AFILES))
LIBDIR = -Llib
LIBS =
HEX = main.hex
all: $(HEX)
@ -26,7 +23,7 @@ all: $(HEX)
$(HEX): $(OFILES)
@echo " LINK " $(HEX)
@$(CROSS)$(OBJCOPY) -B arm -I binary -O elf32-littlearm initrd.img out/initrd.img.o
@$(CROSS)$(CC) $(CFLAGS) $(LIBDIR) $(LIBS) -T link.ld out/*.o -o out/main.elf
@$(CROSS)$(CC) $(CFLAGS) -T link.ld out/*.o -o out/main.elf
@$(CROSS)$(OBJCOPY) $(OFLAGS) out/main.elf $(HEX)
$(OUTDIR)/%.o: src/%.c

31
include/parser.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef PARSER_H_
#define PARSER_H_
#include <variable.h>
typedef void *stack_t;
typedef struct {
uint16_t status;
uint16_t vcount;
variable *vars;
char **names;
stack_t *stack;
} interpreter;
enum status {
READY = 0
};
typedef void (*func_t)(stack_t *);
void interpreter_init(interpreter *);
void interpreter_define_value(interpreter *, const char *, int32_t);
void interpreter_define_cfunc(interpreter *, const char *, func_t);
int32_t interpreter_get_value(interpreter *, const char *);
int interpreter_doline(interpreter *, const char *);
#endif // PARSER_H_

View File

@ -3,6 +3,8 @@
void serial_init(void);
void serial_put(int c);
char serial_get(void);
void serial_gets(char *buf);
#endif // SERIAL_H_

24
include/variable.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef TOKEN_H_
#define TOKEN_H_
#include <stdint.h>
typedef struct {
uint16_t nameidx;
uint8_t type;
uint8_t info;
uint32_t value;
} variable;
#define INFO_ARGS(x) ((x) & 0x07)
#define INFO_RET (1 << 3)
enum vartype {
VALUE = 0,
VARIABLE,
OPERATOR,
FUNCTION,
CFUNCTION
};
#endif // TOKEN_H_

View File

@ -30,9 +30,12 @@ void *hmalloc(uint32_t size)
void *hcalloc(uint32_t count, uint32_t size)
{
uint32_t total = count * size;
/*uint32_t total = count * size;
void *alloc = hmalloc(total);
for (uint32_t i = 0; i < total; i++)
((uint8_t *)alloc)[i] = 0;
return alloc;
return alloc;*/
// calloc broke
return hmalloc(count * size);
}

View File

@ -6,6 +6,7 @@
#include <lcd.h>
#include <initrd.h>
#include <serial.h>
#include <parser.h>
/**
* Accomplishments:
@ -44,19 +45,39 @@ int main(void)
while (1);
}
void serial_getter(void);
void script_puts(stack_t *stack)
{
asm("mov r0, %0; svc 2" :: "r" (stack[0]));
}
void task_interpreter(void)
{
interpreter interp;
interpreter_init(&interp);
interpreter_define_cfunc(&interp, "print", script_puts);
char buf[32];
while (1) {
serial_gets(buf);
interpreter_doline(&interp, buf);
}
}
void kmain(void)
{
asm("cpsie i");
task_start(lcd_handler, 128);
delay(200);
task_start(task_interpreter, 512);
//char *s = initrd_getfile("test.txt");
// svc puts
//asm("mov r0, %0; svc 2" :: "r" (s));
task_start(serial_getter, 128);
//extern void lua_start(void);
//lua_start();
while (1) {
gpio_dout(GPIOA, 5, 1);
delay(500);
@ -65,11 +86,3 @@ void kmain(void)
}
}
void serial_getter(void)
{
char buf[2] = { 0, 0 };
while (1) {
buf[0] = serial_get();
asm("mov r0, %0; svc 2" :: "r" (buf));
}
}

215
src/parser.c Normal file
View File

@ -0,0 +1,215 @@
#include <parser.h>
#define true 1
#define false 0
typedef uint8_t bool;
#include <heap.h>
#include <clock.h>
static const char *interpreter_operators = "=(";
int strcmp(const char *s1, const char *s2)
{
int i = 0;
for (; s1[i] == s2[i] && s1[i] != '\0'; i++);
return s1[i] == s2[i];
}
uint8_t isalpha(char c)
{
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
uint8_t isnum(char c)
{
return (c >= '0' && c <= '9');
}
uint8_t isname(char c)
{
return isalpha(c) || isnum(c);
}
uint8_t isspace(char c)
{
return (c == ' ' || c == '\t' || c == '\n');
}
uint8_t isoper(char c)
{
for (uint8_t i = 0; i < sizeof(interpreter_operators); i++) {
if (c == interpreter_operators[i])
return 1;
}
return 0;
}
void interpreter_init(interpreter *interp)
{
interp->status = READY;
interp->vcount = 0;
interp->vars = (variable *)hcalloc(32, sizeof(variable));
interp->names = (char **)hcalloc(32, sizeof(char *));
interp->stack = (stack_t *)hcalloc(64, sizeof(stack_t));
}
void interpreter_define_value(interpreter *interp, const char *name, int32_t value)
{
interp->names[interp->vcount] = (char *)name;
interp->vars[interp->vcount].nameidx = interp->vcount;
interp->vars[interp->vcount].type = VALUE;
interp->vars[interp->vcount].value = (uint32_t)value;
interp->vcount++;
}
void interpreter_define_cfunc(interpreter *interp, const char *name, func_t addr)
{
interp->names[interp->vcount] = (char *)name;
interp->vars[interp->vcount].nameidx = interp->vcount;
interp->vars[interp->vcount].type = CFUNCTION;
interp->vars[interp->vcount].value = (uint32_t)addr;
interp->vcount++;
}
int32_t interpreter_get_value(interpreter *interp, const char *name)
{
for (uint16_t i = 0; i < interp->vcount; i++) {
if (!strcmp(interp->names[i], name))
return (int32_t)interp->vars[i].value;
}
return 0;
}
/**
* doline section
*/
bool namencmp(const char *name, const char *s)
{
uint16_t i;
for (i = 0; name[i] == s[i] && s[i] != '\0'; i++);
return (name[i] == '\0');
}
uint16_t spacecount(const char *s)
{
uint16_t i;
for (i = 0; isspace(s[i]); i++);
return i;
}
char *copystr(const char *s)
{
uint16_t len = 0;
while (s[len++] != '\n');
char *buf = (char *)hmalloc(len);
for (uint16_t i = 0; i < len; i++)
buf[i] = s[i];
return buf;
}
char *copysubstr(const char *s, int end)
{
char *buf = (char *)hmalloc(end);
for (uint16_t i = 0; i < end; i++)
buf[i] = s[i];
return buf;
}
int interpreter_doline(interpreter *interp, const char *line)
{
variable *bits[16];
uint16_t offset = 0, boffset = 0;
// check for var/func set or usage
getvar:
for (uint16_t i = 0; i < interp->vcount; i++) {
if (namencmp(interp->names[i], line)) {
bits[boffset++] = &interp->vars[i];
// get past name
for (uint16_t j = 0; interp->names[i][j] != '\0'; j++, offset++);
break;
}
}
// defining new variable
if (boffset == 0) {
uint16_t end;
for (end = 0; isname(line[end]); end++);
interpreter_define_value(interp, copysubstr(line, end), 0);
goto getvar; // try again
}
// skip whitespace
offset += spacecount(line + offset);
if (boffset == 0 && line[offset] != '=')
return -1; // variable not found
// find operator
if (line[offset] == '\0') {
// print value
return -99;
} else if (line[offset] == '=') {
return -23;
// assignment/expression
//offset++;
//offset += spacecount(line + offset);
//if (boffset > 0)
// bits[boffset]->value = (uint32_t)copystr(line + offset);
} else if (line[offset] == '(') {
// function call
offset++;
if (bits[0]->type != FUNCTION && bits[0]->type != CFUNCTION)
return -2;
offset += spacecount(line + offset);
// collect arg offsets
uint16_t offsets[8];
uint8_t ooffset = 0;
while (line[offset] != ')' && line[offset] != '\0') {
offsets[ooffset] = offset;
offset += spacecount(line + offset);
uint8_t isvn = 1;
do {
if (line[offset] == ' ' || line[offset] == '\t') {
offset += spacecount(line + offset);
isvn = 0;
}
if (line[offset] == ',') {
offset++;
ooffset++;
break;
} else if (line[offset] == ')') {
ooffset++;
break;
} else if (isvn == 0) {
return -3;
}
} while (++offset);
}
// populate stack
for (uint8_t i = 0; i < ooffset; i++) {
uint16_t j;
for (j = offsets[i]; line[j] != ' ' && line[j] != '\t' &&
line[j] != ',' && line[j] != ')'; j++);
j -= offsets[i];
interp->stack[i] = (char *)hmalloc(j);
for (uint16_t k = 0; k < j; k++)
((char *)interp->stack[i])[k] = line[offsets[i] + k];
}
((func_t)bits[0]->value)(interp->stack);
} else {
return -2; // invalid operation
}
return 0;
}

View File

@ -25,3 +25,15 @@ char serial_get(void)
while (!(USART2->ISR & USART_ISR_RXNE));
return USART2->RDR & 0xFF;
}
void serial_gets(char *buf)
{
uint16_t index = 0;
do {
buf[index] = serial_get();
} while (buf[index++] != '\r');
buf[index - 1] = '\0';
//return buf;
}

View File

@ -6,6 +6,22 @@ void _exit(int code)
for (;;);
}
int _getpid(int pid)
{
(void)pid;
return 0;
}
void _kill(int pid)
{
(void)pid;
}
void _sbrk(void)
{
}
char *itoa(int n, int base)
{
static char buf[16];