many bug fixes, minimizing memory/leaks

master
Clyne Sullivan 7 years ago
parent 1fd930598e
commit 3fc57ae22f

@ -1,4 +1,4 @@
CFLAGS = -ggdb CFLAGS = -ggdb -fsigned-char -fno-builtin -Wall -Wextra -Werror -pedantic
CFILES = $(wildcard *.c) CFILES = $(wildcard *.c)
all: all:
@ -6,8 +6,6 @@ all:
@gcc -m32 $(CFLAGS) $(CFILES) -o shell @gcc -m32 $(CFLAGS) $(CFILES) -o shell
arm: arm:
@mv shell.c shell.c.bak
@arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 $(CFLAGS) -c *.c @arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 $(CFLAGS) -c *.c
@arm-none-eabi-ar r libinterp.a *.o @arm-none-eabi-ar r libinterp.a *.o
@mv shell.c.bak shell.c
@rm *.o @rm *.o

@ -68,7 +68,7 @@ int bn_end(instance *it)
if_cond = ipop(it); if_cond = ipop(it);
} else if (sig == WHILE_SIG) { } else if (sig == WHILE_SIG) {
uint32_t lnidx = ipop(it); uint32_t lnidx = ipop(it);
if (lnidx != (int32_t)-1) if (lnidx != (uint32_t)-1)
it->lnidx = lnidx - 1; it->lnidx = lnidx - 1;
} else if (sig == CALL_SIG) { } else if (sig == CALL_SIG) {
it->lnidx = ipop(it); it->lnidx = ipop(it);

@ -12,6 +12,30 @@
#define MAX_STACK 64 #define MAX_STACK 64
#define MAX_LINES 1000 #define MAX_LINES 1000
int bracket_open(instance *it)
{
it->indent++;
if (it->sindent & SKIP) {
ipush(it, SKIP_SIG);
ipush(it, 0);
}
return 0;
}
int bracket_close(instance *it)
{
it->indent--;
if (it->indent < (it->sindent & ~(SKIP)))
it->sindent = 0;
bn_end(it);
return 0;
}
static variable bopen = {
0, CFUNC, 0, {.p = (uint32_t)bracket_open}
};
static variable bclose = {
0, CFUNC, 0, {.p = (uint32_t)bracket_close}
};
char *strnclone(const char *s, size_t c) char *strnclone(const char *s, size_t c)
{ {
char *b = strncpy((char *)malloc(c + 1), s, c); char *b = strncpy((char *)malloc(c + 1), s, c);
@ -55,7 +79,7 @@ instance *inewinstance(void)
it->names = (char **)calloc(MAX_VARS, sizeof(char *)); it->names = (char **)calloc(MAX_VARS, sizeof(char *));
it->stack = (uint32_t *)malloc(MAX_STACK * sizeof(uint32_t)); it->stack = (uint32_t *)malloc(MAX_STACK * sizeof(uint32_t));
it->stidx = 0; it->stidx = 0;
it->lines = (char **)calloc(MAX_LINES, sizeof(char *)); it->lines = (variable ***)calloc(MAX_LINES, sizeof(variable **));
it->lnidx = 0; it->lnidx = 0;
it->ret = 0; it->ret = 0;
it->indent = 0; it->indent = 0;
@ -72,7 +96,7 @@ void idelinstance(instance *it)
free(it->names[i]); free(it->names[i]);
free(it->names); free(it->names);
free(it->stack); free(it->stack);
for (uint32_t i = 0; i < MAX_VARS; i++) for (uint32_t i = 0; i < MAX_LINES; i++) // TODO free vars!
free(it->lines[i]); free(it->lines[i]);
free(it->lines); free(it->lines);
itryfree(it->ret); itryfree(it->ret);
@ -189,7 +213,7 @@ variable *make_num(const char *text)
return v; return v;
} }
variable *igetop(instance *it, const char *name) variable *igetop(const char *name)
{ {
for (uint32_t i = 0; i < OPS_COUNT; i++) { for (uint32_t i = 0; i < OPS_COUNT; i++) {
if (opnames[i] != 0 && !strcmp(name, opnames[i])) { if (opnames[i] != 0 && !strcmp(name, opnames[i])) {
@ -212,26 +236,27 @@ variable *igetvar(instance *it, const char *name)
} }
} }
return igetop(it, name); return igetop(name);
} }
int idoline(instance *it, const char *s) int idoline(instance *it, const char *s)
{ {
it->lines[it->lnidx] = strclone(s); variable **ops = iparse(it, s);
variable **ops; if (ops == 0)
loop: return 0;
ops = iparse(it, it->lines[it->lnidx]); it->lines[it->lnidx] = ops;
loop:
if (it->ret != 0) if (it->ret != 0)
itryfree(it->ret); itryfree(it->ret);
it->ret = 0; it->ret = 0;
if (ops == 0) variable **copy = malloc(32 * sizeof(variable *));
goto next; for (int i = 0; i < 32; i++)
it->ret = isolve(it, ops, 0); copy[i] = it->lines[it->lnidx][i];
it->ret = isolve(it, copy, 0);
free(copy);
next:
free(ops);
it->lnidx++; it->lnidx++;
if (it->lines[it->lnidx] != 0) if (it->lines[it->lnidx] != 0)
goto loop; goto loop;
@ -264,9 +289,11 @@ variable *isolve_(instance *it, variable **ops, uint32_t count)
if (ops[i] == 0) if (ops[i] == 0)
continue; continue;
if (ops[i]->type == CFUNC || ops[i]->type == FUNC) { if (ops[i]->type == CFUNC || ops[i]->type == FUNC) {
uint32_t nargs = (uint32_t)ops[i + 1]; uint32_t nargs = (uint32_t)ops[i + 1] - 1;
uint32_t start = i; uint32_t start = i;
i += 2; i++;
if (nargs > 0)
i++;
int32_t j; int32_t j;
for (j = nargs; j > 0 && i < count; i++) { for (j = nargs; j > 0 && i < count; i++) {
if (ops[i] != 0) { if (ops[i] != 0) {
@ -274,7 +301,8 @@ variable *isolve_(instance *it, variable **ops, uint32_t count)
it->stack[it->stidx + j - 1] = (uint32_t)ops[i]; it->stack[it->stidx + j - 1] = (uint32_t)ops[i];
} else { } else {
char namebuf[6]; char namebuf[6];
snprintf(namebuf, 6, "arg%d", nargs - j); snprintf(namebuf, 6, "arg%u",
(uint16_t)(nargs - j));
if (ops[i]->type == NUMBER) if (ops[i]->type == NUMBER)
inew_number(it, namebuf, ops[i]->value.f); inew_number(it, namebuf, ops[i]->value.f);
else else
@ -293,7 +321,8 @@ variable *isolve_(instance *it, variable **ops, uint32_t count)
uint32_t sidx = it->stidx; uint32_t sidx = it->stidx;
int ret = 0; int ret = 0;
if (!(it->sindent & SKIP)) if (!(it->sindent & SKIP) || (func == bracket_open ||
func == bracket_close))
ret = func(it); ret = func(it);
if (ret != 0) if (ret != 0)
return 0; return 0;
@ -301,7 +330,8 @@ variable *isolve_(instance *it, variable **ops, uint32_t count)
ops[start] = (variable *)ipop(it); ops[start] = (variable *)ipop(it);
else else
ops[start] = 0; ops[start] = 0;
ipopm(it, nargs);
it->stidx -= nargs;
} else { } else {
ipush(it, it->lnidx); ipush(it, it->lnidx);
ipush(it, CALL_SIG); ipush(it, CALL_SIG);
@ -310,7 +340,7 @@ variable *isolve_(instance *it, variable **ops, uint32_t count)
ops[start + 1] = 0; ops[start + 1] = 0;
for (uint32_t j = start + 2; j < i; j++) { for (uint32_t j = start + 2; j < i; j++) {
itryfree(ops[j]); //itryfree(ops[j]);
ops[j] = 0; ops[j] = 0;
} }
} }
@ -339,16 +369,16 @@ variable *isolve_(instance *it, variable **ops, uint32_t count)
return 0; return 0;
if (it->sindent & SKIP) { if (it->sindent & SKIP) {
itryfree(ops[aidx]); //itryfree(ops[aidx]);
itryfree(ops[bidx]); //itryfree(ops[bidx]);
ops[aidx] = 0; ops[aidx] = 0;
} else { } else {
variable *v = varclone(ops[aidx]); variable *v = varclone(ops[aidx]);
if (func(v, ops[aidx], ops[bidx]) != 0) if (func(v, ops[aidx], ops[bidx]) != 0)
return 0; return 0;
itryfree(ops[aidx]); //itryfree(ops[aidx]);
ops[aidx] = v; ops[aidx] = v;
itryfree(ops[bidx]); //itryfree(ops[bidx]);
} }
ops[i] = 0; ops[i] = 0;
ops[bidx] = 0; ops[bidx] = 0;
@ -362,6 +392,7 @@ variable *isolve_(instance *it, variable **ops, uint32_t count)
variable **iparse(instance *it, const char *s) variable **iparse(instance *it, const char *s)
{ {
uint32_t ooffset = 0; uint32_t ooffset = 0;
int32_t boffset = 1;
size_t offset = 0; size_t offset = 0;
while (isblank(s[offset])) while (isblank(s[offset]))
@ -382,10 +413,11 @@ variable **iparse(instance *it, const char *s)
end++; end++;
if (s[end] == '(') { if (s[end] == '(') {
uint32_t argidx = ooffset; uint32_t argidx = ooffset;
uint32_t argcount = 0; uint32_t argcount = 1;
ooffset++; ooffset++;
end++; end++;
for (int last = end, c = 0; c >= 0; end++) { uint32_t last = end;
for (int c = 0; c >= 0; end++) {
if (s[end] == '(') if (s[end] == '(')
c++; c++;
if (c == 0 && last != end && (s[end] == ',' || s[end] == ')')) { if (c == 0 && last != end && (s[end] == ',' || s[end] == ')')) {
@ -410,6 +442,8 @@ variable **iparse(instance *it, const char *s)
if (s[end] != '\0') if (s[end] != '\0')
end++; end++;
ops[argidx] = (variable *)argcount; ops[argidx] = (variable *)argcount;
} else if (ops[ooffset - 1]->type == FUNC || ops[ooffset - 1]->type == CFUNC) {
ops[ooffset++] = (variable *)1;
} }
offset = end; offset = end;
} else if (isdigit(s[offset])) { } else if (isdigit(s[offset])) {
@ -453,22 +487,23 @@ variable **iparse(instance *it, const char *s)
offset = i; offset = i;
} else if (!isblank(s[offset])) { } else if (!isblank(s[offset])) {
size_t end = offset + 1; size_t end = offset + 1;
while (!isblank(s[end]) && s[end] != '\0') while (!isblank(s[end]) && !isalnum(s[end]) && s[end] != '\0')
end++; end++;
char *word = strnclone(s + offset, end - offset); char *word = strnclone(s + offset, end - offset);
// bracket? // bracket?
if (!strcmp(word, "{")) { if (!strcmp(word, "{") || !strcmp(word, "}")) {
it->indent++; for (int32_t i = ooffset - 1; i >= boffset - 1; i--)
if (it->sindent & SKIP) ops[i + 2] = ops[i];
ipush(it, SKIP_SIG); if (word[0] == '{')
} else if (!strcmp(word, "}")) { ops[boffset - 1] = &bopen;
it->indent--; else
if (it->indent < (it->sindent & ~(SKIP))) ops[boffset - 1] = &bclose;
it->sindent = 0; ops[boffset] = (variable *)1; // arg count + 1
bn_end(it); boffset += 2;
ooffset += 2;
} else { } else {
variable *v = igetop(it, word); variable *v = igetop(word);
if (v == 0) if (v == 0)
return 0; return 0;
ops[ooffset++] = v; ops[ooffset++] = v;

@ -10,7 +10,7 @@ typedef struct {
char **names; char **names;
uint32_t *stack; uint32_t *stack;
uint32_t stidx; uint32_t stidx;
char **lines; variable ***lines;
uint32_t lnidx; uint32_t lnidx;
variable *ret; variable *ret;
uint8_t indent; uint8_t indent;

Loading…
Cancel
Save