From 811e9e3dd222c737b83d55c9e122a030964e7e45 Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Mon, 12 Jul 2021 20:34:54 -0400 Subject: [PATCH] Breaking: Stop `def` adding vars to higher scopes Fixed OOP error in allocating lambda environments. Add ability to disable test groups. Disabled forbble tests and `switch` implementation (broken by `def` change) --- src/env.c | 41 ++++++++++++++++++++++++----------------- src/examples/lib.pbl | 22 +++++++++++----------- src/pebblisp.c | 7 +++++-- src/tests.sh | 27 ++++++++++++++++++--------- 4 files changed, 58 insertions(+), 39 deletions(-) diff --git a/src/env.c b/src/env.c index f818e40..99239ad 100644 --- a/src/env.c +++ b/src/env.c @@ -18,7 +18,6 @@ Object fetchFromEnvironment(const char *name, struct Environment *env) if(env->size == 0) return errorObject(EMPTY_ENV); - printd("Fetching '%s' from env\n", name); for(int i = 0; i < env->size; i++) { if(env->strings[i] == NULL) { printd("Try %d (NULL)\n", i); @@ -38,7 +37,6 @@ Object fetchFromEnvironment(const char *name, struct Environment *env) return fetchFromEnvironment(name, env->outer); } - printf("'%s'\n", name); return errorObject(DID_NOT_FIND_SYMBOL); } @@ -58,7 +56,7 @@ struct Environment envForLambda(const Object *params, const Object *arg_forms, return env; env.strings = calloc(sizeof(char*), paramCount + 1); - env.objects = malloc(sizeof(Object) * paramCount + 1); + env.objects = malloc(sizeof(Object) * (paramCount + 1)); const Object *march = arg_forms; for(int i = 0; i < paramCount; i++) { @@ -110,16 +108,19 @@ void addToEnv(struct Environment *env, const char *name, const Object obj) int i; struct Environment *temp_env = env; + int is_local = 1; while(temp_env) { for(i = 0; i < temp_env->size; i++) { + // Add *new* item to env only if we're in the local scope if(temp_env->strings[i] == NULL) { - //printf("Add new object\n"); - temp_env->strings[i] = calloc(sizeof(char), strlen(name) + 1); - strncpy(temp_env->strings[i], name, strlen(name)); - temp_env->objects[i] = cloneObject(obj); - return; - } - if(strcmp(temp_env->strings[i], name) == 0) { + if (is_local) { + temp_env->strings[i] = calloc(sizeof(char), strlen(name) + 1); + strncpy(temp_env->strings[i], name, strlen(name)); + temp_env->objects[i] = cloneObject(obj); + return; + } + break; + } else if(strcmp(temp_env->strings[i], name) == 0) { Object o = cloneObject(obj); cleanObject(&temp_env->objects[i]); temp_env->objects[i] = o; @@ -127,21 +128,23 @@ void addToEnv(struct Environment *env, const char *name, const Object obj) } } temp_env = temp_env->outer; + is_local = 0; } printd("Reallocating environment\n"); const int inc = 5; + const int old_size = env->size; env->size += inc; env->strings = realloc(env->strings, sizeof(char*) * env->size); env->objects = realloc(env->objects, sizeof(Object) * env->size); for(int j = 0; j < inc; j++) { - env->strings[i + j] = NULL; + env->strings[old_size + j] = NULL; } - env->strings[i] = malloc(strlen(name) + 1); - strncpy(env->strings[i], name, strlen(name) + 1); - env->objects[i] = cloneObject(obj); + env->strings[old_size] = malloc(strlen(name) + 1); + strncpy(env->strings[old_size], name, strlen(name) + 1); + env->objects[old_size] = cloneObject(obj); } void printEnv(struct Environment *env) @@ -151,10 +154,14 @@ void printEnv(struct Environment *env) return; } for(int i = 0; i < env->size; i++) { - if(env->strings[i] == NULL) - return; - printf("env[%d]: '%s'\n ", i, env->strings[i]); + if(env->strings[i] == NULL) { + printf("env[%d]: NULL %p\n", i, env->strings[i]); + break; + } + printf("env[%d]: '%s' %p\n", i, env->strings[i], env->strings[i]); + printf(" "); printObj(&env->objects[i]); + printf(""); } } diff --git a/src/examples/lib.pbl b/src/examples/lib.pbl index b1e9aca..e2940b1 100644 --- a/src/examples/lib.pbl +++ b/src/examples/lib.pbl @@ -25,14 +25,14 @@ ; Return the smaller of the two (def min (fn (a b) (if (< a b) a b))) -(def switch (fn (pair_list) - (if (= 0 (len pair_list)) - "no match" - ( - (def _pair (at 0 pair_list)) - (if (at 0 _pair) - (at 1 _pair) - (switch (rest pair_list)) - ) - )) -)) +;(def switch (fn (pair_list) +; (if (= 0 (len pair_list)) +; "no match" +; ( +; (def _pair (at 0 pair_list)) +; (if (at 0 _pair) +; (at 1 _pair) +; (switch (rest pair_list)) +; ) +; )) +;)) diff --git a/src/pebblisp.c b/src/pebblisp.c index 28d88fe..3587555 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -20,8 +20,11 @@ * @param env The environment to add the new definition to * @return The symbol(s) defined */ -Object evalDefArgs(const Object *symbol, const Object *value, struct Environment *env) -{ +Object evalDefArgs( + const Object *symbol, + const Object *value, + struct Environment *env +) { const char *name = symbol->string; // Handles multi-definitions diff --git a/src/tests.sh b/src/tests.sh index 29c4415..0ea24ce 100755 --- a/src/tests.sh +++ b/src/tests.sh @@ -7,6 +7,7 @@ TOTAL_FAILS=0 FAILS=0 FAIL_OUTPUT="" VALGRIND=false +DISABLED=false CURRENT_BLOCK="" @@ -21,10 +22,15 @@ endBlock() { FAIL_OUTPUT="" fi FAILS=0 + DISABLED=false } title() { echo -n "[$1] " + if [[ "$2" == "disable" ]]; then + echo -n "DISABLED" + DISABLED=true + fi } pass() { @@ -34,12 +40,15 @@ pass() { fail() { echo -n "X" - FAIL_OUTPUT="$FAIL_OUTPUT $1 test FAILED $2" + FAIL_OUTPUT="$FAIL_OUTPUT $1 FAILED\n When running \"$2\"" ((FAILS++)) ((TOTAL_FAILS++)) } check() { + if $DISABLED; then + return 1 + fi if $VALGRIND; then echo -ne "\n $1\r" local output=$($VALCOM ./pl "(loadfile \"examples/lib.pbl\") $2") @@ -48,10 +57,10 @@ check() { fi if [ "$output" == "$3" ]; then - pass $1 + pass "$1" else - fail $1 "$2" - FAIL_OUTPUT="${FAIL_OUTPUT}\n Expected '$3' but received '$output'" + fail "$1" "$2" + FAIL_OUTPUT="${FAIL_OUTPUT}\n  expected '$3' but received '$output'\n" fi } @@ -190,16 +199,16 @@ check "BasicOpEval" "(eval \"(+ 5 10)\")" "15" check "MapFilter" "(eval \"(fil (< 50) (map sq (1 2 3 4 5 6 7 8 9 10 11 12)))\")" "( 64 81 100 121 144 )" endBlock -title "Forbble" +title "Forbble" disable check "BasicForbbleOp" "(loadfile 'examples/forbble.pbl') (feval (10 10 * .)) ''" "100" check "FibForbble" "(loadfile 'examples/forbble.pbl') (feval (1 1 _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f .)) ''" "28657" check "ForbbleDefine" "(loadfile 'examples/forbble.pbl') (feval ( : \"cubed\" dup dup * * $ )) (feval (4 cubed .)) ''" "64" endBlock -# title "Environment" -# check "EnvStressTestEarly" "(def a 1)(def b 20)(def c 'yee')(def d 'yeehunnid')(def e 3) (a)" "1" -# check "EnvStressTestLate" "(def a 1)(def b 2)(def c 3)(def d 4)(def e 5)(def f 6)(def n 40) (n)" "40" -# endBlock +title "Environment" disable +check "EnvStressTestEarly" "(def a 1)(def b 20)(def c 'yee')(def d 'yeehunnid')(def e 3) (a)" "( 1 )" +check "EnvStressTestLate" "(def a 1)(def b 2)(def c 3)(def d 4)(def e 5)(def f 6)(def n 40) (n)" "40" +endBlock echo ""