]> code.bitgloo.com Git - clyne/calculator.git/commitdiff
interpreter integration
authorClyne Sullivan <tullivan99@gmail.com>
Tue, 23 Jan 2018 13:23:46 +0000 (08:23 -0500)
committerClyne Sullivan <tullivan99@gmail.com>
Tue, 23 Jan 2018 13:23:46 +0000 (08:23 -0500)
Makefile
include/parser.h [new file with mode: 0644]
include/serial.h
include/variable.h [new file with mode: 0644]
src/heap.c
src/main.c
src/parser.c [new file with mode: 0644]
src/serial.c
src/stdlib.c

index ad5b99f37e2559c0fd258f39100cc1b4a6ec9853..5e13666af17e739d2352fe395456f714053b3ac6 100644 (file)
--- 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 (file)
index 0000000..c6a2b17
--- /dev/null
@@ -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_
index 5b907482b32d3af97125a1d8cf50fd58c4f71ece..97b02d76d725d72a6ba1aac93782784af10b702b 100644 (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_
diff --git a/include/variable.h b/include/variable.h
new file mode 100644 (file)
index 0000000..fd84a6e
--- /dev/null
@@ -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_
index 1eba901763c85365643920d1c0902e97909a65cb..18cb8e63d6e9bc4c8714eac6313499dd43932910 100644 (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);
 }
index 30bb18311ea5185add8c2ea8dd3841e55e457552..55daac9dc8ba7bde807a57463f2fdf5ddf4dd1df 100644 (file)
@@ -6,6 +6,7 @@
 #include <lcd.h>\r
 #include <initrd.h>\r
 #include <serial.h>\r
+#include <parser.h>\r
 \r
 /**\r
  * Accomplishments:\r
@@ -44,19 +45,39 @@ int main(void)
        while (1);\r
 }\r
 \r
-void serial_getter(void);\r
+void script_puts(stack_t *stack)\r
+{\r
+       asm("mov r0, %0; svc 2" :: "r" (stack[0]));\r
+}\r
+\r
+void task_interpreter(void)\r
+{\r
+       interpreter interp;\r
+       interpreter_init(&interp);\r
+       interpreter_define_cfunc(&interp, "print", script_puts);\r
+\r
+       char buf[32];\r
+       while (1) {\r
+               serial_gets(buf);\r
+               interpreter_doline(&interp, buf);\r
+       }\r
+}\r
+\r
 void kmain(void)\r
 {\r
        asm("cpsie i");\r
 \r
        task_start(lcd_handler, 128);\r
        delay(200);\r
+       task_start(task_interpreter, 512);\r
 \r
        //char *s = initrd_getfile("test.txt");\r
        // svc puts\r
        //asm("mov r0, %0; svc 2" :: "r" (s));\r
 \r
-       task_start(serial_getter, 128);\r
+       //extern void lua_start(void);\r
+       //lua_start();\r
+\r
        while (1) {\r
                gpio_dout(GPIOA, 5, 1);\r
                delay(500);\r
@@ -65,11 +86,3 @@ void kmain(void)
        }\r
 }\r
 \r
-void serial_getter(void)\r
-{\r
-       char buf[2] = { 0, 0 };\r
-       while (1) {\r
-               buf[0] = serial_get();\r
-               asm("mov r0, %0; svc 2" :: "r" (buf));\r
-       }\r
-}\r
diff --git a/src/parser.c b/src/parser.c
new file mode 100644 (file)
index 0000000..35cafe2
--- /dev/null
@@ -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;
+}
+
index 692faf0900842d0d40030b93d9c1e25cd6388de0..32fcb95a16cd4f4d7ddfde0c3618e477cdc33923 100644 (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;
+}
index e7bf6224fe2e9f36aa489563a88cbc1692cd6812..fa2806b3ed567602cfb1387b73f006a033b23fda 100644 (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];