aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/heap.c7
-rw-r--r--src/main.c33
-rw-r--r--src/parser.c215
-rw-r--r--src/serial.c12
-rw-r--r--src/stdlib.c16
5 files changed, 271 insertions, 12 deletions
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 <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));
- }
-}
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 <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;
+}
+
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];