interpreter integration
This commit is contained in:
parent
a93e506b78
commit
bf230d6a74
5
Makefile
5
Makefile
@ -16,9 +16,6 @@ OUTDIR = out
|
|||||||
OFILES = $(patsubst src/%.c, $(OUTDIR)/%.o, $(CFILES)) \
|
OFILES = $(patsubst src/%.c, $(OUTDIR)/%.o, $(CFILES)) \
|
||||||
$(patsubst src/%.s, $(OUTDIR)/%.asm.o, $(AFILES))
|
$(patsubst src/%.s, $(OUTDIR)/%.asm.o, $(AFILES))
|
||||||
|
|
||||||
LIBDIR = -Llib
|
|
||||||
LIBS =
|
|
||||||
|
|
||||||
HEX = main.hex
|
HEX = main.hex
|
||||||
|
|
||||||
all: $(HEX)
|
all: $(HEX)
|
||||||
@ -26,7 +23,7 @@ all: $(HEX)
|
|||||||
$(HEX): $(OFILES)
|
$(HEX): $(OFILES)
|
||||||
@echo " LINK " $(HEX)
|
@echo " LINK " $(HEX)
|
||||||
@$(CROSS)$(OBJCOPY) -B arm -I binary -O elf32-littlearm initrd.img out/initrd.img.o
|
@$(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)
|
@$(CROSS)$(OBJCOPY) $(OFLAGS) out/main.elf $(HEX)
|
||||||
|
|
||||||
$(OUTDIR)/%.o: src/%.c
|
$(OUTDIR)/%.o: src/%.c
|
||||||
|
31
include/parser.h
Normal file
31
include/parser.h
Normal 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_
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
void serial_init(void);
|
void serial_init(void);
|
||||||
void serial_put(int c);
|
void serial_put(int c);
|
||||||
|
|
||||||
char serial_get(void);
|
char serial_get(void);
|
||||||
|
void serial_gets(char *buf);
|
||||||
|
|
||||||
#endif // SERIAL_H_
|
#endif // SERIAL_H_
|
||||||
|
24
include/variable.h
Normal file
24
include/variable.h
Normal 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_
|
@ -30,9 +30,12 @@ void *hmalloc(uint32_t size)
|
|||||||
|
|
||||||
void *hcalloc(uint32_t count, 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);
|
void *alloc = hmalloc(total);
|
||||||
for (uint32_t i = 0; i < total; i++)
|
for (uint32_t i = 0; i < total; i++)
|
||||||
((uint8_t *)alloc)[i] = 0;
|
((uint8_t *)alloc)[i] = 0;
|
||||||
return alloc;
|
return alloc;*/
|
||||||
|
|
||||||
|
// calloc broke
|
||||||
|
return hmalloc(count * size);
|
||||||
}
|
}
|
||||||
|
33
src/main.c
33
src/main.c
@ -6,6 +6,7 @@
|
|||||||
#include <lcd.h>
|
#include <lcd.h>
|
||||||
#include <initrd.h>
|
#include <initrd.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
|
#include <parser.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accomplishments:
|
* Accomplishments:
|
||||||
@ -44,19 +45,39 @@ int main(void)
|
|||||||
while (1);
|
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)
|
void kmain(void)
|
||||||
{
|
{
|
||||||
asm("cpsie i");
|
asm("cpsie i");
|
||||||
|
|
||||||
task_start(lcd_handler, 128);
|
task_start(lcd_handler, 128);
|
||||||
delay(200);
|
delay(200);
|
||||||
|
task_start(task_interpreter, 512);
|
||||||
|
|
||||||
//char *s = initrd_getfile("test.txt");
|
//char *s = initrd_getfile("test.txt");
|
||||||
// svc puts
|
// svc puts
|
||||||
//asm("mov r0, %0; svc 2" :: "r" (s));
|
//asm("mov r0, %0; svc 2" :: "r" (s));
|
||||||
|
|
||||||
task_start(serial_getter, 128);
|
//extern void lua_start(void);
|
||||||
|
//lua_start();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
gpio_dout(GPIOA, 5, 1);
|
gpio_dout(GPIOA, 5, 1);
|
||||||
delay(500);
|
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
215
src/parser.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
12
src/serial.c
12
src/serial.c
@ -25,3 +25,15 @@ char serial_get(void)
|
|||||||
while (!(USART2->ISR & USART_ISR_RXNE));
|
while (!(USART2->ISR & USART_ISR_RXNE));
|
||||||
return USART2->RDR & 0xFF;
|
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;
|
||||||
|
}
|
||||||
|
16
src/stdlib.c
16
src/stdlib.c
@ -6,6 +6,22 @@ void _exit(int code)
|
|||||||
for (;;);
|
for (;;);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _getpid(int pid)
|
||||||
|
{
|
||||||
|
(void)pid;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _kill(int pid)
|
||||||
|
{
|
||||||
|
(void)pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _sbrk(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
char *itoa(int n, int base)
|
char *itoa(int n, int base)
|
||||||
{
|
{
|
||||||
static char buf[16];
|
static char buf[16];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user