diff --git a/Makefile b/Makefile index ad5b99f..5e13666 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/include/parser.h b/include/parser.h new file mode 100644 index 0000000..c6a2b17 --- /dev/null +++ b/include/parser.h @@ -0,0 +1,31 @@ +#ifndef PARSER_H_ +#define PARSER_H_ + +#include + +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_ diff --git a/include/serial.h b/include/serial.h index 5b90748..97b02d7 100644 --- a/include/serial.h +++ b/include/serial.h @@ -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_ diff --git a/include/variable.h b/include/variable.h new file mode 100644 index 0000000..fd84a6e --- /dev/null +++ b/include/variable.h @@ -0,0 +1,24 @@ +#ifndef TOKEN_H_ +#define TOKEN_H_ + +#include + +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_ diff --git a/src/heap.c b/src/heap.c index 1eba901..18cb8e6 100644 --- a/src/heap.c +++ b/src/heap.c @@ -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); } diff --git a/src/main.c b/src/main.c index 30bb183..55daac9 100644 --- a/src/main.c +++ b/src/main.c @@ -6,6 +6,7 @@ #include #include #include +#include /** * 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)); - } -} diff --git a/src/parser.c b/src/parser.c new file mode 100644 index 0000000..35cafe2 --- /dev/null +++ b/src/parser.c @@ -0,0 +1,215 @@ +#include + +#define true 1 +#define false 0 +typedef uint8_t bool; + +#include +#include + +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; +} + diff --git a/src/serial.c b/src/serial.c index 692faf0..32fcb95 100644 --- a/src/serial.c +++ b/src/serial.c @@ -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; +} diff --git a/src/stdlib.c b/src/stdlib.c index e7bf622..fa2806b 100644 --- a/src/stdlib.c +++ b/src/stdlib.c @@ -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];