From 100cb2f84ac5c44a904f7d7145cdc2ce1dcf59ba Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Mon, 12 Feb 2018 11:23:59 -0500 Subject: [PATCH] libinterp, actually works --- Makefile | 7 +- include/heap.h | 10 +- include/it | 1 + include/parser.h | 34 -- include/variable.h | 21 -- initrd/init | 10 + libinterp.a | Bin 0 -> 63086 bytes run.sh | 3 + src/heap.c | 44 ++- src/lcd.c | 20 +- src/main.c | 64 +++- src/parser.c | 716 -------------------------------------- src/startup_stm32l476xx.s | 2 +- src/stdlib.c | 38 -- src/task.c | 4 +- 15 files changed, 116 insertions(+), 858 deletions(-) create mode 120000 include/it delete mode 100644 include/parser.h delete mode 100644 include/variable.h create mode 100644 initrd/init create mode 100644 libinterp.a delete mode 100644 src/parser.c diff --git a/Makefile b/Makefile index 08e2bc9..f874cf3 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ OBJCOPY = objcopy MCUFLAGS = -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 AFLAGS = $(MCUFLAGS) -CFLAGS = $(MCUFLAGS) -Iinclude -fno-builtin -fsigned-char -ffreestanding -Wall -Werror -Wextra -Wno-discarded-qualifiers +CFLAGS = $(MCUFLAGS) -Iinclude -Iinclude/it -fno-builtin -fsigned-char -ffreestanding -Wall -Werror -Wextra -Wno-discarded-qualifiers -ggdb LFLAGS = OFLAGS = -O ihex @@ -21,10 +21,11 @@ HEX = main.hex all: $(HEX) -$(HEX): $(OFILES) +$(HEX): $(OFILES) initrd/init @echo " LINK " $(HEX) + @./mkinitrd.sh @$(CROSS)$(OBJCOPY) -B arm -I binary -O elf32-littlearm initrd.img out/initrd.img.o - @$(CROSS)$(CC) $(CFLAGS) $(LFLAGS) -T link.ld out/*.o -o out/main.elf + @$(CROSS)$(CC) $(CFLAGS) $(LFLAGS) -T link.ld out/*.o -o out/main.elf -L. -linterp @$(CROSS)$(OBJCOPY) $(OFLAGS) out/main.elf $(HEX) $(OUTDIR)/%.o: src/%.c diff --git a/include/heap.h b/include/heap.h index 2c7e7c9..9625771 100644 --- a/include/heap.h +++ b/include/heap.h @@ -1,12 +1,12 @@ #ifndef HEAP_H_ #define HEAP_H_ -#include +//#include -uint32_t heap_available(void); +//uint32_t heap_available(void); -void *malloc(uint32_t size); -void *calloc(uint32_t count, uint32_t size); -void free(void *buf); +//void *malloc(uint32_t size); +//void *calloc(uint32_t count, uint32_t size); +//void free(void *buf); #endif // HEAP_H_ diff --git a/include/it b/include/it new file mode 120000 index 0000000..7c2b8d4 --- /dev/null +++ b/include/it @@ -0,0 +1 @@ +../../interpreter \ No newline at end of file diff --git a/include/parser.h b/include/parser.h deleted file mode 100644 index 83a81e1..0000000 --- a/include/parser.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef PARSER_H_ -#define PARSER_H_ - -#include - -typedef variable *stack_t; - -typedef struct { - variable *vars; - char **vnames; - stack_t *stack; - uint32_t stidx; - char **lines; - uint32_t lnidx; - uint8_t indent; -} interpreter; - -typedef int (*func_t)(interpreter *); - -void iinit(interpreter *); - -void inew_string(interpreter *, const char *, char *); -void inew_integer(interpreter *, const char *, int32_t); -void inew_float(interpreter *, const char *, float); -void inew_cfunc(interpreter *, const char *, func_t); - -int idoline(interpreter *, const char *); - -variable *igetarg(interpreter *, uint32_t); -char *igetarg_string(interpreter *, uint32_t); -int igetarg_integer(interpreter *, uint32_t); -float igetarg_float(interpreter *, uint32_t); - -#endif // PARSER_H_ diff --git a/include/variable.h b/include/variable.h deleted file mode 100644 index 067ce13..0000000 --- a/include/variable.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef VARIABLE_H_ -#define VARIABLE_H_ - -#include - -typedef struct { - uint8_t used :1; - uint8_t fromc :1; - uint8_t valtype :2; - uint32_t value; - char *svalue; -} variable; - -enum valtype { - STRING = 0, - INTEGER, - FLOAT, - FUNC -}; - -#endif // VARIABLE_H_ diff --git a/initrd/init b/initrd/init new file mode 100644 index 0000000..bb04364 --- /dev/null +++ b/initrd/init @@ -0,0 +1,10 @@ +set a 0 +do + set a (a + 1) + delay 1 +while (a < 100) + +if (a == 100) + print "All good!" +end + diff --git a/libinterp.a b/libinterp.a new file mode 100644 index 0000000000000000000000000000000000000000..2c87928e2e47b265263fc6e28b9d2aa117efc93f GIT binary patch literal 63086 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 E0&wN;^8f$< literal 0 HcmV?d00001 diff --git a/run.sh b/run.sh index 26750d2..88be7fa 100755 --- a/run.sh +++ b/run.sh @@ -2,3 +2,6 @@ openocd -f /usr/share/openocd/scripts/board/st_nucleo_l476rg.cfg \ -c "init; reset halt; flash write_image erase main.hex; reset run; exit" + +#openocd -f /usr/share/openocd/scripts/board/st_nucleo_l476rg.cfg > /dev/null & +#gdb-multiarch diff --git a/src/heap.c b/src/heap.c index 746f0ef..8a18d38 100644 --- a/src/heap.c +++ b/src/heap.c @@ -1,23 +1,35 @@ #include #include -#define HEAP_SIZE (16 * 1024) - -static uint32_t offset = 0; +#define HEAP_SIZE (64 * 1024) uint8_t heap[HEAP_SIZE]; -void heap_init(void) +void *_sbrk(int inc) { - // what to do... -} + static uint8_t *hend; + uint8_t *prev; -uint32_t heap_available(void) -{ - return HEAP_SIZE - offset; + if (hend == 0) + hend = heap; + + prev = hend; + hend += inc; + + return prev; } -void *malloc(uint32_t size) +//void heap_init(void) +//{ + // what to do... +//} + +//uint32_t heap_available(void) +//{ +// return HEAP_SIZE - offset; +//} + +/*void *malloc(uint32_t size) { void *alloc = &heap[offset]; offset += size; @@ -26,11 +38,11 @@ void *malloc(uint32_t size) void *calloc(uint32_t count, uint32_t 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;*/ + //uint32_t total = count * size; + //void *alloc = hmalloc(total); + //for (uint32_t i = 0; i < total; i++) + // ((uint8_t *)alloc)[i] = 0; + //return alloc; // calloc broke return malloc(count * size); @@ -39,4 +51,4 @@ void *calloc(uint32_t count, uint32_t size) void free(void *ptr) { (void)ptr; -} +}*/ diff --git a/src/lcd.c b/src/lcd.c index 69be7d4..a2a8ca7 100644 --- a/src/lcd.c +++ b/src/lcd.c @@ -128,8 +128,10 @@ void lcd_init(void) * Task code */ -static int bufpos = 0; -static char buf[64]; +volatile int bufpos = 0; +volatile char buf[32]; +volatile uint8_t using = 0; + void lcd_clearbuf(void) { bufpos = 0; @@ -140,9 +142,15 @@ void lcd_clearbuf(void) void lcd_put(const char *s) { int len = strlen(s); - int off = (bufpos + len < 64) ? len : 64 - bufpos; - strncpy(buf + bufpos, s, off); - bufpos += off; + int i; + + using = 1; + for (i = 0; i < len; bufpos++, i++) { + if (bufpos > 31) + bufpos = 0; + buf[bufpos] = s[i]; + } + using = 0; } void lcd_handler(void) @@ -151,7 +159,7 @@ void lcd_handler(void) lcd_clearbuf(); while (1) { - if (buf[0] != '\0') { + if (!using && buf[0] != '\0') { lcd_puts(buf); lcd_clearbuf(); } diff --git a/src/main.c b/src/main.c index 5cce261..520fccd 100644 --- a/src/main.c +++ b/src/main.c @@ -7,22 +7,13 @@ #include #include #include +#include + +#include +#include -/** - * Accomplishments: - * - GPIO in/out - * - got to 80MHz clock - * - basic heap - * - multitask, can exit - * - gpio lib - * - lcd support - * - initrd support - * - lua? - no, something better, smaller - * - serial IO - */ - -void pulse(uint8_t byte); void kmain(void); +void task_interpreter(void); int main(void) { @@ -51,17 +42,58 @@ int main(void) int script_puts(interpreter *it) { char *s = igetarg_string(it, 0); + //lcd_puts(s); asm("mov r0, %0; svc 2" :: "r" (s)); return 0; } +int script_delay(interpreter *it) +{ + int ms = igetarg_integer(it, 0); + delay(ms); + return 0; +} + void task_interpreter(void) { interpreter it; iinit(&it); inew_cfunc(&it, "print", script_puts); + inew_cfunc(&it, "delay", script_delay); + + char *s = initrd_getfile("init"); + if (s == 0) + goto end; + + char *linebuf = (char *)malloc(120); + uint32_t i = 0, prev = 0, lc; + uint32_t size = initrd_getfilesize("init"); + int ret; + while (i < size) { + for (; s[i] != '\n' && s[i] != '\0'; i++); + lc = i - prev; + if (lc == 0) { + prev = ++i; + continue; + } + strncpy(linebuf, s + prev, lc + 1); + linebuf[lc] = '\0'; + ret = idoline(&it, linebuf); + if (ret < 0) + break; + prev = ++i; + } - while (1); + if (ret < 0) { + lcd_puts("Error: "); + lcd_puts(itoa(ret, linebuf, 10)); + } + free(linebuf); + //iend(&it); // nah + +end: + while (1) + delay(10); } void kmain(void) @@ -70,7 +102,7 @@ void kmain(void) task_start(lcd_handler, 128); delay(200); - task_start(task_interpreter, 2048); + task_start(task_interpreter, 4096); //char *s = initrd_getfile("test.txt"); diff --git a/src/parser.c b/src/parser.c deleted file mode 100644 index df2dc21..0000000 --- a/src/parser.c +++ /dev/null @@ -1,716 +0,0 @@ -#include - -#include - -#include -#include - -extern int atoi(char *); -float strtof(char *s, char **e) -{ (void)s; (void)e; return 0;} -#include -extern int ksnprintf(char *, int, const char *, ...); - -#define MAX_VARS 32 -#define MAX_STACK 32 - -#define INT(v) (*((int32_t *)&v->value)) -#define FLOAT(v) (*((float *)&v->value)) - -static char *str_func = "(func)"; -static char *str_undef = "(undefined)"; - -char *strclone(const char *s) -{ - char *clone = (char *)malloc(strlen(s)); - strcpy(clone, s); - return clone; -} - -char *strnclone(const char *s, uint32_t n) -{ - char *clone = (char *)malloc(n); - strncpy(clone, s, n); - return clone; -} - -void fsetstr(variable *f) -{ - if (f->svalue == 0) - f->svalue = (char *)malloc(16); - ksnprintf(f->svalue, 16, "%f", FLOAT(f)); -} - -void isetstr(variable *i) -{ - if (i->svalue == 0) - i->svalue = (char *)malloc(12); - ksnprintf(i->svalue, 12, "%ld", INT(i)); -} - -uint8_t eol(int c) -{ - return c == '\n' || c == '\0'; -} - -uint8_t eot(int c) -{ - return eol(c) || c == ' '; -} - -uint8_t eoe(int c) -{ - return eol(c) || c == ')'; -} - -uint32_t findend(const char *s, char o, char c) -{ - uint8_t indent = 0; - uint32_t i; - for (i = 1; !eol(s[i]); i++) { - if (s[i] == o) { - indent++; - } else if (s[i] == c) { - if (indent == 0) - break; - else - indent--; - } - } - - return i; -} - -int ifunc_set(interpreter *it); -int ifunc_jmp(interpreter *it); -int ifunc_label(interpreter *it); -int ifunc_end(interpreter *it); - -variable *idoexpr(interpreter *interp, const char *line); - -variable *itostring(variable *v); -variable *itoint(variable *v); -variable *itofloat(variable *v); - -void iinit(interpreter *interp) -{ - interp->vars = (variable *)calloc(MAX_VARS, sizeof(variable)); - interp->vnames = (char **)calloc(MAX_VARS, sizeof(char *)); - interp->stack = (stack_t *)calloc(MAX_STACK, sizeof(stack_t)); - interp->stidx = 0; - interp->lines = (char **)calloc(20, sizeof(char *)); - interp->lnidx = 0; - interp->indent = 0; - - inew_cfunc(interp, "set", ifunc_set); - inew_cfunc(interp, "jmp", ifunc_jmp); - inew_cfunc(interp, "func", ifunc_label); - inew_cfunc(interp, "end", ifunc_end); -} - -void ipush(interpreter *it, void *v) -{ - it->stack[it->stidx++] = v; -} - -void *ipop(interpreter *it) -{ - return it->stack[--it->stidx]; -} - -variable *interpreter_get_variable(interpreter *interp, const char *name) -{ - for (uint32_t i = 0; i < MAX_VARS; i++) { - if (!interp->vars[i].used) { - variable *v = &interp->vars[i]; - v->used = 1; - v->fromc = 0; - v->valtype = STRING; - v->value = 0; - v->svalue = str_undef; - interp->vnames[i] = strclone(name); - return v; - } else if (interp->vnames[i] != 0 && !strcmp(interp->vnames[i], name)) { - return &interp->vars[i]; - } - } - return 0; -} - -char *interpreter_get_name(interpreter *interp, variable *v) -{ - for (uint32_t i = 0; i < MAX_VARS; i++) { - if (v == &interp->vars[i]) - return interp->vnames[i]; - } - return str_undef; -} - -void inew_string(interpreter *interp, const char *name, char *value) -{ - variable *v = interpreter_get_variable(interp, name); - if (v != 0) { - v->valtype = STRING; - INT(v) = 0; - v->svalue = strclone(value); - } -} - -void inew_integer(interpreter *interp, const char *name, int32_t value) -{ - variable *v = interpreter_get_variable(interp, name); - if (v != 0) { - v->valtype = INTEGER; - INT(v) = value; - isetstr(v); - } -} - -void inew_float(interpreter *interp, const char *name, float value) -{ - variable *v = interpreter_get_variable(interp, name); - if (v != 0) { - v->valtype = FLOAT; - FLOAT(v) = value; - fsetstr(v); - } -} - -void inew_cfunc(interpreter *interp, const char *name, func_t func) -{ - variable *v = interpreter_get_variable(interp, name); - if (v != 0) { - v->fromc = 1; - v->valtype = FUNC; - v->value = (uint32_t)func; - v->svalue = str_func; - } -} - -variable *make_var(interpreter *interp, const char *line, uint32_t *next) -{ - if (line[0] == '\"') { // string literal - uint32_t end = 1; - while (!eol(line[end])) { - if (line[end] == '\"'/* && line[end - 1] != '\\'*/) { - if (!eot(line[end + 1])) - return 0; - // TODO string breakdown - variable *v = (variable *)malloc(sizeof(variable)); - v->used = 0; - v->valtype = STRING; - v->svalue = strnclone(line + 1, end - 1); - *next = end + 1; - return v; - } - end++; - } - return 0; - } else if (line[0] == '(') { // equation literal - uint32_t end = findend(line, '(', ')'); - if (eot(line[end])) - return 0; - *next = end + 1; - return idoexpr(interp, line + 1); - } else if (isalpha(line[0])) { // variable/func - uint32_t end = 1; - for (; isalnum(line[end]); end++); - if (!eot(line[end])) - return 0; - char *name = (char *)malloc(end + 1); - strncpy(name, line, end); - name[end] = '\0'; - *next = end; - return interpreter_get_variable(interp, name); - } else if (isdigit(line[0])) { // number - uint32_t end = 1; - uint8_t dec = 0; - for (; !eot(line[end]); end++) { - if (!isdigit(line[end])) { - if (line[end] == '.') { - if (!dec) - dec = 1; - else - return 0; - } else { - return 0; - } - } - } - variable *v = (variable *)malloc(sizeof(variable)); - v->used = 0; - if (dec) { - v->valtype = FLOAT; - FLOAT(v) = strtof(line, 0); - fsetstr(v); - } else { - v->valtype = INTEGER; - INT(v) = atoi(line); - isetstr(v); - } - *next = end; - return v; - } - return 0; -} - -int idoline(interpreter *interp, const char *line) -{ - variable *ops[8]; - uint32_t ooffset, offset, next; - - interp->lines[interp->lnidx] = strclone(line); -loop: - if (line[0] == '#') { - goto norun; - } else if (interp->indent > 0) { - if (!strcmp(line, "end")) - interp->indent--; - goto norun; - } - - ooffset = 0; - offset = 0; - - // step 1 - convert to tokens - while (!eol(line[offset])) { - ops[ooffset] = make_var(interp, line + offset, &next); - if (ops[ooffset] == 0) { - return -4; - } else { - ooffset++; - offset += next; - } - - // skip whitespace - for (; line[offset] == ' ' && !eol(line[offset]); offset++); - } - - // step 2 - execute - if (ooffset == 0) - return -1; - - if (ops[0]->valtype != FUNC) - return -2; - - if (ops[0]->value == 0) - return -3; - - for (uint32_t i = ooffset; --i > 0;) - ipush(interp, ops[i]); - - if (ops[0]->fromc) { - int ret = ((func_t)ops[0]->value)(interp); - if (ret != 0) - return ret; - } else { - ipush(interp, (void *)(interp->lnidx + 1)); - interp->lnidx = ops[0]->value; - } - - interp->stidx -= ooffset - 1; - - if ((int32_t)interp->stidx < 0) { - interp->stidx = 0; - return -5; - } - - for (uint32_t i = 0; i < ooffset; i++) { - if (!ops[i]->used) - free(ops[i]); - } - -norun: - interp->lnidx++; - if (interp->lines[interp->lnidx] != 0) { - line = interp->lines[interp->lnidx]; - goto loop; - } - - return 0; -} - -typedef void (*operation_t)(variable *, variable *, variable *); - -#define IOPS_COUNT 15 -static char *iops[IOPS_COUNT] = { - "+", "-", "*", "/", "&", "|", "^", ">>", "<<", - "==", "<", ">", "<=", ">=", "!=" -}; - -void iop_add(variable *, variable *, variable *); -void iop_sub(variable *, variable *, variable *); -void iop_mult(variable *, variable *, variable *); -void iop_div(variable *, variable *, variable *); -void iop_and(variable *, variable *, variable *); -void iop_or(variable *, variable *, variable *); -void iop_xor(variable *, variable *, variable *); -void iop_shr(variable *, variable *, variable *); -void iop_shl(variable *, variable *, variable *); -void iop_eq(variable *, variable *, variable *); -void iop_lt(variable *, variable *, variable *); -void iop_gt(variable *, variable *, variable *); -void iop_lte(variable *, variable *, variable *); -void iop_gte(variable *, variable *, variable *); -void iop_ne(variable *, variable *, variable *); - -static operation_t iopfuncs[IOPS_COUNT] = { - iop_add, iop_sub, iop_mult, iop_div, iop_and, - iop_or, iop_xor, iop_shr, iop_shl, - iop_eq, iop_lt, iop_gt, iop_lte, iop_gte, iop_ne -}; - -variable *idoexpr(interpreter *interp, const char *line) -{ - variable *result = (variable *)malloc(sizeof(variable)); - char *mline = line; - void *ops[16]; - uint32_t ooffset = 0; - uint32_t offset = 0; - uint32_t next; - - // step 1 - break apart line - - // skip whitespace - for (; line[offset] == ' ' && !eol(line[offset]); offset++); - while (!eoe(line[offset])) { - if (line[offset] == '(') { - uint8_t indent = 0; - uint32_t i; - for (i = offset + 1; !eol(line[i]); i++) { - if (line[i] == '(') { - indent++; - } else if (line[i] == ')') { - if (indent == 0) { - break; - } else { - indent--; - } - } - } - if (eol(line[i])) - return 0; - ops[ooffset] = idoexpr(interp, line + offset + 1); - offset = i + 1; - } else { - uint32_t end = offset; - char cend = 0; - if (line[offset] != '\"') { - for (; isalnum(line[end]) || line[end] == '.'; end++); - cend = line[end]; - mline[end] = ' '; - } - ops[ooffset] = make_var(interp, line + offset, &next); - if (end != 0) - mline[end] = cend; - } - if (ops[ooffset] == 0) - return 0; - - ooffset++; - offset += next; - - // skip whitespace - for (; line[offset] == ' ' && !eoe(line[offset]); offset++); - if (eoe(line[offset])) - break; - - for (uint32_t i = 0; i < IOPS_COUNT; i++) { - int len = strlen(iops[i]); - if (!strncmp(iops[i], line + offset, len)) { - ops[ooffset] = (void *)(i + 1); - offset += len; - break; - } - } - if (ops[ooffset] == 0) - return 0; - ooffset++; - - // skip whitespace - for (; line[offset] == ' ' && !eol(line[offset]); offset++); - } - - if (ooffset % 2 == 0) - return 0; - - // step 2 - do operations - result->valtype = ((variable *)ops[0])->valtype; - result->value = ((variable *)ops[0])->value; - for (uint32_t i = 1; i < ooffset; i += 2) { - iopfuncs[(uint32_t)ops[i] - 1](result, result, ops[i + 1]); - } - - for (uint32_t i = 0; i < ooffset; i += 2) { - if (!((variable *)ops[i])->used) - free(ops[i]); - } - - if (result->valtype == INTEGER) - isetstr(result); - else - fsetstr(result); - - return result; -} - -variable *igetarg(interpreter *interp, uint32_t index) -{ - return interp->stack[interp->stidx - index - 1]; -} - -char *igetarg_string(interpreter *interp, uint32_t index) -{ - if (index >= interp->stidx) - return 0; - variable *v = igetarg(interp, index); - return v->svalue; -} - -int igetarg_integer(interpreter *interp, uint32_t index) -{ - if (index >= interp->stidx) - return 0; - variable *v = igetarg(interp, index); - return INT(itoint(v)); -} - -float igetarg_float(interpreter *interp, uint32_t index) -{ - if (index >= interp->stidx) - return 0; - variable *v = igetarg(interp, index); - return FLOAT(itofloat(v)); -} - -variable *itostring(variable *v) -{ - switch (v->valtype) { - case INTEGER: - v->valtype = STRING; - isetstr(v); - break; - case FLOAT: - v->valtype = STRING; - fsetstr(v); - break; - } - return v; -} - -variable *itoint(variable *v) -{ - switch (v->valtype) { - case STRING: - v->valtype = INTEGER; - INT(v) = atoi(v->svalue); - isetstr(v); - break; - case FLOAT: - v->valtype = INTEGER; - INT(v) = (int32_t)FLOAT(v); - isetstr(v); - break; - } - return v; -} - -variable *itofloat(variable *v) -{ - switch (v->valtype) { - case STRING: - v->valtype = FLOAT; - FLOAT(v) = strtof(v->svalue, 0); - fsetstr(v); - break; - case INTEGER: - v->valtype = FLOAT; - FLOAT(v) = (float)INT(v); - fsetstr(v); - break; - } - return v; -} - -/** - * Builtin functions - */ - -int ifunc_set(interpreter *it) -{ - variable *n = igetarg(it, 0); - variable *v = igetarg(it, 1); - - if (n == 0) - return -1; - - n->valtype = v->valtype; - n->value = v->value; - n->svalue = v->svalue; - return 0; -} - -int ifunc_label(interpreter *it) -{ - variable *n = igetarg(it, 0); - - if (n == 0) - return -1; - - n->valtype = FUNC; - n->value = it->lnidx; - n->svalue = str_func; - it->indent++; - return 0; -} - -int ifunc_end(interpreter *it) -{ - if (it->stidx > 0) { - uint32_t line = (uint32_t)ipop(it); - it->lnidx = line - 1; - } - return 0; -} - -int ifunc_jmp(interpreter *it) -{ - int newidx = igetarg_integer(it, 0); - ipop(it); - ipush(it, (void *)(it->lnidx + 1)); - ipush(it, 0); - it->lnidx = newidx - 1; - return 0; -} - -/** - * Builtin operations - */ - -void iop_add(variable *r, variable *a, variable *b) -{ - if (a->valtype == INTEGER && b->valtype == INTEGER) { - INT(r) = INT(a) + INT(b); - } else { - itofloat(a); - itofloat(b); - FLOAT(r) = FLOAT(a) + FLOAT(b); - } -} - -void iop_sub(variable *r, variable *a, variable *b) -{ - if (a->valtype == INTEGER && b->valtype == INTEGER) { - INT(r) = INT(a) - INT(b); - } else { - itofloat(a); - itofloat(b); - FLOAT(r) = FLOAT(a) - FLOAT(b); - } -} - -void iop_mult(variable *r, variable *a, variable *b) -{ - if (a->valtype == INTEGER && b->valtype == INTEGER) { - INT(r) = INT(a) * INT(b); - } else { - itofloat(a); - itofloat(b); - FLOAT(r) = FLOAT(a) * FLOAT(b); - } -} - -void iop_div(variable *r, variable *a, variable *b) -{ - if (a->valtype == INTEGER && b->valtype == INTEGER) { - INT(r) = INT(a) / INT(b); - } else { - itofloat(a); - itofloat(b); - FLOAT(r) = FLOAT(a) / FLOAT(b); - } -} - -void iop_and(variable *r, variable *a, variable *b) -{ - if (a->valtype == INTEGER && b->valtype == INTEGER) { - INT(r) = INT(a) & INT(b); - } -} - -void iop_or(variable *r, variable *a, variable *b) -{ - if (a->valtype == INTEGER && b->valtype == INTEGER) { - INT(r) = INT(a) | INT(b); - } -} - -void iop_xor(variable *r, variable *a, variable *b) -{ - if (a->valtype == INTEGER && b->valtype == INTEGER) { - INT(r) = INT(a) ^ INT(b); - } -} - -void iop_shr(variable *r, variable *a, variable *b) -{ - if (a->valtype == INTEGER && b->valtype == INTEGER) { - INT(r) = INT(a) >> INT(b); - } -} - -void iop_shl(variable *r, variable *a, variable *b) -{ - if (a->valtype == INTEGER && b->valtype == INTEGER) { - INT(r) = INT(a) << INT(b); - } -} - -void iop_eq(variable *r, variable *a, variable *b) -{ - if (a->valtype == INTEGER && b->valtype == INTEGER) - INT(r) = INT(a) == INT(b); - else - INT(r) = FLOAT(a) == FLOAT(b); -} - -void iop_lt(variable *r, variable *a, variable *b) -{ - if (a->valtype == INTEGER && b->valtype == INTEGER) - INT(r) = INT(a) < INT(b); - else - INT(r) = FLOAT(a) < FLOAT(b); -} - -void iop_gt(variable *r, variable *a, variable *b) -{ - if (a->valtype == INTEGER && b->valtype == INTEGER) - INT(r) = INT(a) > INT(b); - else - INT(r) = FLOAT(a) > FLOAT(b); -} - -void iop_lte(variable *r, variable *a, variable *b) -{ - if (a->valtype == INTEGER && b->valtype == INTEGER) - INT(r) = INT(a) <= INT(b); - else - INT(r) = FLOAT(a) <= FLOAT(b); -} - -void iop_gte(variable *r, variable *a, variable *b) -{ - if (a->valtype == INTEGER && b->valtype == INTEGER) - INT(r) = INT(a) >= INT(b); - else - INT(r) = FLOAT(a) >= FLOAT(b); -} - -void iop_ne(variable *r, variable *a, variable *b) -{ - if (a->valtype == INTEGER && b->valtype == INTEGER) - INT(r) = INT(a) != INT(b); - else - INT(r) = FLOAT(a) != FLOAT(b); -} - diff --git a/src/startup_stm32l476xx.s b/src/startup_stm32l476xx.s index 340d080..f7e18a4 100644 --- a/src/startup_stm32l476xx.s +++ b/src/startup_stm32l476xx.s @@ -62,7 +62,7 @@ defined in linker script */ /* end address for the .bss section. defined in linker script */ .word _ebss -//.equ BootRAM, 0xF1E0F85F +.equ BootRAM, 0xF1E0F85F /** * @brief This is the code that gets called when the processor first * starts execution following a reset event. Only the absolutely diff --git a/src/stdlib.c b/src/stdlib.c index 1832033..3f11d57 100644 --- a/src/stdlib.c +++ b/src/stdlib.c @@ -1,44 +1,6 @@ -#include -#include -#include - -#include - -extern char *itoa(int, char *, int); - void _exit(int code) { (void)code; for (;;); } -int ksnprintf(char *buf, unsigned int count, const char *format, ...) -{ - (void)count; - - va_list args; - va_start(args, format); - - unsigned int i = 0, o = 0; - while (o < count && format[i] != '\0') { - if (format[i] == '%') { - if (format[i + 1] == 'd') { - char *s = itoa(va_arg(args, int), malloc(16), 10); - strncpy(buf + o, s, count - o); - o += strlen(s); - free(s); - } else if (format[i + 1] == 'f') { - strncpy(buf + o, "float", count - o); - o += 5; - } - i++; - } else { - buf[o++] = format[i]; - } - - i++; - } - - return o; -} - diff --git a/src/task.c b/src/task.c index 1685bb9..71c829c 100644 --- a/src/task.c +++ b/src/task.c @@ -1,5 +1,5 @@ #include -#include +#include #include typedef struct { @@ -21,7 +21,7 @@ void task_init(void (*init)(void)) for (int i = 0; i < MAX_TASKS; i++) tasks[i].use = 0; - task_start(init, 1024); + task_start(init, 4096); asm("\ msr psp, %0; \ mrs r0, control; \