Added while, and other fixes.

This commit is contained in:
antirez 2022-12-21 21:32:48 +01:00
parent 68e6076719
commit 16c99cf2a0
2 changed files with 29 additions and 19 deletions

View file

@ -1,7 +1,10 @@
all: aocla all: aocla
SANITIZE=-fsanitize=address
aocla: aocla.c aocla: aocla.c
$(CC) -g -ggdb aocla.c -Wall -W -pedantic -O2 -o aocla $(CC) -g -ggdb aocla.c -Wall -W -pedantic -O2 \
$(SANITIZE) -o aocla
clean: clean:
rm -rf aocla *.dSYM rm -rf aocla *.dSYM

43
aocla.c
View file

@ -496,7 +496,7 @@ aoclactx *newInterpreter(void) {
i->stacklen = 0; i->stacklen = 0;
i->stack = NULL; /* Will be allocated on push of new elements. */ i->stack = NULL; /* Will be allocated on push of new elements. */
i->proc = NULL; /* That's a linked list. Starts empty. */ i->proc = NULL; /* That's a linked list. Starts empty. */
i->frame = newStackFrame(i); i->frame = newStackFrame(NULL);
loadLibrary(i); loadLibrary(i);
return i; return i;
} }
@ -778,9 +778,11 @@ int procDef(aoclactx *ctx) {
return 0; return 0;
} }
/* if and ifelse. */ /* if, ifelse, while. */
int procIf(aoclactx *ctx) { int procIf(aoclactx *ctx) {
int e = ctx->frame->curproc->name[2] == 'e'; /* ifelse? */ int w = ctx->frame->curproc->name[0] == 'w'; /* while? */
int e = ctx->frame->curproc->name[2] == 'e'; /* ifelse? */
int retval = 1;
if (e) { if (e) {
if (checkStackType(ctx,3,OBJ_TYPE_LIST,OBJ_TYPE_LIST,OBJ_TYPE_LIST)) if (checkStackType(ctx,3,OBJ_TYPE_LIST,OBJ_TYPE_LIST,OBJ_TYPE_LIST))
return 1; return 1;
@ -794,27 +796,31 @@ int procIf(aoclactx *ctx) {
ifbranch = stackPop(ctx); ifbranch = stackPop(ctx);
cond = stackPop(ctx); cond = stackPop(ctx);
/* Evaluate the conditional program. */ while(w) {
if (eval(ctx,cond)) goto rterr; /* Evaluate the conditional program. */
if (checkStackType(ctx,1,OBJ_TYPE_BOOL)) goto rterr; if (eval(ctx,cond)) goto rterr;
obj *condres = stackPop(ctx); if (checkStackType(ctx,1,OBJ_TYPE_BOOL)) goto rterr;
int res = condres->istrue; obj *condres = stackPop(ctx);
release(condres); int res = condres->istrue;
release(condres);
/* Now eval the true or false branch depending on the /* Now eval the true or false branch depending on the
* result. */ * result. */
if (res) { if (res) {
if (eval(ctx,ifbranch)) goto rterr; if (eval(ctx,ifbranch)) goto rterr;
} else if (e) { } else if (e) {
if (eval(ctx,elsebranch)) goto rterr; if (eval(ctx,elsebranch)) goto rterr;
} else if (w) {
break; /* If while condition is false, break the loop. */
}
} }
return 0; retval = 0; /* Success. */
rterr: /* Run time error. */ rterr: /* Cleanup. We jump here on error with retval = 1. */
release(cond); release(cond);
release(ifbranch); release(ifbranch);
release(elsebranch); release(elsebranch);
return 1; return retval;
} }
/* Evaluate the given list. */ /* Evaluate the given list. */
@ -850,6 +856,7 @@ void loadLibrary(aoclactx *ctx) {
addProc(ctx,"def",procDef,NULL); addProc(ctx,"def",procDef,NULL);
addProc(ctx,"if",procIf,NULL); addProc(ctx,"if",procIf,NULL);
addProc(ctx,"ifelse",procIf,NULL); addProc(ctx,"ifelse",procIf,NULL);
addProc(ctx,"while",procIf,NULL);
addProc(ctx,"eval",procEval,NULL); addProc(ctx,"eval",procEval,NULL);
addProc(ctx,"print",procPrint,NULL); addProc(ctx,"print",procPrint,NULL);
addProcString(ctx,"dup","[(x) $x $x]"); addProcString(ctx,"dup","[(x) $x $x]");